Update for task EXT-2081 - Object IM chiclets art needs to be hooked up to LLDialog chiclets.

Cleaned code, added comments.

--HG--
branch : product-engine
master
Dmitry Zaporozhan 2009-11-23 15:50:49 +02:00
parent d0c1593d85
commit 9f0dbcf4c0
8 changed files with 155 additions and 88 deletions

View File

@ -56,6 +56,7 @@ static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notif
static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t3("chiclet_im_p2p");
static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t4("chiclet_im_group");
static LLDefaultChildRegistry::Register<LLAdHocChiclet> t5("chiclet_im_adhoc");
static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script");
static const LLRect CHICLET_RECT(0, 25, 25, 0);
static const LLRect CHICLET_ICON_RECT(0, 22, 22, 0);
@ -1418,24 +1419,21 @@ LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
//////////////////////////////////////////////////////////////////////////
LLScriptChiclet::Params::Params()
: avatar_icon("avatar_icon")
: icon("icon")
{
// *TODO Vadim: Get rid of hardcoded values.
rect(CHICLET_RECT);
name("dialog_chiclet");
avatar_icon.name("avatar_icon");
avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
avatar_icon.rect(CHICLET_ICON_RECT);
avatar_icon.mouse_opaque(false);
rect(CHICLET_RECT);
icon.rect(CHICLET_ICON_RECT);
}
LLScriptChiclet::LLScriptChiclet(const Params&p)
: LLIMChiclet(p)
, mChicletIconCtrl(NULL)
{
mImage = LLUI::getUIImage("Generic_Object_Small");
LLIconCtrl::Params icon_params = p.icon;
mChicletIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
// Let "new message" icon be on top, else it will be hidden behind chiclet icon.
addChildInBack(mChicletIconCtrl);
}
void LLScriptChiclet::setSessionId(const LLUUID& session_id)
@ -1443,20 +1441,14 @@ void LLScriptChiclet::setSessionId(const LLUUID& session_id)
setShowNewMessagesIcon( getSessionId() != session_id );
LLIMChiclet::setSessionId(session_id);
LLNotificationPtr notification = LLNotifications::getInstance()->find(
LLScriptFloaterManager::getInstance()->getNotificationId(session_id));
LLUUID notification_id = LLScriptFloaterManager::getInstance()->findNotificationId(session_id);
LLNotificationPtr notification = LLNotifications::getInstance()->find(notification_id);
if(notification)
{
setToolTip(notification->getSubstitutions()["TITLE"].asString());
}
}
void LLScriptChiclet::draw()
{
mImage->draw(getLocalRect());
LLIMChiclet::draw();
}
void LLScriptChiclet::onMouseDown()
{
LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId());
@ -1467,3 +1459,5 @@ BOOL LLScriptChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
onMouseDown();
return LLChiclet::handleMouseDown(x, y, mask);
}
// EOF

View File

