FIRE-17318: Add option to use legacy notification well window (simple list view)

master
Ansariel 2015-11-19 21:32:47 +01:00
parent 28d861d982
commit d7282efb6f
11 changed files with 352 additions and 7 deletions

View File

@ -23712,6 +23712,30 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>FSLegacyNotificationWell</key>
<map>
<key>Comment</key>
<string>Enables the legacy notifications and system messages well</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSInternalLegacyNotificationWell</key>
<map>
<key>Comment</key>
<string>Internal state of FSLegacyNotificationWell</string>
<key>Persist</key>
<integer>0</integer>
<key>HideFromEditor</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
</map>
</llsd>

View File

@ -1036,6 +1036,9 @@ bool LLAppViewer::init()
settings_map["floater"] = &gSavedSettings; // *TODO: New settings file
settings_map["account"] = &gSavedPerAccountSettings;
// <FS:Ansariel> Optional legacy notification well
gSavedSettings.setBOOL("FSInternalLegacyNotificationWell", gSavedSettings.getBOOL("FSLegacyNotificationWell"));
LLUI::initClass(settings_map,
LLUIImageList::getInstance(),
ui_audio_callback,

View File

@ -150,7 +150,17 @@ void LLChannelManager::onLoginCompleted()
S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
mStartUpChannel->setMouseDownCallback(boost::bind(&LLFloaterNotificationsTabbed::onStartUpToastClick, LLFloaterNotificationsTabbed::getInstance(), _2, _3, _4));
// <FS:Ansariel> Optional legacy notification well
//mStartUpChannel->setMouseDownCallback(boost::bind(&LLFloaterNotificationsTabbed::onStartUpToastClick, LLFloaterNotificationsTabbed::getInstance(), _2, _3, _4));
if (!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell"))
{
mStartUpChannel->setMouseDownCallback(boost::bind(&LLFloaterNotificationsTabbed::onStartUpToastClick, LLFloaterNotificationsTabbed::getInstance(), _2, _3, _4));
}
else
{
mStartUpChannel->setMouseDownCallback(boost::bind(&LLNotificationWellWindow::onStartUpToastClick, LLNotificationWellWindow::getInstance(), _2, _3, _4));
}
// </FS:Ansariel>
mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime"));

View File

@ -313,7 +313,16 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p)
mNotificationChannel.reset(new ChicletNotificationChannel(this));
// ensure that notification well window exists, to synchronously
// handle toast add/delete events.
LLFloaterNotificationsTabbed::getInstance()->setSysWellChiclet(this);
// <FS:Ansariel> Optional legacy notification well
//LLFloaterNotificationsTabbed::getInstance()->setSysWellChiclet(this);
if (!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell"))
{
LLFloaterNotificationsTabbed::getInstance()->setSysWellChiclet(this);
}
else
{
LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
}
}
void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
@ -321,7 +330,16 @@ void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
std::string action = user_data.asString();
if("close all" == action)
{
LLFloaterNotificationsTabbed::getInstance()->closeAll();
// <FS:Ansariel> Optional legacy notification well
//LLFloaterNotificationsTabbed::getInstance()->closeAll();
if (!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell"))
{
LLFloaterNotificationsTabbed::getInstance()->closeAll();
}
else
{
LLNotificationWellWindow::getInstance()->closeAll();
}
// <FS:Ansariel> [FS communication UI] - We have our own IM well button again
//LLIMWellWindow::getInstance()->closeAll();
}
@ -374,7 +392,11 @@ bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNo
if ( (notification->getName() == "ScriptDialog") // special case for scripts
// if there is no toast window for the notification, filter it
//|| (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID()))
|| (!LLFloaterNotificationsTabbed::getInstance()->findItemByID(notification->getID(), notification->getName()))
// <FS:Ansariel> Optional legacy notification well
//|| (!LLFloaterNotificationsTabbed::getInstance()->findItemByID(notification->getID(), notification->getName()))
|| ((!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell") && !LLFloaterNotificationsTabbed::getInstance()->findItemByID(notification->getID(), notification->getName()))
|| (gSavedSettings.getBOOL("FSInternalLegacyNotificationWell") && !LLNotificationWellWindow::getInstance()->findItemByID(notification->getID())))
// </FS:Ansariel>
)
{
displayNotification = false;

View File

@ -150,7 +150,17 @@ BOOL LLChicletBar::postBuild()
// <FS:Ansariel> [FS communication UI]
showWellButton("im_well", !LLIMWellWindow::getInstance()->isWindowEmpty());
showWellButton("notification_well", !LLFloaterNotificationsTabbed::getInstance()->isWindowEmpty());
// <FS:Ansariel> Optional legacy notification well
//showWellButton("notification_well", !LLFloaterNotificationsTabbed::getInstance()->isWindowEmpty());
if (!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell"))
{
showWellButton("notification_well", !LLFloaterNotificationsTabbed::getInstance()->isWindowEmpty());
}
else
{
showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty());
}
// </FS:Ansariel>
LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
LLPanelTopInfoBar::instance().setVisibleCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));

View File

@ -604,7 +604,7 @@ bool idle_startup()
gSavedSettings.setString("FSInternalSkinCurrent", gSavedSettings.getString("FSSkinCurrentReadableName"));
gSavedSettings.setString("FSInternalSkinCurrentTheme", gSavedSettings.getString("FSSkinCurrentThemeReadableName"));
// </FS:Ansariel>
if (LLFeatureManager::getInstance()->isSafe())
{
LLNotificationsUtil::add("DisplaySetToSafe");

View File

@ -438,6 +438,186 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas
return mChiclet->handleRightMouseDown(x, y, mask);
}
// <FS:Ansariel> Optional legacy notification well
/************************************************************************/
/* LLNotificationWellWindow implementation */
/************************************************************************/
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window)
: LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())),
mWellWindow(well_window)
{
connectToChannel("Notifications");
connectToChannel("Group Notifications");
connectToChannel("Offer");
}
LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key)
: LLSysWellWindow(key)
{
mNotificationUpdates.reset(new WellNotificationChannel(this));
mUpdateLocked = false;
}
// static
LLNotificationWellWindow* LLNotificationWellWindow::getInstance(const LLSD& key /*= LLSD()*/)
{
return LLFloaterReg::getTypedInstance<LLNotificationWellWindow>("notification_well_window", key);
}
// virtual
BOOL LLNotificationWellWindow::postBuild()
{
BOOL rv = LLSysWellWindow::postBuild();
setTitle(getString("title_notification_well_window"));
return rv;
}
// virtual
void LLNotificationWellWindow::setVisible(BOOL visible)
{
if (visible)
{
// when Notification channel is cleared, storable toasts will be added into the list.
clearScreenChannels();
}
LLSysWellWindow::setVisible(visible);
}
//---------------------------------------------------------------------------------
void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
{
LLSD value = p.notification_id;
// do not add clones
if( mMessageList->getItemByValue(value))
return;
LLSysWellItem* new_item = new LLSysWellItem(p);
if (mMessageList->addItem(new_item, value, ADD_TOP, !mUpdateLocked))
{
if( !mUpdateLocked )
{
mSysWellChiclet->updateWidget(isWindowEmpty());
reshapeWindow();
}
new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1));
new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1));
}
else
{
LL_WARNS() << "Unable to add Notification into the list, notification ID: " << p.notification_id
<< ", title: " << p.title
<< LL_ENDL;
new_item->die();
}
}
void LLNotificationWellWindow::closeAll()
{
// Need to clear notification channel, to add storable toasts into the list.
clearScreenChannels();
std::vector<LLPanel*> items;
mMessageList->getItems(items);
LLPersistentNotificationStorage::getInstance()->startBulkUpdate(); // <FS:ND/>
for (std::vector<LLPanel*>::iterator
iter = items.begin(),
iter_end = items.end();
iter != iter_end; ++iter)
{
LLSysWellItem* sys_well_item = dynamic_cast<LLSysWellItem*>(*iter);
if (sys_well_item)
onItemClose(sys_well_item);
}
// <FS:ND> All done, renable normal mode and save.
LLPersistentNotificationStorage::getInstance()->endBulkUpdate();
LLPersistentNotificationStorage::getInstance()->saveNotifications();
// </FS:ND>
}
void LLNotificationWellWindow::unlockWindowUpdate()
{
mUpdateLocked = false;
mSysWellChiclet->updateWidget(isWindowEmpty());
// Let the list rearrange itself. This is normally called during addItem if the window is not locked.
LLSD oNotify;
oNotify["rearrange"] = 1;
mMessageList->notify( oNotify );
reshapeWindow();
}
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
void LLNotificationWellWindow::initChannel()
{
LLSysWellWindow::initChannel();
if(mChannel)
{
mChannel->addOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
}
}
void LLNotificationWellWindow::clearScreenChannels()
{
// 1 - remove StartUp toast and channel if present
if(!LLNotificationsUI::LLScreenChannel::getStartUpToastShown())
{
LLNotificationsUI::LLChannelManager::getInstance()->onStartUpToastClose();
}
// 2 - remove toasts in Notification channel
if(mChannel)
{
mChannel->removeAndStoreAllStorableToasts();
}
}
void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
{
LLSysWellItem::Params p;
p.notification_id = id;
p.title = static_cast<LLToastPanel*>(info_panel)->getTitle();
addItem(p);
}
void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)
{
LLUUID id = item->getID();
LLFloaterReg::showInstance("inspect_toast", id);
}
void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)
{
LLUUID id = item->getID();
if(mChannel)
{
// removeItemByID() is invoked from killToastByNotificationID() and item will removed;
mChannel->killToastByNotificationID(id);
}
else
{
// removeItemByID() should be called one time for each item to remove it from notification well
removeItemByID(id);
}
}
void LLNotificationWellWindow::onAdd( LLNotificationPtr notify )
{
removeItemByID(notify->getID());
}
// </FS:Ansariel>
/************************************************************************/
/* LLIMWellWindow implementation */
/************************************************************************/

