summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llchiclet.cpp50
-rw-r--r--indra/newview/llchiclet.h40
-rw-r--r--indra/newview/llnotificationscripthandler.cpp59
-rw-r--r--indra/newview/llscreenchannel.cpp4
-rw-r--r--indra/newview/llscriptfloater.cpp335
-rw-r--r--indra/newview/llscriptfloater.h164
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermessage.cpp12
-rw-r--r--indra/newview/skins/default/textures/textures.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_script.xml19
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml21
-rw-r--r--indra/newview/skins/default/xui/en/widgets/chiclet_script.xml9
13 files changed, 701 insertions, 18 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e8302ab5eb..46dd045f61 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -364,6 +364,7 @@ set(viewer_SOURCE_FILES
llremoteparcelrequest.cpp
llsavedsettingsglue.cpp
llscreenchannel.cpp
+ llscriptfloater.cpp
llscrollingpanelparam.cpp
llsearchcombobox.cpp
llsearchhistory.cpp
@@ -860,6 +861,7 @@ set(viewer_HEADER_FILES
llrootview.h
llsavedsettingsglue.h
llscreenchannel.h
+ llscriptfloater.h
llscrollingpanelparam.h
llsearchcombobox.h
llsearchhistory.h
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 6a5877f673..433f70700c 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -43,6 +43,7 @@
#include "lllocalcliprect.h"
#include "llmenugl.h"
#include "lloutputmonitorctrl.h"
+#include "llscriptfloater.h"
#include "lltextbox.h"
#include "llvoiceclient.h"
#include "llvoicecontrolpanel.h"
@@ -55,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);
@@ -1411,3 +1413,51 @@ LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
: LLOutputMonitorCtrl(p)
{
}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLScriptChiclet::Params::Params()
+ : icon("icon")
+{
+ // *TODO Vadim: Get rid of hardcoded values.
+ rect(CHICLET_RECT);
+ icon.rect(CHICLET_ICON_RECT);
+}
+
+LLScriptChiclet::LLScriptChiclet(const Params&p)
+ : LLIMChiclet(p)
+ , mChicletIconCtrl(NULL)
+{
+ 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)
+{
+ setShowNewMessagesIcon( getSessionId() != session_id );
+
+ LLIMChiclet::setSessionId(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::onMouseDown()
+{
+ LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId());
+}
+
+BOOL LLScriptChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ onMouseDown();
+ return LLChiclet::handleMouseDown(x, y, mask);
+}
+
+// EOF
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 03935d21a6..1ea141e6c4 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -534,6 +534,46 @@ private:
};
/**
+ * Chiclet for script floaters.
+ */
+class LLScriptChiclet : public LLIMChiclet
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
+ {
+ Optional<LLIconCtrl::Params> icon;
+
+ Params();
+ };
+
+ /*virtual*/ void setSessionId(const LLUUID& session_id);
+
+ /*virtual*/ void setCounter(S32 counter){}
+
+ /*virtual*/ S32 getCounter() { return 0; }
+
+ /**
+ * Toggle script floater
+ */
+ /*virtual*/ void onMouseDown();
+
+ /**
+ * Override default handler
+ */
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+protected:
+
+ LLScriptChiclet(const Params&);
+ friend class LLUICtrlFactory;
+
+private:
+
+ LLIconCtrl* mChicletIconCtrl;
+};
+
+/**
* Implements Group chat chiclet.
*/
class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 4be98201d1..f01f2e4441 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -38,9 +38,13 @@
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llnotificationmanager.h"
+#include "llscriptfloater.h"
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)
{
@@ -90,25 +94,40 @@ bool LLScriptHandler::processNotification(const LLSD& notify)
if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
{
- LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
-
- LLToast::Params p;
- p.notif_id = notification->getID();
- p.notification = notification;
- p.panel = notify_box;
- p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
-
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
- if(channel)
- channel->addToast(p);
-
- // send a signal to the counter manager
- mNewNotificationSignal();
-
+ if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName())
+ {
+ LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
+ }
+ else
+ {
+ LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
+
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.notification = notification;
+ p.panel = notify_box;
+ p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ {
+ channel->addToast(p);
+ }
+
+ // send a signal to the counter manager
+ mNewNotificationSignal();
+ }
}
else if (notify["sigtype"].asString() == "delete")
{
- mChannel->killToastByNotificationID(notification->getID());
+ if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName())
+ {
+ LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
+ }
+ else
+ {
+ mChannel->killToastByNotificationID(notification->getID());
+ }
}
return true;
}
@@ -123,6 +142,14 @@ void LLScriptHandler::onDeleteToast(LLToast* toast)
// send a signal to a listener to let him perform some action
// in this case listener is a SysWellWindow and it will remove a corresponding item from its list
mNotificationIDSignal(toast->getNotificationID());
+
+ LLNotificationPtr notification = LLNotifications::getInstance()->find(toast->getNotificationID());
+
+ if( notification &&
+ (SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName()) )
+ {
+ LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
+ }
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 24505f6bd6..fb9db42cf6 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -46,6 +46,7 @@
#include "lldockablefloater.h"
#include "llsyswellwindow.h"
#include "llimfloater.h"
+#include "llscriptfloater.h"
#include <algorithm>
@@ -686,7 +687,8 @@ void LLScreenChannel::updateShowToastsState()
}
// for IM floaters showed in a docked state - prohibit showing of ani toast
- if(dynamic_cast<LLIMFloater*>(floater))
+ if(dynamic_cast<LLIMFloater*>(floater)
+ || dynamic_cast<LLScriptFloater*>(floater) )
{
setShowToasts(!(floater->getVisible() && floater->isDocked()));
if (!getShowToasts())
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
new file mode 100644
index 0000000000..bdea6ff459
--- /dev/null
+++ b/indra/newview/llscriptfloater.cpp
@@ -0,0 +1,335 @@
+/**
+ * @file llscriptfloater.cpp
+ * @brief LLScriptFloater class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llscriptfloater.h"
+
+#include "llbottomtray.h"
+#include "llchannelmanager.h"
+#include "llchiclet.h"
+#include "llfloaterreg.h"
+#include "llscreenchannel.h"
+#include "lltoastnotifypanel.h"
+#include "llviewerwindow.h"
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLUUID notification_id_to_object_id(const LLUUID& notification_id)
+{
+ LLNotificationPtr notification = LLNotifications::getInstance()->find(notification_id);
+ if(notification)
+ {
+ return notification->getPayload()["object_id"].asUUID();
+ }
+ return LLUUID::null;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLScriptFloater::LLScriptFloater(const LLSD& key)
+: LLTransientDockableFloater(NULL, true, key)
+, mScriptForm(NULL)
+, mObjectId(key.asUUID())
+{
+}
+
+bool LLScriptFloater::toggle(const LLUUID& object_id)
+{
+ LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", object_id);
+
+ // show existing floater
+ if(floater)
+ {
+ if(floater->getVisible())
+ {
+ floater->setVisible(false);
+ return false;
+ }
+ else
+ {
+ floater->setVisible(TRUE);
+ floater->setFocus(TRUE);
+ return true;
+ }
+ }
+ // create and show new floater
+ else
+ {
+ show(object_id);
+ return true;
+ }
+}
+
+LLScriptFloater* LLScriptFloater::show(const LLUUID& object_id)
+{
+ LLScriptFloater* floater = LLFloaterReg::showTypedInstance<LLScriptFloater>("script_floater", object_id);
+ floater->createForm(object_id);
+
+ if (floater->getDockControl() == NULL)
+ {
+ LLChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(object_id);
+ if (chiclet == NULL)
+ {
+ llerror("Dock chiclet for LLScriptFloater doesn't exist", 0);
+ }
+ else
+ {
+ LLBottomTray::getInstance()->getChicletPanel()->scrollToChiclet(chiclet);
+ }
+
+ floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
+ LLDockControl::TOP, boost::bind(&LLScriptFloater::getAllowedRect, floater, _1)));
+ }
+
+ return floater;
+}
+
+void LLScriptFloater::getAllowedRect(LLRect& rect)
+{
+ rect = gViewerWindow->getWorldViewRectRaw();
+}
+
+void LLScriptFloater::createForm(const LLUUID& object_id)
+{
+ // delete old form
+ if(mScriptForm)
+ {
+ removeChild(mScriptForm);
+ mScriptForm->die();
+ }
+
+ LLNotificationPtr notification = LLNotifications::getInstance()->find(
+ LLScriptFloaterManager::getInstance()->findNotificationId(object_id));
+ if(NULL == notification)
+ {
+ return;
+ }
+
+ // create new form
+ mScriptForm = new LLToastNotifyPanel(notification);
+ addChild(mScriptForm);
+
+ // 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());
+ setShape(toast_rect);
+}
+
+void LLScriptFloater::onClose(bool app_quitting)
+{
+ LLScriptFloaterManager::getInstance()->removeNotificationByObjectId(getObjectId());
+}
+
+void LLScriptFloater::setDocked(bool docked, bool pop_on_undock /* = true */)
+{
+ LLTransientDockableFloater::setDocked(docked, pop_on_undock);
+
+ hideToastsIfNeeded();
+}
+
+void LLScriptFloater::setVisible(BOOL visible)
+{
+ LLTransientDockableFloater::setVisible(visible);
+
+ hideToastsIfNeeded();
+}
+
+void LLScriptFloater::hideToastsIfNeeded()
+{
+ using namespace LLNotificationsUI;
+
+ // find channel
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->findChannelByID(
+ LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+ // update notification channel state
+ if(channel)
+ {
+ channel->updateShowToastsState();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
+{
+ // get scripted Object's ID
+ LLUUID object_id = notification_id_to_object_id(notification_id);
+ if(object_id.isNull())
+ {
+ llwarns << "Invalid notification, no object id" << llendl;
+ return;
+ }
+
+ // If an Object spawns more-than-one floater, only the newest one is shown.
+ // The previous is automatically closed.
+ script_notification_map_t::iterator it = mNotifications.find(object_id);
+ if(it != mNotifications.end())
+ {
+ onRemoveNotification(notification_id);
+ }
+
+ LLNotificationData nd = {notification_id};
+ mNotifications.insert(std::make_pair(object_id, nd));
+
+ LLBottomTray::getInstance()->getChicletPanel()->createChiclet<LLScriptChiclet>(object_id);
+}
+
+void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id)
+{
+ LLUUID object_id = notification_id_to_object_id(notification_id);
+ if(object_id.isNull())
+ {
+ llwarns << "Invalid notification, no object id" << llendl;
+ return;
+ }
+
+ using namespace LLNotificationsUI;
+
+ // remove related toast
+ LLUUID channel_id(gSavedSettings.getString("NotificationChannelUUID"));
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>
+ (LLChannelManager::getInstance()->findChannelByID(channel_id));
+ if(channel)
+ {
+ channel->killToastByNotificationID(findNotificationToastId(object_id));
+ }
+
+ mNotifications.erase(object_id);
+
+ // remove related chiclet
+ LLBottomTray::getInstance()->getChicletPanel()->removeChiclet(object_id);
+
+ // close floater
+ LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", object_id);
+ if(floater)
+ {
+ floater->closeFloater();
+ }
+}
+
+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
+ LLIMChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(object_id);
+ if(chiclet)
+ {
+ chiclet->setShowNewMessagesIcon(false);
+ }
+
+ // kill toast
+ using namespace LLNotificationsUI;
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->findChannelByID(
+ LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+ if(channel)
+ {
+ channel->killToastByNotificationID(findNotificationToastId(object_id));
+ }
+
+ // toggle floater
+ LLScriptFloater::toggle(object_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)
+ {
+ it->second.toast_notification_id = notification_id;
+ }
+}
+
+LLUUID LLScriptFloaterManager::findNotificationId(const LLUUID& object_id)
+{
+ script_notification_map_t::const_iterator it = mNotifications.find(object_id);
+ if(mNotifications.end() != it)
+ {
+ return it->second.notification_id;
+ }
+ return LLUUID::null;
+}
+
+LLUUID LLScriptFloaterManager::findNotificationToastId(const LLUUID& object_id)
+{
+ script_notification_map_t::const_iterator it = mNotifications.find(object_id);
+ if(mNotifications.end() != it)
+ {
+ return it->second.toast_notification_id;
+ }
+ return LLUUID::null;
+}
+
+//static
+void LLScriptFloaterManager::onToastButtonClick(const LLSD&notification, const LLSD&response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ LLUUID object_id = notification["payload"]["object_id"].asUUID();
+
+ switch(option)
+ {
+ case 0: // "Open"
+ LLScriptFloaterManager::getInstance()->toggleScriptFloater(object_id);
+ break;
+ case 1: // "Ignore"
+ LLScriptFloaterManager::getInstance()->removeNotificationByObjectId(object_id);
+ break;
+ case 2: // "Block"
+ LLMuteList::getInstance()->add(LLMute(object_id, notification["substitutions"]["TITLE"], LLMute::OBJECT));
+ LLScriptFloaterManager::getInstance()->removeNotificationByObjectId(object_id);
+ break;
+ default:
+ llwarns << "Unexpected value" << llendl;
+ break;
+ }
+}
+
+// EOF
diff --git a/indra/newview/llscriptfloater.h b/indra/newview/llscriptfloater.h
new file mode 100644
index 0000000000..0e1a7f36b7
--- /dev/null
+++ b/indra/newview/llscriptfloater.h
@@ -0,0 +1,164 @@
+/**
+ * @file llscriptfloater.h
+ * @brief LLScriptFloater class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_SCRIPTFLOATER_H
+#define LL_SCRIPTFLOATER_H
+
+#include "lltransientdockablefloater.h"
+
+class LLToastNotifyPanel;
+
+/**
+ * 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);
+
+ LLUUID findNotificationId(const LLUUID& object_id);
+
+ LLUUID findNotificationToastId(const LLUUID& object_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:
+
+ struct LLNotificationData
+ {
+ LLUUID notification_id;
+ LLUUID toast_notification_id;
+ };
+
+ // <object_id, notification_data>
+ typedef std::map<LLUUID, LLNotificationData> script_notification_map_t;
+
+ script_notification_map_t mNotifications;
+};
+
+/**
+ * Floater script forms.
+ * LLScriptFloater will create script form based on notification data and
+ * will auto fit the form.
+ */
+class LLScriptFloater : public LLTransientDockableFloater
+{
+public:
+
+ /**
+ * key - UUID of scripted Object
+ */
+ LLScriptFloater(const LLSD& key);
+
+ 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);
+
+ /**
+ * Hide all notification toasts.
+ */
+ static void hideToastsIfNeeded();
+
+ void setObjectId(const LLUUID& id) { mObjectId = id; }
+
+private:
+ LLToastNotifyPanel* mScriptForm;
+ LLUUID mObjectId;
+};
+
+#endif //LL_SCRIPTFLOATER_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 7772f613f0..812107dd72 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -124,6 +124,7 @@
#include "llpreviewsound.h"
#include "llpreviewtexture.h"
#include "llsyswellwindow.h"
+#include "llscriptfloater.h"
// *NOTE: Please add files in alphabetical order to keep merges easy.
@@ -171,6 +172,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
+ LLFloaterReg::add("script_floater", "floater_script.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLScriptFloater>);
LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);
LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>);
LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 8db6d5917a..4d7d3ee8ac 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -101,6 +101,7 @@
#include "llpanelgrouplandmoney.h"
#include "llpanelplaces.h"
#include "llrecentpeople.h"
+#include "llscriptfloater.h"
#include "llselectmgr.h"
#include "llsidetray.h"
#include "llstartup.h"
@@ -5380,6 +5381,17 @@ void process_script_dialog(LLMessageSystem* msg, void**)
notification = LLNotifications::instance().add(
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()->setNotificationToastId(
+ object_id, notification->getID());
}
//---------------------------------------------------------------------------
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index f4a239be62..6678918db8 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -161,7 +161,7 @@ with the same filename but different name
<texture name="Generic_Group" file_name="icons/Generic_Group.png" preload="false" />
<texture name="Generic_Group_Large" file_name="icons/Generic_Group_Large.png" preload="false" />
<texture name="Generic_Object_Medium" file_name="icons/Generic_Object_Medium.png" preload="false" />
- <texture name="Generic_Object_Small" file_name="icons/ Generic_Object_Small.png" preload="false" />
+ <texture name="Generic_Object_Small" file_name="icons/Generic_Object_Small.png" preload="false" />
<texture name="Generic_Object_Large" file_name="icons/Generic_Object_Large.png" preload="false" />
<texture name="Generic_Person" file_name="icons/Generic_Person.png" preload="false" />
<texture name="Generic_Person_Large" file_name="icons/Generic_Person_Large.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_script.xml b/indra/newview/skins/default/xui/en/floater_script.xml
new file mode 100644
index 0000000000..f44ba6d873
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_script.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ background_visible="true"
+ follows="left|top|right|bottom"
+ height="369"
+ layout="topleft"
+ left="0"
+ name="script_floater"
+ help_topic="script_floater"
+ top="0"
+ can_dock="true"
+ can_minimize="true"
+ visible="true"
+ width="520"
+ can_resize="true"
+ min_width="350"
+ min_height="369">
+</floater>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 90e32cdd9c..9d1bcb8f60 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5307,6 +5307,27 @@ Grant this request?
<notification
icon="notify.tga"
+ name="ScriptToast"
+ type="notify">
+ [FIRST] [LAST]&apos;s &apos;[TITLE]&apos; is requesting user input.
+ <form name="form">
+ <button
+ index="0"
+ name="Open"
+ text="Open Dialog"/>
+ <button
+ index="1"
+ name="Ignore"
+ text="Ignore"/>
+ <button
+ index="2"
+ name="Block"
+ text="Block"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
name="FirstBalanceIncrease"
type="notify">
You just received L$[AMOUNT].
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml
new file mode 100644
index 0000000000..5011bf6a61
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml
@@ -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> \ No newline at end of file