@ -533,28 +533,35 @@ private:
LLMenuGL* mPopupMenu;
};
/**
* Chiclet for script floaters.
*/
class LLScriptChiclet : public LLIMChiclet
{
public:
struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
{
Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
Optional<LLIconCtrl::Params> icon;
Params();
};
void setSessionId(const LLUUID& session_id);
/*virtual*/ void setSessionId(const LLUUID& session_id);
void setCounter(S32 counter){}
/*virtual*/ void setCounter(S32 counter){}
S32 getCounter() { return 0; }
/*virtual*/ S32 getCounter() { return 0; }
void onMouseDown();
/**
* Toggle script floater
*/
/*virtual*/ void onMouseDown();
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
void draw();
/**
* Override default handler
*/
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
protected:
@ -563,8 +570,7 @@ protected:
private:
LLPointer<LLUIImage> mImage;
LLChicletAvatarIconCtrl* mChicletIconCtrl;
LLIconCtrl* mChicletIconCtrl;
};
/**

View File

@ -42,6 +42,9 @@
using namespace LLNotificationsUI;
static const std::string SCRIPT_DIALOG ("ScriptDialog");
static const std::string SCRIPT_DIALOG_GROUP ("ScriptDialogGroup");
//--------------------------------------------------------------------------
LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
{
@ -91,7 +94,7 @@ bool LLScriptHandler::processNotification(const LLSD& notify)
if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
{
if("ScriptDialog" == notification->getName() || "ScriptDialogGroup" == notification->getName())
if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName())
{
LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
}
@ -117,11 +120,14 @@ bool LLScriptHandler::processNotification(const LLSD& notify)
}
else if (notify["sigtype"].asString() == "delete")
{
mChannel->killToastByNotificationID(notification->getID());
if("ScriptDialog" == notification->getName())
if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName())
{
LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
}
else
{
mChannel->killToastByNotificationID(notification->getID());
}
}
return true;
}
@ -139,8 +145,8 @@ void LLScriptHandler::onDeleteToast(LLToast* toast)
LLNotificationPtr notification = LLNotifications::getInstance()->find(toast->getNotificationID());
if( notification && ("ScriptDialog" == notification->getName()
|| "ScriptDialogGroup" == notification->getName()) )
if( notification &&
(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName()) )
{
LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
}

View File

@ -61,6 +61,7 @@ LLUUID notification_id_to_object_id(const LLUUID& notification_id)
LLScriptFloater::LLScriptFloater(const LLSD& key)
: LLTransientDockableFloater(NULL, true, key)
, mScriptForm(NULL)
, mObjectId(key.asUUID())
{
}
@ -84,6 +85,7 @@ bool LLScriptFloater::toggle(const LLUUID& object_id)
return true;
}
}
// create and show new floater
else
{
show(object_id);
@ -122,58 +124,54 @@ void LLScriptFloater::getAllowedRect(LLRect& rect)
void LLScriptFloater::createForm(const LLUUID& object_id)
{
static const std::string PANEL_NAME = "_notification_panel_";
LLPanel* old_panel = findChild<LLPanel>(PANEL_NAME);
if(old_panel)
// delete old form
if(mScriptForm)
{
removeChild(old_panel);
removeChild(mScriptForm);
mScriptForm->die();
}
LLNotificationPtr notification = LLNotifications::getInstance()->find(
LLScriptFloaterManager::getInstance()->getNotificationId(object_id));
LLScriptFloaterManager::getInstance()->findNotificationId(object_id));
if(NULL == notification)
{
return;
}
LLToastNotifyPanel* panel = new LLToastNotifyPanel(notification);
panel->setName(PANEL_NAME);
addChild(panel);
LLRect panel_rect;
// create new form
mScriptForm = new LLToastNotifyPanel(notification);
addChild(mScriptForm);
panel_rect = panel->getRect();
panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight());
reshape(panel_rect.getWidth(), panel_rect.getHeight());
panel->setRect(panel_rect);
// position form on floater
mScriptForm->setOrigin(0, 0);
// make floater size fit form size
LLRect toast_rect = getRect();
LLRect panel_rect = mScriptForm->getRect();
toast_rect.setLeftTopAndSize(toast_rect.mLeft, toast_rect.mTop, panel_rect.getWidth(), panel_rect.getHeight() + getHeaderHeight());
reshape(toast_rect.getWidth(), toast_rect.getHeight());
setRect(toast_rect);
setShape(toast_rect);
}
void LLScriptFloater::onClose(bool app_quitting)
{
LLScriptFloaterManager::getInstance()->closeScriptFloater(getObjectId());
setObjectId(LLUUID::null);
LLScriptFloaterManager::getInstance()->removeNotificationByObjectId(getObjectId());
}
void LLScriptFloater::setDocked(bool docked, bool pop_on_undock /* = true */)
{
LLTransientDockableFloater::setDocked(docked, pop_on_undock);
updateToasts();
hideToastsIfNeeded();
}
void LLScriptFloater::setVisible(BOOL visible)
{
LLTransientDockableFloater::setVisible(visible);
updateToasts();
hideToastsIfNeeded();
}
void LLScriptFloater::updateToasts()
void LLScriptFloater::hideToastsIfNeeded()
{
using namespace LLNotificationsUI;
@ -197,12 +195,12 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
LLUUID object_id = notification_id_to_object_id(notification_id);
if(object_id.isNull())
{
llerrs << "Invalid notification, no object id" << llendl;
llwarns << "Invalid notification, no object id" << llendl;
return;
}
// If an Object spawns more-than-one floater, only the newest one is shown.
// The other is automatically closed.
// The previous is automatically closed.
script_notification_map_t::iterator it = mNotifications.find(object_id);
if(it != mNotifications.end())
{
@ -220,18 +218,19 @@ void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id)
LLUUID object_id = notification_id_to_object_id(notification_id);
if(object_id.isNull())
{
llerrs << "Invalid notification, no object id" << llendl;
llwarns << "Invalid notification, no object id" << llendl;
return;
}
using namespace LLNotificationsUI;
// remove related toast
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->findChannelByID(
LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
LLUUID channel_id(gSavedSettings.getString("NotificationChannelUUID"));
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>
(LLChannelManager::getInstance()->findChannelByID(channel_id));
if(channel)
{
channel->killToastByNotificationID(getToastNotificationId(object_id));
channel->killToastByNotificationID(findNotificationToastId(object_id));
}
mNotifications.erase(object_id);
@ -247,6 +246,17 @@ void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id)
}
}
void LLScriptFloaterManager::removeNotificationByObjectId(const LLUUID& object_id)
{
// Check we have not removed notification yet
LLNotificationPtr notification = LLNotifications::getInstance()->find(
findNotificationId(object_id));
if(notification)
{
onRemoveNotification(notification->getID());
}
}
void LLScriptFloaterManager::toggleScriptFloater(const LLUUID& object_id)
{
// hide "new message" icon from chiclet
@ -262,24 +272,14 @@ void LLScriptFloaterManager::toggleScriptFloater(const LLUUID& object_id)
LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
if(channel)
{
channel->killToastByNotificationID(getToastNotificationId(object_id));
channel->killToastByNotificationID(findNotificationToastId(object_id));
}
// toggle floater
LLScriptFloater::toggle(object_id);
}
void LLScriptFloaterManager::closeScriptFloater(const LLUUID& object_id)
{
LLNotificationPtr notification = LLNotifications::getInstance()->find(
getNotificationId(object_id));
if(notification)
{
onRemoveNotification(notification->getID());
}
}
void LLScriptFloaterManager::setToastNotificationId(const LLUUID& object_id, const LLUUID& notification_id)
void LLScriptFloaterManager::setNotificationToastId(const LLUUID& object_id, const LLUUID& notification_id)
{
script_notification_map_t::iterator it = mNotifications.find(object_id);
if(mNotifications.end() != it)
@ -288,7 +288,7 @@ void LLScriptFloaterManager::setToastNotificationId(const LLUUID& object_id, con
}
}
const LLUUID& LLScriptFloaterManager::getNotificationId(const LLUUID& object_id)
LLUUID LLScriptFloaterManager::findNotificationId(const LLUUID& object_id)
{
script_notification_map_t::const_iterator it = mNotifications.find(object_id);
if(mNotifications.end() != it)
@ -298,7 +298,7 @@ const LLUUID& LLScriptFloaterManager::getNotificationId(const LLUUID& object_id)
return LLUUID::null;
}
const LLUUID& LLScriptFloaterManager::getToastNotificationId(const LLUUID& object_id)
LLUUID LLScriptFloaterManager::findNotificationToastId(const LLUUID& object_id)
{
script_notification_map_t::const_iterator it = mNotifications.find(object_id);
if(mNotifications.end() != it)
@ -320,11 +320,11 @@ void LLScriptFloaterManager::onToastButtonClick(const LLSD&notification, const L
LLScriptFloaterManager::getInstance()->toggleScriptFloater(object_id);
break;
case 1: // "Ignore"
LLScriptFloaterManager::getInstance()->closeScriptFloater(object_id);
LLScriptFloaterManager::getInstance()->removeNotificationByObjectId(object_id);
break;
case 2: // "Mute"
case 2: // "Block"
LLMuteList::getInstance()->add(LLMute(object_id, notification["substitutions"]["TITLE"], LLMute::OBJECT));
LLScriptFloaterManager::getInstance()->closeScriptFloater(object_id);
LLScriptFloaterManager::getInstance()->removeNotificationByObjectId(object_id);
break;
default:
llwarns << "Unexpected value" << llendl;

View File

@ -35,27 +35,52 @@
#include "lltransientdockablefloater.h"
class LLToastNotifyPanel;
/**
* This class manages Object script floaters.
* Handles script notifications ("ScriptDialog" and "ScriptDialogGroup")
* and manages Script Floaters.
*/
class LLScriptFloaterManager : public LLSingleton<LLScriptFloaterManager>
{
public:
/**
* Handles new notifications.
* Saves notification and object ids, removes old notification if needed, creates script chiclet
* Note that one object can spawn one script floater.
*/
void onAddNotification(const LLUUID& notification_id);
/**
* Handles notification removal.
* Removes script notification toast, removes script chiclet, closes script floater
*/
void onRemoveNotification(const LLUUID& notification_id);
/**
* Wrapper for onRemoveNotification, removes notification by object id.
*/
void removeNotificationByObjectId(const LLUUID& object_id);
/**
* Toggles script floater.
* Removes "new message" icon from chiclet and removes notification toast.
*/
void toggleScriptFloater(const LLUUID& object_id);
void closeScriptFloater(const LLUUID& object_id);
LLUUID findNotificationId(const LLUUID& object_id);
const LLUUID& getNotificationId(const LLUUID& object_id);
LLUUID findNotificationToastId(const LLUUID& object_id);
const LLUUID& getToastNotificationId(const LLUUID& object_id);
void setToastNotificationId(const LLUUID& object_id, const LLUUID& notification_id);
/**
* Associate notification toast id with object id.
*/
void setNotificationToastId(const LLUUID& object_id, const LLUUID& notification_id);
/**
* Callback for notification toast buttons.
*/
static void onToastButtonClick(const LLSD&notification, const LLSD&response);
private:
@ -66,13 +91,16 @@ private:
LLUUID toast_notification_id;
};
// <object_id, notification_data>
typedef std::map<LLUUID, LLNotificationData> script_notification_map_t;
script_notification_map_t mNotifications;
};
/**
* Floater for displaying script forms
* Floater script forms.
* LLScriptFloater will create script form based on notification data and
* will auto fit the form.
*/
class LLScriptFloater : public LLTransientDockableFloater
{
@ -85,29 +113,51 @@ public:
virtual ~LLScriptFloater(){};
/**
* Toggle existing floater or create and show a new one.
*/
static bool toggle(const LLUUID& object_id);
/**
* Creates and shows floater
*/
static LLScriptFloater* show(const LLUUID& object_id);
const LLUUID& getObjectId() { return mObjectId; }
/**
* Close notification if script floater is closed.
*/
/*virtual*/ void onClose(bool app_quitting);
/**
* Hide all notification toasts when we show dockable floater
*/
/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
/**
* Hide all notification toasts when we show dockable floater
*/
/*virtual*/ void setVisible(BOOL visible);
protected:
/**
* Creates script form, will delete old form if floater is shown for same object.
*/
void createForm(const LLUUID& object_id);
/*virtual*/ void getAllowedRect(LLRect& rect);
static void updateToasts();
/**
* Hide all notification toasts.
*/
static void hideToastsIfNeeded();
void setObjectId(const LLUUID& id) { mObjectId = id; }
private:
LLToastNotifyPanel* mScriptForm;
LLUUID mObjectId;
};

View File

@ -5382,13 +5382,15 @@ void process_script_dialog(LLMessageSystem* msg, void**)
LLNotification::Params("ScriptDialogGroup").substitutions(args).payload(payload).form_elements(form.asLLSD()));
}
// "ScriptDialog" and "ScriptDialogGroup" are handles by LLScriptFloaterManager.
// We want to inform user that there is a script floater, lets add "ScriptToast"
LLNotification::Params p("ScriptToast");
p.substitutions(args).payload(payload).functor.function(boost::bind(
LLScriptFloaterManager::onToastButtonClick, _1, _2));
notification = LLNotifications::instance().add(p);
LLScriptFloaterManager::getInstance()->setToastNotificationId(
LLScriptFloaterManager::getInstance()->setNotificationToastId(
object_id, notification->getID());
}

View File

@ -5314,8 +5314,8 @@ Grant this request?
text="Ignore"/>
<button
index="2"
name="Mute"
text="Mute"/>
name="Block"
text="Block"/>
</form>
</notification>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<chiclet_script
name="script_chiclet">
<icon
name="chiclet_icon"
follows="all"
mouse_opaque="false"
image_name="Generic_Object_Small" />
</expandable_text>