View File

@ -102,6 +102,65 @@ protected:
bool mIsReshapedByUser;
};
// <FS:Ansariel> Optional legacy notification well
/**
* Class intended to manage incoming notifications.
*
* It contains a list of notifications that have not been responded to.
*/
class LLNotificationWellWindow : public LLSysWellWindow
{
bool mUpdateLocked;
public:
LLNotificationWellWindow(const LLSD& key);
static LLNotificationWellWindow* getInstance(const LLSD& key = LLSD());
/*virtual*/ BOOL postBuild();
/*virtual*/ void setVisible(BOOL visible);
/*virtual*/ void onAdd(LLNotificationPtr notify);
// Operating with items
void addItem(LLSysWellItem::Params p);
// Closes all notifications and removes them from the Notification Well
void closeAll();
void lockWindowUpdate()
{ mUpdateLocked = true; }
void unlockWindowUpdate();
protected:
struct WellNotificationChannel : public LLNotificationChannel
{
WellNotificationChannel(LLNotificationWellWindow*);
void onDelete(LLNotificationPtr notify)
{
mWellWindow->removeItemByID(notify->getID());
}
LLNotificationWellWindow* mWellWindow;
};
LLNotificationChannelPtr mNotificationUpdates;
/*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; }
private:
// init Window's channel
void initChannel();
void clearScreenChannels();
void onStoreToast(LLPanel* info_panel, LLUUID id);
// Handlers
void onItemClick(LLSysWellItem* item);
void onItemClose(LLSysWellItem* item);
// ID of a toast loaded by user (by clicking notification well item)
LLUUID mLoadedToastId;
};
// </FS:Ansariel>
/**
* Class intended to manage incoming messages in IM chats.
*

View File

@ -322,7 +322,17 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
LLFloaterReg::add("notification_well_window", "floater_notifications_tabbed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationsTabbed>);
// <FS:Ansariel> Optional legacy notification well
//LLFloaterReg::add("notification_well_window", "floater_notifications_tabbed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationsTabbed>);
if (!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell"))
{
LLFloaterReg::add("notification_well_window", "floater_notifications_tabbed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationsTabbed>);
}
else
{
LLFloaterReg::add("notification_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNotificationWellWindow>);
}
// </FS:Ansariel>
LLFloaterReg::add("object_weights", "floater_object_weights.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterObjectWeights>);
LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);

View File

@ -23,6 +23,10 @@
name="title_im_well_window">
Conversations
</string>
<string
name="title_notification_well_window">
Notifications
</string>
<flat_list_view
color="FloaterDefaultBackgroundColor"

View File

@ -396,6 +396,29 @@
tool_tip="If checked, Firestorm will not show any group / IM chat chiclets (notifications envelope and sum of IMs will remain on the screen)."
top_pad="6"
width="256" />
<check_box
control_name="FSLegacyNotificationWell"
height="16"
initial_value="true"
label="Use legacy list layout for Notifications window"
layout="topleft"
left="5"
name="FSLegacyNotificationWell"
tool_tip="If checked, Firestorm will use the legacy list view to display stored notifications."
top_pad="3"
width="265" />
<text
type="string"
left_pad="10"
top_pad="-15"
width="128"
follows="left|top"
height="12"
layout="topleft"
text_color="White_50"
name="FSLegacyNotificationWellRequiresRestart">
(requires restart)
</text>
<slider
control_name="FlashCount"