summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2009-07-21 00:57:23 +0000
committerSteven Bennetts <steve@lindenlab.com>2009-07-21 00:57:23 +0000
commit73a97010e6c8c7874fdc1778ab46e492f77d9394 (patch)
treef0c8efb1cebcc6157c8e6678cf0eb39b5792a1d7
parentdedb5be906b53d1ea8601ff6b9c4b726fda02da8 (diff)
merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0/indra@1059 https://svn.aws.productengine.com/secondlife/pe/stable-1/indra@1070 -> svn+ssh://svn.lindenlab.com/svn/linden/branches/viewer/viewer-2.0.0-3
-rw-r--r--indra/llui/llui.h5
-rw-r--r--indra/newview/CMakeLists.txt12
-rw-r--r--indra/newview/llagent.cpp13
-rw-r--r--indra/newview/llavataractions.cpp276
-rw-r--r--indra/newview/llavataractions.h88
-rw-r--r--indra/newview/llavatariconctrl.cpp8
-rw-r--r--indra/newview/llbottomtray.cpp361
-rw-r--r--indra/newview/llbottomtray.h57
-rw-r--r--indra/newview/llchatbar.cpp692
-rw-r--r--indra/newview/llchatbar.h120
-rw-r--r--indra/newview/llchiclet.cpp900
-rw-r--r--indra/newview/llchiclet.h584
-rw-r--r--indra/newview/llfavoritesbar.cpp66
-rw-r--r--indra/newview/llfavoritesbar.h2
-rw-r--r--indra/newview/llfloaterchat.cpp22
-rw-r--r--indra/newview/llfloaterchat.h1
-rw-r--r--indra/newview/llfloaterfriends.cpp16
-rw-r--r--indra/newview/llfloaterinspect.cpp6
-rw-r--r--indra/newview/llfloaterland.cpp6
-rw-r--r--indra/newview/llfloaterproperties.cpp6
-rw-r--r--indra/newview/llgesturemgr.cpp4
-rw-r--r--indra/newview/llhudtext.cpp5
-rw-r--r--indra/newview/llimpanel.cpp4
-rw-r--r--indra/newview/llimview.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp19
-rw-r--r--indra/newview/llmenucommands.cpp13
-rw-r--r--indra/newview/lloverlaybar.cpp8
-rw-r--r--indra/newview/llpanelavatar.cpp12
-rw-r--r--indra/newview/llpanelclassified.cpp5
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp4
-rw-r--r--indra/newview/llpanelgrouproles.cpp4
-rw-r--r--indra/newview/llpanellandmarks.cpp5
-rw-r--r--indra/newview/llpanellandmarks.h1
-rw-r--r--indra/newview/llpanelpeople.cpp30
-rw-r--r--indra/newview/llpanelpermissions.cpp6
-rw-r--r--indra/newview/llpanelpick.cpp18
-rw-r--r--indra/newview/llpanelpick.h5
-rw-r--r--indra/newview/llpanelplaceinfo.cpp43
-rw-r--r--indra/newview/llpanelplaceinfo.h6
-rw-r--r--indra/newview/llpanelplaces.cpp75
-rw-r--r--indra/newview/llpanelplaces.h16
-rw-r--r--indra/newview/llsidetray.cpp6
-rw-r--r--indra/newview/llviewergesture.cpp5
-rw-r--r--indra/newview/llviewerkeyboard.cpp27
-rw-r--r--indra/newview/llviewermenu.cpp12
-rw-r--r--indra/newview/llviewerwindow.cpp53
-rw-r--r--indra/newview/skins/default/xui/en/accordion_drag.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_imchiclet_group.xml27
-rw-r--r--indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml43
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml5
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml42
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_list_item.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_places.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray.xml124
-rw-r--r--indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml29
56 files changed, 2156 insertions, 1765 deletions
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 6f0da05535..9399eff2ab 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -397,8 +397,13 @@ public:
delete sInstance;
sInstance = NULL;
}
+
+ static bool instanceExists() { return NULL != sInstance; }
private:
+ LLUISingleton(const LLUISingleton&){}
+ LLUISingleton& operator=(const LLUISingleton&){}
+private:
static T* sInstance;
};
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d9d2f6f732..ac3163a1bd 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -63,6 +63,7 @@ include_directories(
)
set(viewer_SOURCE_FILES
+ llaccordionctrltab.cpp
llaccordionpanel.cpp
llagent.cpp
llagentaccess.cpp
@@ -75,6 +76,7 @@ set(viewer_SOURCE_FILES
llassetuploadresponders.cpp
llassetuploadqueue.cpp
llaudiosourcevo.cpp
+ llavataractions.cpp
llavatariconctrl.cpp
llavatarlist.cpp
llavatarlistitem.cpp
@@ -86,13 +88,11 @@ set(viewer_SOURCE_FILES
llcallingcard.cpp
llcapabilitylistener.cpp
llcaphttpsender.cpp
- llchatbar.cpp
llchathistoryscroll.cpp
llchiclet.cpp
llclassifiedinfo.cpp
llclassifiedstatsresponder.cpp
llcloud.cpp
- llcollapsiblectrl.cpp
llcolorswatch.cpp
llcommandhandler.cpp
llcommandlineparser.cpp
@@ -213,7 +213,6 @@ set(viewer_SOURCE_FILES
llfolderview.cpp
llfolderviewitem.cpp
llfollowcam.cpp
- llfriendactions.cpp
llgesturemgr.cpp
llgivemoney.cpp
llglsandbox.cpp
@@ -350,6 +349,7 @@ set(viewer_SOURCE_FILES
lltexturectrl.cpp
lltexturefetch.cpp
lltextureview.cpp
+ lltoggleablemenu.cpp
lltoolbar.cpp
lltoolbrush.cpp
lltoolcomp.cpp
@@ -483,6 +483,7 @@ endif (LINUX)
set(viewer_HEADER_FILES
CMakeLists.txt
ViewerInstall.cmake
+ llaccordionctrltab.h
llaccordionpanel.h
llagent.h
llagentaccess.h
@@ -496,6 +497,7 @@ set(viewer_HEADER_FILES
llassetuploadresponders.h
llassetuploadqueue.h
llaudiosourcevo.h
+ llavataractions.h
llavatariconctrl.h
llavatarlist.h
llavatarlistitem.h
@@ -508,13 +510,11 @@ set(viewer_HEADER_FILES
llcapabilitylistener.h
llcapabilityprovider.h
llcaphttpsender.h
- llchatbar.h
llchathistoryscroll.h
llchiclet.h
llclassifiedinfo.h
llclassifiedstatsresponder.h
llcloud.h
- llcollapsiblectrl.h
llcolorswatch.h
llcommandhandler.h
llcommandlineparser.h
@@ -637,7 +637,6 @@ set(viewer_HEADER_FILES
llfoldervieweventlistener.h
llfolderviewitem.h
llfollowcam.h
- llfriendactions.h
llgesturemgr.h
llgivemoney.h
llgroupactions.h
@@ -777,6 +776,7 @@ set(viewer_HEADER_FILES
lltexturectrl.h
lltexturefetch.h
lltextureview.h
+ lltoggleablemenu.h
lltool.h
lltoolbar.h
lltoolbrush.h
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index cdf9a6b059..afad88770e 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -37,7 +37,6 @@
#include "llanimationstates.h"
#include "llcallingcard.h"
-#include "llchatbar.h"
#include "llconsole.h"
#include "lldrawable.h"
#include "llfirstuse.h"
@@ -2722,8 +2721,7 @@ void LLAgent::startTyping()
{
sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
}
- if(gBottomTray)
- gBottomTray->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
+ LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
}
//-----------------------------------------------------------------------------
@@ -2735,8 +2733,7 @@ void LLAgent::stopTyping()
{
clearRenderState(AGENT_STATE_TYPING);
sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
- if(gBottomTray)
- gBottomTray->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
+ LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
}
}
@@ -2811,8 +2808,7 @@ void LLAgent::endAnimationUpdateUI()
LLNavigationBar::getInstance()->setVisible(TRUE);
gStatusBar->setVisibleForMouselook(true);
- if(gBottomTray)
- gBottomTray->setVisible(TRUE);
+ LLBottomTray::getInstance()->setVisible(TRUE);
LLSideTray::getInstance()->setVisible(TRUE);
@@ -2902,8 +2898,7 @@ void LLAgent::endAnimationUpdateUI()
LLNavigationBar::getInstance()->setVisible(FALSE);
gStatusBar->setVisibleForMouselook(false);
- if(gBottomTray)
- gBottomTray->setVisible(FALSE);
+ LLBottomTray::getInstance()->setVisible(FALSE);
LLSideTray::getInstance()->setVisible(FALSE);
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
new file mode 100644
index 0000000000..2cf7298569
--- /dev/null
+++ b/indra/newview/llavataractions.cpp
@@ -0,0 +1,276 @@
+/**
+ * @file llavataractions.cpp
+ * @brief Friend-related actions (add, remove, offer teleport, etc)
+ *
+ * $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 "llavataractions.h"
+
+#include "llsd.h"
+#include "lldarray.h"
+#include "llnotifications.h"
+
+#include "llagent.h"
+#include "llappviewer.h" // for gLastVersionChannel
+#include "llcallingcard.h" // for LLAvatarTracker
+#include "llinventorymodel.h"
+#include "llimview.h" // for gIMMgr
+#include "llsidetray.h"
+#include "llviewermessage.h" // for handle_lure
+#include "llviewerregion.h"
+
+// static
+void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
+{
+ if(id == gAgentID)
+ {
+ LLNotifications::instance().add("AddSelfFriend");
+ return;
+ }
+
+ LLSD args;
+ args["NAME"] = name;
+ LLSD payload;
+ payload["id"] = id;
+ payload["name"] = name;
+ // Look for server versions like: Second Life Server 1.24.4.95600
+ if (gLastVersionChannel.find(" 1.24.") != std::string::npos)
+ {
+ // Old and busted server version, doesn't support friend
+ // requests with messages.
+ LLNotifications::instance().add("AddFriend", args, payload, &callbackAddFriend);
+ }
+ else
+ {
+ LLNotifications::instance().add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
+ }
+}
+
+// static
+void LLAvatarActions::removeFriendDialog(const LLUUID& id)
+{
+ if (id.isNull())
+ return;
+
+ std::vector<LLUUID> ids;
+ ids.push_back(id);
+ removeFriendsDialog(ids);
+}
+
+// static
+void LLAvatarActions::removeFriendsDialog(const std::vector<LLUUID>& ids)
+{
+ if(ids.size() == 0)
+ return;
+
+ LLSD args;
+ std::string msgType;
+ if(ids.size() == 1)
+ {
+ LLUUID agent_id = ids[0];
+ std::string first, last;
+ if(gCacheName->getName(agent_id, first, last))
+ {
+ args["FIRST_NAME"] = first;
+ args["LAST_NAME"] = last;
+ }
+
+ msgType = "RemoveFromFriends";
+ }
+ else
+ {
+ msgType = "RemoveMultipleFromFriends";
+ }
+
+ LLSD payload;
+ for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ payload["ids"].append(*it);
+ }
+
+ LLNotifications::instance().add(msgType,
+ args,
+ payload,
+ &handleRemove);
+}
+
+// static
+void LLAvatarActions::offerTeleport(const LLUUID& invitee)
+{
+ if (invitee.isNull())
+ return;
+
+ LLDynamicArray<LLUUID> ids;
+ ids.push_back(invitee);
+ offerTeleport(ids);
+}
+
+// static
+void LLAvatarActions::offerTeleport(const std::vector<LLUUID>& ids)
+{
+ if (ids.size() > 0)
+ handle_lure(ids);
+}
+
+// static
+void LLAvatarActions::startIM(const LLUUID& id)
+{
+ if (id.isNull())
+ return;
+
+ std::string name;
+ gCacheName->getFullName(id, name);
+ gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id);
+ make_ui_sound("UISndStartIM");
+}
+
+// static
+void LLAvatarActions::startConference(const std::vector<LLUUID>& ids)
+{
+ // *HACK: Copy into dynamic array
+ LLDynamicArray<LLUUID> id_array;
+ for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ id_array.push_back(*it);
+ }
+ gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], id_array);
+ make_ui_sound("UISndStartIM");
+}
+
+// static
+void LLAvatarActions::showProfile(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ LLSD params;
+ params["id"] = id;
+ params["open_tab_name"] = "panel_profile";
+
+ //Show own profile
+ if(gAgent.getID() == id)
+ {
+ LLSideTray::getInstance()->showPanel("panel_me_profile", params);
+ }
+ //Show other user profile
+ else
+ {
+ LLSideTray::getInstance()->showPanel("panel_profile_view", params);
+ }
+ }
+}
+
+//== private methods ========================================================================================
+
+// static
+bool LLAvatarActions::handleRemove(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+
+ const LLSD& ids = notification["payload"]["ids"];
+ for (LLSD::array_const_iterator itr = ids.beginArray(); itr != ids.endArray(); ++itr)
+ {
+ LLUUID id = itr->asUUID();
+ const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id);
+ if (ip)
+ {
+ switch (option)
+ {
+ case 0: // YES
+ if( ip->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS))
+ {
+ LLAvatarTracker::instance().empower(id, FALSE);
+ LLAvatarTracker::instance().notifyObservers();
+ }
+ LLAvatarTracker::instance().terminateBuddy(id);
+ LLAvatarTracker::instance().notifyObservers();
+ gInventory.addChangedMask(LLInventoryObserver::LABEL | LLInventoryObserver::CALLING_CARD, LLUUID::null);
+ gInventory.notifyObservers();
+ break;
+
+ case 1: // NO
+ default:
+ llinfos << "No removal performed." << llendl;
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+// static
+bool LLAvatarActions::callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ requestFriendship(notification["payload"]["id"].asUUID(),
+ notification["payload"]["name"].asString(),
+ response["message"].asString());
+ }
+ return false;
+}
+
+// static
+bool LLAvatarActions::callbackAddFriend(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ // Servers older than 1.25 require the text of the message to be the
+ // calling card folder ID for the offering user. JC
+ LLUUID calling_card_folder_id =
+ gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+ std::string message = calling_card_folder_id.asString();
+ requestFriendship(notification["payload"]["id"].asUUID(),
+ notification["payload"]["name"].asString(),
+ message);
+ }
+ return false;
+}
+
+// static
+void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message)
+{
+ LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+ send_improved_im(target_id,
+ target_name,
+ message,
+ IM_ONLINE,
+ IM_FRIENDSHIP_OFFERED,
+ calling_card_folder_id);
+}
+
+//static
+bool LLAvatarActions::isFriend(const LLUUID& id)
+{
+ return ( NULL != LLAvatarTracker::instance().getBuddyInfo(id) );
+}
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
new file mode 100644
index 0000000000..73325d21f1
--- /dev/null
+++ b/indra/newview/llavataractions.h
@@ -0,0 +1,88 @@
+/**
+ * @file llavataractions.h
+ * @brief Friend-related actions (add, remove, offer teleport, etc)
+ *
+ * $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_LLAVATARACTIONS_H
+#define LL_LLAVATARACTIONS_H
+
+/**
+ * Friend-related actions (add, remove, offer teleport, etc)
+ */
+class LLAvatarActions
+{
+public:
+ /**
+ * Show a dialog explaining what friendship entails, then request friendship.
+ */
+ static void requestFriendshipDialog(const LLUUID& id, const std::string& name);
+
+ /**
+ * Show a friend removal dialog.
+ */
+ static void removeFriendDialog(const LLUUID& id);
+ static void removeFriendsDialog(const std::vector<LLUUID>& ids);
+
+ /**
+ * Show teleport offer dialog.
+ */
+ static void offerTeleport(const LLUUID& invitee);
+ static void offerTeleport(const std::vector<LLUUID>& ids);
+
+ /**
+ * Start instant messaging session.
+ */
+ static void startIM(const LLUUID& id);
+
+ /**
+ * Start conference chat with the given avatars.
+ */
+ static void startConference(const std::vector<LLUUID>& ids);
+
+ /**
+ * Show avatar profile.
+ */
+ static void showProfile(const LLUUID& id);
+
+ /**
+ * Return true if avatar with "id" is a friend
+ */
+ static bool isFriend(const LLUUID& id);
+
+private:
+ static bool callbackAddFriend(const LLSD& notification, const LLSD& response);
+ static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
+ static bool handleRemove(const LLSD& notification, const LLSD& response);
+
+ // Just request friendship, no dialog.
+ static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message);
+};
+
+#endif // LL_LLAVATARACTIONS_H
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index bf18abfdb3..a3b8f6726d 100644
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -36,7 +36,7 @@
#include "llavatarconstants.h"
#include "llavatariconctrl.h"
#include "llcallingcard.h" // for LLAvatarTracker
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llimview.h"
#include "llmenugl.h"
#include "lluictrlfactory.h"
@@ -230,7 +230,7 @@ void LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked(const LLSD& userdata)
if (level == "profile")
{
- LLFriendActions::showProfile(id);
+ LLAvatarActions::showProfile(id);
}
else if (level == "im")
{
@@ -248,10 +248,10 @@ void LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked(const LLSD& userdata)
name.append(" ");
name.append(getLastName());
- LLFriendActions::requestFriendshipDialog(id, name);
+ LLAvatarActions::requestFriendshipDialog(id, name);
}
else if (level == "remove")
{
- LLFriendActions::removeFriendDialog(id);
+ LLAvatarActions::removeFriendDialog(id);
}
}
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index d7fd97e067..e37b660951 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -40,24 +40,133 @@
#include "llgesturemgr.h"
#include "llanimationstates.h"
#include "llmultigesture.h"
+#include "llviewerstats.h"
+#include "llcommandhandler.h"
-//FIXME: temporary, for send_chat_from_viewer() proto
-#include "llchatbar.h"
//FIXME: temporary, for stand up proto
#include "llselectmgr.h"
#include "llvoavatarself.h"
-//
-// Globals
-//
-//FIXME: made it adjustable
-const F32 AGENT_TYPING_TIMEOUT = 5.f; // seconds
-LLBottomTray* gBottomTray = NULL;
+S32 LLBottomTray::mLastSpecialChatChannel = 0;
-LLBottomTray::LLBottomTray()
- : mLastSpecialChatChannel(0)
+// legacy calllback glue
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
+
+static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box");
+
+LLGestureComboBox::LLGestureComboBox(const LLComboBox::Params& p)
+ : LLComboBox(p)
, mGestureLabelTimer()
- , mChatBox(NULL)
+{
+ setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this, _1));
+
+ // now register us as observer since we have a place to put the results
+ gGestureManager.addObserver(this);
+
+ // refresh list from current active gestures
+ refreshGestures();
+}
+
+LLGestureComboBox::~LLGestureComboBox()
+{
+ gGestureManager.removeObserver(this);
+}
+
+void LLGestureComboBox::refreshGestures()
+{
+ //store current selection so we can maintain it
+ std::string cur_gesture = getValue().asString();
+ selectFirstItem();
+ std::string label = getValue().asString();;
+ // clear
+ clearRows();
+
+ // collect list of unique gestures
+ std::map <std::string, BOOL> unique;
+ LLGestureManager::item_map_t::iterator it;
+ for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it)
+ {
+ LLMultiGesture* gesture = (*it).second;
+ if (gesture)
+ {
+ if (!gesture->mTrigger.empty())
+ {
+ unique[gesture->mTrigger] = TRUE;
+ }
+ }
+ }
+
+ // add unique gestures
+ std::map <std::string, BOOL>::iterator it2;
+ for (it2 = unique.begin(); it2 != unique.end(); ++it2)
+ {
+ addSimpleElement((*it2).first);
+ }
+
+ sortByName();
+ // Insert label after sorting, at top, with separator below it
+ addSeparator(ADD_TOP);
+ //FIXME: get it from xml
+ addSimpleElement("Gestures", ADD_TOP);
+
+ if (!cur_gesture.empty())
+ {
+ selectByValue(LLSD(cur_gesture));
+ }
+ else
+ {
+ selectFirstItem();
+ }
+}
+
+void LLGestureComboBox::onCommitGesture(LLUICtrl* ctrl)
+{
+ LLCtrlListInterface* gestures = getListInterface();
+ if (gestures)
+ {
+ S32 index = gestures->getFirstSelectedIndex();
+ if (index == 0)
+ {
+ return;
+ }
+ const std::string& trigger = gestures->getSelectedValue().asString();
+
+ // pretend the user chatted the trigger string, to invoke
+ // substitution and logging.
+ std::string text(trigger);
+ std::string revised_text;
+ gGestureManager.triggerAndReviseString(text, &revised_text);
+
+ revised_text = utf8str_trim(revised_text);
+ if (!revised_text.empty())
+ {
+ // Don't play nodding animation
+ LLBottomTray::sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE);
+ }
+ }
+
+ mGestureLabelTimer.start();
+ // free focus back to chat bar
+ setFocus(FALSE);
+}
+
+//virtual
+void LLGestureComboBox::draw()
+{
+ // HACK: Leave the name of the gesture in place for a few seconds.
+ const F32 SHOW_GESTURE_NAME_TIME = 2.f;
+ if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME)
+ {
+ LLCtrlListInterface* gestures = getListInterface();
+ if (gestures) gestures->selectFirstItem();
+ mGestureLabelTimer.stop();
+ }
+
+ LLComboBox::draw();
+}
+
+LLBottomTray::LLBottomTray(const LLSD&)
+ : mChatBox(NULL)
, mChicletPanel(NULL)
, mIMWell(NULL)
, mSysWell(NULL)
@@ -72,7 +181,7 @@ LLBottomTray::LLBottomTray()
mSysWell = getChild<LLNotificationChiclet>("sys_well",TRUE,FALSE);
mChatBox = getChild<LLLineEditor>("chat_box",TRUE,FALSE);
- mChicletPanel->setChicletClickCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));
+ mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));
if (mChatBox)
{
@@ -91,17 +200,7 @@ LLBottomTray::LLBottomTray()
}
- mGestureCombo = getChild<LLComboBox>( "Gesture", TRUE, FALSE);
- if (mGestureCombo)
- {
- mGestureCombo->setCommitCallback(boost::bind(&LLBottomTray::onCommitGesture, this, _1));
-
- // now register us as observer since we have a place to put the results
- gGestureManager.addObserver(this);
-
- // refresh list from current active gestures
- refreshGestures();
- }
+ mGestureCombo = getChild<LLGestureComboBox>( "Gesture", TRUE, FALSE);
////FIXME: temporary, for stand up proto
mStandUpBtn = getChild<LLButton> ("stand", TRUE, FALSE);
@@ -116,11 +215,13 @@ LLBottomTray::LLBottomTray()
//and thus is deleted at the end of the viewers lifetime, but to be cleanly
//destroyed LLBottomTray requires some subsystems that are long gone
LLUI::getRootView()->addChild(this);
+
+ // Necessary for focus movement among child controls
+ setFocusRoot(TRUE);
}
LLBottomTray::~LLBottomTray()
{
- gGestureManager.removeObserver(this);
if (!LLSingleton<LLIMMgr>::destroyed())
{
LLIMMgr::getInstance()->removeSessionObserver(this);
@@ -132,7 +233,7 @@ void LLBottomTray::onChicletClick(LLUICtrl* ctrl)
LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl);
if (chiclet)
{
- LLFloaterReg::showInstance("communicate", chiclet->getIMSessionId());
+ LLFloaterReg::showInstance("communicate", chiclet->getSessionId());
}
}
@@ -278,30 +379,23 @@ void LLBottomTray::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata
gAgent.stopTyping();
}
-void LLBottomTray::refresh()
+BOOL LLBottomTray::inputEditorHasFocus()
{
- // HACK: Leave the name of the gesture in place for a few seconds.
- const F32 SHOW_GESTURE_NAME_TIME = 2.f;
- if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME)
- {
- LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
- if (gestures) gestures->selectFirstItem();
- mGestureLabelTimer.stop();
- }
+ return mChatBox && mChatBox->hasFocus();
+}
- if ((gAgent.getTypingTime() > AGENT_TYPING_TIMEOUT) && (gAgent.getRenderState() & AGENT_STATE_TYPING))
- {
- gAgent.stopTyping();
- }
-
- LLPanel::refresh();
+std::string LLBottomTray::getCurrentChat()
+{
+ return mChatBox ? mChatBox->getText() : LLStringUtil::null;
}
+//virtual
void LLBottomTray::draw()
{
refreshStandUp();
LLPanel::draw();
}
+
void LLBottomTray::refreshStandUp()
{
//FIXME: temporary, for stand up proto
@@ -329,39 +423,6 @@ void LLBottomTray::updateRightPosition(const S32 new_right_position)
}
}
-void LLBottomTray::onCommitGesture(LLUICtrl* ctrl)
-{
- LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
- if (gestures)
- {
- S32 index = gestures->getFirstSelectedIndex();
- if (index == 0)
- {
- return;
- }
- const std::string& trigger = gestures->getSelectedValue().asString();
-
- // pretend the user chatted the trigger string, to invoke
- // substitution and logging.
- std::string text(trigger);
- std::string revised_text;
- gGestureManager.triggerAndReviseString(text, &revised_text);
-
- revised_text = utf8str_trim(revised_text);
- if (!revised_text.empty())
- {
- // Don't play nodding animation
- sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE);
- }
- }
- mGestureLabelTimer.start();
- if (mGestureCombo != NULL)
- {
- // free focus back to chat bar
- mGestureCombo->setFocus(FALSE);
- }
-}
-
//FIXME: temporary, for stand up proto
void LLBottomTray::onCommitStandUp(LLUICtrl* ctrl)
{
@@ -369,80 +430,56 @@ void LLBottomTray::onCommitStandUp(LLUICtrl* ctrl)
gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
}
-void LLBottomTray::refreshGestures()
+//virtual
+void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
{
- if (mGestureCombo)
+ if(getChicletPanel())
{
-
- //store current selection so we can maintain it
- std::string cur_gesture = mGestureCombo->getValue().asString();
- mGestureCombo->selectFirstItem();
- std::string label = mGestureCombo->getValue().asString();;
- // clear
- mGestureCombo->clearRows();
-
- // collect list of unique gestures
- std::map <std::string, BOOL> unique;
- LLGestureManager::item_map_t::iterator it;
- for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it)
- {
- LLMultiGesture* gesture = (*it).second;
- if (gesture)
- {
- if (!gesture->mTrigger.empty())
- {
- unique[gesture->mTrigger] = TRUE;
- }
- }
- }
-
- // add unique gestures
- std::map <std::string, BOOL>::iterator it2;
- for (it2 = unique.begin(); it2 != unique.end(); ++it2)
+ if(getChicletPanel()->findChiclet<LLChiclet>(session_id))
{
- mGestureCombo->addSimpleElement((*it2).first);
- }
-
- mGestureCombo->sortByName();
- // Insert label after sorting, at top, with separator below it
- mGestureCombo->addSeparator(ADD_TOP);
- mGestureCombo->addSimpleElement(getString("gesture_label"), ADD_TOP);
-
- if (!cur_gesture.empty())
- {
- mGestureCombo->selectByValue(LLSD(cur_gesture));
+
}
else
{
- mGestureCombo->selectFirstItem();
+ LLIMChiclet* chicklet = getChicletPanel()->createChiclet<LLIMChiclet>(session_id);
+ chicklet->setIMSessionName(name);
+ chicklet->setOtherParticipantId(other_participant_id);
+
+ if(getChicletPanel()->getChicletCount())
+ {
+ setChicletPanelVisible(true);
+ }
}
}
}
//virtual
-void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+void LLBottomTray::sessionRemoved(const LLUUID& session_id)
{
if(getChicletPanel())
{
- if(getChicletPanel()->findIMChiclet(session_id))
- {
+ getChicletPanel()->removeChiclet(session_id);
- }
- else
+ if(0 == getChicletPanel()->getChicletCount())
{
- LLIMChiclet* chicklet = (LLIMChiclet *)getChicletPanel()->createChiclet(session_id);
- chicklet->setIMSessionName(name);
- chicklet->setOtherParticipantId(other_participant_id);
+ setChicletPanelVisible(false);
}
}
}
-//virtual
-void LLBottomTray::sessionRemoved(const LLUUID& session_id)
+void LLBottomTray::setChicletPanelVisible(bool visible)
{
- if(getChicletPanel())
+ // Chiclet panel is placed in layout_panel, which is child of layout_stack.
+ // To gide chiclet panel we need to also hide layout_panel to make layout_stack resize its
+ // content.
+ getChicletPanel()->getParent()->setVisible(visible);
+ if(visible)
{
- getChicletPanel()->removeIMChiclet(session_id);
+ // Reshape layout stack after making chiclet panel visible
+ LLView* layout = getChild<LLView>("toolbar_stack");
+ LLRect rc = layout->getRect();
+ layout->reshape(rc.getWidth(), rc.getHeight());
+ layout->setRect(rc);
}
}
@@ -503,6 +540,41 @@ void LLBottomTray::setVisible(BOOL visible)
}
+// static
+void LLBottomTray::startChat(const char* line)
+{
+ LLBottomTray *bt = LLBottomTray::getInstance();
+
+ if(bt && bt->getChatBox())
+ {
+ bt->setVisible(TRUE);
+ bt->getChatBox()->setFocus(TRUE);
+
+ if (line)
+ {
+ std::string line_string(line);
+ bt->getChatBox()->setText(line_string);
+ }
+
+ bt->getChatBox()->setCursorToEnd();
+ }
+}
+
+// Exit "chat mode" and do the appropriate focus changes
+// static
+void LLBottomTray::stopChat()
+{
+ LLBottomTray *bt = LLBottomTray::getInstance();
+
+ if(bt && bt->getChatBox())
+ {
+ bt->getChatBox()->setFocus(FALSE);
+ }
+
+ // stop typing animation
+ gAgent.stopTyping();
+}
+
void LLBottomTray::sendChat( EChatType type )
{
if (mChatBox)
@@ -593,3 +665,42 @@ LLWString LLBottomTray::stripChannelNumber(const LLWString &mesg, S32* channel)
return mesg;
}
}
+
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_ChatFromViewer);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_ChatData);
+ msg->addStringFast(_PREHASH_Message, utf8_out_text);
+ msg->addU8Fast(_PREHASH_Type, type);
+ msg->addS32("Channel", channel);
+
+ gAgent.sendReliableMessage();
+
+ LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
+}
+
+class LLChatHandler : public LLCommandHandler
+{
+public:
+ // not allowed from outside the app
+ LLChatHandler() : LLCommandHandler("chat", true) { }
+
+ // Your code here
+ bool handle(const LLSD& tokens, const LLSD& query_map,
+ LLWebBrowserCtrl* web)
+ {
+ if (tokens.size() < 2) return false;
+ S32 channel = tokens[0].asInteger();
+ std::string mesg = tokens[1].asString();
+ send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
+ return true;
+ }
+};
+
+// Creating the object registers with the dispatcher.
+LLChatHandler gChatHandler;
+
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 0d477122d1..1d4e271f80 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -37,20 +37,40 @@
#include "llimview.h"
#include "llchat.h"
#include "llgesturemgr.h"
+#include "llcombobox.h"
class LLChicletPanel;
class LLNotificationChiclet;
class LLTalkButton;
-class LLComboBox;
-class LLBottomTray
- : public LLPanel
- , public LLIMSessionObserver
+class LLGestureComboBox
+ : public LLComboBox
, public LLGestureManagerObserver
{
+protected:
+ LLGestureComboBox(const LLComboBox::Params&);
+ friend class LLUICtrlFactory;
public:
- LLBottomTray();
+ ~LLGestureComboBox();
+
+ void refreshGestures();
+ void onCommitGesture(LLUICtrl* ctrl);
+ virtual void draw();
+
+ // LLGestureManagerObserver trigger
+ virtual void changed() { refreshGestures(); }
+
+protected:
+ LLFrameTimer mGestureLabelTimer;
+};
+class LLBottomTray
+ : public LLUISingleton<LLBottomTray>
+ , public LLPanel
+ , public LLIMSessionObserver
+{
+ friend class LLUISingleton<LLBottomTray>;
+public:
~LLBottomTray();
LLLineEditor* getChatBox() {return mChatBox;}
@@ -59,12 +79,14 @@ public:
LLNotificationChiclet* getSysWell() {return mSysWell;}
void onChatBoxCommit();
- void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
- void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
+ static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
+ static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
- void refresh();
+ BOOL inputEditorHasFocus();
+ std::string getCurrentChat();
+
/*virtual*/void draw();
void refreshStandUp();
void updateRightPosition(const S32 new_right_position);
@@ -77,33 +99,34 @@ public:
virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
virtual void sessionRemoved(const LLUUID& session_id);
- // LLGestureManagerObserver trigger
- virtual void changed() { refreshGestures(); }
-
virtual void onFocusLost();
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual void setVisible(BOOL visible);
+ static void startChat(const char* line);
+ static void stopChat();
+
protected:
+ LLBottomTray(const LLSD& key = LLSD());
+
void sendChat( EChatType type );
- LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
+ static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
void onChicletClick(LLUICtrl* ctrl);
+ void setChicletPanelVisible(bool visible);
+
// Which non-zero channel did we last chat on?
- S32 mLastSpecialChatChannel;
+ static S32 mLastSpecialChatChannel;
LLLineEditor* mChatBox;
LLChicletPanel* mChicletPanel;
LLNotificationChiclet* mIMWell;
LLNotificationChiclet* mSysWell;
LLTalkButton* mTalkBtn;
- LLComboBox* mGestureCombo;
- LLFrameTimer mGestureLabelTimer;
+ LLGestureComboBox* mGestureCombo;
LLButton* mStandUpBtn;
};
-extern LLBottomTray* gBottomTray;
-
#endif // LL_LLBOTTOMPANEL_H
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
deleted file mode 100644
index b94229704f..0000000000
--- a/indra/newview/llchatbar.cpp
+++ /dev/null
@@ -1,692 +0,0 @@
-/**
- * @file llchatbar.cpp
- * @brief LLChatBar class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-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 "llchatbar.h"
-
-#include "imageids.h"
-#include "llfontgl.h"
-#include "llrect.h"
-#include "llerror.h"
-#include "llparcel.h"
-#include "llstring.h"
-#include "message.h"
-#include "llfocusmgr.h"
-
-#include "llagent.h"
-#include "llbutton.h"
-#include "llcombobox.h"
-#include "llcommandhandler.h" // secondlife:///app/chat/ support
-#include "llviewercontrol.h"
-#include "llfloaterchat.h"
-#include "llgesturemgr.h"
-#include "llkeyboard.h"
-#include "lllineeditor.h"
-#include "llstatusbar.h"
-#include "lltextbox.h"
-#include "lluiconstants.h"
-#include "llviewergesture.h" // for triggering gestures
-#include "llviewermenu.h" // for deleting object with DEL key
-#include "llviewerstats.h"
-#include "llviewerwindow.h"
-#include "llframetimer.h"
-#include "llresmgr.h"
-#include "llworld.h"
-#include "llinventorymodel.h"
-#include "llmultigesture.h"
-#include "llui.h"
-#include "llviewermenu.h"
-#include "lluictrlfactory.h"
-#include "llbottomtray.h"
-
-//
-// Globals
-//
-const F32 AGENT_TYPING_TIMEOUT = 5.f; // seconds
-
-LLChatBar *gChatBar = NULL;
-
-class LLChatBarGestureObserver : public LLGestureManagerObserver
-{
-public:
- LLChatBarGestureObserver(LLChatBar* chat_barp) : mChatBar(chat_barp){}
- virtual ~LLChatBarGestureObserver() {}
- virtual void changed() { mChatBar->refreshGestures(); }
-private:
- LLChatBar* mChatBar;
-};
-
-
-//
-// Functions
-//
-
-LLChatBar::LLChatBar()
-: LLPanel(),
- mInputEditor(NULL),
- mGestureLabelTimer(),
- mLastSpecialChatChannel(0),
- mIsBuilt(FALSE),
- mGestureCombo(NULL),
- mObserver(NULL)
-{
- setIsChrome(TRUE);
-
-#if !LL_RELEASE_FOR_DOWNLOAD
- childDisplayNotFound();
-#endif
-}
-
-
-LLChatBar::~LLChatBar()
-{
- gGestureManager.removeObserver(mObserver);
- delete mObserver;
- mObserver = NULL;
- // LLView destructor cleans up children
-}
-
-BOOL LLChatBar::postBuild()
-{
- getChild<LLUICtrl>("Say")->setCommitCallback(boost::bind(&LLChatBar::onClickSay, this, _1));
-
- // attempt to bind to an existing combo box named gesture
- setGestureCombo(getChild<LLComboBox>( "Gesture", TRUE, FALSE));
-
- mInputEditor = getChild<LLLineEditor>("Chat Editor");
- mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke, this);
- mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this);
- mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this );
- mInputEditor->setCommitOnFocusLost( FALSE );
- mInputEditor->setRevertOnEsc( FALSE );
- mInputEditor->setIgnoreTab(TRUE);
- mInputEditor->setPassDelete(TRUE);
- mInputEditor->setReplaceNewlinesWithSpaces(FALSE);
-
- mInputEditor->setMaxTextLength(1023);
- mInputEditor->setEnableLineHistory(TRUE);
-
- mIsBuilt = TRUE;
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------
-// Overrides
-//-----------------------------------------------------------------------
-
-// virtual
-BOOL LLChatBar::handleKeyHere( KEY key, MASK mask )
-{
- BOOL handled = FALSE;
-
- // ALT-RETURN is reserved for windowed/fullscreen toggle
- if( KEY_RETURN == key )
- {
- if (mask == MASK_CONTROL)
- {
- // shout
- sendChat(CHAT_TYPE_SHOUT);
- handled = TRUE;
- }
- else if (mask == MASK_NONE)
- {
- // say
- sendChat( CHAT_TYPE_NORMAL );
- handled = TRUE;
- }
- }
- // only do this in main chatbar
- else if ( KEY_ESCAPE == key && gChatBar == this)
- {
- stopChat();
-
- handled = TRUE;
- }
-
- return handled;
-}
-
-void LLChatBar::refresh()
-{
- // HACK: Leave the name of the gesture in place for a few seconds.
- const F32 SHOW_GESTURE_NAME_TIME = 2.f;
- if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME)
- {
- LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
- if (gestures) gestures->selectFirstItem();
- mGestureLabelTimer.stop();
- }
-
- if ((gAgent.getTypingTime() > AGENT_TYPING_TIMEOUT) && (gAgent.getRenderState() & AGENT_STATE_TYPING))
- {
- gAgent.stopTyping();
- }
-
- childSetEnabled("Say", mInputEditor->getText().size() > 0);
-
-}
-
-void LLChatBar::refreshGestures()
-{
- if (mGestureCombo)
- {
- //store current selection so we can maintain it
- std::string cur_gesture = mGestureCombo->getValue().asString();
- mGestureCombo->selectFirstItem();
- std::string label = mGestureCombo->getValue().asString();;
- // clear
- mGestureCombo->clearRows();
-
- // collect list of unique gestures
- std::map <std::string, BOOL> unique;
- LLGestureManager::item_map_t::iterator it;
- for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it)
- {
- LLMultiGesture* gesture = (*it).second;
- if (gesture)
- {
- if (!gesture->mTrigger.empty())
- {
- unique[gesture->mTrigger] = TRUE;
- }
- }
- }
-
- // add unique gestures
- std::map <std::string, BOOL>::iterator it2;
- for (it2 = unique.begin(); it2 != unique.end(); ++it2)
- {
- mGestureCombo->addSimpleElement((*it2).first);
- }
-
- mGestureCombo->sortByName();
- // Insert label after sorting, at top, with separator below it
- mGestureCombo->addSeparator(ADD_TOP);
- mGestureCombo->addSimpleElement(getString("gesture_label"), ADD_TOP);
-
- if (!cur_gesture.empty())
- {
- mGestureCombo->selectByValue(LLSD(cur_gesture));
- }
- else
- {
- mGestureCombo->selectFirstItem();
- }
- }
-}
-
-// Move the cursor to the correct input field.
-void LLChatBar::setKeyboardFocus(BOOL focus)
-{
- if (focus)
- {
- if (mInputEditor)
- {
- mInputEditor->setFocus(TRUE);
- mInputEditor->selectAll();
- }
- }
- else if (gFocusMgr.childHasKeyboardFocus(this))
- {
- if (mInputEditor)
- {
- mInputEditor->deselect();
- }
- setFocus(FALSE);
- }
-}
-
-
-// Ignore arrow keys in chat bar
-void LLChatBar::setIgnoreArrowKeys(BOOL b)
-{
- if (mInputEditor)
- {
- mInputEditor->setIgnoreArrowKeys(b);
- }
-}
-
-BOOL LLChatBar::inputEditorHasFocus()
-{
- return mInputEditor && mInputEditor->hasFocus();
-}
-
-std::string LLChatBar::getCurrentChat()
-{
- return mInputEditor ? mInputEditor->getText() : LLStringUtil::null;
-}
-
-void LLChatBar::setGestureCombo(LLComboBox* combo)
-{
- mGestureCombo = combo;
- if (mGestureCombo)
- {
- mGestureCombo->setCommitCallback(boost::bind(&LLChatBar::onCommitGesture, this, _1));
-
- // now register observer since we have a place to put the results
- mObserver = new LLChatBarGestureObserver(this);
- gGestureManager.addObserver(mObserver);
-
- // refresh list from current active gestures
- refreshGestures();
- }
-}
-
-//-----------------------------------------------------------------------
-// Internal functions
-//-----------------------------------------------------------------------
-
-// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
-// Otherwise returns input and channel 0.
-LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
-{
- if (mesg[0] == '/'
- && mesg[1] == '/')
- {
- // This is a "repeat channel send"
- *channel = mLastSpecialChatChannel;
- return mesg.substr(2, mesg.length() - 2);
- }
- else if (mesg[0] == '/'
- && mesg[1]
- && LLStringOps::isDigit(mesg[1]))
- {
- // This a special "/20" speak on a channel
- S32 pos = 0;
-
- // Copy the channel number into a string
- LLWString channel_string;
- llwchar c;
- do
- {
- c = mesg[pos+1];
- channel_string.push_back(c);
- pos++;
- }
- while(c && pos < 64 && LLStringOps::isDigit(c));
-
- // Move the pointer forward to the first non-whitespace char
- // Check isspace before looping, so we can handle "/33foo"
- // as well as "/33 foo"
- while(c && iswspace(c))
- {
- c = mesg[pos+1];
- pos++;
- }
-
- mLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
- *channel = mLastSpecialChatChannel;
- return mesg.substr(pos, mesg.length() - pos);
- }
- else
- {
- // This is normal chat.
- *channel = 0;
- return mesg;
- }
-}
-
-
-void LLChatBar::sendChat( EChatType type )
-{
- if (mInputEditor)
- {
- LLWString text = mInputEditor->getConvertedText();
- if (!text.empty())
- {
- // store sent line in history, duplicates will get filtered
- if (mInputEditor) mInputEditor->updateHistory();
- // Check if this is destined for another channel
- S32 channel = 0;
- stripChannelNumber(text, &channel);
-
- std::string utf8text = wstring_to_utf8str(text);
- // Try to trigger a gesture, if not chat to a script.
- std::string utf8_revised_text;
- if (0 == channel)
- {
- // discard returned "found" boolean
- gGestureManager.triggerAndReviseString(utf8text, &utf8_revised_text);
- }
- else
- {
- utf8_revised_text = utf8text;
- }
-
- utf8_revised_text = utf8str_trim(utf8_revised_text);
-
- if (!utf8_revised_text.empty())
- {
- // Chat with animation
- sendChatFromViewer(utf8_revised_text, type, TRUE);
- }
- }
- }
-
- childSetValue("Chat Editor", LLStringUtil::null);
-
- gAgent.stopTyping();
-
- // If the user wants to stop chatting on hitting return, lose focus
- // and go out of chat mode.
- if (gChatBar == this && gSavedSettings.getBOOL("CloseChatOnReturn"))
- {
- stopChat();
- }
-}
-
-
-//-----------------------------------------------------------------------
-// Static functions
-//-----------------------------------------------------------------------
-
-// static
-void LLChatBar::startChat(const char* line)
-{
- //TODO* remove DUMMY chat
- if(gBottomTray && gBottomTray->getChatBox())
- {
- gBottomTray->setVisible(TRUE);
- gBottomTray->getChatBox()->setFocus(TRUE);
- }
-
- // *TODO Vadim: Why was this code commented out?
-
-// gChatBar->setVisible(TRUE);
-// gChatBar->setKeyboardFocus(TRUE);
-// gSavedSettings.setBOOL("ChatVisible", TRUE);
-//
-// if (line && gChatBar->mInputEditor)
-// {
-// std::string line_string(line);
-// gChatBar->mInputEditor->setText(line_string);
-// }
-// // always move cursor to end so users don't obliterate chat when accidentally hitting WASD
-// gChatBar->mInputEditor->setCursorToEnd();
-}
-
-
-// Exit "chat mode" and do the appropriate focus changes
-// static
-void LLChatBar::stopChat()
-{
- //TODO* remove DUMMY chat
- if(gBottomTray && gBottomTray->getChatBox())
- {
- gBottomTray->getChatBox()->setFocus(FALSE);
- }
-
- // *TODO Vadim: Why was this code commented out?
-
-// // In simple UI mode, we never release focus from the chat bar
-// gChatBar->setKeyboardFocus(FALSE);
-//
-// // If we typed a movement key and pressed return during the
-// // same frame, the keyboard handlers will see the key as having
-// // gone down this frame and try to move the avatar.
-// gKeyboard->resetKeys();
-// gKeyboard->resetMaskKeys();
-//
-// // stop typing animation
-// gAgent.stopTyping();
-//
-// // hide chat bar so it doesn't grab focus back
-// gChatBar->setVisible(FALSE);
-// gSavedSettings.setBOOL("ChatVisible", FALSE);
-}
-
-// static
-void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata )
-{
- LLChatBar* self = (LLChatBar *)userdata;
-
- LLWString raw_text;
- if (self->mInputEditor) raw_text = self->mInputEditor->getWText();
-
- // Can't trim the end, because that will cause autocompletion
- // to eat trailing spaces that might be part of a gesture.
- LLWStringUtil::trimHead(raw_text);
-
- S32 length = raw_text.length();
-
- if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences
- {
- gAgent.startTyping();
- }
- else
- {
- gAgent.stopTyping();
- }
-
- /* Doesn't work -- can't tell the difference between a backspace
- that killed the selection vs. backspace at the end of line.
- if (length > 1
- && text[0] == '/'
- && key == KEY_BACKSPACE)
- {
- // the selection will already be deleted, but we need to trim
- // off the character before
- std::string new_text = raw_text.substr(0, length-1);
- self->mInputEditor->setText( new_text );
- self->mInputEditor->setCursorToEnd();
- length = length - 1;
- }
- */
-
- KEY key = gKeyboard->currentKey();
-
- // Ignore "special" keys, like backspace, arrows, etc.
- if (length > 1
- && raw_text[0] == '/'
- && key < KEY_SPECIAL)
- {
- // we're starting a gesture, attempt to autocomplete
-
- std::string utf8_trigger = wstring_to_utf8str(raw_text);
- std::string utf8_out_str(utf8_trigger);
-
- if (gGestureManager.matchPrefix(utf8_trigger, &utf8_out_str))
- {
- if (self->mInputEditor)
- {
- std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
- self->mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
- S32 outlength = self->mInputEditor->getLength(); // in characters
-
- // Select to end of line, starting from the character
- // after the last one the user typed.
- self->mInputEditor->setSelection(length, outlength);
- }
- }
-
- //llinfos << "GESTUREDEBUG " << trigger
- // << " len " << length
- // << " outlen " << out_str.getLength()
- // << llendl;
- }
-}
-
-// static
-void LLChatBar::onInputEditorFocusLost( LLFocusableElement* caller, void* userdata)
-{
- // stop typing animation
- gAgent.stopTyping();
-}
-
-// static
-void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userdata )
-{
- LLFloaterChat::setHistoryCursorAndScrollToEnd();
-}
-
-void LLChatBar::onClickSay( LLUICtrl* ctrl )
-{
- std::string cmd = ctrl->getValue().asString();
- e_chat_type chat_type = CHAT_TYPE_NORMAL;
- if (cmd == "shout")
- {
- chat_type = CHAT_TYPE_SHOUT;
- }
- else if (cmd == "whisper")
- {
- chat_type = CHAT_TYPE_WHISPER;
- }
- sendChat(chat_type);
-}
-
-void LLChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
-{
- sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
-}
-
-void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
-{
- // Look for "/20 foo" channel chats.
- S32 channel = 0;
- LLWString out_text = stripChannelNumber(wtext, &channel);
- std::string utf8_out_text = wstring_to_utf8str(out_text);
- std::string utf8_text = wstring_to_utf8str(wtext);
-
- utf8_text = utf8str_trim(utf8_text);
- if (!utf8_text.empty())
- {
- utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
- }
-
- // Don't animate for chats people can't hear (chat to scripts)
- if (animate && (channel == 0))
- {
- if (type == CHAT_TYPE_WHISPER)
- {
- lldebugs << "You whisper " << utf8_text << llendl;
- gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
- }
- else if (type == CHAT_TYPE_NORMAL)
- {
- lldebugs << "You say " << utf8_text << llendl;
- gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
- }
- else if (type == CHAT_TYPE_SHOUT)
- {
- lldebugs << "You shout " << utf8_text << llendl;
- gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
- }
- else
- {
- llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
- return;
- }
- }
- else
- {
- if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
- {
- lldebugs << "Channel chat: " << utf8_text << llendl;
- }
- }
-
- send_chat_from_viewer(utf8_out_text, type, channel);
-}
-
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
-{
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ChatFromViewer);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ChatData);
- msg->addStringFast(_PREHASH_Message, utf8_out_text);
- msg->addU8Fast(_PREHASH_Type, type);
- msg->addS32("Channel", channel);
-
- gAgent.sendReliableMessage();
-
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
-}
-
-
-void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
-{
- LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
- if (gestures)
- {
- S32 index = gestures->getFirstSelectedIndex();
- if (index == 0)
- {
- return;
- }
- const std::string& trigger = gestures->getSelectedValue().asString();
-
- // pretend the user chatted the trigger string, to invoke
- // substitution and logging.
- std::string text(trigger);
- std::string revised_text;
- gGestureManager.triggerAndReviseString(text, &revised_text);
-
- revised_text = utf8str_trim(revised_text);
- if (!revised_text.empty())
- {
- // Don't play nodding animation
- sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE);
- }
- }
- mGestureLabelTimer.start();
- if (mGestureCombo != NULL)
- {
- // free focus back to chat bar
- mGestureCombo->setFocus(FALSE);
- }
-}
-
-class LLChatHandler : public LLCommandHandler
-{
-public:
- // not allowed from outside the app
- LLChatHandler() : LLCommandHandler("chat", true) { }
-
- // Your code here
- bool handle(const LLSD& tokens, const LLSD& query_map,
- LLWebBrowserCtrl* web)
- {
- if (tokens.size() < 2) return false;
- S32 channel = tokens[0].asInteger();
- std::string mesg = tokens[1].asString();
- send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
- return true;
- }
-};
-
-// Creating the object registers with the dispatcher.
-LLChatHandler gChatHandler;
diff --git a/indra/newview/llchatbar.h b/indra/newview/llchatbar.h
deleted file mode 100644
index e0e324af6b..0000000000
--- a/indra/newview/llchatbar.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * @file llchatbar.h
- * @brief LLChatBar class definition
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-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_LLCHATBAR_H
-#define LL_LLCHATBAR_H
-
-#include "llpanel.h"
-#include "llframetimer.h"
-#include "llchat.h"
-
-class LLLineEditor;
-class LLMessageSystem;
-class LLUICtrl;
-class LLUUID;
-class LLFrameTimer;
-class LLChatBarGestureObserver;
-class LLComboBox;
-
-// legacy calllback glue
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
-
-class LLChatBar
-: public LLPanel
-{
-public:
- // constructor for inline chat-bars (e.g. hosted in chat history window)
- LLChatBar();
- ~LLChatBar();
- virtual BOOL postBuild();
-
- virtual BOOL handleKeyHere(KEY key, MASK mask);
-
- void refresh();
- void refreshGestures();
-
- // Move cursor into chat input field.
- void setKeyboardFocus(BOOL b);
-
- // Ignore arrow keys for chat bar
- void setIgnoreArrowKeys(BOOL b);
-
- BOOL inputEditorHasFocus();
- std::string getCurrentChat();
-
- // since chat bar logic is reused for chat history
- // gesture combo box might not be a direct child
- void setGestureCombo(LLComboBox* combo);
-
- // Send a chat (after stripping /20foo channel chats).
- // "Animate" means the nodding animation for regular text.
- void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
- void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
-
- // If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
- // Otherwise returns input and channel 0.
- LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
-
- // callbacks
- void onClickSay(LLUICtrl* ctrl);
-
- static void onTabClick( void* userdata );
- static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
- static void onInputEditorFocusLost(LLFocusableElement* caller,void* userdata);
- static void onInputEditorGainFocus(LLFocusableElement* caller,void* userdata);
-
- void onCommitGesture(LLUICtrl* ctrl);
-
- static void startChat(const char* line);
- static void stopChat();
-
-protected:
- void sendChat(EChatType type);
- void updateChat();
-
-protected:
- LLLineEditor* mInputEditor;
-
- LLFrameTimer mGestureLabelTimer;
-
- // Which non-zero channel did we last chat on?
- S32 mLastSpecialChatChannel;
-
- BOOL mIsBuilt;
- LLComboBox* mGestureCombo;
-
- LLChatBarGestureObserver* mObserver;
-};
-
-extern LLChatBar *gChatBar;
-
-#endif
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 4999d05e44..bd946a79d6 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -32,72 +32,58 @@
#include "llviewerprecompiledheaders.h" // must be first include
#include "llchiclet.h"
-#include "llvoiceclient.h"
#include "llagent.h"
-#include "lltextbox.h"
-#include "lliconctrl.h"
-#include "llvoicecontrolpanel.h"
-#include "lloutputmonitorctrl.h"
-#include "llimview.h"
+#include "llavataractions.h"
#include "llbottomtray.h"
+#include "llgroupactions.h"
+#include "lliconctrl.h"
#include "llimpanel.h"
+#include "llimview.h"
+#include "llfloatergroupinfo.h"
+#include "llmenugl.h"
+#include "lloutputmonitorctrl.h"
+#include "lltextbox.h"
+#include "llvoiceclient.h"
+#include "llvoicecontrolpanel.h"
-static const S32 CHICLET_HEIGHT = 25;
-static const S32 CHICLET_SPACING = 0;
-static const S32 CHICLET_PADDING = 3;
-static const S32 AVATAR_WIDTH = 25;
-static const S32 SPEAKER_WIDTH = 20;
-static const S32 COUNTER_WIDTH = 20;
-static const S32 SCROLL_BUTTON_WIDTH = 19;
-static const S32 SCROLL_BUTTON_HEIGHT = 20;
-static const S32 NOTIFICATION_TEXT_TOP_PAD = 5;
+static const std::string P2P_MENU_NAME = "IMChiclet P2P Menu";
+static const std::string GROUP_MENU_NAME = "IMChiclet Group Menu";
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
static LLDefaultChildRegistry::Register<LLNotificationChiclet> t3("chiclet_notification");
-static LLDefaultChildRegistry::Register<LLChicletPanel> t4("chiclet_panel");
+static LLDefaultChildRegistry::Register<LLIMChiclet> t4("chiclet_im");
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
LLNotificationChiclet::Params::Params()
-: image_unselected("image_unselected")
-, image_selected("image_selected")
-, image_overlay("image_overlay")
+: button("button")
+, unread_notifications("unread_notifications")
{
+ button.tab_stop(FALSE);
+ button.label(LLStringUtil::null);
+
+ unread_notifications.font(LLFontGL::getFontSansSerif());
+ unread_notifications.text_color=(LLColor4::white);
+ unread_notifications.font_halign(LLFontGL::HCENTER);
+ unread_notifications.mouse_opaque(FALSE);
}
LLNotificationChiclet::LLNotificationChiclet(const Params& p)
: LLChiclet(p)
, mButton(NULL)
-, mCounterText(NULL)
-{
- LLRect rc(p.rect);
-
- LLButton::Params button_params;
- button_params.name("btn");
- button_params.label(LLStringUtil::null);
- button_params.rect(LLRect(0,rc.getHeight(),rc.getWidth(),0));
- button_params.image_overlay(p.image_overlay);
- button_params.image_unselected(p.image_unselected);
- button_params.image_selected(p.image_selected);
- button_params.tab_stop(false);
+, mCounterCtrl(NULL)
+{
+ LLButton::Params button_params = p.button;
+ button_params.rect(p.rect());
mButton = LLUICtrlFactory::create<LLButton>(button_params);
addChild(mButton);
- LLTextBox::Params textbox_params;
- textbox_params.name("txt");
- textbox_params.rect(LLRect(p.label_left,rc.getHeight(),
- rc.getWidth()-p.label_left,0));
- textbox_params.mouse_opaque(false);
- textbox_params.v_pad(NOTIFICATION_TEXT_TOP_PAD);
- textbox_params.font.style("SansSerif");
- textbox_params.font_halign(LLFontGL::HCENTER);
- mCounterText = LLUICtrlFactory::create<LLTextBox>(textbox_params);
- addChild(mCounterText);
- mCounterText->setColor(LLColor4::white);
- mCounterText->setText(LLStringUtil::null);
+ LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
+ mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
+ addChild(mCounterCtrl);
}
LLNotificationChiclet::~LLNotificationChiclet()
@@ -105,18 +91,15 @@ LLNotificationChiclet::~LLNotificationChiclet()
}
-LLChiclet* LLNotificationChiclet::create(const Params& p)
+void LLNotificationChiclet::setCounter(S32 counter)
{
- LLChiclet* chiclet = new LLNotificationChiclet(p);
- return chiclet;
+ mCounterCtrl->setCounter(counter);
}
-void LLNotificationChiclet::setCounter(S32 counter)
+void LLNotificationChiclet::setShowCounter(bool show)
{
- std::stringstream stream;
- mCounter = counter;
- stream << mCounter;
- mCounterText->setText(stream.str());
+ LLChiclet::setShowCounter(show);
+ mCounterCtrl->setVisible(getShowCounter());
}
boost::signals2::connection LLNotificationChiclet::setClickCallback(
@@ -129,10 +112,16 @@ boost::signals2::connection LLNotificationChiclet::setClickCallback(
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
+LLChiclet::Params::Params()
+ : show_counter("show_counter")
+{
+ show_counter = true;
+}
+
LLChiclet::LLChiclet(const Params& p)
: LLUICtrl(p)
-, mCounter(0)
-, mShowCounter(true)
+, mSessionId(LLUUID::null)
+, mShowCounter(p.show_counter)
{
}
@@ -155,91 +144,133 @@ BOOL LLChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
return TRUE;
}
+boost::signals2::connection LLChiclet::setChicletSizeChangedCallback(
+ const chiclet_size_changed_callback_t& cb)
+{
+ return mChicletSizeChangedSignal.connect(cb);
+}
+
+void LLChiclet::onChicletSizeChanged()
+{
+ mChicletSizeChangedSignal(this, getValue());
+}
+
+LLSD LLChiclet::getValue() const
+{
+ return LLSD(getSessionId());
+}
+
+void LLChiclet::setValue(const LLSD& value)
+{
+ if(value.isUUID())
+ setSessionId(value.asUUID());
+}
+
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLIMChiclet::LLIMChiclet(const LLChiclet::Params& p)
-: LLChiclet(p)
-, mAvatar(NULL)
-, mCounterText(NULL)
-, mSpeaker(NULL)
-, mIMSessionId(LLUUID::null)
-, mShowSpeaker(false)
-, mSpeakerStatus(SPEAKER_IDLE)
-{
- LLAvatarIconCtrl::Params avatar_params;
- avatar_params.control_name("avatar");
- avatar_params.draw_tooltip = FALSE;
- mAvatar = LLUICtrlFactory::create<LLAvatarIconCtrl>(avatar_params);
-
- addChild(mAvatar);
-
- LLTextBox::Params unread_params;
- unread_params.font.style("SansSerif");
- unread_params.font_halign(LLFontGL::HCENTER);
- unread_params.v_pad(5);
- mCounterText = LLUICtrlFactory::create<LLTextBox>(unread_params);
- addChild(mCounterText);
- mCounterText->setColor(LLColor4::white);
- setCounter(getCounter());
+LLIMChiclet::Params::Params()
+: avatar_icon("avatar_icon")
+, unread_notifications("unread_notifications")
+, speaker("speaker")
+, show_speaker("show_speaker")
+{
+ rect(LLRect(0, 25, 45, 0));
+
+ avatar_icon.name("avatar_icon");
+ avatar_icon.rect(LLRect(0, 25, 25, 0));
- LLIconCtrl::Params speaker_params;
- speaker_params.image( LLUI::getUIImage("icn_voice_ptt-on-lvl2.tga") );
- mSpeaker = LLUICtrlFactory::create<LLIconCtrl>(speaker_params);
- addChild(mSpeaker);
- mSpeaker->setVisible(getShowSpeaker());
+ unread_notifications.name("unread");
+ unread_notifications.rect(LLRect(25, 25, 45, 0));
+ unread_notifications.font(LLFontGL::getFontSansSerif());
+ unread_notifications.font_halign(LLFontGL::HCENTER);
+ unread_notifications.v_pad(5);
+ unread_notifications.text_color(LLColor4::white);
- S32 left = 0;
- mAvatar->setRect(LLRect(left,CHICLET_HEIGHT,AVATAR_WIDTH,0));
- left += AVATAR_WIDTH + CHICLET_SPACING;
- mCounterText->setRect(LLRect(left,CHICLET_HEIGHT,left + COUNTER_WIDTH,0));
- left += COUNTER_WIDTH + CHICLET_SPACING;
- mSpeaker->setRect(LLRect(left,CHICLET_HEIGHT,left + SPEAKER_WIDTH,0));
+ speaker.name("speaker");
+ speaker.rect(LLRect(45, 25, 65, 0));
+
+ show_speaker = false;
}
-LLIMChiclet::~LLIMChiclet()
+LLIMChiclet::LLIMChiclet(const Params& p)
+: LLChiclet(p)
+, mAvatarCtrl(NULL)
+, mCounterCtrl(NULL)
+, mSpeakerCtrl(NULL)
+, mShowSpeaker(p.show_speaker)
+, mPopupMenu(NULL)
{
+ LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
+ mAvatarCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
+ addChild(mAvatarCtrl);
+
+ LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
+ mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
+ addChild(mCounterCtrl);
+
+ setCounter(getCounter());
+ setShowCounter(getShowCounter());
+
+ LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
+ mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
+ addChild(mSpeakerCtrl);
+ setShowSpeaker(getShowSpeaker());
}
-LLChiclet* LLIMChiclet::create(const LLUUID& im_session_id /* = LLUUID::null */)
+LLIMChiclet::~LLIMChiclet()
{
- LLIMChiclet* chiclet = new LLIMChiclet(LLChiclet::Params());
- chiclet->setIMSessionId(im_session_id);
- return chiclet;
+
}
void LLIMChiclet::setCounter(S32 counter)
{
- mCounter = counter;
- std::stringstream stream;
- stream << mCounter;
- mCounterText->setText(stream.str());
+ mCounterCtrl->setCounter(counter);
- LLRect rc = mCounterText->getRect();
- rc.mRight = rc.mLeft + calcCounterWidth();
- mCounterText->setRect(rc);
+ if(getShowCounter())
+ {
+ LLRect counter_rect = mCounterCtrl->getRect();
+ LLRect required_rect = mCounterCtrl->getRequiredRect();
+ bool needs_resize = required_rect.getWidth() != counter_rect.getWidth();
+
+ if(needs_resize)
+ {
+ counter_rect.mRight = counter_rect.mLeft + required_rect.getWidth();
+ mCounterCtrl->reshape(counter_rect.getWidth(), counter_rect.getHeight());
+ mCounterCtrl->setRect(counter_rect);
+
+ onChicletSizeChanged();
+ }
+ }
}
LLRect LLIMChiclet::getRequiredRect()
{
- LLRect rect(0,CHICLET_HEIGHT,AVATAR_WIDTH,0);
+ LLRect rect(0, 0, mAvatarCtrl->getRect().getWidth(), 0);
if(getShowCounter())
{
- rect.mRight += CHICLET_SPACING + calcCounterWidth();
+ rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
}
if(getShowSpeaker())
{
- rect.mRight += CHICLET_SPACING + SPEAKER_WIDTH;
+ rect.mRight += mSpeakerCtrl->getRect().getWidth();
}
return rect;
}
void LLIMChiclet::setShowCounter(bool show)
{
+ bool needs_resize = getShowCounter() != show;
+
LLChiclet::setShowCounter(show);
- mCounterText->setVisible(getShowCounter());
+ mCounterCtrl->setVisible(getShowCounter());
+
+ if(needs_resize)
+ {
+ onChicletSizeChanged();
+ }
}
void LLIMChiclet::setIMSessionName(const std::string& name)
@@ -249,16 +280,39 @@ void LLIMChiclet::setIMSessionName(const std::string& name)
void LLIMChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
{
- if (mAvatar)
+ if (mAvatarCtrl)
{
- mAvatar->setValue(other_participant_id);
+ mAvatarCtrl->setValue(other_participant_id);
+ }
+}
+
+void LLIMChiclet::updateMenuItems()
+{
+ if(!mPopupMenu)
+ return;
+ if(getSessionId().isNull())
+ return;
+
+ if(P2P_MENU_NAME == mPopupMenu->getName())
+ {
+ bool is_friend = LLAvatarActions::isFriend(mAvatarCtrl->getAvatarId());
+
+ mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend);
+ mPopupMenu->getChild<LLUICtrl>("Remove Friend")->setEnabled(is_friend);
}
}
void LLIMChiclet::setShowSpeaker(bool show)
{
+ bool needs_resize = getShowSpeaker() != show;
+
mShowSpeaker = show;
- mSpeaker->setVisible(getShowSpeaker());
+ mSpeakerCtrl->setVisible(getShowSpeaker());
+
+ if(needs_resize)
+ {
+ onChicletSizeChanged();
+ }
}
void LLIMChiclet::draw()
@@ -267,45 +321,140 @@ void LLIMChiclet::draw()
gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE);
}
-S32 LLIMChiclet::calcCounterWidth()
+BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if(!mPopupMenu)
+ createPopupMenu();
+
+ updateMenuItems();
+
+ mPopupMenu->arrangeAndClear();
+
+ LLMenuGL::showPopup(this, mPopupMenu, x, y);
+
+ return TRUE;
+}
+
+void LLIMChiclet::createPopupMenu()
{
- S32 font_width = mCounterText->getFont()->getWidth("0");
- S32 text_size = mCounterText->getText().size();
+ if(mPopupMenu)
+ {
+ llwarns << "Menu already exists" << llendl;
+ return;
+ }
+ if(getSessionId().isNull())
+ return;
- return llmax(font_width * text_size, COUNTER_WIDTH);
+ LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId());
+ if(!floater)
+ return;
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("IMChicletMenu.Action", boost::bind(&LLIMChiclet::onMenuItemClicked, this, _2));
+
+ switch(floater->getDialogType())
+ {
+ case IM_SESSION_GROUP_START:
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+ ("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ break;
+ case IM_NOTHING_SPECIAL:
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+ ("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ break;
+ default:
+ llwarns << "Unexpected dialog type" << llendl;
+ break;
+ }
+}
+
+void LLIMChiclet::onMenuItemClicked(const LLSD& user_data)
+{
+ std::string level = user_data.asString();
+ LLUUID other_participant_id = mAvatarCtrl->getAvatarId();
+
+ if("profile" == level)
+ {
+ LLAvatarActions::showProfile(other_participant_id);
+ }
+ else if("im" == level)
+ {
+ LLAvatarActions::startIM(other_participant_id);
+ }
+ else if("add" == level)
+ {
+ std::string name;
+ gCacheName->getFullName(other_participant_id,name);
+ LLAvatarActions::requestFriendshipDialog(other_participant_id,name);
+ }
+ else if("remove" == level)
+ {
+ LLAvatarActions::removeFriendDialog(other_participant_id);
+ }
+ else if("group chat" == level)
+ {
+ LLGroupActions::startChat(other_participant_id);
+ }
+ else if("info" == level)
+ {
+ LLFloaterGroupInfo::showFromUUID(other_participant_id);
+ }
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
+LLChicletPanel::Params::Params()
+: chiclet_padding("chiclet_padding")
+, scrolling_offset("scrolling_offset")
+, left_scroll_button("left_scroll_button")
+, right_scroll_button("right_scroll_button")
+{
+ chiclet_padding = 3;
+ scrolling_offset = 40;
+
+ LLRect scroll_button_rect(0, 25, 19, 5);
+
+ left_scroll_button.name("left_scroll");
+ left_scroll_button.label(LLStringUtil::null);
+ left_scroll_button.rect(scroll_button_rect);
+ left_scroll_button.tab_stop(false);
+ left_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
+ left_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
+ left_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
+
+ right_scroll_button.name("right_scroll");
+ right_scroll_button.label(LLStringUtil::null);
+ right_scroll_button.rect(scroll_button_rect);
+ right_scroll_button.tab_stop(false);
+ right_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
+ right_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
+ right_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
+};
+
LLChicletPanel::LLChicletPanel(const Params&p)
: LLPanel(p)
, mScrollArea(NULL)
-, mLeftScroll(NULL)
-, mRightScroll(NULL)
-{
- LLButton::Params params;
-
- params.name("scroll_left");
- params.label(LLStringUtil::null);
- params.tab_stop(false);
- params.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
- params.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
- params.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
- mLeftScroll = LLUICtrlFactory::create<LLButton>(params);
- addChild(mLeftScroll);
- mLeftScroll->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this));
- mLeftScroll->setEnabled(false);
-
- params.name("scroll_right");
- params.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
- params.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
- params.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
- mRightScroll = LLUICtrlFactory::create<LLButton>(params);
- addChild(mRightScroll);
- mRightScroll->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this));
- mRightScroll->setEnabled(false);
+, mLeftScrollButton(NULL)
+, mRightScrollButton(NULL)
+, mChicletPadding(p.chiclet_padding)
+, mScrollingOffset(p.scrolling_offset)
+{
+ LLButton::Params scroll_button_params = p.left_scroll_button;
+
+ mLeftScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params);
+ addChild(mLeftScrollButton);
+
+ mLeftScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this));
+ mLeftScrollButton->setEnabled(false);
+
+ scroll_button_params = p.right_scroll_button;
+ mRightScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params);
+ addChild(mRightScrollButton);
+
+ mRightScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this));
+ mRightScrollButton->setEnabled(false);
LLPanel::Params panel_params;
mScrollArea = LLUICtrlFactory::create<LLPanel>(panel_params,this);
@@ -320,7 +469,7 @@ LLChicletPanel::~LLChicletPanel()
void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
LLUUID session_id = data["session_id"].asUUID();
- LLChiclet* chiclet = panel->findIMChiclet(session_id);
+ LLChiclet* chiclet = panel->findChiclet<LLChiclet>(session_id);
if (chiclet)
{
@@ -341,38 +490,28 @@ BOOL LLChicletPanel::postBuild()
return TRUE;
}
-LLChiclet* LLChicletPanel::createChiclet(const LLUUID& im_session_id /* = LLUUID::null */, S32 pos /* = 0 */)
-{
- LLChiclet* chiclet = LLIMChiclet::create(im_session_id);
- if(!chiclet)
- {
- assert(false);
- return NULL;
- }
-
- if(!addChiclet(chiclet, pos))
- {
- assert(false);
- return NULL;
- }
-
- return chiclet;
-}
-
-bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 pos)
+bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
{
if(mScrollArea->addChild(chiclet))
{
- // if first chiclet is scrolled left, the created one should be scrolled left too
- if(0 == pos && canScrollLeft())
+ S32 offset = 0;
+ // Do not scroll chiclets if chiclets are scrolled right and new
+ // chiclet is added to the beginning of the list
+ if(canScrollLeft())
{
- LLRect first_chiclet_rect = getChiclet(0)->getRect();
- chiclet->setRect(first_chiclet_rect);
+ offset = - (chiclet->getRequiredRect().getWidth() + getChicletPadding());
+ if(0 == index)
+ {
+ offset += getChiclet(0)->getRect().mLeft;
+ }
}
- mChicletList.insert(mChicletList.begin() + pos, chiclet);
+ mChicletList.insert(mChicletList.begin() + index, chiclet);
+
+ getChiclet(0)->translate(offset, 0);
chiclet->setLeftButtonClickCallback(boost::bind(&LLChicletPanel::onChicletClick, this, _1, _2));
+ chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index));
arrange();
showScrollButtonsIfNeeded();
@@ -383,6 +522,29 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 pos)
return false;
}
+void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param)
+{
+ S32 chiclet_width = ctrl->getRect().getWidth();
+ S32 chiclet_new_width = ctrl->getRequiredRect().getWidth();
+
+ if(chiclet_new_width == chiclet_width)
+ {
+ return;
+ }
+
+ LLRect chiclet_rect = ctrl->getRect();
+ chiclet_rect.mRight = chiclet_rect.mLeft + chiclet_new_width;
+
+ ctrl->setRect(chiclet_rect);
+
+ S32 offset = chiclet_new_width - chiclet_width;
+ S32 index = getChicletIndex(ctrl);
+
+ shiftChiclets(offset, index + 1);
+ trimChiclets();
+ showScrollButtonsIfNeeded();
+}
+
void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD&param)
{
LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl);
@@ -391,66 +553,42 @@ void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD&param)
S32 x, y;
LLRect rect = getRect();
localPointToScreen(rect.getCenterX(), 0, &x, &y);
- LLIMFloater::show(chiclet->getIMSessionId(), x);
+ LLIMFloater::show(chiclet->getSessionId(), x);
}
mCommitSignal(ctrl,param);
}
-LLChiclet* LLChicletPanel::findIMChiclet(const LLUUID& im_session_id)
-{
- chiclet_list_t::const_iterator it = mChicletList.begin();
- for( ; mChicletList.end() != it; ++it)
- {
- // Only IM Chiclets have session id, skip non IM Chiclets
- LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
- if(!chiclet)
- {
- continue;
- }
-
- if(chiclet->getIMSessionId() == im_session_id)
- {
- return chiclet;
- }
- }
- return NULL;
-}
-
-LLChiclet* LLChicletPanel::getChiclet(S32 pos)
-{
- return mChicletList[pos];
-}
-
void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it)
{
- // if possible, after deletion shift chiclets right
- if(canScrollLeft() && !canScrollRight())
- {
- LLChiclet* chiclet = *it;
- LLRect first_chiclet_rect = getChiclet(0)->getRect();
- S32 deleted_chiclet_width = chiclet->getRect().getWidth();
- deleted_chiclet_width += CHICLET_PADDING;
-
- first_chiclet_rect.mLeft += deleted_chiclet_width;
- first_chiclet_rect.mRight += deleted_chiclet_width;
-
- getChiclet(0)->setRect(first_chiclet_rect);
- }
-
mScrollArea->removeChild(*it);
mChicletList.erase(it);
arrange();
+ trimChiclets();
showScrollButtonsIfNeeded();
}
-void LLChicletPanel::removeChiclet(S32 pos)
+void LLChicletPanel::removeChiclet(S32 index)
{
- if(0 > pos || getChicletCount() <= pos)
+ if(index >= 0 && index < getChicletCount())
{
- return;
+ removeChiclet(mChicletList.begin() + index);
}
- removeChiclet(mChicletList.begin() + pos);
+}
+
+S32 LLChicletPanel::getChicletIndex(const LLChiclet* chiclet)
+{
+ if(mChicletList.empty())
+ return -1;
+
+ S32 size = getChicletCount();
+ for(int n = 0; n < size; ++n)
+ {
+ if(chiclet == mChicletList[n])
+ return n;
+ }
+
+ return -1;
}
void LLChicletPanel::removeChiclet(LLChiclet*chiclet)
@@ -467,19 +605,14 @@ void LLChicletPanel::removeChiclet(LLChiclet*chiclet)
}
}
-void LLChicletPanel::removeIMChiclet(const LLUUID& im_session_id)
+void LLChicletPanel::removeChiclet(const LLUUID& im_session_id)
{
chiclet_list_t::iterator it = mChicletList.begin();
for( ; mChicletList.end() != it; ++it)
{
- // Only IM Chiclets have session id, skip non IM Chiclets
LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
- if(!chiclet)
- {
- continue;
- }
- if(chiclet->getIMSessionId() == im_session_id)
+ if(chiclet->getSessionId() == im_session_id)
{
removeChiclet(it);
return;
@@ -489,7 +622,11 @@ void LLChicletPanel::removeIMChiclet(const LLUUID& im_session_id)
void LLChicletPanel::removeAll()
{
- mScrollArea->deleteAllChildren();
+ S32 size = getChicletCount();
+ for(S32 n = 0; n < size; ++n)
+ {
+ mScrollArea->removeChild(mChicletList[n]);
+ }
mChicletList.erase(mChicletList.begin(), mChicletList.end());
@@ -500,75 +637,67 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )
{
LLPanel::reshape(width,height,called_from_parent);
- mLeftScroll->setRect(LLRect(0,CHICLET_HEIGHT,SCROLL_BUTTON_WIDTH,
- CHICLET_HEIGHT - SCROLL_BUTTON_HEIGHT));
- mRightScroll->setRect(LLRect(width-SCROLL_BUTTON_WIDTH,CHICLET_HEIGHT,
- width,CHICLET_HEIGHT - SCROLL_BUTTON_HEIGHT));
+ static const S32 SCROLL_BUTTON_PAD = 5;
- S32 old_scroll_width = mScrollArea->getRect().getWidth();
+ LLRect scroll_button_rect = mLeftScrollButton->getRect();
+ mLeftScrollButton->setRect(LLRect(0,height,scroll_button_rect.getWidth(),
+ height - scroll_button_rect.getHeight()));
- mScrollArea->setRect(LLRect(SCROLL_BUTTON_WIDTH + 5,CHICLET_HEIGHT + 1,
- width - SCROLL_BUTTON_WIDTH - 5, 0));
+ scroll_button_rect = mRightScrollButton->getRect();
+ mRightScrollButton->setRect(LLRect(width - scroll_button_rect.getWidth(),height,
+ width, height - scroll_button_rect.getHeight()));
- S32 current_scroll_width = mScrollArea->getRect().getWidth();
- reshapeScrollArea(current_scroll_width - old_scroll_width);
+ mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD,
+ height + 1, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
+
+ trimChiclets();
showScrollButtonsIfNeeded();
}
-void LLChicletPanel::reshapeScrollArea(S32 delta_width)
+void LLChicletPanel::arrange()
{
if(mChicletList.empty())
return;
- S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
- S32 scroll_width = mScrollArea->getRect().getWidth();
+ S32 chiclet_left = getChiclet(0)->getRect().mLeft;
- // Align all chiclets to last chiclet
- // if there is a gap between last chiclet and scroll area right side
- // or last chiclet is at visible area right side
- if( last_chiclet_right < scroll_width
- || last_chiclet_right == scroll_width - delta_width)
+ S32 size = getChicletCount();
+ for( int n = 0; n < size; ++n)
{
- LLRect first_chiclet_rect = getChiclet(0)->getRect();
- // if we can right shift all chiclets
- if(first_chiclet_rect.mLeft < 0)
- {
- first_chiclet_rect.mLeft += delta_width;
- first_chiclet_rect.mRight += delta_width;
+ LLChiclet* chiclet = getChiclet(n);
- getChiclet(0)->setRect(first_chiclet_rect);
+ S32 chiclet_width = chiclet->getRequiredRect().getWidth();
+ LLRect rect = chiclet->getRect();
+ rect.set(chiclet_left, rect.mTop, chiclet_left + chiclet_width, rect.mBottom);
- arrange();
- }
+ chiclet->setRect(rect);
+
+ chiclet_left += chiclet_width + getChicletPadding();
}
}
-void LLChicletPanel::arrange()
+void LLChicletPanel::trimChiclets()
{
- if(mChicletList.empty())
- return;
-
- LLRect first_chiclet_rect = getChiclet(0)->getRect();
- // don't allow gap between first chiclet and scroll area left side
- if(first_chiclet_rect.mLeft > 0)
+ // trim right
+ if(canScrollLeft() && !canScrollRight())
{
- first_chiclet_rect.mRight = first_chiclet_rect.getWidth();
- first_chiclet_rect.mLeft = 0;
+ S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
+ S32 scroll_width = mScrollArea->getRect().getWidth();
+ if(last_chiclet_right < scroll_width)
+ {
+ shiftChiclets(scroll_width - last_chiclet_right);
+ }
}
- S32 left = first_chiclet_rect.mLeft;
-
- S32 size = getChicletCount();
- for( int n = 0; n < size; ++n)
+ // trim left
+ if(!mChicletList.empty())
{
- LLChiclet* chiclet = getChiclet(n);
- S32 chiclet_width = chiclet->getRequiredRect().getWidth();
- LLRect rc(left, CHICLET_HEIGHT, left + chiclet_width, 0);
-
- chiclet->setRect(rc);
-
- left += chiclet_width + CHICLET_PADDING;
+ LLRect first_chiclet_rect = getChiclet(0)->getRect();
+ if(first_chiclet_rect.mLeft > 0)
+ {
+ shiftChiclets( - first_chiclet_rect.mLeft);
+ }
}
}
@@ -577,13 +706,13 @@ void LLChicletPanel::showScrollButtonsIfNeeded()
bool can_scroll_left = canScrollLeft();
bool can_scroll_right = canScrollRight();
- mLeftScroll->setEnabled(can_scroll_left);
- mRightScroll->setEnabled(can_scroll_right);
+ mLeftScrollButton->setEnabled(can_scroll_left);
+ mRightScrollButton->setEnabled(can_scroll_right);
bool show_scroll_buttons = can_scroll_left || can_scroll_right;
- mLeftScroll->setVisible(show_scroll_buttons);
- mRightScroll->setVisible(show_scroll_buttons);
+ mLeftScrollButton->setVisible(show_scroll_buttons);
+ mRightScrollButton->setVisible(show_scroll_buttons);
}
void LLChicletPanel::draw()
@@ -626,42 +755,19 @@ bool LLChicletPanel::canScrollLeft()
return getChiclet(0)->getRect().mLeft < 0;
}
-void LLChicletPanel::scroll(ScrollDirection direction)
+void LLChicletPanel::scroll(S32 offset)
{
- S32 first_visible_chiclet = getFirstVisibleChiclet();
- if(-1 == first_visible_chiclet)
- return;
-
- S32 offset = 0;
+ shiftChiclets(offset);
+}
- if(SCROLL_LEFT == direction)
- {
- if(0 == first_visible_chiclet)
- {
- // shift chiclets in case first chiclet is partially visible
- offset = llabs(getChiclet(first_visible_chiclet)->getRect().mLeft);
- }
- else
- {
- offset = getChiclet(first_visible_chiclet - 1)->getRect().getWidth() + CHICLET_PADDING;
- }
- }
- else if(SCROLL_RIGHT == direction)
+void LLChicletPanel::shiftChiclets(S32 offset, S32 start_index /* = 0 */)
+{
+ if(start_index < 0 || start_index >= getChicletCount())
{
- S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
- S32 scroll_rect_width = mScrollArea->getRect().getWidth();
-
- offset = getChiclet(first_visible_chiclet)->getRect().getWidth() + CHICLET_PADDING;
- offset *= direction;
- // if after scrolling, the last chiclet will not be aligned to
- // scroll area right side - align it.
- if( last_chiclet_right + offset < scroll_rect_width )
- {
- offset = scroll_rect_width - last_chiclet_right;
- }
+ return;
}
- chiclet_list_t::const_iterator it = mChicletList.begin();
+ chiclet_list_t::const_iterator it = mChicletList.begin() + start_index;
for(;mChicletList.end() != it; ++it)
{
LLChiclet* chiclet = *it;
@@ -669,31 +775,20 @@ void LLChicletPanel::scroll(ScrollDirection direction)
}
}
-S32 LLChicletPanel::getFirstVisibleChiclet()
+void LLChicletPanel::scrollLeft()
{
- if(mChicletList.empty())
- return -1;
-
- for(int n = 0; n < getChicletCount(); ++n)
+ if(canScrollLeft())
{
- LLRect rc = getChiclet(n)->getRect();
- if(n > 0)
- rc.mLeft -= CHICLET_PADDING;
- // bottom left of scroll area is first visible point
- if(rc.pointInRect(0,0))
+ S32 offset = getScrollingOffset();
+ LLRect first_chiclet_rect = getChiclet(0)->getRect();
+
+ // shift chiclets in case first chiclet is partially visible
+ if(first_chiclet_rect.mLeft < 0 && first_chiclet_rect.mRight > 0)
{
- return n;
+ offset = llabs(first_chiclet_rect.mLeft);
}
- }
- return -1;
-}
-
-void LLChicletPanel::scrollLeft()
-{
- if(canScrollLeft())
- {
- scroll(SCROLL_LEFT);
+ scroll(offset);
showScrollButtonsIfNeeded();
}
@@ -703,7 +798,18 @@ void LLChicletPanel::scrollRight()
{
if(canScrollRight())
{
- scroll(SCROLL_RIGHT);
+ S32 offset = - getScrollingOffset();
+
+ S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
+ S32 scroll_rect_width = mScrollArea->getRect().getWidth();
+ // if after scrolling, the last chiclet will not be aligned to
+ // scroll area right side - align it.
+ if( last_chiclet_right + offset < scroll_rect_width )
+ {
+ offset = scroll_rect_width - last_chiclet_right;
+ }
+
+ scroll(offset);
showScrollButtonsIfNeeded();
}
@@ -719,7 +825,7 @@ void LLChicletPanel::onRightScrollClick()
scrollRight();
}
-boost::signals2::connection LLChicletPanel::setChicletClickCallback(
+boost::signals2::connection LLChicletPanel::setChicletClickedCallback(
const commit_callback_t& cb)
{
return mCommitSignal.connect(cb);
@@ -742,62 +848,83 @@ BOOL LLChicletPanel::handleScrollWheel(S32 x, S32 y, S32 clicks)
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLTalkButton::LLTalkButton(const LLUICtrl::Params& p)
+LLTalkButton::Params::Params()
+ : speak_button("speak_button")
+ , show_button("show_button")
+ , monitor("monitor")
+{
+ speak_button.name("left");
+ speak_button.label("Speak");
+ speak_button.label_selected("Speak");
+ speak_button.font(LLFontGL::getFontSansSerifSmall());
+ speak_button.tab_stop(false);
+ speak_button.is_toggle(true);
+ speak_button.picture_style(true);
+ speak_button.image_selected(LLUI::getUIImage("SegmentedBtn_Left_Selected"));
+ speak_button.image_unselected(LLUI::getUIImage("SegmentedBtn_Left_Off"));
+
+ show_button.name("right");
+ show_button.label(LLStringUtil::null);
+ show_button.rect(LLRect(0, 0, 20, 0));
+ show_button.tab_stop(false);
+ show_button.is_toggle(true);
+ show_button.picture_style(true);
+ show_button.image_selected(LLUI::getUIImage("ComboButton_Selected"));
+ show_button.image_unselected(LLUI::getUIImage("ComboButton_Off"));
+
+ monitor.name("monitor");
+ monitor.rect(LLRect(0, 10, 16, 0));
+}
+
+LLTalkButton::LLTalkButton(const Params& p)
: LLUICtrl(p)
+, mPrivateCallPanel(NULL)
+, mOutputMonitor(NULL)
+, mSpeakBtn(NULL)
+, mShowBtn(NULL)
{
- static S32 DROPDOWN_BTN_WIDTH = 20;
-
- LLRect rc(p.rect);
-
- LLButton::Params speak_params;
- speak_params.name("left");
- speak_params.rect(LLRect(0,rc.getHeight(),rc.getWidth()-DROPDOWN_BTN_WIDTH,0));
- speak_params.label("Speak");
- speak_params.label_selected("Speak");
- speak_params.font(LLFontGL::getFontSansSerifSmall());
- speak_params.tab_stop(false);
- speak_params.is_toggle(true);
- speak_params.picture_style(true);
- speak_params.image_selected(LLUI::getUIImage("SegmentedBtn_Left_Selected"));
- speak_params.image_unselected(LLUI::getUIImage("SegmentedBtn_Left_Off"));
+ LLRect rect = p.rect();
+ LLRect speak_rect(0, rect.getHeight(), rect.getWidth(), 0);
+ LLRect show_rect = p.show_button.rect();
+ show_rect.set(0, rect.getHeight(), show_rect.getWidth(), 0);
+
+ speak_rect.mRight -= show_rect.getWidth();
+ show_rect.mLeft = speak_rect.getWidth();
+ show_rect.mRight = rect.getWidth();
+
+ LLButton::Params speak_params = p.speak_button;
+ speak_params.rect(speak_rect);
mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
addChild(mSpeakBtn);
mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this));
- mSpeakBtn->setToggleState(false);
-
- LLButton::Params show_params;
- show_params.name("right");
- show_params.rect(LLRect(rc.getWidth()-DROPDOWN_BTN_WIDTH,rc.getHeight(),rc.getWidth(),0));
- show_params.label("");
- show_params.tab_stop(false);
- show_params.is_toggle(true);
- show_params.picture_style(true);
- show_params.image_selected(LLUI::getUIImage("ComboButton_Selected"));
- show_params.image_unselected(LLUI::getUIImage("ComboButton_Off"));
+ mSpeakBtn->setToggleState(FALSE);
+
+ LLButton::Params show_params = p.show_button;
+ show_params.rect(show_rect);
mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
addChild(mShowBtn);
mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this));
- mShowBtn->setToggleState(false);
-
- mSpeakBtn->setToggleState(FALSE);
mShowBtn->setToggleState(FALSE);
- rc = mSpeakBtn->getRect();
+ static const S32 MONITOR_RIGHT_PAD = 2;
- LLOutputMonitorCtrl::Params monitor_param;
- monitor_param.name("monitor");
- monitor_param.draw_border(false);
- monitor_param.rect(LLRect(rc.getWidth()-20,18,rc.getWidth()-3,2));
- monitor_param.visible(true);
- mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_param);
- // never show "muted" because you can't mute yourself
- mOutputMonitor->setIsMuted(false);
+ LLRect monitor_rect = p.monitor.rect();
+ S32 monitor_height = monitor_rect.getHeight();
+ monitor_rect.mLeft = speak_rect.getWidth() - monitor_rect.getWidth() - MONITOR_RIGHT_PAD;
+ monitor_rect.mRight = speak_rect.getWidth() - MONITOR_RIGHT_PAD;
+ monitor_rect.mBottom = (rect.getHeight() / 2) - (monitor_height / 2);
+ monitor_rect.mTop = monitor_rect.mBottom + monitor_height;
+ LLOutputMonitorCtrl::Params monitor_params = p.monitor;
+ monitor_params.draw_border(false);
+ monitor_params.rect(monitor_rect);
+ mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params);
mSpeakBtn->addChild(mOutputMonitor);
- mPrivateCallPanel = NULL;
+ // never show "muted" because you can't mute yourself
+ mOutputMonitor->setIsMuted(false);
}
LLTalkButton::~LLTalkButton()
@@ -838,8 +965,7 @@ void LLTalkButton::onClick_ShowBtn()
mPrivateCallPanel = new LLVoiceControlPanel;
getRootView()->addChild(mPrivateCallPanel);
- if(gBottomTray)
- y = gBottomTray->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight();
+ y = LLBottomTray::getInstance()->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight();
LLRect rect;
rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight());
@@ -857,3 +983,63 @@ void LLTalkButton::onClick_ShowBtn()
mShowBtn->setToggleState(TRUE);
}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p)
+ : LLTextBox(p)
+ , mCounter(0)
+ , mInitialWidth(0)
+{
+ mInitialWidth = getRect().getWidth();
+}
+
+void LLChicletNotificationCounterCtrl::setCounter(S32 counter)
+{
+ mCounter = counter;
+
+ std::stringstream stream;
+ stream << getCounter();
+ setText(stream.str());
+}
+
+LLRect LLChicletNotificationCounterCtrl::getRequiredRect()
+{
+ LLRect rc;
+ S32 text_width = getFont()->getWidth(getText());
+
+ rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth);
+
+ return rc;
+}
+
+void LLChicletNotificationCounterCtrl::setValue(const LLSD& value)
+{
+ if(value.isInteger())
+ setCounter(value.asInteger());
+}
+
+LLSD LLChicletNotificationCounterCtrl::getValue() const
+{
+ return LLSD(getCounter());
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
+ : LLAvatarIconCtrl(p)
+{
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
+ : LLIconCtrl(p)
+{
+}
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index ceda61adea..e467ec012a 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -33,134 +33,333 @@
#ifndef LL_LLCHICLET_H
#define LL_LLCHICLET_H
+#include "llavatariconctrl.h"
#include "llpanel.h"
+#include "lltextbox.h"
+#include "lloutputmonitorctrl.h"
-class LLTextBox;
-class LLIconCtrl;
-class LLAvatarIconCtrl;
class LLVoiceControlPanel;
-class LLOutputMonitorCtrl;
+class LLMenuGL;
+/*
+ * Class for displaying amount of messages/notifications(unread).
+*/
+class LLChicletNotificationCounterCtrl : public LLTextBox
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLTextBox::Params>
+ {
+ Params()
+ {};
+ };
+
+ /*
+ * Sets number of notifications
+ */
+ virtual void setCounter(S32 counter);
+
+ /*
+ * Returns number of notifications
+ */
+ virtual S32 getCounter() const { return mCounter; }
+
+ /*
+ * Returns width, required to display amount of notifications in text form.
+ * Width is the only valid value.
+ */
+ /*virtual*/ LLRect getRequiredRect();
+
+ /*
+ * Sets number of notifications using LLSD
+ */
+ /*virtual*/ void setValue(const LLSD& value);
+
+ /*
+ * Returns number of notifications wrapped in LLSD
+ */
+ /*virtual*/ LLSD getValue() const;
+
+protected:
+
+ LLChicletNotificationCounterCtrl(const Params& p);
+ friend class LLUICtrlFactory;
+
+private:
+
+ S32 mCounter;
+ S32 mInitialWidth;
+};
+
+/*
+ * Class for displaying avatar's icon.
+*/
+class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLAvatarIconCtrl::Params>
+ {
+ Params()
+ {
+ draw_tooltip(FALSE);
+ mouse_opaque(FALSE);
+ };
+ };
+
+protected:
+
+ LLChicletAvatarIconCtrl(const Params& p);
+ friend class LLUICtrlFactory;
+};
+
+/*
+ * Class for displaying status of Voice Chat
+*/
+class LLChicletSpeakerCtrl : public LLIconCtrl
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLIconCtrl::Params>
+ {
+ Params(){};
+ };
+protected:
+
+ LLChicletSpeakerCtrl(const Params&p);
+ friend class LLUICtrlFactory;
+};
+
+/*
+ * Base class for all chiclets.
+ */
class LLChiclet : public LLUICtrl
{
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
- Params(){};
+ Optional<bool> show_counter;
+
+ Params();
};
- virtual ~LLChiclet();
+ /*virtual*/ ~LLChiclet();
+
+ /*
+ * Associates chat session id with chiclet.
+ */
+ virtual void setSessionId(const LLUUID& session_id) { mSessionId = session_id; }
+ /*
+ * Returns associated chat session.
+ */
+ virtual const LLUUID& getSessionId() const { return mSessionId; }
+
+ /*
+ * Sets number of unread notifications.
+ */
virtual void setCounter(S32 counter) = 0;
+ /*
+ * Returns number of unread notifications.
+ */
virtual S32 getCounter() = 0;
- virtual void setShowCounter(bool show) {mShowCounter = show;};
+ /*
+ * Sets show counter state.
+ */
+ virtual void setShowCounter(bool show) { mShowCounter = show; }
+ /*
+ * Returns show counter state.
+ */
virtual bool getShowCounter() {return mShowCounter;};
- virtual boost::signals2::connection setLeftButtonClickCallback(
+ /*
+ * Connects chiclet clicked event with callback.
+ */
+ /*virtual*/ boost::signals2::connection setLeftButtonClickCallback(
const commit_callback_t& cb);
+ typedef boost::function<void (LLChiclet* ctrl, const LLSD& param)>
+ chiclet_size_changed_callback_t;
+
+ /*
+ * Connects chiclets size changed event with callback.
+ */
+ virtual boost::signals2::connection setChicletSizeChangedCallback(
+ const chiclet_size_changed_callback_t& cb);
+
+ /*
+ * Sets IM Session id using LLSD
+ */
+ /*virtual*/ LLSD getValue() const;
+
+ /*
+ * Returns IM Session id using LLSD
+ */
+ /*virtual*/ void setValue(const LLSD& value);
+
protected:
friend class LLUICtrlFactory;
LLChiclet(const Params& p);
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ /*
+ * Notifies subscribers about click on chiclet.
+ */
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+ /*
+ * Notifies subscribers about chiclet size changed event.
+ */
+ virtual void onChicletSizeChanged();
+
+private:
+
+ LLUUID mSessionId;
-protected:
- S32 mCounter;
bool mShowCounter;
+
+ typedef boost::signals2::signal<void (LLChiclet* ctrl, const LLSD& param)>
+ chiclet_size_changed_signal_t;
+
+ chiclet_size_changed_signal_t mChicletSizeChangedSignal;
};
+/*
+* Implements Instant Message chiclet.
+* IMChiclet displays avatar's icon, number of unread messages(optional)
+* and voice chat status(optional).
+*/
class LLIMChiclet : public LLChiclet
{
public:
- static LLChiclet* create(const LLUUID& im_session_id = LLUUID::null);
-
- void setCounter(S32);
-
- S32 getCounter() {return mCounter;};
-
- const LLUUID& getIMSessionId() const {return mIMSessionId;};
+ struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
+ {
+ Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
- void setIMSessionId(const LLUUID& im_session_id) { mIMSessionId = im_session_id; }
- void setIMSessionName(const std::string& name);
- void setOtherParticipantId(const LLUUID& other_participant_id);
+ Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
- void setShowSpeaker(bool show);
+ Optional<LLChicletSpeakerCtrl::Params> speaker;
- bool getShowSpeaker() {return mShowSpeaker;};
+ Optional<bool> show_speaker;
- enum SpeakerStatus
- {
- SPREAKER_ACTIVE,
- SPEAKER_IDLE
+ Params();
};
- void setSpeakerStatus(SpeakerStatus status);
-
- SpeakerStatus getSpeakerStatus() {return mSpeakerStatus;};
-
- ~LLIMChiclet();
+ /*virtual*/ ~LLIMChiclet();
+
+ /*
+ * Sets IM session name. This name will be displayed in chiclet tooltip.
+ */
+ virtual void setIMSessionName(const std::string& name);
+
+ /*
+ * Sets id of person/group user is chatting with.
+ */
+ virtual void setOtherParticipantId(const LLUUID& other_participant_id);
+
+ /*
+ * Shows/hides voice chat status control.
+ */
+ virtual void setShowSpeaker(bool show);
+
+ /*
+ * Returns voice chat status control visibility.
+ */
+ virtual bool getShowSpeaker() {return mShowSpeaker;};
+
+ /*
+ * Sets number of unread messages. Will update chiclet's width if number text
+ * exceeds size of counter and notify it's parent about size change.
+ */
+ /*virtual*/ void setCounter(S32);
+
+ /*
+ * Returns number of unread messages.
+ */
+ /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
+
+ /*
+ * Shows/hides number of unread messages.
+ */
+ /*virtual*/ void setShowCounter(bool show);
+
+ /*
+ * Draws border around chiclet.
+ */
+ /*virtual*/ void draw();
+
+ /*
+ * Returns rect, required to display chiclet.
+ * Width is the only valid value.
+ */
+ /*virtual*/ LLRect getRequiredRect();
protected:
- LLIMChiclet(const LLChiclet::Params& p);
- friend class LLUICtrlFactory;
- S32 calcCounterWidth();
+ LLIMChiclet(const Params& p);
+ friend class LLUICtrlFactory;
- //overrides
-public:
+ /*
+ * Creates chiclet popup menu. Will create P2P or Group IM Chat menu
+ * based on other participant's id.
+ */
+ virtual void createPopupMenu();
- void setShowCounter(bool show);
+ /*
+ * Processes clicks on chiclet popup menu.
+ */
+ virtual void onMenuItemClicked(const LLSD& user_data);
- void draw();
+ /*
+ * Enables/disables menus based on relationship with other participant.
+ */
+ virtual void updateMenuItems();
- LLRect getRequiredRect();
+ /*
+ * Displays popup menu.
+ */
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
protected:
- LLAvatarIconCtrl* mAvatar;
- LLTextBox* mCounterText;
- LLIconCtrl* mSpeaker;
+ LLChicletAvatarIconCtrl* mAvatarCtrl;
+ LLChicletNotificationCounterCtrl* mCounterCtrl;
+ LLChicletSpeakerCtrl* mSpeakerCtrl;
+
+ LLMenuGL* mPopupMenu;
- LLUUID mIMSessionId;
bool mShowSpeaker;
- SpeakerStatus mSpeakerStatus;
};
+/*
+ * Implements notification chiclet. Used to display total amount of unread messages
+ * across all IM sessions, total amount of system notifications.
+*/
class LLNotificationChiclet : public LLChiclet
{
public:
struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
{
- Optional<LLUIImage*>
- image_unselected,
- image_selected,
- image_hover_selected,
- image_hover_unselected,
- image_disabled_selected,
- image_disabled,
- image_overlay;
-
- Optional<S32>
- label_left;
+ Optional<LLButton::Params> button;
+
+ Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
Params();
};
- static LLChiclet* create(const Params& p);
+ /*virtual*/ void setCounter(S32 counter);
- void setCounter(S32 counter);
+ /*virtual*/S32 getCounter() { return mCounterCtrl->getCounter(); }
- S32 getCounter() {return mCounter;};
+ /*virtual*/ void setShowCounter(bool show);
boost::signals2::connection setClickCallback(const commit_callback_t& cb);
- virtual ~ LLNotificationChiclet();
+ /*virtual*/ ~ LLNotificationChiclet();
protected:
LLNotificationChiclet(const Params& p);
@@ -168,112 +367,223 @@ protected:
protected:
LLButton* mButton;
- LLTextBox* mCounterText;
+ LLChicletNotificationCounterCtrl* mCounterCtrl;
};
+/*
+ * Storage class for all IM chiclets. Provides mechanism to display,
+ * scroll, create, remove chiclets.
+*/
class LLChicletPanel : public LLPanel
{
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
- Params(){};
- };
+ Optional<S32> chiclet_padding,
+ scrolling_offset;
- ~LLChicletPanel();
+ Optional<LLButton::Params> left_scroll_button,
+ right_scroll_button;
- LLChiclet* createChiclet(const LLUUID& im_session_id = LLUUID::null, S32 pos = 0);
+ Params();
+ };
- bool addChiclet(LLChiclet*, S32 pos);
+ virtual ~LLChicletPanel();
- LLChiclet* getChiclet(S32 pos);
+ /*
+ * Creates chiclet and adds it to chiclet list.
+ */
+ template<class T> T* createChiclet(const LLUUID& session_id = LLUUID::null, S32 index = 0);
- LLChiclet* findIMChiclet(const LLUUID& im_session_id);
+ /*
+ * Returns pointer to chiclet of specified type at specified index.
+ */
+ template<class T> T* getChiclet(S32 index);
- S32 getChicletCount() {return mChicletList.size();};
+ /*
+ * Returns pointer to LLChiclet at specified index.
+ */
+ LLChiclet* getChiclet(S32 index) { return getChiclet<LLChiclet>(index); }
- void removeChiclet(S32 pos);
+ /*
+ * Searches a chiclet using IM session id.
+ */
+ template<class T> T* findChiclet(const LLUUID& im_session_id);
- void removeChiclet(LLChiclet*);
-
- void removeIMChiclet(const LLUUID& im_session_id);
+ /*
+ * Returns number of hosted chiclets.
+ */
+ S32 getChicletCount() {return mChicletList.size();};
+ /*
+ * Returns index of chiclet in list.
+ */
+ S32 getChicletIndex(const LLChiclet* chiclet);
+
+ /*
+ * Removes chiclet by index.
+ */
+ void removeChiclet(S32 index);
+
+ /*
+ * Removes chiclet by pointer.
+ */
+ void removeChiclet(LLChiclet* chiclet);
+
+ /*
+ * Removes chiclet by IM session id.
+ */
+ void removeChiclet(const LLUUID& im_session_id);
+
+ /*
+ * Removes all chiclets.
+ */
void removeAll();
- void scrollLeft();
-
- void scrollRight();
-
- void onLeftScrollClick();
-
- void onRightScrollClick();
-
- boost::signals2::connection setChicletClickCallback(
+ boost::signals2::connection setChicletClickedCallback(
const commit_callback_t& cb);
- void onChicletClick(LLUICtrl*ctrl,const LLSD&param);
-
- //overrides
-public:
/*virtual*/ BOOL postBuild();
- void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
+ /*
+ * Reshapes controls and rearranges chiclets if needed.
+ */
+ /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
- void draw();
+ /*virtual*/ void draw();
protected:
LLChicletPanel(const Params&p);
friend class LLUICtrlFactory;
+ /*
+ * Adds chiclet to list and rearranges all chiclets.
+ */
+ bool addChiclet(LLChiclet*, S32 index);
+
+ /*
+ * Arranges chiclets.
+ */
void arrange();
+ /*
+ * Returns true if chiclets can be scrolled right.
+ */
bool canScrollRight();
+ /*
+ * Returns true if chiclets can be scrolled left.
+ */
bool canScrollLeft();
+ /*
+ * Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled.
+ */
void showScrollButtonsIfNeeded();
- S32 getFirstVisibleChiclet();
+ /*
+ * Shifts chiclets left or right.
+ */
+ void shiftChiclets(S32 offset, S32 start_index = 0);
+
+ /*
+ * Removes gaps between first chiclet and scroll area left side,
+ * last chiclet and scroll area right side.
+ */
+ void trimChiclets();
+
+ /*
+ * Scrolls chiclets to right or left.
+ */
+ void scroll(S32 offset);
+
+ /*
+ * Verifies that chiclets can be scrolled left, then calls scroll()
+ */
+ void scrollLeft();
- void reshapeScrollArea(S32 delta_width);
+ /*
+ * Verifies that chiclets can be scrolled right, then calls scroll()
+ */
+ void scrollRight();
- enum ScrollDirection
- {
- SCROLL_LEFT = 1,
- SCROLL_RIGHT = -1
- };
+ /*
+ * Callback for left scroll button clicked
+ */
+ void onLeftScrollClick();
+
+ /*
+ * Callback for right scroll button clicked
+ */
+ void onRightScrollClick();
- void scroll(ScrollDirection direction);
+ /*
+ * Callback for mouse wheel scrolled, calls scrollRight() or scrollLeft()
+ */
+ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+
+ /*
+ * Notifies subscribers about click on chiclet.
+ * Do not place any code here, instead subscribe on event (see setChicletClickedCallback).
+ */
+ void onChicletClick(LLUICtrl*ctrl,const LLSD&param);
+
+ /*
+ * Callback for chiclet size changed event, rearranges chiclets.
+ */
+ void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);
typedef std::vector<LLChiclet*> chiclet_list_t;
+ /*
+ * Removes chiclet from scroll area and chiclet list.
+ */
void removeChiclet(chiclet_list_t::iterator it);
- BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ S32 getChicletPadding() { return mChicletPadding; }
+
+ S32 getScrollingOffset() { return mScrollingOffset; }
protected:
chiclet_list_t mChicletList;
- LLButton* mLeftScroll;
- LLButton* mRightScroll;
+ LLButton* mLeftScrollButton;
+ LLButton* mRightScrollButton;
LLPanel* mScrollArea;
-};
+ S32 mChicletPadding;
+ S32 mScrollingOffset;
+};
+/*
+ * Button displaying voice chat status. Displays voice chat options When clicked.
+*/
class LLTalkButton : public LLUICtrl
{
public:
- virtual ~LLTalkButton();
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLButton::Params> speak_button,
+ show_button;
- void onClick_SpeakBtn();
- void onClick_ShowBtn();
+ Optional<LLOutputMonitorCtrl::Params> monitor;
- void draw();
+ Params();
+ };
+
+ /*virtual*/ ~LLTalkButton();
+
+ /*virtual*/ void draw();
protected:
friend class LLUICtrlFactory;
- LLTalkButton(const LLUICtrl::Params& p);
+ LLTalkButton(const Params& p);
+
+ void onClick_SpeakBtn();
+
+ void onClick_ShowBtn();
private:
LLButton* mSpeakBtn;
@@ -282,4 +592,68 @@ private:
LLOutputMonitorCtrl* mOutputMonitor;
};
+template<class T>
+T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S32 index /*= 0*/)
+{
+ typename T::Params params;
+ T* chiclet = LLUICtrlFactory::create<T>(params);
+ if(!chiclet)
+ {
+ llwarns << "Could not create chiclet" << llendl;
+ return NULL;
+ }
+ if(!addChiclet(chiclet, index))
+ {
+ delete chiclet;
+ llwarns << "Could not add chiclet to chiclet panel" << llendl;
+ return NULL;
+ }
+
+ chiclet->setSessionId(session_id);
+
+ return chiclet;
+}
+
+template<class T>
+T* LLChicletPanel::findChiclet(const LLUUID& im_session_id)
+{
+ if(im_session_id.isNull())
+ {
+ return NULL;
+ }
+
+ chiclet_list_t::const_iterator it = mChicletList.begin();
+ for( ; mChicletList.end() != it; ++it)
+ {
+ LLChiclet* chiclet = *it;
+
+ if(chiclet->getSessionId() == im_session_id)
+ {
+ T* result = dynamic_cast<T*>(chiclet);
+ if(!result && chiclet)
+ {
+ llwarns << "Found chiclet but of wrong type " << llendl;
+ }
+ return result;
+ }
+ }
+ return NULL;
+}
+
+template<class T> T* LLChicletPanel::getChiclet(S32 index)
+{
+ if(index < 0 || index >= getChicletCount())
+ {
+ return NULL;
+ }
+
+ LLChiclet* chiclet = mChicletList[index];
+ T*result = dynamic_cast<T*>(chiclet);
+ if(!result && chiclet)
+ {
+ llwarns << "Found chiclet but of wrong type " << llendl;
+ }
+ return result;
+}
+
#endif // LL_LLCHICLET_H
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 92e2d3563a..00d4f80054 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -43,6 +43,8 @@
#include "llagent.h"
#include "llinventorybridge.h"
#include "llinventorymodel.h"
+#include "llsidetray.h"
+#include "lltoggleablemenu.h"
#include "llviewerinventory.h"
#include "llviewermenu.h"
#include "llviewermenu.h"
@@ -69,41 +71,6 @@ struct LLFavoritesSort
}
};
-class LLVisibilityTrackingMenuGL : public LLMenuGL
-{
-protected:
- LLVisibilityTrackingMenuGL(const LLMenuGL::Params&);
- friend class LLUICtrlFactory;
-public:
- virtual void onVisibilityChange (BOOL curVisibilityIn);
- void setChevronRect(const LLRect& rect) { mChevronRect = rect; }
-
- bool getClosedByChevronClick() { return mClosedByChevronClick; }
- void resetClosedByChevronClick() { mClosedByChevronClick = false; }
-
-protected:
- bool mClosedByChevronClick;
- LLRect mChevronRect;
-};
-
-LLVisibilityTrackingMenuGL::LLVisibilityTrackingMenuGL(const LLMenuGL::Params& p)
-: LLMenuGL(p),
- mClosedByChevronClick(false)
-{
-}
-
-//virtual
-void LLVisibilityTrackingMenuGL::onVisibilityChange (BOOL curVisibilityIn)
-{
- S32 x,y;
- LLUI::getCursorPositionLocal(LLUI::getRootView(), &x, &y);
-
- if (!curVisibilityIn && mChevronRect.pointInRect(x, y))
- {
- mClosedByChevronClick = true;
- }
-}
-
LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
: LLUICtrl(p),
mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()),
@@ -269,10 +236,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
LLRect rect;
rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap);
chevron_button->setRect(rect);
-
- S32 chevron_root_x, chevron_root_y;
- localPointToOtherView(rect.mLeft, rect.mBottom, &chevron_root_x, &chevron_root_y, LLUI::getRootView());
- mChevronRect.setOriginAndSize(chevron_root_x, chevron_root_y, rect.getWidth(), rect.getHeight());
+ mChevronRect = rect;
}
return;
}
@@ -355,9 +319,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
addChildInBack(LLUICtrlFactory::create<LLButton> (bparams));
- S32 chevron_root_x, chevron_root_y;
- localPointToOtherView(rect.mLeft, rect.mBottom, &chevron_root_x, &chevron_root_y, LLUI::getRootView());
- mChevronRect.setOriginAndSize(chevron_root_x, chevron_root_y, rect.getWidth(), rect.getHeight());
+ mChevronRect = rect;
}
}
@@ -400,25 +362,25 @@ void LLFavoritesBarCtrl::showDropDownMenu()
menu_p.visible(false);
menu_p.scrollable(true);
- LLVisibilityTrackingMenuGL* menu = LLUICtrlFactory::create<LLVisibilityTrackingMenuGL>(menu_p);
+ LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p);
mPopupMenuHandle = menu->getHandle();
}
- LLVisibilityTrackingMenuGL* menu = (LLVisibilityTrackingMenuGL*)mPopupMenuHandle.get();
+ LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get();
if(menu)
{
- if (menu->getClosedByChevronClick())
+ if (menu->getClosedByButtonClick())
{
- menu->resetClosedByChevronClick();
+ menu->resetClosedByButtonClick();
return;
}
if (menu->getVisible())
{
menu->setVisible(FALSE);
- menu->resetClosedByChevronClick();
+ menu->resetClosedByButtonClick();
return;
}
@@ -449,7 +411,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
- menu->setChevronRect(mChevronRect);
+ menu->setButtonRect(mChevronRect, this);
LLMenuGL::showPopup(this, menu, getRect().getWidth() - menu->getRect().getWidth(), 0);
return;
@@ -514,7 +476,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
- menu->setChevronRect(mChevronRect);
+ menu->setButtonRect(mChevronRect, this);
LLMenuGL::showPopup(this, menu, getRect().getWidth() - max_width, 0);
}
@@ -565,7 +527,11 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
}
else if (action == "about")
{
- LLFloaterReg::showInstance("preview_landmark", LLSD(mSelectedItemID), TAKE_FOCUS_YES);
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = mSelectedItemID;
+
+ LLSideTray::getInstance()->showPanel("panel_places", key);
}
else if (action == "rename")
{
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 646e98cabb..a559692331 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -34,7 +34,7 @@
#define LL_LLFAVORITESBARCTRL_H
#include "lluictrl.h"
-#include "lliconctrl.h"
+
#include "llinventorymodel.h"
class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 1bfb11e3ae..dd0df15348 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -54,7 +54,6 @@
//#include "lllineeditor.h"
#include "llmutelist.h"
//#include "llresizehandle.h"
-#include "llchatbar.h"
#include "llrecentpeople.h"
#include "llstatusbar.h"
#include "llviewertexteditor.h"
@@ -63,7 +62,6 @@
#include "llviewerwindow.h"
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
-#include "llchatbar.h"
#include "lllogchat.h"
#include "lltexteditor.h"
#include "lltextparser.h"
@@ -99,7 +97,6 @@ LLFloaterChat::LLFloaterChat(const LLSD& seed)
: LLFloater(seed),
mPanel(NULL)
{
- mFactoryMap["chat_panel"] = LLCallbackMap(createChatPanel, NULL);
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL);
//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_chat_history.xml");
@@ -121,12 +118,6 @@ void LLFloaterChat::draw()
childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel"));
- LLChatBar* chat_barp = findChild<LLChatBar>("chat_panel", TRUE);
- if (chat_barp)
- {
- chat_barp->refresh();
- }
-
mPanel->refreshSpeakers();
LLFloater::draw();
}
@@ -135,12 +126,6 @@ BOOL LLFloaterChat::postBuild()
{
mPanel = (LLPanelActiveSpeakers*)getChild<LLPanel>("active_speakers_panel");
- LLChatBar* chat_barp = findChild<LLChatBar>("chat_panel", TRUE);
- if (chat_barp)
- {
- chat_barp->setGestureCombo(getChild<LLComboBox>( "Gesture"));
- }
-
childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes
childSetVisible("Chat History Editor with mute",FALSE);
childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
@@ -540,13 +525,6 @@ void* LLFloaterChat::createSpeakersPanel(void* data)
return new LLPanelActiveSpeakers(LLLocalSpeakerMgr::getInstance(), TRUE);
}
-//static
-void* LLFloaterChat::createChatPanel(void* data)
-{
- LLChatBar* chatp = new LLChatBar();
- return chatp;
-}
-
// static
void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata)
{
diff --git a/indra/newview/llfloaterchat.h b/indra/newview/llfloaterchat.h
index 2bae4ea0c2..042d270aa6 100644
--- a/indra/newview/llfloaterchat.h
+++ b/indra/newview/llfloaterchat.h
@@ -82,7 +82,6 @@ public:
static void chatFromLogFile(LLLogChat::ELogLineType type,std::string line, void* userdata);
static void loadHistory();
static void* createSpeakersPanel(void* data);
- static void* createChatPanel(void* data);
static LLFloaterChat* getInstance(); // *TODO:Skinning Deprecate
diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp
index 1e8129c7d3..1e8e7bad74 100644
--- a/indra/newview/llfloaterfriends.cpp
+++ b/indra/newview/llfloaterfriends.cpp
@@ -46,7 +46,7 @@
#include "llfloateravatarpicker.h"
#include "llviewerwindow.h"
#include "llbutton.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llinventorymodel.h"
#include "llnamelistctrl.h"
#include "llnotify.h"
@@ -62,7 +62,7 @@
#include "lltextbox.h"
#include "llvoiceclient.h"
-// *TODO: Move more common stuff to LLFriendActions?
+// *TODO: Move more common stuff to LLAvatarActions?
//Maximum number of people you can select to do an operation on at once.
#define MAX_FRIEND_SELECT 20
@@ -546,7 +546,7 @@ void LLPanelFriends::onClickProfile(void* user_data)
if(ids.size() > 0)
{
LLUUID agent_id = ids[0];
- LLFriendActions::showProfile(agent_id);
+ LLAvatarActions::showProfile(agent_id);
}
}
@@ -560,11 +560,11 @@ void LLPanelFriends::onClickIM(void* user_data)
{
if(ids.size() == 1)
{
- LLFriendActions::startIM(ids[0]);
+ LLAvatarActions::startIM(ids[0]);
}
else
{
- LLFriendActions::startConference(ids);
+ LLAvatarActions::startConference(ids);
}
}
}
@@ -576,7 +576,7 @@ void LLPanelFriends::onPickAvatar(const std::vector<std::string>& names,
{
if (names.empty()) return;
if (ids.empty()) return;
- LLFriendActions::requestFriendshipDialog(ids[0], names[0]);
+ LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
}
// static
@@ -595,14 +595,14 @@ void LLPanelFriends::onClickAddFriend(void* user_data)
void LLPanelFriends::onClickRemove(void* user_data)
{
LLPanelFriends* panelp = (LLPanelFriends*)user_data;
- LLFriendActions::removeFriendsDialog(panelp->getSelectedIDs());
+ LLAvatarActions::removeFriendsDialog(panelp->getSelectedIDs());
}
// static
void LLPanelFriends::onClickOfferTeleport(void* user_data)
{
LLPanelFriends* panelp = (LLPanelFriends*)user_data;
- LLFriendActions::offerTeleport(panelp->getSelectedIDs());
+ LLAvatarActions::offerTeleport(panelp->getSelectedIDs());
}
// static
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index 972b3b9528..e26937e93f 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -36,7 +36,7 @@
#include "llfloaterreg.h"
#include "llfloatertools.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llcachename.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
@@ -144,7 +144,7 @@ void LLFloaterInspect::onClickCreatorProfile()
LLSelectNode* node = mObjectSelection->getFirstNode(&func);
if(node)
{
- LLFriendActions::showProfile(node->mPermissions->getCreator());
+ LLAvatarActions::showProfile(node->mPermissions->getCreator());
}
}
}
@@ -170,7 +170,7 @@ void LLFloaterInspect::onClickOwnerProfile()
if(node)
{
const LLUUID& owner_id = node->mPermissions->getOwner();
- LLFriendActions::showProfile(owner_id);
+ LLAvatarActions::showProfile(owner_id);
}
}
}
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index f7e5eaadd3..4b665a789e 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -52,7 +52,7 @@
#include "llfloaterauction.h"
#include "llfloatergroups.h"
#include "llfloatergroupinfo.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "lllineeditor.h"
#include "llnamelistctrl.h"
#include "llnotify.h"
@@ -811,7 +811,7 @@ void LLPanelLandGeneral::onClickProfile(void* data)
else
{
const LLUUID& avatar_id = parcel->getOwnerID();
- LLFriendActions::showProfile(avatar_id);
+ LLAvatarActions::showProfile(avatar_id);
}
}
@@ -1084,7 +1084,7 @@ void LLPanelLandObjects::onDoubleClickOwner(void *userdata)
}
else
{
- LLFriendActions::showProfile(owner_id);
+ LLAvatarActions::showProfile(owner_id);
}
}
}
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index dc72b66949..efc273c6e5 100644
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
@@ -44,7 +44,7 @@
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llfloatergroupinfo.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llinventorymodel.h"
#include "lllineeditor.h"
#include "llradiogroup.h"
@@ -611,7 +611,7 @@ void LLFloaterProperties::onClickCreator(void* data)
if(!item) return;
if(!item->getCreatorUUID().isNull())
{
- LLFriendActions::showProfile(item->getCreatorUUID());
+ LLAvatarActions::showProfile(item->getCreatorUUID());
}
}
@@ -628,7 +628,7 @@ void LLFloaterProperties::onClickOwner(void* data)
}
else
{
- LLFriendActions::showProfile(item->getPermissions().getOwner());
+ LLAvatarActions::showProfile(item->getPermissions().getOwner());
}
}
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 66ed680984..8ec9eac196 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -50,7 +50,6 @@
// newview
#include "llagent.h"
-#include "llchatbar.h"
#include "lldelayedgestureerror.h"
#include "llinventorymodel.h"
#include "llnotify.h"
@@ -872,8 +871,7 @@ void LLGestureManager::runStep(LLMultiGesture* gesture, LLGestureStep* step)
const BOOL animate = FALSE;
- if(gBottomTray)
- gBottomTray->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
+ LLBottomTray::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
gesture->mCurrentStep++;
break;
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 953d99c7ac..c71262c311 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -39,7 +39,6 @@
#include "llagent.h"
#include "llviewercontrol.h"
-#include "llchatbar.h"
#include "llcriticaldamp.h"
#include "lldrawable.h"
#include "llfontgl.h"
@@ -803,10 +802,6 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)
LLRect world_rect = gViewerWindow->getVirtualWorldViewRect();
S32 bottom = world_rect.mBottom + STATUS_BAR_HEIGHT;
- if (gChatBar && gChatBar->getVisible())
- {
- bottom += CHAT_BAR_HEIGHT;
- }
LLVector2 screen_center;
screen_center.mV[VX] = llclamp((F32)screen_pos_vec.mV[VX], (F32)world_rect.mLeft + mWidth * 0.5f, (F32)world_rect.mRight - mWidth * 0.5f);
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 9bf147584a..0652119f18 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -51,7 +51,7 @@
#include "llfloater.h"
#include "llfloatercall.h"
#include "llfloatergroupinfo.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llimview.h"
#include "llinventory.h"
#include "llinventorymodel.h"
@@ -1569,7 +1569,7 @@ void LLFloaterIMPanel::onClickProfile( void* userdata )
if (self->getOtherParticipantID().notNull())
{
- LLFriendActions::showProfile(self->getOtherParticipantID());
+ LLAvatarActions::showProfile(self->getOtherParticipantID());
}
}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index f8dd35e956..38335fe68f 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -51,7 +51,7 @@
#include "llresmgr.h"
#include "llfloaterchat.h"
#include "llfloaterchatterbox.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llhttpnode.h"
#include "llimpanel.h"
#include "llresizebar.h"
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 54d8208e9e..b705543e44 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -57,7 +57,7 @@
#include "llfloaterworldmap.h"
#include "llfocusmgr.h"
#include "llfolderview.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llgesturemgr.h"
#include "lliconctrl.h"
#include "llinventorymodel.h"
@@ -88,6 +88,7 @@
#include "lltabcontainer.h"
#include "lluictrlfactory.h"
#include "llselectmgr.h"
+#include "llsidetray.h"
#include "llfloateropenobject.h"
#include "lltrans.h"
@@ -2825,7 +2826,15 @@ void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* mod
LLViewerInventoryItem* item = getItem();
if(item)
{
- LLFloaterReg::showInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES);
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = item->getUUID();
+
+ LLSideTray::getInstance()->showPanel("panel_places", key);
+
+ // Floater preview_landmark disabled,
+ // its functionality moved to Side Tray Places Panel
+ //LLFloaterReg::showInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES);
}
}
else
@@ -2925,7 +2934,7 @@ void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel*
if (item && (item->getCreatorUUID() != gAgent.getID()) &&
(!item->getCreatorUUID().isNull()))
{
- LLFriendActions::offerTeleport(item->getCreatorUUID());
+ LLAvatarActions::offerTeleport(item->getCreatorUUID());
}
}
else LLItemBridge::performAction(folder, model, action);
@@ -2967,7 +2976,7 @@ void LLCallingCardBridge::openItem()
LLViewerInventoryItem* item = getItem();
if(item && !item->getCreatorUUID().isNull())
{
- LLFriendActions::showProfile(item->getCreatorUUID());
+ LLAvatarActions::showProfile(item->getCreatorUUID());
}
*/
}
@@ -4891,7 +4900,7 @@ void LLCallingCardBridgeAction::doIt()
LLViewerInventoryItem* item = getItem();
if(item && item->getCreatorUUID().notNull())
{
- LLFriendActions::showProfile(item->getCreatorUUID());
+ LLAvatarActions::showProfile(item->getCreatorUUID());
}
LLInvFVBridgeAction::doIt();
diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp
index c0225ebfca..0c652621f4 100644
--- a/indra/newview/llmenucommands.cpp
+++ b/indra/newview/llmenucommands.cpp
@@ -44,7 +44,6 @@
#include "llagent.h"
#include "llcallingcard.h"
-#include "llchatbar.h"
#include "llviewercontrol.h"
#include "llfirstuse.h"
#include "llfloaterchat.h"
@@ -84,20 +83,20 @@ void handle_mouselook(void*)
void handle_chat(void*)
{
// give focus to chatbar if it's open but not focused
- if (gBottomTray && gSavedSettings.getBOOL("ChatVisible") &&
- gFocusMgr.childHasKeyboardFocus(gBottomTray->getChatBox()))
+ if (gSavedSettings.getBOOL("ChatVisible") &&
+ gFocusMgr.childHasKeyboardFocus(LLBottomTray::getInstance()->getChatBox()))
{
- LLChatBar::stopChat();
+ LLBottomTray::stopChat();
}
else
{
- LLChatBar::startChat(NULL);
+ LLBottomTray::startChat(NULL);
}
}
void handle_slash_key(void*)
{
- // LLChatBar::startChat("/");
+ // LLBottomTray::startChat("/");
//
// Don't do this, it results in a double-slash in the input field.
// Another "/" will be automatically typed for us, because the WM_KEYDOWN event
@@ -107,5 +106,5 @@ void handle_slash_key(void*)
// menu accelerators that put input focus into a field. And Mac works
// the same way. JC
- LLChatBar::startChat(NULL);
+ LLBottomTray::startChat(NULL);
}
diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp
index d03e39280f..a24d1ed54a 100644
--- a/indra/newview/lloverlaybar.cpp
+++ b/indra/newview/lloverlaybar.cpp
@@ -41,7 +41,6 @@
#include "llrender.h"
#include "llagent.h"
#include "llbutton.h"
-#include "llchatbar.h"
#include "llfocusmgr.h"
#include "llimview.h"
#include "llmediaremotectrl.h"
@@ -92,12 +91,6 @@ void* LLOverlayBar::createVoiceRemote(void* userdata)
return self->mVoiceRemote;
}
-void* LLOverlayBar::createChatBar(void* userdata)
-{
- gChatBar = new LLChatBar();
- return gChatBar;
-}
-
LLOverlayBar::LLOverlayBar()
: LLPanel(),
mMediaRemote(NULL),
@@ -111,7 +104,6 @@ LLOverlayBar::LLOverlayBar()
mFactoryMap["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);
mFactoryMap["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this);
- mFactoryMap["chat_bar"] = LLCallbackMap(LLOverlayBar::createChatBar, this);
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml");
}
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index e3c4167d73..868d4d9200 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -38,7 +38,7 @@
#include "llavatarconstants.h"
#include "llcallingcard.h"
#include "llcombobox.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llimview.h"
#include "lltexteditor.h"
#include "lltexturectrl.h"
@@ -182,7 +182,7 @@ void LLPanelProfileTab::onAddFriend()
{
std::string name;
gCacheName->getFullName(getAvatarId(),name);
- LLFriendActions::requestFriendshipDialog(getAvatarId(), name);
+ LLAvatarActions::requestFriendshipDialog(getAvatarId(), name);
}
}
@@ -200,7 +200,7 @@ void LLPanelProfileTab::onTeleport()
{
if(getAvatarId().notNull())
{
- LLFriendActions::offerTeleport(getAvatarId());
+ LLAvatarActions::offerTeleport(getAvatarId());
}
}
@@ -296,7 +296,7 @@ void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType ty
bool online = avatar_data->flags & AVATAR_ONLINE;
- if(LLFriendActions::isFriend(avatar_data->avatar_id))
+ if(LLAvatarActions::isFriend(avatar_data->avatar_id))
{
// Online status NO could be because they are hidden
// If they are a friend, we may know the truth!
@@ -536,7 +536,7 @@ void LLPanelAvatarProfile::updateChildrenList()
childSetVisible("partner_edit_link", false);
//hide for friends
- childSetEnabled("add_friend", !LLFriendActions::isFriend(getAvatarId()));
+ childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId()));
//need to update profile view on every activate
mUpdated = false;
@@ -730,5 +730,5 @@ void LLPanelAvatarNotes::onActivate(const LLUUID& id)
void LLPanelAvatarNotes::updateChildrenList()
{
//hide for friends
- childSetEnabled("add_friend", !LLFriendActions::isFriend(getAvatarId()));
+ childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId()));
}
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index bd4625ab11..df687ffb30 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -42,10 +42,12 @@
#include "lldispatcher.h"
#include "llfloaterreg.h"
#include "llparcel.h"
+#include "lltabcontainer.h"
#include "message.h"
#include "llagent.h"
#include "llalertdialog.h"
+#include "llavataractions.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llclassifiedflags.h"
@@ -53,7 +55,6 @@
#include "llcommandhandler.h" // for classified HTML detail page click tracking
#include "llviewercontrol.h"
#include "lllineeditor.h"
-#include "llfloateravatarinfo.h"
#include "llfloaterclassified.h"
#include "lltextbox.h"
#include "llcombobox.h"
@@ -959,7 +960,7 @@ void LLPanelClassified::onClickMap(void* data)
void LLPanelClassified::onClickProfile(void* data)
{
LLPanelClassified* self = (LLPanelClassified*)data;
- LLFloaterAvatarInfo::showFromDirectory(self->mCreatorID);
+ LLAvatarActions::showProfile(self->mCreatorID);
self->sendClassifiedClickMessage("profile");
}
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index d495373cc4..6f8d161001 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -44,7 +44,7 @@
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "lldbstrings.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "lllineeditor.h"
#include "llnamebox.h"
#include "llnamelistctrl.h"
@@ -375,7 +375,7 @@ void LLPanelGroupGeneral::openProfile(void* data)
LLScrollListItem* selected = self->mListVisibleMembers->getFirstSelected();
if (selected)
{
- LLFriendActions::showProfile(selected->getUUID());
+ LLAvatarActions::showProfile(selected->getUUID());
}
}
}
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 365f07e4b6..1c52c3cea4 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -37,7 +37,7 @@
#include "llagent.h"
#include "llbutton.h"
#include "llfloatergroupinvite.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "lliconctrl.h"
#include "lllineeditor.h"
#include "llnamelistctrl.h"
@@ -1289,7 +1289,7 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
LLScrollListItem* selected = mMembersList->getFirstSelected();
if (selected)
{
- LLFriendActions::showProfile(selected->getUUID());
+ LLAvatarActions::showProfile(selected->getUUID());
}
}
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 6fad582eee..453183ad74 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -268,3 +268,8 @@ void LLLandmarksPanel::onSelectorButtonClicked()
LLSideTray::getInstance()->showPanel("panel_places", key);
}
}
+
+void LLLandmarksPanel::setSelectedItem(const LLUUID& obj_id)
+{
+ mInventoryPanel->setSelection(obj_id, FALSE);
+}
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 8889a99925..0b11270fb5 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -52,6 +52,7 @@ public:
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
void onSelectorButtonClicked();
+ void setSelectedItem(const LLUUID& obj_id);
private:
LLInventoryPanel* mInventoryPanel;
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 82c8f97d4d..d2879a675f 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -47,7 +47,7 @@
#include "llcallingcard.h" // for LLAvatarTracker
#include "llfloateravatarpicker.h"
#include "llfloaterminiinspector.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llgroupactions.h"
#include "llgrouplist.h"
#include "llrecentpeople.h"
@@ -508,17 +508,19 @@ void LLPanelPeople::updateButtons()
if (group_tab_active)
{
+ bool item_selected = mGroupList->getFirstSelected() != NULL;
bool cur_group_active = true;
- selected_id = mGroupList->getCurrentID();
- if (selected_id.notNull())
+ if (item_selected)
+ {
+ selected_id = mGroupList->getCurrentID();
cur_group_active = (gAgent.getGroupID() == selected_id);
-
- bool item_selected = selected_id.notNull();
+ }
+
LLPanel* groups_panel = mTabContainer->getCurrentPanel();
- groups_panel->childSetEnabled("activate_btn", !item_selected || !cur_group_active); // "none" or a non-active group selected
+ groups_panel->childSetEnabled("activate_btn", item_selected && !cur_group_active); // "none" or a non-active group selected
groups_panel->childSetEnabled("plus_btn", item_selected);
- groups_panel->childSetEnabled("minus_btn", item_selected);
+ groups_panel->childSetEnabled("minus_btn", item_selected && selected_id.notNull());
}
else
{
@@ -623,6 +625,8 @@ void LLPanelPeople::onSearchEdit(const std::string& search_string)
filterFriendList();
filterRecentList();
updateGroupList();
+
+ updateButtons();
}
void LLPanelPeople::onTabSelected(const LLSD& param)
@@ -653,7 +657,7 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)
void LLPanelPeople::onViewProfileButtonClicked()
{
LLUUID id = getCurrentItemID();
- LLFriendActions::showProfile(id);
+ LLAvatarActions::showProfile(id);
}
void LLPanelPeople::onAddFriendButtonClicked()
@@ -663,7 +667,7 @@ void LLPanelPeople::onAddFriendButtonClicked()
{
std::string name;
gCacheName->getFullName(id, name);
- LLFriendActions::requestFriendshipDialog(id, name);
+ LLAvatarActions::requestFriendshipDialog(id, name);
}
}
@@ -680,7 +684,7 @@ void LLPanelPeople::onAddFriendWizButtonClicked()
void LLPanelPeople::onDeleteFriendButtonClicked()
{
- LLFriendActions::removeFriendDialog(getCurrentItemID());
+ LLAvatarActions::removeFriendDialog(getCurrentItemID());
}
void LLPanelPeople::onGroupInfoButtonClicked()
@@ -702,7 +706,7 @@ void LLPanelPeople::onImButtonClicked()
LLUUID id = getCurrentItemID();
if (id.notNull())
{
- LLFriendActions::startIM(id);
+ LLAvatarActions::startIM(id);
}
}
@@ -718,7 +722,7 @@ void LLPanelPeople::onAvatarPicked(
void*)
{
if (!names.empty() && !ids.empty())
- LLFriendActions::requestFriendshipDialog(ids[0], names[0]);
+ LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
}
bool LLPanelPeople::onFriendListUpdate(U32 changed_mask)
@@ -765,7 +769,7 @@ void LLPanelPeople::onCallButtonClicked()
void LLPanelPeople::onTeleportButtonClicked()
{
- LLFriendActions::offerTeleport(getCurrentItemID());
+ LLAvatarActions::offerTeleport(getCurrentItemID());
}
void LLPanelPeople::onShareButtonClicked()
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 9fdde9e757..96e8cbfd71 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -59,7 +59,7 @@
#include "lldbstrings.h"
#include "llfloatergroupinfo.h"
#include "llfloatergroups.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llnamebox.h"
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
@@ -811,7 +811,7 @@ void LLPanelPermissions::onClickCreator(void *data)
{
LLPanelPermissions *self = (LLPanelPermissions *)data;
- LLFriendActions::showProfile(self->mCreatorID);
+ LLAvatarActions::showProfile(self->mCreatorID);
}
// static
@@ -827,7 +827,7 @@ void LLPanelPermissions::onClickOwner(void *data)
}
else
{
- LLFriendActions::showProfile(self->mOwnerID);
+ LLAvatarActions::showProfile(self->mOwnerID);
}
}
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index b1efb71abb..961c54d667 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -219,9 +219,6 @@ void LLPanelPick::setEditMode( BOOL edit_mode )
mEditMode = edit_mode;
// preserve data before killing controls
- std::string name = getPickName();
- std::string desc = getPickDesc();
- std::string location = getPickLocation();
LLUUID snapshot_id = mSnapshotCtrl->getImageAssetID();
LLRect old_rect = getRect();
@@ -242,9 +239,9 @@ void LLPanelPick::setEditMode( BOOL edit_mode )
setRect(old_rect);
// time to restore data
- setPickName(name);
- setPickDesc(desc);
- setPickLocation(location);
+ setPickName(mName);
+ setPickDesc(mDesc);
+ setPickLocation(mLocation);
mSnapshotCtrl->setImageAssetID(snapshot_id);
updateButtons();
@@ -260,6 +257,9 @@ void LLPanelPick::setPickName(std::string name)
{
childSetWrappedText(XML_NAME, name);
}
+
+ //preserving non-wrapped text for info/edit modes switching
+ mName = name;
}
void LLPanelPick::setPickDesc(std::string desc)
@@ -272,11 +272,17 @@ void LLPanelPick::setPickDesc(std::string desc)
{
childSetWrappedText(XML_DESC, desc);
}
+
+ //preserving non-wrapped text for info/edit modes switching
+ mDesc = desc;
}
void LLPanelPick::setPickLocation(std::string location)
{
childSetWrappedText(XML_LOCATION, location);
+
+ //preserving non-wrapped text for info/edit modes switching
+ mLocation = location;
}
std::string LLPanelPick::getPickName()
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index db943f4eaf..15b0d6c541 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -122,6 +122,11 @@ protected:
LLUUID mParcelId;
std::string mSimName;
+ //These strings are used to keep non-wrapped text
+ std::string mName;
+ std::string mDesc;
+ std::string mLocation;
+
commit_callback_t mBackCb;
};
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 5bbcf4207f..590eae555e 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -235,27 +235,46 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
if (!mInfoPanel)
return;
- if (type == PLACE)
+ switch(type)
{
- mCurrentTitle = getString("title_place");
- }
- else
- {
- mCurrentTitle = getString("title_landmark");
+ case PLACE:
+ mCurrentTitle = getString("title_place");
+
+ if (!isMediaPanelVisible())
+ {
+ mTitle->setText(mCurrentTitle);
+ }
+ break;
+
+ // Hide Media Panel if showing information about
+ // a landmark or a teleport history item
+ case LANDMARK:
+ mCurrentTitle = getString("title_landmark");
+
+ toggleMediaPanel(FALSE);
+ break;
+
+ case TELEPORT_HISTORY:
+ mCurrentTitle = getString("title_place");
+
+ toggleMediaPanel(FALSE);
+ break;
}
+}
+
+BOOL LLPanelPlaceInfo::isMediaPanelVisible()
+{
+ if (!mMediaPanel)
+ return FALSE;
- if (mInfoPanel->getVisible())
- {
- mTitle->setText(mCurrentTitle);
- }
+ return mMediaPanel->getVisible();
}
-void LLPanelPlaceInfo::toggleMediaPanel()
+void LLPanelPlaceInfo::toggleMediaPanel(BOOL visible)
{
if (!(mMediaPanel && mInfoPanel))
return;
- bool visible = mInfoPanel->getVisible();
if (visible)
{
mTitle->setText(getString("title_media"));
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 8b00507ba0..7f98b6cb76 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -56,7 +56,8 @@ public:
enum INFO_TYPE
{
PLACE,
- LANDMARK
+ LANDMARK,
+ TELEPORT_HISTORY
};
LLPanelPlaceInfo();
@@ -77,7 +78,8 @@ public:
// sets a corresponding title and contents.
void setInfoType(INFO_TYPE type);
- void toggleMediaPanel();
+ BOOL isMediaPanelVisible();
+ void toggleMediaPanel(BOOL visible);
void displayItemInfo(const LLInventoryItem* pItem);
/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index f5e225c51b..c162a9ba33 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -44,8 +44,23 @@
#include "llpanelplaces.h"
#include "llpanellandmarks.h"
#include "llpanelteleporthistory.h"
+#include "llsidetray.h"
+#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
+LLPanelPlaces::LLParcelUpdateTimer::LLParcelUpdateTimer(F32 period)
+: LLEventTimer(period)
+{
+};
+
+// virtual
+BOOL LLPanelPlaces::LLParcelUpdateTimer::tick()
+{
+ LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "agent"));
+
+ return TRUE;
+}
+
static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places");
LLPanelPlaces::LLPanelPlaces()
@@ -57,6 +72,9 @@ LLPanelPlaces::LLPanelPlaces()
{
gInventory.addObserver(this);
+ LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback(
+ boost::bind(&LLPanelPlaces::onAgentParcelChange, this));
+
//LLUICtrlFactory::getInstance()->buildPanel(this, "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
}
@@ -90,7 +108,7 @@ BOOL LLPanelPlaces::postBuild()
}
// *TODO: Assign the action to an appropriate event.
- childSetAction("overflow_btn", boost::bind(&LLPanelPlaceInfo::toggleMediaPanel, mPlaceInfo), this);
+ childSetAction("overflow_btn", boost::bind(&LLPanelPlaces::toggleMediaPanel, this), this);
}
//childSetAction("share_btn", boost::bind(&LLPanelPlaces::onShareButtonClicked, this), this);
@@ -100,19 +118,14 @@ BOOL LLPanelPlaces::postBuild()
return TRUE;
}
-void LLPanelPlaces::draw()
-{
- LLPanel::draw();
-}
-
void LLPanelPlaces::onOpen(const LLSD& key)
{
if(key.size() == 0)
return;
- togglePlaceInfoPanel(TRUE);
-
mPlaceInfoType = key["type"].asString();
+
+ togglePlaceInfoPanel(TRUE);
if (mPlaceInfoType == "agent")
{
@@ -127,7 +140,8 @@ void LLPanelPlaces::onOpen(const LLSD& key)
}
else if (mPlaceInfoType == "landmark")
{
- LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
+ LLUUID item_uuid = key["id"].asUUID();
+ LLInventoryItem* item = gInventory.getItem(item_uuid);
if (!item)
return;
@@ -138,6 +152,12 @@ void LLPanelPlaces::onOpen(const LLSD& key)
if (!landmark)
return;
+ // Select Landmarks tab and set selection to requested landmark so that
+ // context dependent Verbs buttons update properly.
+ mTabContainer->selectFirstTab(); // Assume that first tab is Landmarks tab.
+ LLLandmarksPanel* landmarks_panel = dynamic_cast<LLLandmarksPanel*>(mTabContainer->getCurrentPanel());
+ landmarks_panel->setSelectedItem(item_uuid);
+
LLUUID region_id;
landmark->getRegionID(region_id);
LLVector3d pos_global;
@@ -145,7 +165,6 @@ void LLPanelPlaces::onOpen(const LLSD& key)
mPlaceInfo->displayParcelInfo(landmark->getRegionPos(),
region_id,
pos_global);
-
}
else if (mPlaceInfoType == "teleport_history")
{
@@ -161,7 +180,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]);
- mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE);
+ mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
mPlaceInfo->displayParcelInfo(pos_local,
hist_items[index].mRegionID,
pos_global);
@@ -186,11 +205,11 @@ void LLPanelPlaces::onSearchEdit(const std::string& search_string)
void LLPanelPlaces::onTabSelected()
{
mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel());
- if (mActivePanel)
- {
- mActivePanel->onSearchEdit(mFilterSubString);
- mActivePanel->updateVerbs();
- }
+ if (!mActivePanel)
+ return;
+
+ onSearchEdit(mFilterSubString);
+ mActivePanel->updateVerbs();
}
void LLPanelPlaces::onShareButtonClicked()
@@ -242,6 +261,13 @@ void LLPanelPlaces::onBackButtonClicked()
togglePlaceInfoPanel(FALSE);
}
+void LLPanelPlaces::toggleMediaPanel()
+{
+ if (!mPlaceInfo)
+ return;
+
+ mPlaceInfo->toggleMediaPanel(!mPlaceInfo->isMediaPanelVisible());
+}
void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
if (!mPlaceInfo)
@@ -250,6 +276,9 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
mPlaceInfo->setVisible(visible);
mSearchEditor->setVisible(!visible);
mTabContainer->setVisible(!visible);
+
+ // Enable overflow button only for the information about agent's current location.
+ getChild<LLButton>("overflow_btn")->setEnabled(visible && mPlaceInfoType == "agent");
if (visible)
{
@@ -275,7 +304,7 @@ void LLPanelPlaces::changed(U32 mask)
mTabContainer->addTabPanel(
LLTabContainer::TabPanelParams().
panel(landmarks_panel).
- label("Landmarks").
+ label(getString("landmarks_tab_title")).
insert_at(LLTabContainer::END));
}
@@ -287,7 +316,7 @@ void LLPanelPlaces::changed(U32 mask)
mTabContainer->addTabPanel(
LLTabContainer::TabPanelParams().
panel(teleport_history_panel).
- label("Teleport History").
+ label(getString("teleport_history_tab_title")).
insert_at(LLTabContainer::END));
}
@@ -299,3 +328,13 @@ void LLPanelPlaces::changed(U32 mask)
// so remove the observer
gInventory.removeObserver(this);
}
+
+void LLPanelPlaces::onAgentParcelChange()
+{
+ if (mPlaceInfo->getVisible() && mPlaceInfoType == "agent")
+ {
+ // Using timer to delay obtaining agent's coordinates
+ // not to get the coordinates of previous parcel.
+ new LLParcelUpdateTimer(.5);
+ }
+}
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 89758fc34f..6fbb7562c9 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -32,6 +32,8 @@
#ifndef LL_LLPANELPLACES_H
#define LL_LLPANELPLACES_H
+#include "lltimer.h"
+
#include "llpanel.h"
#include "llinventory.h"
@@ -50,7 +52,6 @@ public:
virtual ~LLPanelPlaces();
/*virtual*/ BOOL postBuild();
- /*virtual*/ void draw();
/*virtual*/ void changed(U32 mask);
/*virtual*/ void onOpen(const LLSD& key);
@@ -62,7 +63,9 @@ public:
void onTeleportButtonClicked();
void onShowOnMapButtonClicked();
void onBackButtonClicked();
+ void toggleMediaPanel();
void togglePlaceInfoPanel(BOOL visible);
+ void onAgentParcelChange();
private:
LLSearchEditor* mSearchEditor;
@@ -73,6 +76,17 @@ private:
// Place information type currently shown in Information panel
std::string mPlaceInfoType;
+
+ // Helper class to delay the coordinates update
+ // when agent changes parcel
+ class LLParcelUpdateTimer : public LLEventTimer
+ {
+ public:
+ LLParcelUpdateTimer(F32 period);
+ virtual ~LLParcelUpdateTimer() {};
+
+ virtual BOOL tick();
+ };
};
#endif //LL_LLPANELPLACES_H
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index f50f5a3db0..d8be1386c3 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -40,7 +40,7 @@
#include "llfocusmgr.h"
#include "llrootview.h"
-#include "llcollapsiblectrl.h"
+#include "llaccordionctrltab.h"
#include "llfloater.h" //for gFloaterView
#include "lliconctrl.h"//for Home tab icon
@@ -664,7 +664,7 @@ void LLSideTray::createHomeTab()
panel->setCommitCallback(boost::bind(&LLSideTray::onTabButtonClick, this, sidebar_tab->getName()));
- LLCollapsibleCtrl::Params panel_params;
+ LLAccordionCtrlTab::Params panel_params;
panel_params.display_children(true);
panel_params.collapsible(false);
panel_params.header_visible(false);
@@ -676,7 +676,7 @@ void LLSideTray::createHomeTab()
panel_params.padding_bottom(5);
panel_params.name(sidebar_tab->getTabTitle());
- LLCollapsibleCtrl* ctrl = LLUICtrlFactory::create<LLCollapsibleCtrl>(panel_params);
+ LLAccordionCtrlTab* ctrl = LLUICtrlFactory::create<LLAccordionCtrlTab>(panel_params);
ctrl->setPanel(panel);
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index bbd34835ca..62ed861c86 100644
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -39,7 +39,6 @@
#include "llviewerinventory.h"
#include "sound_ids.h" // for testing
-#include "llchatbar.h"
#include "llkeyboard.h" // for key shortcuts for testing
#include "llinventorymodel.h"
#include "llvoavatar.h"
@@ -133,11 +132,11 @@ void LLViewerGesture::doTrigger( BOOL send_chat )
}
}
- if (gBottomTray && send_chat && !mOutputString.empty())
+ if (send_chat && !mOutputString.empty())
{
// Don't play nodding animation, since that might not blend
// with the gesture animation.
- gBottomTray->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
+ LLBottomTray::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
}
}
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index ab5cdeba44..63234c2990 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -36,7 +36,7 @@
#include "llviewerkeyboard.h"
#include "llmath.h"
#include "llagent.h"
-#include "llchatbar.h"
+#include "llbottomtray.h"
#include "llviewercontrol.h"
#include "llfocusmgr.h"
#include "llmorphview.h"
@@ -500,8 +500,7 @@ void stop_moving( EKeystate s )
void start_chat( EKeystate s )
{
// start chat
- LLChatBar::startChat(NULL);
-// gChatBar->startChat(NULL);
+ LLBottomTray::startChat(NULL);
}
void start_gesture( EKeystate s )
@@ -509,18 +508,16 @@ void start_gesture( EKeystate s )
if (KEYSTATE_UP == s &&
!(gFocusMgr.getKeyboardFocus() && gFocusMgr.getKeyboardFocus()->acceptsTextInput()))
{
- //TODO* remove DUMMY chatbar
- LLChatBar::startChat(NULL);
-// if (gChatBar->getCurrentChat().empty())
-// {
-// // No existing chat in chat editor, insert '/'
-// gChatBar->startChat("/");
-// }
-// else
-// {
-// // Don't overwrite existing text in chat editor
-// gChatBar->startChat(NULL);
-// }
+ if (LLBottomTray::getInstance()->getCurrentChat().empty())
+ {
+ // No existing chat in chat editor, insert '/'
+ LLBottomTray::getInstance()->startChat("/");
+ }
+ else
+ {
+ // Don't overwrite existing text in chat editor
+ LLBottomTray::getInstance()->startChat(NULL);
+ }
}
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 63854abfea..e06e180ed5 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -131,7 +131,7 @@
#include "llfloaterworldmap.h"
#include "llfloatermemleak.h"
#include "llfasttimerview.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llmemoryview.h"
#include "llgivemoney.h"
#include "llgroupmgr.h"
@@ -3607,7 +3607,7 @@ bool LLHaveCallingcard::operator()(LLInventoryCategory* cat,
BOOL is_agent_mappable(const LLUUID& agent_id)
{
- return (LLFriendActions::isFriend(agent_id) &&
+ return (LLAvatarActions::isFriend(agent_id) &&
LLAvatarTracker::instance().getBuddyInfo(agent_id)->isOnline() &&
LLAvatarTracker::instance().getBuddyInfo(agent_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)
);
@@ -3620,7 +3620,7 @@ class LLAvatarEnableAddFriend : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
- bool new_value = avatar && !LLFriendActions::isFriend(avatar->getID());
+ bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID());
return new_value;
}
};
@@ -3644,7 +3644,7 @@ void request_friendship(const LLUUID& dest_id)
}
if (!fullname.empty())
{
- LLFriendActions::requestFriendshipDialog(dest_id, fullname);
+ LLAvatarActions::requestFriendshipDialog(dest_id, fullname);
}
else
{
@@ -5376,7 +5376,7 @@ class LLAvatarAddFriend : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if(avatar && !LLFriendActions::isFriend(avatar->getID()))
+ if(avatar && !LLAvatarActions::isFriend(avatar->getID()))
{
request_friendship(avatar->getID());
}
@@ -5720,7 +5720,7 @@ class LLShowAgentProfile : public view_listener_t
LLVOAvatar* avatar = find_avatar_from_object(agent_id);
if (avatar)
{
- LLFriendActions::showProfile(avatar->getID());
+ LLAvatarActions::showProfile(avatar->getID());
}
return true;
}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 039faa2bf9..1468b376b0 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -78,7 +78,6 @@
#include "llagent.h"
#include "llalertdialog.h"
#include "llbox.h"
-#include "llchatbar.h"
#include "llconsole.h"
#include "llviewercontrol.h"
#include "llcylinder.h"
@@ -1557,13 +1556,12 @@ void LLViewerWindow::initWorldUI()
getRootView()->sendChildToFront(gSnapshotFloaterView);
// new bottom panel
- gBottomTray = new LLBottomTray();
- LLRect rc = gBottomTray->getRect();
+ LLRect rc = LLBottomTray::getInstance()->getRect();
rc.mLeft = 0;
rc.mRight = mRootView->getRect().getWidth();
- mRootView->addChild(gBottomTray);
- gBottomTray->reshape(rc.getWidth(),rc.getHeight(),FALSE);
- gBottomTray->setRect(rc);
+ mRootView->addChild(LLBottomTray::getInstance());
+ LLBottomTray::getInstance()->reshape(rc.getWidth(),rc.getHeight(),FALSE);
+ LLBottomTray::getInstance()->setRect(rc);
// View for hover information
LLHoverView::Params hvp;
@@ -1595,9 +1593,9 @@ void LLViewerWindow::initWorldUI()
LLRect floater_view_rect = gFloaterView->getRect();
LLRect notify_view_rect = gNotifyBoxView->getRect();
floater_view_rect.mTop -= NAVIGATION_BAR_HEIGHT;
- floater_view_rect.mBottom += gBottomTray->getRect().getHeight();
+ floater_view_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight();
notify_view_rect.mTop -= NAVIGATION_BAR_HEIGHT;
- notify_view_rect.mBottom += gBottomTray->getRect().getHeight();
+ notify_view_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight();
gFloaterView->setRect(floater_view_rect);
gNotifyBoxView->setRect(notify_view_rect);
@@ -1854,10 +1852,10 @@ void LLViewerWindow::reshape(S32 width, S32 height)
// Hide normal UI when a logon fails
void LLViewerWindow::setNormalControlsVisible( BOOL visible )
{
- if(gBottomTray)
+ if(LLBottomTray::instanceExists())
{
- gBottomTray->setVisible(visible);
- gBottomTray->setEnabled(visible);
+ LLBottomTray::getInstance()->setVisible(visible);
+ LLBottomTray::getInstance()->setEnabled(visible);
}
if ( gMenuBarView )
@@ -2165,11 +2163,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();
if( keyboard_focus )
{
- LLLineEditor* chat_bar = gBottomTray ? gBottomTray->getChatBox() : NULL;
+ LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getChatBox() : NULL;
// arrow keys move avatar while chatting hack
- if (chat_bar && chat_bar->hasFocus())
+ if (chat_editor && chat_editor->hasFocus())
{
- if (chat_bar->getText().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar"))
+ if (chat_editor->getText().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar"))
{
switch(key)
{
@@ -2399,10 +2397,14 @@ void LLViewerWindow::updateUI()
updateWorldViewRect();
- if(gBottomTray && LLSideTray::instanceCreated())
+ if(LLBottomTray::instanceExists() && LLSideTray::instanceCreated())
{
- S32 delta = llround((F32)LLSideTray::getInstance()->getTrayWidth() * mDisplayScale.mV[VX]);
- gBottomTray->updateRightPosition(mWindowRect.mRight - delta);
+ S32 delta = 0;
+ if(LLSideTray::getInstance()->getVisible())
+ {
+ delta = llround((F32)LLSideTray::getInstance()->getTrayWidth() * mDisplayScale.mV[VX]);
+ }
+ LLBottomTray::getInstance()->updateRightPosition(mWindowRect.mRight - delta);
}
LLView::sMouseHandlerMessage.clear();
@@ -2939,19 +2941,6 @@ void LLViewerWindow::updateKeyboardFocus()
if(LLSideTray::instanceCreated())//just getInstance will create sidetray. we don't want this
LLSideTray::getInstance()->highlightFocused();
-
- //NOTE: this behavior is no longer desirable with a permanently visible chat batr
- // which would *always* steal focus, disallowing navigation of the world via WASD controls --RN
-
- //if (gSavedSettings.getBOOL("ChatBarStealsFocus")
- // && gChatBar
- // && gFocusMgr.getKeyboardFocus() == NULL
- // && gChatBar->isInVisibleChain())
- //{
- // gChatBar->startChat(NULL);
- //}
-
-
}
void LLViewerWindow::updateWorldViewRect(bool use_full_window)
@@ -4912,8 +4901,8 @@ S32 LLViewerWindow::getChatConsoleBottomPad()
{
S32 offset = 0;
- if(gBottomTray)
- offset += gBottomTray->getRect().getHeight();
+ if(LLBottomTray::instanceExists())
+ offset += LLBottomTray::getInstance()->getRect().getHeight();
return offset;
}
diff --git a/indra/newview/skins/default/xui/en/accordion_drag.xml b/indra/newview/skins/default/xui/en/accordion_drag.xml
new file mode 100644
index 0000000000..94839a7593
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/accordion_drag.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel border_thickness="2" visible ="true" name="splitter_drag"
+ width="100"
+ height="5"
+ left="50"
+ top="50"
+ follows="left|bottom|right" background_visible="true" label="splitter_drag" title="">
+</panel>
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
new file mode 100644
index 0000000000..542e319792
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="101"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="IMChiclet Group Menu"
+ top="724"
+ visible="false"
+ width="128">
+ <menu_item_call
+ label="Chat..."
+ layout="topleft"
+ name="Chat">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="group chat" />
+ </menu_item_call>
+ <menu_item_call
+ label="Info..."
+ layout="topleft"
+ name="Show Profile">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="info" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
new file mode 100644
index 0000000000..bad6e1e212
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="101"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="IMChiclet P2P Menu"
+ top="724"
+ visible="false"
+ width="128">
+ <menu_item_call
+ label="Show Profile..."
+ layout="topleft"
+ name="Show Profile">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="profile" />
+ </menu_item_call>
+ <menu_item_call
+ label="Send IM..."
+ layout="topleft"
+ name="Send IM">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="im" />
+ </menu_item_call>
+ <menu_item_call
+ label="Add Friend..."
+ layout="topleft"
+ name="Add Friend">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="add" />
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Friend..."
+ layout="topleft"
+ name="Remove Friend">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="remove" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index ef6f2237ad..d890edcfed 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3068,9 +3068,10 @@ Are you sure you want to teleport?
type="alertmodal">
Teleport to [PICK]?
<usetemplate
- name="okcancelbuttons"
+ ignoretext="When teleporting from double-clicking a pick"
+ name="okcancelignore"
notext="Cancel"
- yestext="OK"/>
+ yestext="Teleport"/>
</notification>
<notification
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 6c4f47a34f..7006203dcd 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -11,10 +11,6 @@
top="28"
border_visible="true"
width="1000">
- <panel.string
- name="gesture_label">
- Gestures
- </panel.string>
<layout_stack
border_size="0"
follows="left|right|bottom|top"
@@ -53,7 +49,7 @@
layout="topleft"
left="0"
name="chat_box"
- right="-39"
+ right="-39"
top="3"
width="250" />
<button follows="right" width="36" top="3" left="214" resize="false"
@@ -131,7 +127,7 @@
width="90"
top="0"
min_width="90">
- <combo_box
+ <gesture_combo_box
bottom="22"
follows="right"
height="20"
@@ -192,8 +188,8 @@
min_height="28"
top="0"
name="chiclet_list_panel"
- width="250"
- min_width="100">
+ width="150"
+ min_width="70">
<chiclet_panel
follows="left|right"
height="25"
@@ -201,7 +197,9 @@
left="0"
name="chiclet_list"
top="1"
- width="250" />
+ chiclet_padding="3"
+ scrolling_offset="40"
+ width="150" />
</layout_panel>
<icon
auto_resize="false"
@@ -227,13 +225,19 @@
<chiclet_notification
follows="right"
height="25"
- image_selected="im_notifications.tga"
- image_unselected="im_notifications.tga"
layout="topleft"
left="0"
name="im_well"
top="1"
- width="40" >
+ width="40">
+ <button
+ image_selected="im_notifications.tga"
+ image_unselected="im_notifications.tga"/>
+ <unread_notifications
+ width="20"
+ height="20"
+ left="18"
+ top="23"/>
<chiclet_notification.commit_callback
function="Notification.Show"
parameter="ClickUnimplemented" />
@@ -254,7 +258,7 @@
auto_resize="false"
bevel_style="in"
follows="left|right"
- height="30"
+ height="28"
layout="topleft"
left="270"
name="well_separator"
@@ -284,13 +288,19 @@
<chiclet_notification
follows="right"
height="25"
- image_selected="bottom_tray_sys_notifications.tga"
- image_unselected="bottom_tray_sys_notifications.tga"
layout="topleft"
left="0"
name="sys_well"
top="1"
- width="48" >
+ width="48">
+ <button
+ image_selected="bottom_tray_sys_notifications.tga"
+ image_unselected="bottom_tray_sys_notifications.tga"/>
+ <unread_notifications
+ width="20"
+ height="20"
+ left="22"
+ top="23"/>
<chiclet_notification.commit_callback
function="Notification.Show"
parameter="ClickUnimplemented" />
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index a017e7398e..9cc3a00696 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -77,6 +77,7 @@
height="20"
layout="topleft"
left="10"
+ max_length="63"
name="pick_name"
right="-10"
text_color="black"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
index 6a819d0ef4..686dc931d3 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
@@ -32,7 +32,8 @@
name="picture_name"
text_color="black"
top="5"
- width="170" />
+ use_ellipses="true"
+ width="170"/>
<text
follows="right"
font="SansSerif"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index 2aa566543f..366c3ecf6c 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -12,6 +12,14 @@
name="places panel"
top="400"
width="355">
+ <panel.string
+ name="landmarks_tab_title">
+ Landmarks
+ </panel.string>
+ <panel.string
+ name="teleport_history_tab_title">
+ Teleport History
+ </panel.string>
<search_editor
follows="left|top|right"
height="16"
@@ -73,7 +81,7 @@
top_delta="0"
width="60" />
<button
- enabled="true"
+ enabled="false"
follows="bottom|right"
font="SansSerifSmallBold"
height="25"
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml
index feba6a7d02..01052f4bbe 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml
@@ -17,7 +17,7 @@
background_visible="true"
bg_opaque_color="0.5 0.5 0.5 1.0"
>
- <collapsible_ctrl
+ <accordionctrl_tab
name="people_accordion"
title="People"
collapsable="true"
@@ -35,7 +35,7 @@
label="People"
border="true"
/>
- </collapsible_ctrl>
+ </accordionctrl_tab>
</sidetray_tab>
<!-- *TODO Vadim: isn't the sidetray_tab "label" attribute redundant since we have "tab_title" ? -->
<sidetray_tab
@@ -48,7 +48,7 @@
background_visible="true"
bg_opaque_color="0.5 0.5 0.5 1.0"
>
- <collapsible_ctrl
+ <accordionctrl_tab
name="places_accordian"
title="Places"
collapsable="true"
@@ -63,7 +63,7 @@
label="Places"
border="true"
/>
- </collapsible_ctrl>
+ </accordionctrl_tab>
</sidetray_tab>
<sidetray_tab
@@ -75,7 +75,7 @@
background_visible="true"
bg_opaque_color="0.5 0.5 0.5 1.0"
>
- <collapsible_ctrl
+ <accordionctrl_tab
name="me_accordion"
title="Me"
collapsable="false"
@@ -90,7 +90,7 @@
label="Me"
border="true"
/>
- </collapsible_ctrl>
+ </accordionctrl_tab>
</sidetray_tab>
<!--
@@ -103,7 +103,7 @@
tab_title="Groups"
description="Manage Groups."
>
- <collapsible_ctrl
+ <accordionctrl_tab
name="group_accordion"
title="Group General"
expanded="true"
@@ -119,12 +119,12 @@
label="Group"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="groupland_accordion"
title="Group Land and Money"
expanded="false"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
header_visible="true"
@@ -136,12 +136,12 @@
label="Group"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="groupnotices_accordion"
title="Group Notices"
expanded="false"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
header_visible="true"
@@ -153,12 +153,12 @@
label="Group"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="grouproles_accordion"
title="Group Roles"
expanded="false"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
header_visible="true"
@@ -170,7 +170,7 @@
label="Group"
border="true"
/>
- </collapsible_ctrl>
+ </accordionctrl_tab>
</sidetray_tab>
@@ -184,7 +184,7 @@
tab_title="Previews"
description="Previews."
>
- <collapsible_ctrl
+ <accordionctrl_tab
name="floater_preview_animation"
title="Preview Animation"
collapsable="true"
@@ -202,8 +202,8 @@
label="Preview_Animation"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_preview_gesture"
title="Preview Gesture"
collapsable="true"
@@ -221,8 +221,8 @@
label="Preview_Gesture"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_preview_existing_landmark"
title="Preview Existing Landmark"
collapsable="true"
@@ -240,8 +240,8 @@
label="Preview_Existing_Landmark"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_preview_sound"
title="Preview Sound"
collapsable="true"
@@ -259,8 +259,8 @@
label="Preview_Sound"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_preview_url"
title="Preview URL"
collapsable="true"
@@ -278,8 +278,8 @@
label="Preview_URL"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_URL_entry"
title="URL Entry"
collapsable="true"
@@ -297,7 +297,7 @@
label="URL_entry"
border="true"
/>
- </collapsible_ctrl>
+ </accordionctrl_tab>
</sidetray_tab>
<sidetray_tab
@@ -310,7 +310,7 @@
tab_title="Region"
description="Region."
>
- <collapsible_ctrl
+ <accordionctrl_tab
name="panel_region_covenant"
title="Region Covenant"
collapsable="true"
@@ -328,8 +328,8 @@
label="Panel_Region_Covenant"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="panel_region_debug"
title="Region Debug"
collapsable="true"
@@ -347,8 +347,8 @@
label="Panel_Region_Debug"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="panel_region_estate"
title="Region Estate"
collapsable="true"
@@ -366,8 +366,8 @@
label="Panel_Region_Estate"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="panel_region_general"
title="Region General"
collapsable="true"
@@ -385,8 +385,8 @@
label="Panel_Region_General"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="panel_region_terrain"
title="Region Terrain"
collapsable="true"
@@ -404,8 +404,8 @@
label="Panel_Region_Terrain"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="panel_region_texture"
title="Region Texture"
collapsable="true"
@@ -423,8 +423,8 @@
label="Panel_Region_Texture"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_region_info"
title="Region Info"
collapsable="true"
@@ -442,7 +442,7 @@
label="Floater_Region_Info"
border="true"
/>
- </collapsible_ctrl>
+ </accordionctrl_tab>
</sidetray_tab>
<sidetray_tab
@@ -455,7 +455,7 @@
tab_title="Build"
description="Build"
>
- <collapsible_ctrl
+ <accordionctrl_tab
name="floater_tools"
title="Tools"
collapsable="true"
@@ -473,8 +473,8 @@
label="Tools"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_bulk_perms"
title="Bulk Perms"
collapsable="true"
@@ -492,8 +492,8 @@
label="Tools"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_build_options"
title="Build Options"
collapsable="true"
@@ -511,7 +511,7 @@
label="Tools"
border="true"
/>
- </collapsible_ctrl>
+ </accordionctrl_tab>
</sidetray_tab>
@@ -525,7 +525,7 @@
tab_title="Other Tools"
description="Other Tools"
>
- <collapsible_ctrl
+ <accordionctrl_tab
name="floater_gesture"
title="Gestures"
collapsable="true"
@@ -543,9 +543,9 @@
label="Gesture"
border="true"
/>
- </collapsible_ctrl>
+ </accordionctrl_tab>
- <collapsible_ctrl
+ <accordionctrl_tab
name="floater_buy_contents"
title="Buy Contents"
collapsable="true"
@@ -563,8 +563,8 @@
label="buy_contents"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_buy_object"
title="Buy Object"
collapsable="true"
@@ -583,7 +583,7 @@
border="true"
/>
</collapsible_ctrl>
- <collapsible_ctrl
+ <accordionctrl_tab
name="floater_inventory_view_finder"
title="Inventory View Finder"
collapsable="true"
@@ -601,8 +601,8 @@
label="view_finder"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_mute"
title="Mute"
collapsable="true"
@@ -620,8 +620,8 @@
label="mute"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_sell_land"
title="Sell Land"
collapsable="true"
@@ -639,8 +639,8 @@
label="sell_land"
border="true"
/>
- </collapsible_ctrl>
- <collapsible_ctrl
+ </accordionctrl_tab>
+ <accordionctrl_tab
name="floater_telehub"
title="Telehub"
collapsable="true"
@@ -658,7 +658,7 @@
label="telehub"
border="true"
/>
- </collapsible_ctrl>
+ </accordionctrl_tab>
</sidetray_tab>
-->
diff --git a/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml
new file mode 100644
index 0000000000..45b1e1eb9f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<combo_box font="SansSerifSmall"
+ list_position="below"
+ max_chars="20"
+ follows="right|top">
+ <combo_box.combo_button name="Combobox Button"
+ label=""
+ hover_glow_amount="0.15"
+ font="SansSerifSmall"
+ scale_image="true"
+ image_unselected="ComboButton_Off"
+ image_selected="ComboButton_Selected"
+ image_disabled="ComboButton_Disabled"
+ image_disabled_selected="ComboButton_Disabled_Selected" />
+ <combo_box.drop_down_button name="Drop Down Button"
+ label=""
+ hover_glow_amount="0.15"
+ font="SansSerifSmall"
+ scale_image="true"
+ pad_right="24"
+ image_unselected="DropDown_Off"
+ image_selected="DropDown_Selected"
+ image_disabled="DropDown_Disabled"
+ image_disabled_selected="DropDown_Disabled_Selected" />
+ <combo_box.combo_list bg_writeable_color="white" />
+ <combo_box.combo_editor name="Combo Text Entry"
+ select_on_focus="true"
+ font="SansSerifSmall" />
+</combo_box>