summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2009-07-30 23:22:41 +0000
committerSteven Bennetts <steve@lindenlab.com>2009-07-30 23:22:41 +0000
commite97f7728a90dd66014f6b3f0cd5e8d4c71f48691 (patch)
tree4be178df6b50a3395105cdd3ac0044d6467a9fa3 /indra
parentd5aa10143a0e6457b3326ba839c81b7c956a015e (diff)
merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0/indra@1170 https://svn.aws.productengine.com/secondlife/pe/stable-1/indra@1187 -> viewer-2.0.0-3
Diffstat (limited to 'indra')
-rw-r--r--indra/llui/llmenugl.cpp10
-rw-r--r--indra/llui/llmenugl.h6
-rw-r--r--indra/llui/llnotifications.cpp18
-rw-r--r--indra/llui/llnotifications.h9
-rw-r--r--indra/newview/CMakeLists.txt4
-rw-r--r--indra/newview/app_settings/settings.xml77
-rw-r--r--indra/newview/llagent.cpp48
-rw-r--r--indra/newview/llagent.h2
-rw-r--r--indra/newview/llappviewer.cpp3
-rw-r--r--indra/newview/llappviewer.h5
-rw-r--r--indra/newview/llavataractions.cpp3
-rw-r--r--indra/newview/llavatariconctrl.cpp82
-rw-r--r--indra/newview/llavatariconctrl.h14
-rw-r--r--indra/newview/llavatarlist.cpp134
-rw-r--r--indra/newview/llavatarlist.h18
-rw-r--r--indra/newview/llbottomtray.cpp543
-rw-r--r--indra/newview/llbottomtray.h51
-rw-r--r--indra/newview/llchannelmanager.cpp46
-rw-r--r--indra/newview/llchannelmanager.h7
-rw-r--r--indra/newview/llchatitemscontainerctrl.cpp88
-rw-r--r--indra/newview/llchatitemscontainerctrl.h2
-rw-r--r--indra/newview/llchatmsgbox.cpp21
-rw-r--r--indra/newview/llchatmsgbox.h11
-rw-r--r--indra/newview/llchiclet.cpp23
-rw-r--r--indra/newview/llchiclet.h5
-rw-r--r--indra/newview/llfavoritesbar.cpp179
-rw-r--r--indra/newview/llfloaterbuy.cpp2
-rw-r--r--indra/newview/llgesturemgr.cpp4
-rw-r--r--indra/newview/llgrouplist.cpp6
-rw-r--r--indra/newview/llgrouplist.h1
-rw-r--r--indra/newview/lllandmarkactions.cpp141
-rw-r--r--indra/newview/lllandmarkactions.h68
-rw-r--r--indra/newview/lllocationhistory.cpp6
-rw-r--r--indra/newview/lllocationhistory.h5
-rw-r--r--indra/newview/lllocationinputctrl.cpp48
-rw-r--r--indra/newview/lllocationinputctrl.h3
-rw-r--r--indra/newview/llmenucommands.cpp10
-rw-r--r--indra/newview/llnavigationbar.cpp15
-rw-r--r--indra/newview/llnavigationbar.h2
-rw-r--r--indra/newview/llnearbychat.cpp173
-rw-r--r--indra/newview/llnearbychat.h6
-rw-r--r--indra/newview/llnearbychatbar.cpp549
-rw-r--r--indra/newview/llnearbychatbar.h104
-rw-r--r--indra/newview/llnearbychathandler.cpp10
-rw-r--r--indra/newview/llnotificationalerthandler.cpp2
-rw-r--r--indra/newview/llnotificationgrouphandler.cpp4
-rw-r--r--indra/newview/llnotificationhandler.h2
-rw-r--r--indra/newview/lloverlaybar.h1
-rw-r--r--indra/newview/llpanelavatar.cpp15
-rw-r--r--indra/newview/llpanellandmarks.cpp3
-rw-r--r--indra/newview/llpanelpeople.cpp24
-rw-r--r--indra/newview/llpanelpeople.h2
-rw-r--r--indra/newview/llpanelpicks.cpp9
-rw-r--r--indra/newview/llpanelpicks.h2
-rw-r--r--indra/newview/llpanelplaceinfo.cpp55
-rw-r--r--indra/newview/llpanelplaceinfo.h9
-rw-r--r--indra/newview/llpanelplaces.cpp254
-rw-r--r--indra/newview/llpanelplaces.h55
-rw-r--r--indra/newview/llpanelplacestab.cpp8
-rw-r--r--indra/newview/llpanelplacestab.h2
-rw-r--r--indra/newview/llpanelteleporthistory.cpp3
-rw-r--r--indra/newview/llscreenchannel.cpp92
-rw-r--r--indra/newview/llscreenchannel.h17
-rw-r--r--indra/newview/llsidetray.cpp151
-rw-r--r--indra/newview/llsidetray.h9
-rw-r--r--indra/newview/llstartup.cpp4
-rw-r--r--indra/newview/lltoast.cpp3
-rw-r--r--indra/newview/lltoast.h1
-rw-r--r--indra/newview/lltoastgroupnotifypanel.cpp79
-rw-r--r--indra/newview/lltoastgroupnotifypanel.h1
-rw-r--r--indra/newview/lltooldraganddrop.cpp5
-rw-r--r--indra/newview/llurldispatcher.cpp47
-rw-r--r--indra/newview/llviewergesture.cpp4
-rw-r--r--indra/newview/llviewerkeyboard.cpp10
-rw-r--r--indra/newview/llviewermenu.cpp23
-rw-r--r--indra/newview/llviewermessage.cpp7
-rw-r--r--indra/newview/llviewerparcelmgr.cpp8
-rw-r--r--indra/newview/llviewertexteditor.cpp19
-rw-r--r--indra/newview/llviewertexture.cpp5
-rw-r--r--indra/newview/llviewerwindow.cpp13
-rw-r--r--indra/newview/llvoiceclient.cpp5
-rw-r--r--indra/newview/skins/default/colors.xml9
-rw-r--r--indra/newview/skins/default/xui/en/floater_nearby_chat.xml18
-rw-r--r--indra/newview/skins/default/xui/en/menu_navbar.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml60
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml5
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml118
-rw-r--r--indra/newview/skins/default/xui/en/panel_chat_item.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notify.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml51
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_list_item.xml21
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray.xml96
-rw-r--r--indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml90
-rw-r--r--indra/newview/skins/default/xui/en/panel_toast.xml6
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/en/widgets/location_input.xml5
-rw-r--r--indra/newview/skins/default/xui/en/widgets/slider_bar.xml1
97 files changed, 2625 insertions, 1388 deletions
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index fdb4bdd5c1..ad2d8afe45 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -793,6 +793,16 @@ BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask )
return FALSE;
}
+BOOL LLMenuItemCallGL::handleRightMouseUp(S32 x, S32 y, MASK mask)
+{
+ if (pointInView(x, y))
+ {
+ mRightClickSignal(this, getValue());
+ }
+
+ return TRUE;
+}
+
///============================================================================
/// Class LLMenuItemCheckGL
///============================================================================
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 262f75f1e1..f786c891d7 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -283,6 +283,7 @@ public:
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
virtual BOOL handleKeyHere(KEY key, MASK mask);
+ virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
//virtual void draw();
@@ -295,6 +296,11 @@ public:
{
return mEnableSignal.connect(cb);
}
+
+ boost::signals2::connection setRightClickedCallback( const commit_signal_t::slot_type& cb )
+ {
+ return mRightClickSignal.connect(cb);
+ }
private:
enable_signal_t mEnableSignal;
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 2b6ae1f67e..9845b7e2ce 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -710,6 +710,15 @@ LLBoundListener LLNotificationChannelBase::connectChangedImpl(const LLEventListe
return mChanged.connect(slot);
}
+LLBoundListener LLNotificationChannelBase::connectAtFrontChangedImpl(const LLEventListener& slot)
+{
+ for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
+ {
+ slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id()));
+ }
+ return mChanged.connect(slot, boost::signals2::at_front);
+}
+
LLBoundListener LLNotificationChannelBase::connectPassedFilterImpl(const LLEventListener& slot)
{
// these two filters only fire for notifications added after the current one, because
@@ -1076,10 +1085,13 @@ void LLNotifications::createDefaultChannels()
// connect action methods to these channels
LLNotifications::instance().getChannel("Expiration")->
connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
+ // uniqueHandler slot should be added as first slot of the signal due to
+ // usage LLStopWhenHandled combiner in LLStandardSignal
LLNotifications::instance().getChannel("Unique")->
- connectChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
- LLNotifications::instance().getChannel("Unique")->
- connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
+ connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
+// failedUniquenessTest slot isn't necessary
+// LLNotifications::instance().getChannel("Unique")->
+// connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
LLNotifications::instance().getChannel("Ignore")->
connectFailedFilter(&handleIgnoredNotification);
}
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 63eae7278f..4da121c9c5 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -693,6 +693,14 @@ public:
this,
_1));
}
+ template <typename LISTENER>
+ LLBoundListener connectAtFrontChanged(const LISTENER& slot)
+ {
+ return LLEventDetail::visit_and_connect(slot,
+ boost::bind(&LLNotificationChannelBase::connectAtFrontChangedImpl,
+ this,
+ _1));
+ }
template <typename LISTENER>
LLBoundListener connectPassedFilter(const LISTENER& slot)
{
@@ -718,6 +726,7 @@ public:
protected:
LLBoundListener connectChangedImpl(const LLEventListener& slot);
+ LLBoundListener connectAtFrontChangedImpl(const LLEventListener& slot);
LLBoundListener connectPassedFilterImpl(const LLEventListener& slot);
LLBoundListener connectFailedFilterImpl(const LLEventListener& slot);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 2e29a56e79..9a0c9d9c7b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -243,6 +243,7 @@ set(viewer_SOURCE_FILES
llinventoryfilter.cpp
llinventorymodel.cpp
lljoystickbutton.cpp
+ lllandmarkactions.cpp
lllandmarklist.cpp
lllistbrowser.cpp
lllistview.cpp
@@ -269,6 +270,7 @@ set(viewer_SOURCE_FILES
llnamelistctrl.cpp
llnavigationbar.cpp
llnearbychat.cpp
+ llnearbychatbar.cpp
llnearbychathandler.cpp
llnetmap.cpp
llnotificationalerthandler.cpp
@@ -680,6 +682,7 @@ set(viewer_HEADER_FILES
llinventoryfilter.h
llinventorymodel.h
lljoystickbutton.h
+ lllandmarkactions.h
lllandmarklist.h
lllightconstants.h
lllistbrowser.h
@@ -707,6 +710,7 @@ set(viewer_HEADER_FILES
llnamelistctrl.h
llnavigationbar.h
llnearbychat.h
+ llnearbychatbar.h
llnearbychathandler.h
llnetmap.h
llnotificationhandler.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ab9b018150..edcd288b7d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4749,6 +4749,83 @@
<key>Value</key>
<integer>350</integer>
</map>
+ <key>NotificationToastTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>5</integer>
+ </map>
+ <key>StartUpToastTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>10</integer>
+ </map>
+ <key>ToastMargin</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>5</integer>
+ </map>
+ <key>ChannelBottomPanelMargin</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>35</integer>
+ </map>
+ <key>NotificationChannelRightMargin</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>10</integer>
+ </map>
+ <key>NavBarMargin</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>60</integer>
+ </map>
+ <key>OverflowToastHeight</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>72</integer>
+ </map>
<key>NotifyMoneyChange</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index afad88770e..f527719a7a 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -98,6 +98,7 @@
#include "pipeline.h"
#include "lltrans.h"
#include "llbottomtray.h"
+#include "llnearbychatbar.h"
#include "stringize.h"
#include "llcapabilitylistener.h"
@@ -2721,7 +2722,7 @@ void LLAgent::startTyping()
{
sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
}
- LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
+ LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
}
//-----------------------------------------------------------------------------
@@ -2733,7 +2734,7 @@ void LLAgent::stopTyping()
{
clearRenderState(AGENT_STATE_TYPING);
sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
- LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
+ LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
}
}
@@ -6575,49 +6576,6 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename)
}//end for (all message sets in xml file)
}
-// static
-void LLAgent::createLandmarkHere()
-{
- std::string landmark_name, landmark_desc;
-
- gAgent.buildLocationString(landmark_name, LLAgent::LOCATION_FORMAT_LANDMARK);
- gAgent.buildLocationString(landmark_desc, LLAgent::LOCATION_FORMAT_FULL);
- LLUUID folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
-
- createLandmarkHere(landmark_name, landmark_desc, folder_id);
-}
-
-// static
-void LLAgent::createLandmarkHere(const std::string& name, const std::string& desc, const LLUUID& folder_id)
-{
- LLViewerRegion* agent_region = gAgent.getRegion();
- if(!agent_region)
- {
- llwarns << "No agent region" << llendl;
- return;
- }
- LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (!agent_parcel)
- {
- llwarns << "No agent parcel" << llendl;
- return;
- }
- if (!agent_parcel->getAllowLandmark()
- && !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
- {
- LLNotifications::instance().add("CannotCreateLandmarkNotOwner");
- return;
- }
-
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- folder_id, LLTransactionID::tnull,
- name, desc,
- LLAssetType::AT_LANDMARK,
- LLInventoryType::IT_LANDMARK,
- NOT_WEARABLE, PERM_ALL,
- NULL);
-}
-
void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility )
{
gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo);
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 22b3790c6b..e25bb0a578 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -263,8 +263,6 @@ public:
std::string getSLURL() const;
BOOL inPrelude();
BOOL buildLocationString(std::string& str, ELocationFormat fmt = LOCATION_FORMAT_LANDMARK); // Utility to build a location string
- static void createLandmarkHere();
- static void createLandmarkHere(const std::string& name, const std::string& desc, const LLUUID& folder_id);
private:
LLViewerRegion *mRegionp;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 2299a439e6..245e358d80 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -4034,5 +4034,8 @@ void LLAppViewer::handleLoginComplete()
{
gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
}
+
+ mOnLoginCompleted();
+
writeDebugInfo();
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index bbc2b646c4..646b677264 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -161,6 +161,11 @@ public:
LLAllocator & getAllocator() { return mAlloc; }
+ // On LoginCompleted callback
+ typedef boost::signals2::signal<void (void)> login_completed_signal_t;
+ login_completed_signal_t mOnLoginCompleted;
+ boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); }
+
void purgeCache(); // Clear the local cache.
protected:
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 2cf7298569..281d73b18b 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -73,6 +73,9 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin
{
LLNotifications::instance().add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
}
+
+ // add friend to recent people list
+ LLRecentPeople::instance().add(id);
}
// static
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index a3b8f6726d..f6eb7f6494 100644
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -42,12 +42,15 @@
#include "lluictrlfactory.h"
#include "llcachename.h"
+#include "llagentdata.h"
#define MENU_ITEM_VIEW_PROFILE 0
#define MENU_ITEM_SEND_IM 1
static LLDefaultChildRegistry::Register<LLAvatarIconCtrl> r("avatar_icon");
+LLAvatarIconCtrl::avatar_image_map_t LLAvatarIconCtrl::sImagesCache;
+
LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
: LLIconCtrl(p),
mDrawTooltip(p.draw_tooltip)
@@ -137,7 +140,17 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
LLAvatarPropertiesProcessor::getInstance()->addObserver(value.asUUID(), this);
LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(value.asUUID(),APT_PROPERTIES);
mAvatarId = value.asUUID();
+
+ // Check if cache already contains image_id for that avatar
+ avatar_image_map_t::iterator it;
+
+ it = sImagesCache.find(mAvatarId);
+ if (it != sImagesCache.end())
+ {
+ updateFromCache(it->second);
+ }
}
+
}
else
{
@@ -147,6 +160,37 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
gCacheName->get(mAvatarId, FALSE, boost::bind(&LLAvatarIconCtrl::nameUpdatedCallback, this, _1, _2, _3, _4));
}
+void LLAvatarIconCtrl::updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data)
+{
+ // Update the avatar
+ if (data.image_id.notNull())
+ {
+ LLIconCtrl::setValue(data.image_id);
+ }
+ else
+ {
+ LLIconCtrl::setValue("default_profile_picture.j2c");
+ }
+
+ // Update color of status symbol and tool tip
+ if (data.flags & AVATAR_ONLINE)
+ {
+ mStatusSymbol->setColor(LLColor4::green);
+ if (mDrawTooltip)
+ {
+ setToolTip((LLStringExplicit)"Online");
+ }
+ }
+ else
+ {
+ mStatusSymbol->setColor(LLColor4::grey);
+ if (mDrawTooltip)
+ {
+ setToolTip((LLStringExplicit)"Offline");
+ }
+ }
+}
+
//virtual
void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
{
@@ -160,33 +204,10 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
return;
}
- // Update the avatar
- if (avatar_data->image_id.notNull())
- {
- LLIconCtrl::setValue(avatar_data->image_id);
- }
- else
- {
- LLIconCtrl::setValue("default_profile_picture.j2c");
- }
+ LLAvatarIconCtrl::LLImagesCacheItem data(avatar_data->image_id, avatar_data->flags);
- // Update color of status symbol and tool tip
- if (avatar_data->flags & AVATAR_ONLINE)
- {
- mStatusSymbol->setColor(LLColor4::green);
- if (mDrawTooltip)
- {
- setToolTip((LLStringExplicit)"Online");
- }
- }
- else
- {
- mStatusSymbol->setColor(LLColor4::grey);
- if (mDrawTooltip)
- {
- setToolTip((LLStringExplicit)"Offline");
- }
- }
+ updateFromCache(data);
+ sImagesCache.insert(std::pair<LLUUID, LLAvatarIconCtrl::LLImagesCacheItem>(mAvatarId, data));
}
}
}
@@ -198,10 +219,17 @@ BOOL LLAvatarIconCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
if(menu)
{
bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarId) != NULL;
-
+
menu->setItemEnabled("Add Friend", !is_friend);
menu->setItemEnabled("Remove Friend", is_friend);
+ if(gAgentID == mAvatarId)
+ {
+ menu->setItemEnabled("Add Friend", false);
+ menu->setItemEnabled("Send IM", false);
+ menu->setItemEnabled("Remove Friend", false);
+ }
+
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index e34f2ff474..10ce827d6d 100644
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -85,6 +85,20 @@ protected:
std::string mLastName;
LLHandle<LLView> mPopupMenuHandle;
bool mDrawTooltip;
+
+ struct LLImagesCacheItem
+ {
+ LLUUID image_id;
+ U32 flags;
+
+ LLImagesCacheItem(LLUUID image_id_, U32 flags_) : image_id(image_id_), flags(flags_) {}
+ };
+
+ typedef std::map<LLUUID, LLAvatarIconCtrl::LLImagesCacheItem> avatar_image_map_t;
+
+ static avatar_image_map_t sImagesCache;
+
+ void updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data);
};
#endif // LL_LLAVATARICONCTRL_H
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 7b5ce765d3..a85f8710c7 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -37,24 +37,40 @@
// newview
#include "llcallingcard.h" // for LLAvatarTracker
#include "llcachename.h"
+#include "lloutputmonitorctrl.h"
+#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
LLAvatarList::Params::Params()
+:
+ volume_column_width("volume_column_width", 0)
+ , online_go_first("online_go_first", true)
{
draw_heading = true;
draw_stripes = false;
multi_select = false;
column_padding = 0;
- search_column = LIST_NAME;
- sort_column = LIST_NAME;
+ search_column = COL_NAME;
+ sort_column = COL_NAME;
}
LLAvatarList::LLAvatarList(const Params& p)
: LLScrollListCtrl(p)
+ , mHaveVolumeColumn(p.volume_column_width > 0)
+ , mOnlineGoFirst(p.online_go_first)
{
setCommitOnSelectionChange(TRUE); // there's no such param in LLScrollListCtrl::Params
+ // "volume" column
+ {
+ LLScrollListColumn::Params col_params;
+ col_params.name = "volume";
+ col_params.header.label = "Volume"; // *TODO: localize or remove the header
+ col_params.width.pixel_width = p.volume_column_width;
+ addColumn(col_params);
+ }
+
// "name" column
{
LLScrollListColumn::Params col_params;
@@ -63,18 +79,42 @@ LLAvatarList::LLAvatarList(const Params& p)
col_params.width.dynamic_width = true;
addColumn(col_params);
}
+
+ // "online status" column
+ {
+ LLScrollListColumn::Params col_params;
+ col_params.name = "online";
+ col_params.header.label = "Online"; // *TODO: localize or remove the header
+ col_params.width.pixel_width = 0; // invisible column
+ addColumn(col_params);
+ }
+
// invisible "id" column
{
LLScrollListColumn::Params col_params;
col_params.name = "id";
+ col_params.header.label = "ID"; // *TODO: localize or remove the header
col_params.width.pixel_width = 0;
addColumn(col_params);
}
- // The corresponding parameters don't work because we create columns dynamically.
- sortByColumnIndex(LIST_NAME, TRUE);
- setSearchColumn(LIST_NAME);
+ // Primary sort = online status, secondary sort = name
+ // The corresponding parameters don't work because we create columns dynamically.
+ sortByColumnIndex(COL_NAME, TRUE);
+ if (mOnlineGoFirst)
+ sortByColumnIndex(COL_ONLINE, FALSE);
+ setSearchColumn(COL_NAME);
+}
+
+// virtual
+void LLAvatarList::draw()
+{
+ LLScrollListCtrl::draw();
+ if (mHaveVolumeColumn)
+ {
+ updateVolume();
+ }
}
std::vector<LLUUID> LLAvatarList::getSelectedIDs()
@@ -97,17 +137,30 @@ void LLAvatarList::addItem(const LLUUID& id, const std::string& name, BOOL is_bo
LLSD element;
element["id"] = id;
- LLSD& friend_column = element["columns"][LIST_NAME];
+ // Update volume column (if we have one)
+ {
+ std::string icon = mHaveVolumeColumn ? getVolumeIcon(id) : "";
+ LLSD& volume_column = element["columns"][COL_VOLUME];
+ volume_column["column"] = "volume";
+ volume_column["type"] = "icon";
+ volume_column["value"] = icon;
+ }
+
+ LLSD& friend_column = element["columns"][COL_NAME];
friend_column["column"] = "name";
friend_column["value"] = name;
+ LLSD& online_column = element["columns"][COL_ONLINE];
+ online_column["column"] = "online";
+ online_column["value"] = is_bold ? "1" : "0";
+
LLScrollListItem* new_itemp = addElement(element, pos);
// Indicate buddy online status.
// (looks like parsing font parameters from LLSD is broken)
if (is_bold)
{
- LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(new_itemp->getColumn(LIST_NAME));
+ LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(new_itemp->getColumn(COL_NAME));
if (name_textp)
name_textp->setFontStyle(LLFontGL::BOLD);
else
@@ -169,3 +222,70 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
return have_names;
}
+
+// static
+std::string LLAvatarList::getVolumeIcon(const LLUUID& id)
+{
+ //
+ // Determine icon appropriate for the current avatar volume.
+ //
+ // *TODO: remove this in favor of LLOutputMonitorCtrl
+ // when ListView widget is implemented
+ // which is capable of containing arbitrary widgets.
+ //
+ static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams<LLOutputMonitorCtrl>());
+ bool muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id);
+ F32 power = gVoiceClient->getCurrentPower(id);
+ std::string icon;
+
+ if (muted)
+ {
+ icon = default_monitor_params.image_mute.name;
+ }
+ else if (power == 0.f)
+ {
+ icon = default_monitor_params.image_off.name;
+ }
+ else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
+ {
+ S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
+ switch(icon_image_idx)
+ {
+ default:
+ case 0:
+ icon = default_monitor_params.image_on.name;
+ break;
+ case 1:
+ icon = default_monitor_params.image_level_1.name;
+ break;
+ case 2:
+ icon = default_monitor_params.image_level_2.name;
+ break;
+ }
+ }
+ else
+ {
+ // overdriven
+ icon = default_monitor_params.image_level_3.name;
+ }
+
+ return icon;
+}
+
+// Update volume column for all list rows.
+void LLAvatarList::updateVolume()
+{
+ item_list& items = getItemList();
+
+ for (item_list::iterator item_it = items.begin();
+ item_it != items.end();
+ ++item_it)
+ {
+ LLScrollListItem* itemp = (*item_it);
+ LLUUID speaker_id = itemp->getUUID();
+
+ LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME);
+ if (icon_cell)
+ icon_cell->setValue(getVolumeIcon(speaker_id));
+ }
+}
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 9dba719fee..8b419dbb57 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -42,23 +42,37 @@ class LLAvatarList : public LLScrollListCtrl
public:
struct Params : public LLInitParam::Block<Params, LLScrollListCtrl::Params>
{
+ Optional<S32> volume_column_width;
+ Optional<bool> online_go_first;
Params();
};
- enum AVATAR_LIST_COLUMN_ORDER
+ enum EColumnOrder
{
- LIST_NAME,
+ COL_VOLUME,
+ COL_NAME,
+ COL_ONLINE,
+ COL_ID,
};
LLAvatarList(const Params&);
virtual ~LLAvatarList() {}
+ /*virtual*/ void draw();
+
BOOL update(const std::vector<LLUUID>& all_buddies,
const std::string& name_filter = LLStringUtil::null);
protected:
std::vector<LLUUID> getSelectedIDs();
void addItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+
+private:
+ static std::string getVolumeIcon(const LLUUID& id); /// determine volume icon from current avatar volume
+ void updateVolume(); // update volume for all avatars
+
+ bool mHaveVolumeColumn;
+ bool mOnlineGoFirst;
};
#endif // LL_LLAVATARLIST_H
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 963946e888..1781e6b3f1 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -37,174 +37,30 @@
#include "llchiclet.h"
#include "llfloaterreg.h"
#include "llflyoutbutton.h"
-#include "llimpanel.h"
-#include "llkeyboard.h"
-#include "lllineeditor.h"
-#include "llgesturemgr.h"
-#include "llanimationstates.h"
-#include "llmultigesture.h"
-#include "llviewerstats.h"
-#include "llcommandhandler.h"
+#include "llnearbychatbar.h"
//FIXME: temporary, for stand up proto
#include "llselectmgr.h"
#include "llvoavatarself.h"
-S32 LLBottomTray::sLastSpecialChatChannel = 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()
-{
- 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)
+ : mChicletPanel(NULL)
, mIMWell(NULL)
, mSysWell(NULL)
, mTalkBtn(NULL)
- , mGestureCombo(NULL)
, mStandUpBtn(NULL) ////FIXME: temporary, for stand up proto
+ , mNearbyChatBar(NULL)
{
+ mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL);
+
LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml");
mChicletPanel = getChild<LLChicletPanel>("chiclet_list",TRUE,FALSE);
mIMWell = getChild<LLNotificationChiclet>("im_well",TRUE,FALSE);
mSysWell = getChild<LLNotificationChiclet>("sys_well",TRUE,FALSE);
- mChatBox = getChild<LLLineEditor>("chat_box",TRUE,FALSE);
mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));
- if (mChatBox)
- {
- mChatBox->setCommitCallback(boost::bind(&LLBottomTray::onChatBoxCommit, this));
- mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
- mChatBox->setFocusLostCallback(&onChatBoxFocusLost, this);
-
- mChatBox->setIgnoreArrowKeys(TRUE);
- mChatBox->setCommitOnFocusLost( FALSE );
- mChatBox->setRevertOnEsc( FALSE );
- mChatBox->setIgnoreTab(TRUE);
- mChatBox->setPassDelete(TRUE);
- mChatBox->setReplaceNewlinesWithSpaces(FALSE);
- mChatBox->setMaxTextLength(1023);
- mChatBox->setEnableLineHistory(TRUE);
-
- }
-
- mGestureCombo = getChild<LLGestureComboBox>( "Gesture", TRUE, FALSE);
-
////FIXME: temporary, for stand up proto
mStandUpBtn = getChild<LLButton> ("stand", TRUE, FALSE);
if (mStandUpBtn)
@@ -246,156 +102,15 @@ void LLBottomTray::onChicletClick(LLUICtrl* ctrl)
}
}
-void LLBottomTray::onChatBoxCommit()
-{
- if (mChatBox && mChatBox->getText().length() > 0)
- {
- sendChat(CHAT_TYPE_NORMAL);
- }
-
- gAgent.stopTyping();
-}
-
-void LLBottomTray::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
-{
- sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
-}
-
-void LLBottomTray::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);
-}
-
-// static
-void LLBottomTray::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
-{
- LLBottomTray* self = (LLBottomTray *)userdata;
-
- LLWString raw_text;
- if (self->getChatBox()) raw_text = self->getChatBox()->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->getChatBox())
- {
- std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
- self->getChatBox()->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
- S32 outlength = self->getChatBox()->getLength(); // in characters
-
- // Select to end of line, starting from the character
- // after the last one the user typed.
- self->getChatBox()->setSelection(length, outlength);
- }
- }
-
- //llinfos << "GESTUREDEBUG " << trigger
- // << " len " << length
- // << " outlen " << out_str.getLength()
- // << llendl;
- }
-}
-
-// static
-void LLBottomTray::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
+void* LLBottomTray::createNearbyChatBar(void* userdata)
{
- // stop typing animation
- gAgent.stopTyping();
-}
+ LLBottomTray *bt = LLBottomTray::getInstance();
+ if (!bt)
+ return NULL;
-BOOL LLBottomTray::inputEditorHasFocus()
-{
- return mChatBox && mChatBox->hasFocus();
-}
+ bt->mNearbyChatBar = new LLNearbyChatBar();
-std::string LLBottomTray::getCurrentChat()
-{
- return mChatBox ? mChatBox->getText() : LLStringUtil::null;
+ return bt->mNearbyChatBar;
}
//virtual
@@ -440,14 +155,9 @@ void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& nam
}
else
{
- LLIMChiclet* chicklet = getChicletPanel()->createChiclet<LLIMChiclet>(session_id);
- chicklet->setIMSessionName(name);
- chicklet->setOtherParticipantId(other_participant_id);
-
- if(getChicletPanel()->getChicletCount())
- {
- setChicletPanelVisible(true);
- }
+ LLIMChiclet* chiclet = getChicletPanel()->createChiclet<LLIMChiclet>(session_id);
+ chiclet->setIMSessionName(name);
+ chiclet->setOtherParticipantId(other_participant_id);
}
}
}
@@ -458,27 +168,6 @@ void LLBottomTray::sessionRemoved(const LLUUID& session_id)
if(getChicletPanel())
{
getChicletPanel()->removeChiclet(session_id);
-
- if(0 == getChicletPanel()->getChicletCount())
- {
- setChicletPanelVisible(false);
- }
- }
-}
-
-void LLBottomTray::setChicletPanelVisible(bool visible)
-{
- // 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)
- {
- // 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);
}
}
@@ -491,22 +180,6 @@ void LLBottomTray::onFocusLost()
}
}
-// virtual
-BOOL LLBottomTray::handleKeyHere( KEY key, MASK mask )
-{
- BOOL handled = FALSE;
-
- // ALT-RETURN is reserved for windowed/fullscreen toggle
- if( KEY_RETURN == key && mask == MASK_CONTROL)
- {
- // shout
- sendChat(CHAT_TYPE_SHOUT);
- handled = TRUE;
- }
-
- return handled;
-}
-
//virtual
// setVisible used instead of onVisibilityChange, since LLAgent calls it on entering/leaving mouselook mode.
// If bottom tray is already visible in mouselook mode, then onVisibilityChange will not be called from setVisible(true),
@@ -514,192 +187,22 @@ void LLBottomTray::setVisible(BOOL visible)
{
LLPanel::setVisible(visible);
-
- BOOL visibility = gAgent.cameraMouselook() ? false : true;
+ LLView* stack = getChild<LLView>("toolbar_stack",TRUE,FALSE);
- LLViewBorder* separator = getChild<LLViewBorder>("well_separator",TRUE,FALSE);
-
- if (separator && separator->getVisible() == visibility)
- return;
-
- if (separator)
- separator->setVisible(visibility);
-
- LLPanel* p = getChild<LLPanel>("chiclet_list_panel",TRUE,FALSE);
- if (p)
- p->setVisible(visibility);
-
- p = getChild<LLPanel>("im_well_panel",TRUE,FALSE);
- if (p)
- p->setVisible(visibility);
-
- p = getChild<LLPanel>("sys_well_panel",TRUE,FALSE);
- if (p)
- p->setVisible(visibility);
-
-}
-
-// static
-void LLBottomTray::startChat(const char* line)
-{
- LLBottomTray *bt = LLBottomTray::getInstance();
-
- if(bt && bt->getChatBox())
+ if (stack)
{
- bt->setVisible(TRUE);
- bt->getChatBox()->setFocus(TRUE);
+ BOOL visibility = gAgent.cameraMouselook() ? false : true;
- if (line)
+ for ( child_list_const_iter_t child_it = stack->getChildList()->begin(); child_it != stack->getChildList()->end(); child_it++)
{
- 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)
- {
- LLWString text = mChatBox->getConvertedText();
- if (!text.empty())
- {
- // store sent line in history, duplicates will get filtered
- mChatBox->updateHistory();
- // Check if this is destined for another channel
- S32 channel = 0;
- stripChannelNumber(text, &channel);
+ LLView* viewp = *child_it;
- 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())
+ if ("chat_bar" == viewp->getName())
+ continue;
+ else
{
- // Chat with animation
- sendChatFromViewer(utf8_revised_text, type, TRUE);
+ viewp->setVisible(visibility);
}
}
-
- mChatBox->setText(LLStringExplicit(""));
}
-
- gAgent.stopTyping();
}
-
-// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
-// Otherwise returns input and channel 0.
-LLWString LLBottomTray::stripChannelNumber(const LLWString &mesg, S32* channel)
-{
- if (mesg[0] == '/'
- && mesg[1] == '/')
- {
- // This is a "repeat channel send"
- *channel = sLastSpecialChatChannel;
- 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++;
- }
-
- sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
- *channel = sLastSpecialChatChannel;
- return mesg.substr(pos, mesg.length() - pos);
- }
- else
- {
- // This is normal chat.
- *channel = 0;
- 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 08f5cb91d8..e5848f72dc 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -35,35 +35,12 @@
#include "llpanel.h"
#include "llimview.h"
-#include "llchat.h"
-#include "llgesturemgr.h"
-#include "llcombobox.h"
class LLChicletPanel;
class LLLineEditor;
class LLNotificationChiclet;
class LLTalkButton;
-
-class LLGestureComboBox
- : public LLComboBox
- , public LLGestureManagerObserver
-{
-protected:
- LLGestureComboBox(const LLComboBox::Params&);
- friend class LLUICtrlFactory;
-public:
- ~LLGestureComboBox();
-
- void refreshGestures();
- void onCommitGesture(LLUICtrl* ctrl);
- virtual void draw();
-
- // LLGestureManagerObserver trigger
- virtual void changed() { refreshGestures(); }
-
-protected:
- LLFrameTimer mGestureLabelTimer;
-};
+class LLNearbyChatBar;
class LLBottomTray
: public LLUISingleton<LLBottomTray>
@@ -74,19 +51,10 @@ class LLBottomTray
public:
~LLBottomTray();
- LLLineEditor* getChatBox() {return mChatBox;}
LLChicletPanel* getChicletPanel() {return mChicletPanel;}
LLNotificationChiclet* getIMWell() {return mIMWell;}
LLNotificationChiclet* getSysWell() {return mSysWell;}
-
- void onChatBoxCommit();
- 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);
-
- BOOL inputEditorHasFocus();
- std::string getCurrentChat();
+ LLNearbyChatBar* getNearbyChatBar() {return mNearbyChatBar;}
/*virtual*/void draw();
void refreshStandUp();
@@ -100,33 +68,22 @@ public:
virtual void sessionRemoved(const LLUUID& session_id);
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 );
- 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?
- static S32 sLastSpecialChatChannel;
+ static void* createNearbyChatBar(void* userdata);
- LLLineEditor* mChatBox;
LLChicletPanel* mChicletPanel;
LLNotificationChiclet* mIMWell;
LLNotificationChiclet* mSysWell;
LLTalkButton* mTalkBtn;
- LLGestureComboBox* mGestureCombo;
LLButton* mStandUpBtn;
+ LLNearbyChatBar* mNearbyChatBar;
};
#endif // LL_LLBOTTOMPANEL_H
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 723bf2a248..0eb0801a2c 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -34,6 +34,9 @@
#include "llchannelmanager.h"
+#include "llappviewer.h"
+#include "llviewercontrol.h"
+
#include <algorithm>
using namespace LLNotificationsUI;
@@ -41,6 +44,7 @@ using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
LLChannelManager::LLChannelManager()
{
+ LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLChannelManager::onLoginCompleted, this));
}
//--------------------------------------------------------------------------
@@ -50,6 +54,45 @@ LLChannelManager::~LLChannelManager()
}
//--------------------------------------------------------------------------
+void LLChannelManager::onLoginCompleted()
+{
+ S32 hidden_notifications = 0;
+
+ for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it)
+ {
+ //(*it).channel->showToasts();
+ hidden_notifications +=(*it).channel->getNumberOfHiddenToasts();
+ }
+
+ if(!hidden_notifications)
+ {
+ LLScreenChannel::setStartUpToastShown();
+ return;
+ }
+
+ LLChannelManager::Params p;
+ p.id = LLUUID(STARTUP_CHANNEL_ID);
+ p.channel_right_bound = getRootView()->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ p.channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+ mStartUpChannel = NULL;
+ mStartUpChannel = createChannel(p);
+
+ if(!mStartUpChannel)
+ return;
+
+ static_cast<LLUICtrl*>(mStartUpChannel)->setCommitCallback(boost::bind(&LLChannelManager::enableShowToasts, this));
+ mStartUpChannel->setNumberOfHiddenToasts(hidden_notifications);
+ mStartUpChannel->createOverflowToast(gSavedSettings.getS32("ChannelBottomPanelMargin"), gSavedSettings.getS32("StartUpToastTime"));
+}
+
+//--------------------------------------------------------------------------
+void LLChannelManager::enableShowToasts()
+{
+ LLScreenChannel::setStartUpToastShown();
+ delete mStartUpChannel;
+}
+
+//--------------------------------------------------------------------------
LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
{
LLScreenChannel* new_channel = NULL;
@@ -67,7 +110,8 @@ LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
return new_channel;
new_channel = new LLScreenChannel();
- new_channel->init(p.channel_right_bound - p.channel_width, getRootView());
+ getRootView()->addChild(new_channel);
+ new_channel->init(p.channel_right_bound - p.channel_width, p.channel_right_bound);
new_channel->setToastAlignment(p.align);
ChannelElem new_elem;
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index 564535ff24..3914d20ebc 100644
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
@@ -45,6 +45,8 @@
namespace LLNotificationsUI
{
+#define STARTUP_CHANNEL_ID "AEED3193-8709-4693-8558-7452CCA97AE5"
+
/**
* Manager for screen channels.
* Responsible for instantiating and retrieving screen channels.
@@ -98,6 +100,10 @@ public:
LLChannelManager();
virtual ~LLChannelManager();
+ // On LoginCompleted - show StartUp toast
+ void onLoginCompleted();
+ void enableShowToasts();
+
//TODO: make protected? in order to be shure that channels are created only by notification handlers
LLScreenChannel* createChannel(LLChannelManager::Params& p);
@@ -108,6 +114,7 @@ public:
private:
+ LLScreenChannel* mStartUpChannel;
std::vector<ChannelElem> mChannelList;
};
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index bb31b7f2e8..2b455485ca 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -41,6 +41,7 @@
#include "lltrans.h"
#include "llviewercontrol.h"
+#include "llagentdata.h"
static const S32 BORDER_MARGIN = 2;
static const S32 PARENT_BORDER_MARGIN = 0;
@@ -51,6 +52,9 @@ static const F32 MIN_AUTO_SCROLL_RATE = 120.f;
static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
+static const S32 msg_left_offset = 30;
+static const S32 msg_right_offset = 10;
+
#define MAX_CHAT_HISTORY 100
@@ -89,8 +93,8 @@ void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
LLRect msg_text_rect = msg_text->getRect();
- msg_text_rect.setLeftTopAndSize( 10, height - caption_rect.getHeight() , width - 20, height - caption_rect.getHeight());
- msg_text->reshape( width - 20, height - caption_rect.getHeight(), 1);
+ msg_text_rect.setLeftTopAndSize( msg_left_offset, height - caption_rect.getHeight() , width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight());
+ msg_text->reshape( width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight(), 1);
msg_text->setRect(msg_text_rect);
}
@@ -132,11 +136,22 @@ void LLChatItemCtrl::setMessage (const LLChat& msg)
LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
if(!caption)
return;
- caption->getChild<LLTextBox>("sender_name",false,false)->setText(msg.mFromName);
+
+ std::string str_sender;
+
+
+ if(gAgentID != msg.mFromID)
+ str_sender = msg.mFromName;
+ else
+ str_sender = LLTrans::getString("You");;
+
+ caption->getChild<LLTextBox>("sender_name",false,false)->setText(str_sender);
+
std::string tt = appendTime();
caption->getChild<LLTextBox>("msg_time",false,false)->setText(tt);
+
caption->getChild<LLAvatarIconCtrl>("avatar_icon",false,false)->setValue(msg.mFromID);
mOriginalMessage = msg;
@@ -153,6 +168,28 @@ void LLChatItemCtrl::setMessage (const LLChat& msg)
}
+void LLChatItemCtrl::snapToMessageHeight ()
+{
+ LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text",false,false);
+ if(!text_box)
+ return;///actually assert fits better
+ S32 new_height = text_box->getTextPixelHeight();
+ LLRect panel_rect = getRect();
+
+ S32 caption_height = 0;
+ LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
+ if(caption)
+ caption_height = caption->getRect().getHeight();
+
+
+ panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth() , caption_height + new_height);
+
+ reshape( getRect().getWidth(), caption_height + new_height, 1);
+
+ setRect(panel_rect);
+
+}
+
void LLChatItemCtrl::setWidth(S32 width)
{
@@ -160,7 +197,7 @@ void LLChatItemCtrl::setWidth(S32 width)
if(!text_box)
return;///actually assert fits better
- text_box->reshape(width - 20,100/*its not magic number, we just need any number*/);
+ text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/);
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false);
if(msg_text && mOriginalMessage.mText.length())
@@ -169,13 +206,8 @@ void LLChatItemCtrl::setWidth(S32 width)
for(size_t i=0;i<mMessages.size();++i)
msg_text->addText(mMessages[i]);
- S32 new_height = text_box->getTextPixelHeight();
- LLRect panel_rect = getRect();
- panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, width , 35 + new_height);
-
- reshape( width, panel_rect.getHeight(), 1);
-
- setRect(panel_rect);
+ setRect(LLRect(getRect().mLeft, getRect().mTop, getRect().mLeft + width , getRect().mBottom));
+ snapToMessageHeight ();
}
void LLChatItemCtrl::onMouseLeave (S32 x, S32 y, MASK mask)
@@ -190,6 +222,8 @@ void LLChatItemCtrl::onMouseLeave (S32 x, S32 y, MASK mask)
}
void LLChatItemCtrl::onMouseEnter (S32 x, S32 y, MASK mask)
{
+ if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ return;
LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
if(!caption)
return;
@@ -200,8 +234,10 @@ void LLChatItemCtrl::onMouseEnter (S32 x, S32 y, MASK mask)
BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
{
+ if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ return LLPanel::handleMouseDown(x,y,mask);
LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
- if(mOriginalMessage.mSourceType == CHAT_SOURCE_AGENT && caption)
+ if(caption)
{
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
if(msg_inspector)
@@ -242,6 +278,23 @@ bool LLChatItemCtrl::canAddText ()
return msg_text->getTextLinesNum()<10;
}
+BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
+ if(!caption)
+ return LLPanel::handleRightMouseDown(x,y,mask);
+ LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon",false,false);
+ if(!avatar_icon)
+ return LLPanel::handleRightMouseDown(x,y,mask);
+ S32 local_x = x - avatar_icon->getRect().mLeft - caption->getRect().mLeft;
+ S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom;
+
+ //eat message for avatar icon if msg was from object
+ if(avatar_icon->pointInView(local_x, local_y) && mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ return TRUE;
+ return LLPanel::handleRightMouseDown(x,y,mask);
+}
+
//*******************************************************************************************************************
//LLChatItemsContainerCtrl
@@ -264,13 +317,18 @@ void LLChatItemsContainerCtrl::addMessage(const LLChat& msg)
LLChatItemCtrl* item = mItems[0];
removeChild(item);
delete item;
+ mItems.erase(mItems.begin());
}
- if(mItems.size() > 0 && msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID && mItems[mItems.size()-1]->canAddText())
+ if(mItems.size() > 0
+ && msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID
+ && (msg.mTime-mItems[mItems.size()-1]->getMessage().mTime)<60
+ && mItems[mItems.size()-1]->canAddText()
+ )
{
mItems[mItems.size()-1]->addText(msg.mText);
- mItems[mItems.size()-1]->setWidth(getRect().getWidth() - 16);
+ mItems[mItems.size()-1]->snapToMessageHeight();
}
else
{
@@ -279,6 +337,8 @@ void LLChatItemsContainerCtrl::addMessage(const LLChat& msg)
addChild(item,0);
item->setWidth(getRect().getWidth() - 16);
item->setMessage(msg);
+ item->snapToMessageHeight();
+
item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
item->setVisible(true);
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index f5791078aa..de16cf9505 100644
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -63,6 +63,7 @@ public:
void addText (const std::string& message);
void setMessage (const LLChat& msg);
void setWidth (S32 width);
+ void snapToMessageHeight ();
bool canAddText ();
@@ -75,6 +76,7 @@ public:
void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
void setHeaderVisibility(EShowItemHeader e);
+ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
private:
std::string appendTime ();
diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp
index 8fb4b78cb8..933d9b8771 100644
--- a/indra/newview/llchatmsgbox.cpp
+++ b/indra/newview/llchatmsgbox.cpp
@@ -51,9 +51,8 @@ LLChatMsgBox::Params::Params()
disabled_color("disabled_color"),
background_color("background_color"),
border_color("border_color"),
- v_pad("v_pad", 0),
- h_pad("h_pad", 0),
- line_spacing("line_spacing", 0),
+ line_spacing("line_spacing", 4),
+ block_spacing("block_spacing",10),
text("text"),
font_shadow("font_shadow", LLFontGL::NO_SHADOW)
{}
@@ -68,8 +67,6 @@ LLChatMsgBox::LLChatMsgBox(const LLChatMsgBox::Params& p)
mShadowType( p.font_shadow ),
mBorderDropShadowVisible( p.border_drop_shadow_visible ),
mUseEllipses( p.use_ellipses ),
- mHPad(p.h_pad),
- mVPad(p.v_pad),
mVAlign( LLFontGL::TOP ),
mClickedCallback(NULL),
mTextColor(p.text_color()),
@@ -79,6 +76,7 @@ LLChatMsgBox::LLChatMsgBox(const LLChatMsgBox::Params& p)
mHoverColor(p.hover_color()),
mHAlign(p.font_halign),
mLineSpacing(p.line_spacing),
+ mBlockSpasing(p.block_spacing),
mWordWrap( p.word_wrap ),
mFontStyle(LLFontGL::getStyleFromString(p.font.style))
{
@@ -271,7 +269,7 @@ S32 LLChatMsgBox::getTextLinesNum()
S32 LLChatMsgBox::getTextPixelHeight()
{
S32 num_lines = getTextLinesNum();
- return (S32)(num_lines * mFontGL->getLineHeight() + (num_lines-1)*4);
+ return (S32)(num_lines * mFontGL->getLineHeight() + (num_lines-1)*mLineSpacing + mBlockSpasing*(mTextStrings.size()-1) + 2*mLineSpacing);//some extra space
}
void LLChatMsgBox::setValue(const LLSD& value )
@@ -305,17 +303,16 @@ void LLChatMsgBox::draw()
switch( mHAlign )
{
case LLFontGL::LEFT:
- text_x = mHPad;
break;
case LLFontGL::HCENTER:
text_x = getRect().getWidth() / 2;
break;
case LLFontGL::RIGHT:
- text_x = getRect().getWidth() - mHPad;
+ text_x = getRect().getWidth() ;
break;
}
- S32 text_y = getRect().getHeight() - mVPad;
+ S32 text_y = getRect().getHeight() ;
if ( getEnabled() )
{
@@ -358,6 +355,7 @@ void LLChatMsgBox::reshape(S32 width, S32 height, BOOL called_from_parent)
void LLChatMsgBox::drawText( S32 x, S32 y, const LLColor4& color )
{
S32 width = getRect().getWidth()-10;
+
for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();
it!=mTextStrings.end();++it)
@@ -383,8 +381,9 @@ void LLChatMsgBox::drawText( S32 x, S32 y, const LLColor4& color )
if(next == mTextStrings.end())
break;
//separator
- gl_line_2d(5,y-2,width,y-2,LLColor4::grey);
- y-=4;
+ gl_line_2d(5,y-mBlockSpasing/2,width,y-mBlockSpasing/2,LLColor4::grey);
+ y-=mBlockSpasing;
}
+
}
diff --git a/indra/newview/llchatmsgbox.h b/indra/newview/llchatmsgbox.h
index c0e1964afa..61035499c7 100644
--- a/indra/newview/llchatmsgbox.h
+++ b/indra/newview/llchatmsgbox.h
@@ -71,9 +71,9 @@ public:
background_color,
border_color;
- Optional<S32> v_pad,
- h_pad,
- line_spacing;
+ Optional<S32> line_spacing;
+
+ Optional<S32> block_spacing;
Params();
};
@@ -104,8 +104,6 @@ public:
void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; }
void setBorderVisible(BOOL visible) { mBorderVisible = visible; }
void setBorderDropshadowVisible(BOOL visible){ mBorderDropShadowVisible = visible; }
- void setHPad(S32 pixels) { mHPad = pixels; }
- void setVPad(S32 pixels) { mVPad = pixels; }
void setRightAlign() { mHAlign = LLFontGL::RIGHT; }
void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
void setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); } // mouse down and up within button
@@ -145,9 +143,8 @@ private:
BOOL mUseEllipses;
S32 mLineSpacing;
+ S32 mBlockSpasing;
- S32 mHPad;
- S32 mVPad;
LLFontGL::HAlign mHAlign;
LLFontGL::VAlign mVAlign;
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index bfa4e06d2e..f71ea9f8ad 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -428,9 +428,11 @@ LLChicletPanel::Params::Params()
, scrolling_offset("scrolling_offset")
, left_scroll_button("left_scroll_button")
, right_scroll_button("right_scroll_button")
+, min_width("min_width")
{
chiclet_padding = 3;
scrolling_offset = 40;
+ min_width = 70;
LLRect scroll_button_rect(0, 25, 19, 5);
@@ -458,6 +460,8 @@ LLChicletPanel::LLChicletPanel(const Params&p)
, mRightScrollButton(NULL)
, mChicletPadding(p.chiclet_padding)
, mScrollingOffset(p.scrolling_offset)
+, mMinWidth(p.min_width)
+, mShowControls(true)
{
LLButton::Params scroll_button_params = p.left_scroll_button;
@@ -660,6 +664,9 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )
mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD,
height + 7, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
+ mShowControls = width > mMinWidth;
+ mScrollArea->setVisible(mShowControls);
+
trimChiclets();
showScrollButtonsIfNeeded();
@@ -719,7 +726,7 @@ void LLChicletPanel::showScrollButtonsIfNeeded()
mLeftScrollButton->setEnabled(can_scroll_left);
mRightScrollButton->setEnabled(can_scroll_right);
- bool show_scroll_buttons = can_scroll_left || can_scroll_right;
+ bool show_scroll_buttons = (can_scroll_left || can_scroll_right) && mShowControls;
mLeftScrollButton->setVisible(show_scroll_buttons);
mRightScrollButton->setVisible(show_scroll_buttons);
@@ -950,6 +957,11 @@ void LLTalkButton::draw()
LLUICtrl::draw();
}
+void LLTalkButton::setSpeakBtnToggleState(bool state)
+{
+ mSpeakBtn->setToggleState(state);
+}
+
void LLTalkButton::onClick_SpeakBtn()
{
bool speaking = mSpeakBtn->getToggleState();
@@ -1012,7 +1024,14 @@ void LLChicletNotificationCounterCtrl::setCounter(S32 counter)
std::stringstream stream;
stream << getCounter();
- setText(stream.str());
+ if(mCounter != 0)
+ {
+ setText(stream.str());
+ }
+ else
+ {
+ setText(std::string(""));
+ }
}
LLRect LLChicletNotificationCounterCtrl::getRequiredRect()
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 415ae59ca2..c20c81e052 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -390,6 +390,8 @@ public:
Optional<LLButton::Params> left_scroll_button,
right_scroll_button;
+ Optional<S32> min_width;
+
Params();
};
@@ -558,6 +560,8 @@ protected:
S32 mChicletPadding;
S32 mScrollingOffset;
+ S32 mMinWidth;
+ bool mShowControls;
};
/*
@@ -580,6 +584,7 @@ public:
/*virtual*/ ~LLTalkButton();
/*virtual*/ void draw();
+ void setSpeakBtnToggleState(bool state);
protected:
friend class LLUICtrlFactory;
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 00d4f80054..72bfac70fc 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -216,6 +216,8 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
}
}
+ bool recreate_buttons = true;
+
// If inventory items are not changed up to mFirstDropDownItem, no need to recreate them
if (mFirstDropDownItem == first_drop_down_item && (mItemNamesCache.size() == count || mItemNamesCache.size() == mFirstDropDownItem))
{
@@ -229,97 +231,113 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
}
if (i == mFirstDropDownItem)
{
- // Chevron button should stay right aligned
- LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE);
- if (chevron_button)
+ recreate_buttons = false;
+ }
+ }
+
+ if (recreate_buttons)
+ {
+ mFirstDropDownItem = first_drop_down_item;
+
+ mItemNamesCache.clear();
+ for (S32 i = 0; i < mFirstDropDownItem; i++)
+ {
+ mItemNamesCache.put(items.get(i)->getName());
+ }
+
+ // Rebuild the buttons only
+ // child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator
+ for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); )
+ {
+ child_list_const_iter_t cur_it = child_it++;
+ LLView* viewp = *cur_it;
+ LLButton* button = dynamic_cast<LLButton*>(viewp);
+ if (button)
{
- LLRect rect;
- rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap);
- chevron_button->setRect(rect);
- mChevronRect = rect;
+ removeChild(button);
+ delete button;
}
- return;
}
- }
- mFirstDropDownItem = first_drop_down_item;
+ // Adding buttons
+ for(S32 i = mFirstDropDownItem -1; i >= 0; i--)
+ {
- mItemNamesCache.clear();
- for (S32 i = 0; i < mFirstDropDownItem; i++)
- {
- mItemNamesCache.put(items.get(i)->getName());
- }
+ LLInventoryItem* item = items.get(i);
- // Rebuild the buttons only
- // child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator
- for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); )
- {
- child_list_const_iter_t cur_it = child_it++;
- LLView* viewp = *cur_it;
- LLButton* button = dynamic_cast<LLButton*>(viewp);
- if (button)
- {
- removeChild(button);
- delete button;
- }
- }
-
- // Adding buttons
- for(S32 i = 0; i < mFirstDropDownItem; i++)
- {
-
- LLInventoryItem* item = items.get(i);
-
- S32 buttonWidth = mFont->getWidth(item->getName()) + buttonHPad * 2;
-
- LLRect rect;
- rect.setOriginAndSize(curr_x, buttonVGap, buttonWidth, getRect().getHeight()-buttonVGap);
-
- LLButton::Params bparams;
- bparams.image_unselected.name(flat_icon);
- bparams.image_disabled.name(flat_icon);
- bparams.image_selected.name(hover_icon_selected);
- bparams.image_hover_selected.name(hover_icon_selected);
- bparams.image_disabled_selected.name(hover_icon_selected);
- bparams.image_hover_unselected.name(hover_icon);
- bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM);
- bparams.rect (rect);
- bparams.tab_stop(false);
- bparams.font(mFont);
- bparams.name(item->getName());
- bparams.tool_tip(item->getName());
- bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
- bparams.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID()));
-
- addChildInBack(LLUICtrlFactory::create<LLButton> (bparams));
-
- curr_x += buttonWidth + buttonHGap;
+ S32 buttonWidth = mFont->getWidth(item->getName()) + buttonHPad * 2;
+
+ LLRect rect;
+ rect.setOriginAndSize(curr_x, buttonVGap, buttonWidth, getRect().getHeight()-buttonVGap);
+
+ LLButton::Params bparams;
+ bparams.image_unselected.name(flat_icon);
+ bparams.image_disabled.name(flat_icon);
+ bparams.image_selected.name(hover_icon_selected);
+ bparams.image_hover_selected.name(hover_icon_selected);
+ bparams.image_disabled_selected.name(hover_icon_selected);
+ bparams.image_hover_unselected.name(hover_icon);
+ bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+ bparams.rect (rect);
+ bparams.tab_stop(false);
+ bparams.font(mFont);
+ bparams.name(item->getName());
+ bparams.tool_tip(item->getName());
+ bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
+ bparams.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID()));
+
+ addChildInBack(LLUICtrlFactory::create<LLButton> (bparams));
+
+ curr_x += buttonWidth + buttonHGap;
+ }
}
// Chevron button
if (mFirstDropDownItem != count)
{
- LLButton::Params bparams;
-
- LLRect rect;
- rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap);
-
- bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM);
- bparams.image_unselected.name(flat_icon);
- bparams.image_disabled.name(flat_icon);
- bparams.image_selected.name(hover_icon_selected);
- bparams.image_hover_selected.name(hover_icon_selected);
- bparams.image_disabled_selected.name(hover_icon_selected);
- bparams.image_hover_unselected.name(hover_icon);
- bparams.rect (rect);
- bparams.tab_stop(false);
- bparams.font(mFont);
- bparams.name(">>");
- bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this));
-
- addChildInBack(LLUICtrlFactory::create<LLButton> (bparams));
-
- mChevronRect = rect;
+ // Chevron button should stay right aligned
+ LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE);
+ if (chevron_button)
+ {
+ LLRect rect;
+ rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap);
+ chevron_button->setRect(rect);
+ chevron_button->setVisible(TRUE);
+ mChevronRect = rect;
+ }
+ else
+ {
+ LLButton::Params bparams;
+
+ LLRect rect;
+ rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap);
+
+ bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+ bparams.image_unselected.name(flat_icon);
+ bparams.image_disabled.name(flat_icon);
+ bparams.image_selected.name(hover_icon_selected);
+ bparams.image_hover_selected.name(hover_icon_selected);
+ bparams.image_disabled_selected.name(hover_icon_selected);
+ bparams.image_hover_unselected.name(hover_icon);
+ bparams.rect (rect);
+ bparams.tab_stop(false);
+ bparams.font(mFont);
+ bparams.name(">>");
+ bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this));
+
+ addChildInBack(LLUICtrlFactory::create<LLButton> (bparams));
+
+ mChevronRect = rect;
+ }
+ }
+ else
+ {
+ // Hide chevron button if all items are visible on bar
+ LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE);
+ if (chevron_button)
+ {
+ chevron_button->setVisible(FALSE);
+ }
}
}
@@ -444,6 +462,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
item_params.label(item_name);
item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
+ item_params.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID()));
LLMenuItemCallGL *menu_item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp
index aba2402b0c..6cae4b8abc 100644
--- a/indra/newview/llfloaterbuy.cpp
+++ b/indra/newview/llfloaterbuy.cpp
@@ -276,7 +276,7 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
std::string text = obj->getName();
if (!(next_owner_mask & PERM_COPY))
{
- text.append(getString("no_copy"));
+ text.append(LLTrans::getString("no_copy"));
}
if (!(next_owner_mask & PERM_MODIFY))
{
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 8ec9eac196..eb2c6768f3 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -56,7 +56,7 @@
#include "llviewermessage.h"
#include "llvoavatarself.h"
#include "llviewerstats.h"
-#include "llbottomtray.h"
+#include "llnearbychatbar.h"
LLGestureManager gGestureManager;
@@ -871,7 +871,7 @@ void LLGestureManager::runStep(LLMultiGesture* gesture, LLGestureStep* step)
const BOOL animate = FALSE;
- LLBottomTray::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
+ LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
gesture->mCurrentStep++;
break;
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 85da2eb2e3..278fd5b9f6 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -42,6 +42,12 @@
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
+LLGroupList::Params::Params()
+{
+ // Prevent the active group from being always first in the list.
+ online_go_first = false;
+}
+
LLGroupList::LLGroupList(const Params& p)
: LLAvatarList(p)
{
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index a246650822..e893313f4b 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -44,6 +44,7 @@ class LLGroupList: public LLAvatarList
public:
struct Params : public LLInitParam::Block<Params, LLAvatarList::Params>
{
+ Params();
};
LLGroupList(const Params&);
diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp
new file mode 100644
index 0000000000..b51064f226
--- /dev/null
+++ b/indra/newview/lllandmarkactions.cpp
@@ -0,0 +1,141 @@
+/**
+* @file lllandmarkactions.cpp
+* @brief LLLandmarkActions class implementation
+*
+* $LicenseInfo:firstyear=2001&license=viewergpl$
+*
+* Copyright (c) 2001-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 "lllandmarkactions.h"
+
+#include "llagent.h"
+#include "llinventory.h"
+#include "llinventorymodel.h"
+#include "lllandmark.h"
+#include "lllandmarklist.h"
+#include "llnotifications.h"
+#include "llparcel.h"
+#include "llviewerinventory.h"
+#include "llviewerparcelmgr.h"
+#include "roles_constants.h"
+
+// Returns true if the given inventory item is a landmark pointing to the current parcel.
+// Used to filter inventory items.
+class LLIsAgentParcelLandmark : public LLInventoryCollectFunctor
+{
+public:
+ /*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+ {
+ if (!item || item->getType() != LLAssetType::AT_LANDMARK)
+ return false;
+
+ LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID());
+ if (!landmark) // the landmark not been loaded yet
+ return false;
+
+ LLVector3d landmark_global_pos;
+ if (!landmark->getGlobalPos(landmark_global_pos))
+ return false;
+
+ return LLViewerParcelMgr::getInstance()->inAgentParcel(landmark_global_pos);
+ }
+};
+
+bool LLLandmarkActions::landmarkAlreadyExists()
+{
+ // Determine whether there are landmarks pointing to the current parcel.
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLIsAgentParcelLandmark is_current_parcel_landmark;
+ gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_current_parcel_landmark);
+
+ return !items.empty();
+}
+
+bool LLLandmarkActions::canCreateLandmarkHere()
+{
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(!agent_parcel)
+ {
+ llwarns << "No agent region" << llendl;
+ return false;
+ }
+ if (agent_parcel->getAllowLandmark()
+ || LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void LLLandmarkActions::createLandmarkHere(
+ const std::string& name,
+ const std::string& desc,
+ const LLUUID& folder_id)
+{
+ if(!gAgent.getRegion())
+ {
+ llwarns << "No agent region" << llendl;
+ return;
+ }
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!agent_parcel)
+ {
+ llwarns << "No agent parcel" << llendl;
+ return;
+ }
+ if (!canCreateLandmarkHere())
+ {
+ LLNotifications::instance().add("CannotCreateLandmarkNotOwner");
+ return;
+ }
+
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ folder_id, LLTransactionID::tnull,
+ name, desc,
+ LLAssetType::AT_LANDMARK,
+ LLInventoryType::IT_LANDMARK,
+ NOT_WEARABLE, PERM_ALL,
+ NULL);
+}
+
+void LLLandmarkActions::createLandmarkHere()
+{
+ std::string landmark_name, landmark_desc;
+
+ gAgent.buildLocationString(landmark_name, LLAgent::LOCATION_FORMAT_LANDMARK);
+ gAgent.buildLocationString(landmark_desc, LLAgent::LOCATION_FORMAT_FULL);
+ LLUUID folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
+
+ createLandmarkHere(landmark_name, landmark_desc, folder_id);
+}
diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h
new file mode 100644
index 0000000000..e1e94edb75
--- /dev/null
+++ b/indra/newview/lllandmarkactions.h
@@ -0,0 +1,68 @@
+/**
+* @file lllandmarkactions.h
+* @brief LLLandmark class declaration
+*
+* $LicenseInfo:firstyear=2000&license=viewergpl$
+*
+* Copyright (c) 2000-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_LLLANDMARKACTIONS_H
+#define LL_LLLANDMARKACTIONS_H
+
+/**
+* @brief Provides helper functions to manage landmarks
+*/
+class LLLandmarkActions
+{
+public:
+
+ /**
+ * @brief Checks whether landmark exists for current parcel.
+ */
+ static bool landmarkAlreadyExists();
+
+ /**
+ * @brief Checks whether agent has rights to create landmark for current parcel.
+ */
+ static bool canCreateLandmarkHere();
+
+ /**
+ * @brief Creates landmark for current parcel.
+ */
+ static void createLandmarkHere();
+
+ /**
+ * @brief Creates landmark for current parcel.
+ */
+ static void createLandmarkHere(
+ const std::string& name,
+ const std::string& desc,
+ const LLUUID& folder_id);
+
+};
+
+#endif //LL_LLLANDMARKACTIONS_H
diff --git a/indra/newview/lllocationhistory.cpp b/indra/newview/lllocationhistory.cpp
index ed56e3e195..471a0868bc 100644
--- a/indra/newview/lllocationhistory.cpp
+++ b/indra/newview/lllocationhistory.cpp
@@ -39,8 +39,7 @@
#include "llui.h"
LLLocationHistory::LLLocationHistory() :
- mFilename("typed_locations.txt"),
- mLoadedCallback(NULL)
+ mFilename("typed_locations.txt")
{
}
@@ -134,6 +133,5 @@ void LLLocationHistory::load()
file.close();
- if (mLoadedCallback)
- mLoadedCallback();
+ mLoadedSignal();
}
diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h
index b6552c12ca..19032686c1 100644
--- a/indra/newview/lllocationhistory.h
+++ b/indra/newview/lllocationhistory.h
@@ -46,6 +46,7 @@ class LLLocationHistory: public LLSingleton<LLLocationHistory>
public:
typedef std::vector<std::string> location_list_t;
typedef boost::function<void()> loaded_callback_t;
+ typedef boost::signals2::signal<void()> loaded_signal_t;
LLLocationHistory();
@@ -54,7 +55,7 @@ public:
size_t getItemCount() const { return mItems.size(); }
const location_list_t& getItems() const { return mItems; }
bool getMatchingItems(std::string substring, location_list_t& result) const;
- void setLoadedCallback(loaded_callback_t cb) { mLoadedCallback = cb; }
+ boost::signals2::connection setLoadedCallback(loaded_callback_t cb) { return mLoadedSignal.connect(cb); }
void save() const;
void load();
@@ -63,7 +64,7 @@ public:
private:
std::vector<std::string> mItems;
std::string mFilename; /// File to store the history to.
- loaded_callback_t mLoadedCallback;
+ loaded_signal_t mLoadedSignal;
};
#endif
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 99f6823ba1..94abd128c4 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -48,6 +48,7 @@
#include "llagent.h"
#include "llfloaterland.h"
#include "llinventorymodel.h"
+#include "lllandmarkactions.h"
#include "lllandmarklist.h"
#include "lllocationhistory.h"
#include "llsidetray.h"
@@ -83,28 +84,6 @@
* and choose the appropriate image for the "Add landmark" button.
*/
-// Returns true if the given inventory item is a landmark pointing to the current parcel.
-// Used to filter inventory items.
-class LLIsAgentParcelLandmark : public LLInventoryCollectFunctor
-{
-public:
- /*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
- {
- if (!item || item->getType() != LLAssetType::AT_LANDMARK)
- return false;
-
- LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID());
- if (!landmark) // the landmark not been loaded yet
- return false;
-
- LLVector3d landmark_global_pos;
- if (!landmark->getGlobalPos(landmark_global_pos))
- return false;
-
- return LLViewerParcelMgr::getInstance()->inAgentParcel(landmark_global_pos);
- }
-};
-
/**
* Initiates loading the landmarks that have been just added.
*
@@ -213,10 +192,10 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
// - Make the "Add landmark" button updated when either current parcel gets changed
// or a landmark gets created or removed from the inventory.
// - Update the location string on parcel change.
- LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback(
+ mParcelMgrConnection = LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback(
boost::bind(&LLLocationInputCtrl::onAgentParcelChange, this));
- LLLocationHistory::getInstance()->setLoadedCallback(
+ mLocationHistoryConnection = LLLocationHistory::getInstance()->setLoadedCallback(
boost::bind(&LLLocationInputCtrl::onLocationHistoryLoaded, this));
mRemoveLandmarkObserver = new LLRemoveLandmarkObserver(this);
@@ -231,6 +210,9 @@ LLLocationInputCtrl::~LLLocationInputCtrl()
gInventory.removeObserver(mAddLandmarkObserver);
delete mRemoveLandmarkObserver;
delete mAddLandmarkObserver;
+
+ mParcelMgrConnection.disconnect();
+ mLocationHistoryConnection.disconnect();
}
void LLLocationInputCtrl::setEnabled(BOOL enabled)
@@ -356,6 +338,10 @@ void LLLocationInputCtrl::onInfoButtonClicked()
void LLLocationInputCtrl::onAddLandmarkButtonClicked()
{
+ LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark"));
+
+ // Floater "Add Landmark" functionality moved to Side Tray
+ // TODO* Disable floater "Add Landmark" call
LLFloaterReg::showInstance("add_landmark");
}
@@ -450,19 +436,7 @@ void LLLocationInputCtrl::enableAddLandmarkButton(bool val)
// depending on whether current parcel has been landmarked.
void LLLocationInputCtrl::updateAddLandmarkButton()
{
- bool cur_parcel_landmarked = false;
- // Determine whether there are landmarks pointing to the current parcel.
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- LLIsAgentParcelLandmark is_current_parcel_landmark;
- gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- is_current_parcel_landmark);
- cur_parcel_landmarked = !items.empty();
-
- enableAddLandmarkButton(!cur_parcel_landmarked);
+ enableAddLandmarkButton(!LLLandmarkActions::landmarkAlreadyExists());
}
void LLLocationInputCtrl::updateWidgetlayout()
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index 0a863f6dd8..2cc63a33b7 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -112,6 +112,9 @@ private:
LLAddLandmarkObserver* mAddLandmarkObserver;
LLRemoveLandmarkObserver* mRemoveLandmarkObserver;
+
+ boost::signals2::connection mParcelMgrConnection;
+ boost::signals2::connection mLocationHistoryConnection;
};
#endif
diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp
index cfcb331912..efa15e05da 100644
--- a/indra/newview/llmenucommands.cpp
+++ b/indra/newview/llmenucommands.cpp
@@ -67,7 +67,7 @@
#include "llworld.h"
#include "llworldmap.h"
#include "llfocusmgr.h"
-#include "llbottomtray.h"
+#include "llnearbychatbar.h"
void handle_pay_by_id(const LLUUID& agent_id)
{
@@ -85,13 +85,13 @@ void handle_chat(void*)
{
// give focus to chatbar if it's open but not focused
if (gSavedSettings.getBOOL("ChatVisible") &&
- gFocusMgr.childHasKeyboardFocus(LLBottomTray::getInstance()->getChatBox()))
+ gFocusMgr.childHasKeyboardFocus(LLNearbyChatBar::getInstance()->getChatBox()))
{
- LLBottomTray::stopChat();
+ LLNearbyChatBar::stopChat();
}
else
{
- LLBottomTray::startChat(NULL);
+ LLNearbyChatBar::startChat(NULL);
}
}
@@ -107,5 +107,5 @@ void handle_slash_key(void*)
// menu accelerators that put input focus into a field. And Mac works
// the same way. JC
- LLBottomTray::startChat(NULL);
+ LLNearbyChatBar::startChat(NULL);
}
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index c0bddd101e..58ec2d24a8 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -42,6 +42,7 @@
#include "llagent.h"
#include "llfloaterhtmlhelp.h"
+#include "lllandmarkactions.h"
#include "lllocationhistory.h"
#include "lllocationinputctrl.h"
#include "llteleporthistory.h"
@@ -175,7 +176,6 @@ LLNavigationBar::LLNavigationBar()
mBtnBack(NULL),
mBtnForward(NULL),
mBtnHome(NULL),
- mBtnHelp(NULL),
mCmbLocation(NULL),
mLeSearch(NULL),
mPurgeTPHistoryItems(false)
@@ -202,12 +202,11 @@ BOOL LLNavigationBar::postBuild()
mBtnBack = getChild<LLButton>("back_btn");
mBtnForward = getChild<LLButton>("forward_btn");
mBtnHome = getChild<LLButton>("home_btn");
- mBtnHelp = getChild<LLButton>("help_btn");
mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");
mLeSearch = getChild<LLSearchEditor>("search_input");
- if (!mBtnBack || !mBtnForward || !mBtnHome || !mBtnHelp ||
+ if (!mBtnBack || !mBtnForward || !mBtnHome ||
!mCmbLocation || !mLeSearch)
{
llwarns << "Malformed navigation bar" << llendl;
@@ -223,7 +222,6 @@ BOOL LLNavigationBar::postBuild()
mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2));
mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this));
- mBtnHelp->setClickedCallback(boost::bind(&LLNavigationBar::onHelpButtonClicked, this));
mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));
@@ -297,11 +295,6 @@ void LLNavigationBar::onHomeButtonClicked()
gAgent.teleportHome();
}
-void LLNavigationBar::onHelpButtonClicked()
-{
- gViewerHtmlHelp.show();
-}
-
void LLNavigationBar::onSearchCommit()
{
invokeSearch(mLeSearch->getValue().asString());
@@ -523,6 +516,10 @@ bool LLNavigationBar::onLocationContextMenuItemEnabled(const LLSD& userdata)
{
return location_entry->canSelectAll();
}
+ else if(item == std::string("can_landmark"))
+ {
+ return !LLLandmarkActions::landmarkAlreadyExists();
+ }
return false;
}
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index a82dfc73ff..a46c59306d 100644
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -80,7 +80,6 @@ private:
void onHelpButtonClicked();
void onLocationSelection();
void onLocationPrearrange(const LLSD& data);
- void onLocationHistoryLoaded();
void onSearchCommit();
void onRegionNameResponse(
std::string typed_location,
@@ -96,7 +95,6 @@ private:
LLButton* mBtnBack;
LLButton* mBtnForward;
LLButton* mBtnHome;
- LLButton* mBtnHelp;
LLSearchEditor* mLeSearch;
LLLocationInputCtrl* mCmbLocation;
bool mPurgeTPHistoryItems;
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 411aa72690..847262ddfd 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -36,7 +36,7 @@
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llrootview.h"
-#include "llchatitemscontainerctrl.h"
+//#include "llchatitemscontainerctrl.h"
#include "lliconctrl.h"
#include "llsidetray.h"
#include "llfocusmgr.h"
@@ -45,6 +45,9 @@
#include "llmenugl.h"
#include "llviewermenu.h"//for gMenuHolder
+#include "llnearbychathandler.h"
+#include "llchannelmanager.h"
+
static const S32 RESIZE_BAR_THICKNESS = 3;
LLNearbyChat::LLNearbyChat(const LLSD& key) :
@@ -66,6 +69,11 @@ BOOL LLNearbyChat::postBuild()
mResizeBar[LLResizeBar::LEFT]->setVisible(false);
mResizeBar[LLResizeBar::RIGHT]->setVisible(false);
+ mResizeBar[LLResizeBar::BOTTOM]->setResizeLimits(120,500);
+ mResizeBar[LLResizeBar::TOP]->setResizeLimits(120,500);
+ mResizeBar[LLResizeBar::LEFT]->setResizeLimits(220,600);
+ mResizeBar[LLResizeBar::RIGHT]->setResizeLimits(220,600);
+
mResizeHandle[0]->setVisible(false);
mResizeHandle[1]->setVisible(false);
mResizeHandle[2]->setVisible(false);
@@ -86,24 +94,160 @@ BOOL LLNearbyChat::postBuild()
gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true);
+ /*
LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);
if(panel)
{
panel->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
}
+ */
reshape(getRect().getWidth(), getRect().getHeight(), FALSE);
return LLFloater::postBuild();
}
-void LLNearbyChat::addMessage(const LLChat& message)
+#include "llagent.h" // gAgent
+#include "llfloaterscriptdebug.h"
+#include "llviewertexteditor.h"
+#include "llstylemap.h"
+
+LLColor4 nearbychat_get_text_color(const LLChat& chat)
+{
+ LLColor4 text_color;
+
+ if(chat.mMuted)
+ {
+ text_color.setVec(0.8f, 0.8f, 0.8f, 1.f);
+ }
+ else
+ {
+ switch(chat.mSourceType)
+ {
+ case CHAT_SOURCE_SYSTEM:
+ text_color = LLUIColorTable::instance().getColor("SystemChatColor");
+ break;
+ case CHAT_SOURCE_AGENT:
+ if (chat.mFromID.isNull())
+ {
+ text_color = LLUIColorTable::instance().getColor("SystemChatColor");
+ }
+ else
+ {
+ if(gAgentID == chat.mFromID)
+ {
+ text_color = LLUIColorTable::instance().getColor("UserChatColor");
+ }
+ else
+ {
+ text_color = LLUIColorTable::instance().getColor("AgentChatColor");
+ }
+ }
+ break;
+ case CHAT_SOURCE_OBJECT:
+ if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
+ {
+ text_color = LLUIColorTable::instance().getColor("ScriptErrorColor");
+ }
+ else if ( chat.mChatType == CHAT_TYPE_OWNER )
+ {
+ text_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor");
+ }
+ else
+ {
+ text_color = LLUIColorTable::instance().getColor("ObjectChatColor");
+ }
+ break;
+ default:
+ text_color.setToWhite();
+ }
+
+ if (!chat.mPosAgent.isExactlyZero())
+ {
+ LLVector3 pos_agent = gAgent.getPositionAgent();
+ F32 distance = dist_vec(pos_agent, chat.mPosAgent);
+ if (distance > gAgent.getNearChatRadius())
+ {
+ // diminish far-off chat
+ text_color.mV[VALPHA] = 0.8f;
+ }
+ }
+ }
+
+ return text_color;
+}
+
+void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color)
+{
+ std::string line = chat.mFromName;
+ line +=": ";
+ line +=chat.mText;
+
+ bool prepend_newline = true;
+ if (gSavedSettings.getBOOL("ChatShowTimestamps"))
+ {
+ edit->appendTime(prepend_newline);
+ prepend_newline = false;
+ }
+
+ // If the msg is from an agent (not yourself though),
+ // extract out the sender name and replace it with the hotlinked name.
+ if (chat.mSourceType == CHAT_SOURCE_AGENT &&
+ chat.mFromID != LLUUID::null)
+ {
+ chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
+ }
+
+ // If the chat line has an associated url, link it up to the name.
+ if (!chat.mURL.empty()
+ && (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0))
+ {
+ std::string start_line = line.substr(0, chat.mFromName.length() + 1);
+ line = line.substr(chat.mFromName.length() + 1);
+ const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID,chat.mURL);
+ edit->appendStyledText(start_line, false, prepend_newline, sourceStyle);
+ prepend_newline = false;
+ }
+ edit->appendColoredText(line, false, prepend_newline, color);
+}
+
+
+
+void LLNearbyChat::addMessage(const LLChat& chat)
{
+ /*
LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);
if(!panel)
return;
panel->addMessage(message);
+ */
+
+ //"Chat History Editor" !!!!!
+
+ LLColor4 color = nearbychat_get_text_color(chat);
+
+ if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
+ {
+ LLFloaterScriptDebug::addScriptLine(chat.mText,
+ chat.mFromName,
+ color,
+ chat.mFromID);
+ if (!gSavedSettings.getBOOL("ScriptErrorsAsChat"))
+ {
+ return;
+ }
+ }
+
+ // could flash the chat button in the status bar here. JC
+
+ LLViewerTextEditor* history_editor = getChild<LLViewerTextEditor>("Chat History Editor");
+
+ history_editor->setParseHTML(TRUE);
+ history_editor->setParseHighlights(TRUE);
+
+ if (!chat.mMuted)
+ nearbychat_add_timestamped_line(history_editor, chat, color);
}
void LLNearbyChat::onNearbySpeakers()
@@ -166,7 +310,9 @@ void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent)
caption->setRect(caption_rect);
}
- LLPanel* scroll_panel = getChild<LLPanel>("chat_history",false,false);
+ //LLPanel* scroll_panel = getChild<LLPanel>("chat_history",false,false);
+ LLViewerTextEditor* scroll_panel = getChild<LLViewerTextEditor>("Chat History Editor");
+
if (scroll_panel)
{
LLRect scroll_rect = scroll_panel->getRect();
@@ -305,10 +451,13 @@ void LLNearbyChat::float_panel()
mResizeBar[LLResizeBar::BOTTOM]->setVisible(true);
mResizeBar[LLResizeBar::LEFT]->setVisible(true);
mResizeBar[LLResizeBar::RIGHT]->setVisible(true);
+
+ translate(4,4);
}
void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
{
+ /*
LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);
if(!panel)
return;
@@ -322,15 +471,18 @@ void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
panel->setHeaderVisibility(CHATITEMHEADER_SHOW_BOTH);
gSavedSettings.setS32("nearbychat_showicons_and_names", (S32)panel->getHeaderVisibility());
-
-
+ */
}
bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
{
+ std::string str = userdata.asString();
+ if(str == "nearby_people")
+ onNearbySpeakers();
+ /*
LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);
if(!panel)
return false;
- std::string str = userdata.asString();
+
if(str == "show_buddy_icons")
return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_ONLY_ICON;
else if(str == "show_names")
@@ -339,6 +491,7 @@ bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_BOTH;
else if(str == "nearby_people")
onNearbySpeakers();
+ */
return false;
}
@@ -360,3 +513,11 @@ BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask)
return LLFloater::handleRightMouseDown(x, y, mask);
}
+void LLNearbyChat::onOpen(const LLSD& key )
+{
+ LLNotificationsUI::LLScreenChannel* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->getChannelByID(LLUUID(NEARBY_CHAT_ID));
+ if(chat_channel)
+ {
+ chat_channel->removeToastsFromChannel();
+ }
+}
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 61ff8890ea..74e3710f40 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -77,8 +77,10 @@ public:
void onNearbyChatContextMenuItemClicked(const LLSD& userdata);
bool onNearbyChatCheckContextMenuItem(const LLSD& userdata);
- virtual void onClose(bool app_quitting) { if(app_quitting) destroy(); else setVisible(false); }
-
+ virtual void onClose (bool app_quitting) { if(app_quitting) destroy(); else setVisible(false); }
+
+ virtual void onOpen (const LLSD& key);
+
private:
void pinn_panel();
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
new file mode 100644
index 0000000000..7b67ae645c
--- /dev/null
+++ b/indra/newview/llnearbychatbar.cpp
@@ -0,0 +1,549 @@
+/**
+ * @file llnearbychatbar.cpp
+ * @brief LLNearbyChatBar 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 "llnearbychatbar.h"
+#include "llbottomtray.h"
+#include "llagent.h"
+#include "llgesturemgr.h"
+#include "llmultigesture.h"
+#include "llkeyboard.h"
+#include "llanimationstates.h"
+#include "llviewerstats.h"
+#include "llcommandhandler.h"
+#include "llviewercontrol.h"
+
+S32 LLNearbyChatBar::sLastSpecialChatChannel = 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()
+ , mLabel(p.label)
+{
+ 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();
+ // 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);
+ addSimpleElement(mLabel, 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
+ LLNearbyChatBar::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();
+}
+
+LLNearbyChatBar::LLNearbyChatBar()
+ : LLPanel()
+ , mChatBox(NULL)
+{
+}
+
+//virtual
+BOOL LLNearbyChatBar::postBuild()
+{
+ mChatBox = getChild<LLLineEditor>("chat_box",TRUE,FALSE);
+
+ if (mChatBox)
+ {
+ mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));
+ mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
+ mChatBox->setFocusLostCallback(&onChatBoxFocusLost, this);
+
+ mChatBox->setIgnoreArrowKeys(TRUE);
+ mChatBox->setCommitOnFocusLost( FALSE );
+ mChatBox->setRevertOnEsc( FALSE );
+ mChatBox->setIgnoreTab(TRUE);
+ mChatBox->setPassDelete(TRUE);
+ mChatBox->setReplaceNewlinesWithSpaces(FALSE);
+ mChatBox->setMaxTextLength(1023);
+ mChatBox->setEnableLineHistory(TRUE);
+ }
+
+ mTalkBtn = getChild<LLTalkButton>("talk",TRUE,FALSE);
+
+ return TRUE;
+}
+
+//static
+LLNearbyChatBar* LLNearbyChatBar::getInstance()
+{
+ return LLBottomTray::getInstance() ? LLBottomTray::getInstance()->getNearbyChatBar() : NULL;
+}
+
+std::string LLNearbyChatBar::getCurrentChat()
+{
+ return mChatBox ? mChatBox->getText() : LLStringUtil::null;
+}
+
+// virtual
+BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask )
+{
+ BOOL handled = FALSE;
+
+ // ALT-RETURN is reserved for windowed/fullscreen toggle
+ if( KEY_RETURN == key && mask == MASK_CONTROL)
+ {
+ // shout
+ sendChat(CHAT_TYPE_SHOUT);
+ handled = TRUE;
+ }
+
+ return handled;
+}
+
+void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
+{
+ LLNearbyChatBar* self = (LLNearbyChatBar *)userdata;
+
+ LLWString raw_text;
+ if (self->mChatBox) raw_text = self->mChatBox->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->mChatBox)
+ {
+ std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+ self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
+ S32 outlength = self->mChatBox->getLength(); // in characters
+
+ // Select to end of line, starting from the character
+ // after the last one the user typed.
+ self->mChatBox->setSelection(length, outlength);
+ }
+ }
+
+ //llinfos << "GESTUREDEBUG " << trigger
+ // << " len " << length
+ // << " outlen " << out_str.getLength()
+ // << llendl;
+ }
+}
+
+// static
+void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
+{
+ // stop typing animation
+ gAgent.stopTyping();
+}
+
+void LLNearbyChatBar::sendChat( EChatType type )
+{
+ if (mChatBox)
+ {
+ LLWString text = mChatBox->getConvertedText();
+ if (!text.empty())
+ {
+ // store sent line in history, duplicates will get filtered
+ mChatBox->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);
+ }
+ }
+
+ mChatBox->setText(LLStringExplicit(""));
+ }
+
+ gAgent.stopTyping();
+
+ // If the user wants to stop chatting on hitting return, lose focus
+ // and go out of chat mode.
+ if (gSavedSettings.getBOOL("CloseChatOnReturn"))
+ {
+ stopChat();
+ }
+}
+
+void LLNearbyChatBar::onChatBoxCommit()
+{
+ if (mChatBox && mChatBox->getText().length() > 0)
+ {
+ sendChat(CHAT_TYPE_NORMAL);
+ }
+
+ gAgent.stopTyping();
+}
+
+void LLNearbyChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
+{
+ sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
+}
+
+void LLNearbyChatBar::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);
+}
+
+// static
+void LLNearbyChatBar::startChat(const char* line)
+{
+ LLBottomTray *bt = LLBottomTray::getInstance();
+
+ if (!bt)
+ return;
+
+ LLNearbyChatBar* cb = bt->getNearbyChatBar();
+
+ if (!cb || !cb->mChatBox)
+ return;
+
+ bt->setVisible(TRUE);
+ cb->mChatBox->setFocus(TRUE);
+
+ if (line)
+ {
+ std::string line_string(line);
+ cb->mChatBox->setText(line_string);
+ }
+
+ cb->mChatBox->setCursorToEnd();
+}
+
+// Exit "chat mode" and do the appropriate focus changes
+// static
+void LLNearbyChatBar::stopChat()
+{
+ LLBottomTray *bt = LLBottomTray::getInstance();
+
+ if (!bt)
+ return;
+
+ LLNearbyChatBar* cb = bt->getNearbyChatBar();
+
+ if (!cb || !cb->mChatBox)
+ return;
+
+ cb->mChatBox->setFocus(FALSE);
+
+ // stop typing animation
+ gAgent.stopTyping();
+}
+
+// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
+// Otherwise returns input and channel 0.
+LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
+{
+ if (mesg[0] == '/'
+ && mesg[1] == '/')
+ {
+ // This is a "repeat channel send"
+ *channel = sLastSpecialChatChannel;
+ 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++;
+ }
+
+ sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
+ *channel = sLastSpecialChatChannel;
+ return mesg.substr(pos, mesg.length() - pos);
+ }
+ else
+ {
+ // This is normal chat.
+ *channel = 0;
+ return mesg;
+ }
+}
+
+void LLNearbyChatBar::setPTTState(bool state)
+{
+ mTalkBtn->setSpeakBtnToggleState(state);
+}
+
+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/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
new file mode 100644
index 0000000000..d1f5fbff6b
--- /dev/null
+++ b/indra/newview/llnearbychatbar.h
@@ -0,0 +1,104 @@
+/**
+ * @file llnearbychatbar.h
+ * @brief LLNearbyChatBar 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_LLNEARBYCHATBAR_H
+#define LL_LLNEARBYCHATBAR_H
+
+#include "llpanel.h"
+#include "llcombobox.h"
+#include "llgesturemgr.h"
+#include "llchat.h"
+#include "llchiclet.h"
+
+class LLGestureComboBox
+ : public LLComboBox
+ , public LLGestureManagerObserver
+{
+protected:
+ LLGestureComboBox(const LLComboBox::Params&);
+ friend class LLUICtrlFactory;
+public:
+ ~LLGestureComboBox();
+
+ void refreshGestures();
+ void onCommitGesture(LLUICtrl* ctrl);
+ virtual void draw();
+
+ // LLGestureManagerObserver trigger
+ virtual void changed() { refreshGestures(); }
+
+protected:
+ LLFrameTimer mGestureLabelTimer;
+ std::string mLabel;
+};
+
+class LLNearbyChatBar
+: public LLPanel
+{
+public:
+ // constructor for inline chat-bars (e.g. hosted in chat history window)
+ LLNearbyChatBar();
+ ~LLNearbyChatBar() {}
+
+ virtual BOOL postBuild();
+
+ static LLNearbyChatBar* getInstance();
+
+ LLLineEditor* getChatBox() { return mChatBox; }
+
+ std::string getCurrentChat();
+ virtual BOOL handleKeyHere( KEY key, MASK mask );
+
+ void setPTTState(bool state);
+ static void startChat(const char* line);
+ static void stopChat();
+
+ static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
+ static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
+
+protected:
+ static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
+ static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
+
+ void sendChat( EChatType type );
+ void onChatBoxCommit();
+
+ static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
+
+ // Which non-zero channel did we last chat on?
+ static S32 sLastSpecialChatChannel;
+
+ LLLineEditor* mChatBox;
+ LLTalkButton* mTalkBtn;
+};
+
+#endif
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index ab66421d35..cb1b65a604 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -61,6 +61,7 @@ LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& i
// Getting a Channel for our notifications
mChannel = LLChannelManager::getInstance()->createChannel(p);
mChannel->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_TOP);
+ mChannel->setOverflowFormatString("You have %d unread nearby chat messages");
mChannel->setStoreToasts(false);
}
LLNearbyChatHandler::~LLNearbyChatHandler()
@@ -71,6 +72,9 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
if(chat_msg.mSourceType == CHAT_SOURCE_AGENT && chat_msg.mFromID.notNull())
LLRecentPeople::instance().add(chat_msg.mFromID);
+ if(chat_msg.mText.empty())
+ return;//don't process empty messages
+
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
nearby_chat->addMessage(chat_msg);
if(nearby_chat->getVisible())
@@ -82,7 +86,9 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
item->setMessage(chat_msg);
- item->setWidth(nearby_chat->getRect().getWidth() - 16);
+ //static S32 chat_item_width = nearby_chat->getRect().getWidth() - 16;
+ static S32 chat_item_width = 304;
+ item->setWidth(chat_item_width);
item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
item->setVisible(true);
@@ -91,7 +97,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
LLToast* toast = mChannel->addToast(id, item);
toast->setOnMouseEnterCallback(boost::bind(&LLNearbyChatHandler::onToastDestroy, this, toast));
- toast->setAndStartTimer(10); //TODO: set correct time
+ toast->setAndStartTimer(gSavedSettings.getS32("NotificationToastTime"));
}
void LLNearbyChatHandler::onToastDestroy(LLToast* toast)
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 757a0e5999..06826998bf 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -49,7 +49,7 @@ LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsMo
LLBottomTray* tray = LLBottomTray::getInstance();
LLChannelManager::Params p;
- p.id = LLUUID("F3E07BC8-A973-476D-8C7F-F3B7293975D1");
+ p.id = LLUUID(ALERT_CHANNEL_ID);
p.channel_right_bound = tray->getRect().getWidth() / 2;
p.channel_width = 0;
p.align = NA_CENTRE;
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index cde7efe901..ad09f43c10 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -50,7 +50,7 @@ LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id)
mChiclet = tray->getSysWell();
LLChannelManager::Params p;
p.chiclet = mChiclet;
- p.channel_right_bound = tray->getRect().mRight - 10; //HACK: need to correctly resolve SysWell's position
+ p.channel_right_bound = tray->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
p.channel_width = gSavedSettings.getS32("NotifyBoxWidth");
// Getting a Channel for our notifications
@@ -74,7 +74,7 @@ void LLGroupHandler::processNotification(const LLSD& notify)
toast = mChannel->addToast(notification->getID(), notify_box);
if(!toast)
return;
- toast->setAndStartTimer(5);
+ toast->setAndStartTimer(gSavedSettings.getS32("NotificationToastTime"));
toast->setOnToastDestroyCallback((boost::bind(&LLGroupHandler::onToastDestroy, this, toast)));
mChiclet->setCounter(mChiclet->getCounter() + 1);
}
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 7f53809c07..9037fc82ab 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -42,6 +42,8 @@
namespace LLNotificationsUI
{
+// ID for channel that displays Alert Notifications
+#define ALERT_CHANNEL_ID "F3E07BC8-A973-476D-8C7F-F3B7293975D1"
// ENotificationType enumerates all possible types of notifications that could be met
//
diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h
index f0cf480458..ffdbd96f60 100644
--- a/indra/newview/lloverlaybar.h
+++ b/indra/newview/lloverlaybar.h
@@ -85,7 +85,6 @@ public:
protected:
static void* createMediaRemote(void* userdata);
static void* createVoiceRemote(void* userdata);
- static void* createChatBar(void* userdata);
void enableMediaButtons();
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index bf6ecd6bf4..f57489934a 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -340,12 +340,17 @@ void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType ty
if(avatar_groups)
{
std::string groups;
- LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin();
- for(; avatar_groups->group_list.end() != it; ++it)
- {
+ if (!avatar_groups->group_list.empty()) {
+ LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin();
LLAvatarGroups::LLGroupData group_data = *it;
- groups += group_data.group_name;
- groups += ", ";
+ groups+= group_data.group_name;
+ while (++it != avatar_groups->group_list.end())
+ {
+ group_data = *it;
+ groups += ", ";
+ groups += group_data.group_name;
+
+ }
}
childSetValue("sl_groups",groups);
}
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 0cbf10f7c2..7bf7ceb6d2 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -200,6 +200,9 @@ void LLLandmarksPanel::onCopySLURL()
// virtual
void LLLandmarksPanel::updateVerbs()
{
+ if (!isTabVisible())
+ return;
+
BOOL enabled = FALSE;
LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem();
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index d947003109..92a8653252 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -436,11 +436,13 @@ bool LLPanelPeople::updateGroupList()
bool LLPanelPeople::filterFriendList()
{
- if (mFriendVec.size() > 0)
- return mFriendList->update(mFriendVec, mFilterSubString);
+ // We must always update Friends list to clear the latest removed friend.
+ bool have_names = mFriendList->update(mFriendVec, mFilterSubString);
- mFriendList->setCommentText(getString("no_friends"));
- return true;
+ if (mFriendVec.size() == 0)
+ mFriendList->setCommentText(getString("no_friends"));
+
+ return have_names;
}
bool LLPanelPeople::filterNearbyList()
@@ -784,10 +786,22 @@ void LLPanelPeople::onMoreButtonClicked()
void LLPanelPeople::onOpen(const LLSD& key)
{
- std::string tab_name = key.asString();
+ // Profile View is activated through LLSideTray::showPanel(),
+ // hide Profile View to be able to see Panel People content
+ hideProfileView();
+ std::string tab_name = key.asString();
if (!tab_name.empty())
mTabContainer->selectTabByName(tab_name);
else
reSelectedCurrentTab();
}
+
+void LLPanelPeople::hideProfileView()
+{
+ LLView* view = getChildView("panel_profile_view",true,false);
+ if(view && view->getVisible())
+ {
+ view->setVisible(false);
+ }
+}
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 6c3b5e0664..2ac1bf424c 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -104,6 +104,8 @@ private:
const std::vector<LLUUID>& ids,
void*);
+ void hideProfileView();
+
LLFilterEditor* mFilterEditor;
LLTabContainer* mTabContainer;
LLAvatarList* mFriendList;
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 7bfe94043f..e8d6ff9ec9 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -45,6 +45,7 @@
#include "llpanelavatar.h"
#include "llpanelprofile.h"
#include "llpanelpick.h"
+#include "llscrollcontainer.h"
static const std::string XML_BTN_NEW = "new_btn";
static const std::string XML_BTN_DELETE = "trash_btn";
@@ -203,7 +204,7 @@ void LLPanelPicks::reshapePicksList()
last_bottom -= childp->getRect().getHeight();
last_bottom -= PICK_ITEMS_BETWEEN;
}
- reshapePickItem(childp, last_bottom);
+ reshapePickItem(childp, last_bottom,pickList->getRect().getWidth());
}
S32 height = pickList->getChildCount() * ((*child_first_it)->getRect().getHeight() + PICK_ITEMS_BETWEEN);
@@ -213,13 +214,13 @@ void LLPanelPicks::reshapePicksList()
pickList->setRect(rc);
}
-void LLPanelPicks::reshapePickItem(LLView* const pick_item, const S32 last_bottom)
+void LLPanelPicks::reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth)
{
LLRect rc = pick_item->getRect();
rc.mBottom = last_bottom - rc.getHeight();
rc.mTop = last_bottom;
- pick_item->reshape(rc.getWidth(), rc.getHeight());
pick_item->setRect(rc);
+ pick_item->reshape(newWidth, rc.getHeight());
}
LLView* LLPanelPicks::getPicksList() const
@@ -402,7 +403,7 @@ void LLPanelPicks::setSelectedPickItem(LLPickItem* item)
BOOL LLPanelPicks::isMouseInPick( S32 x, S32 y )
{
- LLView* scroll = getChild<LLView>("profile_scroll");
+ LLScrollContainer* scroll = getChild<LLScrollContainer>("profile_scroll");
if (!scroll->parentPointInView(x, y)) return FALSE;
S32 x_l = x;
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 3bc79daeb3..e0e7f69532 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -102,7 +102,7 @@ private:
bool callbackTeleport(const LLSD& notification, const LLSD& response);
void reshapePicksList();
- void reshapePickItem(LLView* const pick_item, const S32 last_bottom);
+ void reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth);
LLView* getPicksList() const;
void updateButtons();
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 590eae555e..ea05b666db 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -39,6 +39,7 @@
#include "llsecondlifeurls.h"
#include "llinventory.h"
+#include "llparcel.h"
#include "llqueryflags.h"
@@ -52,6 +53,7 @@
#include "llinventorymodel.h"
#include "lltexturectrl.h"
#include "llviewerinventory.h"
+#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llviewertexteditor.h"
#include "llworldmap.h"
@@ -221,6 +223,8 @@ void LLPanelPlaceInfo::resetLocation()
mCreated->setText(not_available);
mTitleEditor->setText(LLStringUtil::null);
mNotesEditor->setText(LLStringUtil::null);
+ mSnapshotCtrl->setImageAssetID(LLUUID::null);
+ mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");
}
//virtual
@@ -237,6 +241,12 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
switch(type)
{
+ case CREATE_LANDMARK:
+ mCurrentTitle = getString("title_create_landmark");
+
+ toggleMediaPanel(FALSE);
+ break;
+
case PLACE:
mCurrentTitle = getString("title_place");
@@ -362,21 +372,33 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
region_z = llround(parcel_data.global_z);
}
+ std::string name;
if (!parcel_data.sim_name.empty())
{
- std::string name = llformat("%s (%d, %d, %d)",
- parcel_data.sim_name.c_str(), region_x, region_y, region_z);
+ name = llformat("%s (%d, %d, %d)",
+ parcel_data.sim_name.c_str(), region_x, region_y, region_z);
mRegionName->setText(name);
}
+
+ if (mCurrentTitle != getString("title_landmark"))
+ {
+ mTitleEditor->setText(parcel_data.name + "; " + name);
+ mNotesEditor->setText(LLStringUtil::null);
+ }
}
void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
const LLUUID& region_id,
const LLVector3d& pos_global)
{
- LLSD body;
mPosRegion = pos_region;
- std::string url = gAgent.getRegion()->getCapability("RemoteParcelRequest");
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ return;
+
+ LLSD body;
+ std::string url = region->getCapability("RemoteParcelRequest");
if (!url.empty())
{
body["location"] = ll_sd_from_vector3(pos_region);
@@ -395,8 +417,29 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
{
mDescEditor->setText(getString("server_update_text"));
}
- mSnapshotCtrl->setImageAssetID(LLUUID::null);
- mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");
+}
+
+void LLPanelPlaceInfo::displayAgentParcelInfo()
+{
+ mPosRegion = gAgent.getPositionAgent();
+
+ LLViewerRegion* region = gAgent.getRegion();
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!region || !parcel)
+ return;
+
+ LLParcelData parcel_data;
+ parcel_data.desc = parcel->getDesc();
+ parcel_data.flags = parcel->getParcelFlags();
+ parcel_data.name = parcel->getName();
+ parcel_data.sim_name = gAgent.getRegion()->getName();
+ parcel_data.snapshot_id = parcel->getSnapshotID();
+ LLVector3d global_pos = gAgent.getPositionGlobal();
+ parcel_data.global_x = global_pos.mdV[0];
+ parcel_data.global_y = global_pos.mdV[1];
+ parcel_data.global_z = global_pos.mdV[2];
+
+ processParcelInfo(parcel_data);
}
void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type)
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 7f98b6cb76..f06a2d1fb7 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -55,6 +55,7 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
public:
enum INFO_TYPE
{
+ CREATE_LANDMARK,
PLACE,
LANDMARK,
TELEPORT_HISTORY
@@ -84,9 +85,17 @@ public:
/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
void sendParcelInfoRequest();
+
+ // Displays information about a remote parcel.
+ // Sends a request to the server.
void displayParcelInfo(const LLVector3& pos_region,
const LLUUID& region_id,
const LLVector3d& pos_global);
+
+ // Displays information about the parcel the agent is currently on
+ // without sending a request to the server.
+ void displayAgentParcelInfo();
+
void nameUpdatedCallback(LLTextBox* text,
const std::string& first,
const std::string& last);
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 57c633dd74..b443cc4d5e 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -31,13 +31,16 @@
#include "llviewerprecompiledheaders.h"
+#include "llassettype.h"
+
+#include "lllandmark.h"
+
#include "llfloaterreg.h"
+#include "llnotifications.h"
#include "llfiltereditor.h"
#include "lltabcontainer.h"
#include "lluictrlfactory.h"
-#include "lllandmark.h"
-
#include "llagent.h"
#include "lllandmarklist.h"
#include "llfloaterworldmap.h"
@@ -48,18 +51,8 @@
#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;
-}
+// Helper function to get local position from global
+const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global);
static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places");
@@ -68,7 +61,9 @@ LLPanelPlaces::LLPanelPlaces()
mFilterSubString(LLStringUtil::null),
mActivePanel(NULL),
mFilterEditor(NULL),
- mPlaceInfo(NULL)
+ mPlaceInfo(NULL),
+ mItem(NULL),
+ mPosGlobal()
{
gInventory.addObserver(this);
@@ -86,6 +81,17 @@ LLPanelPlaces::~LLPanelPlaces()
BOOL LLPanelPlaces::postBuild()
{
+ mTeleportBtn = getChild<LLButton>("teleport_btn");
+ mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this));
+
+ mShowOnMapBtn = getChild<LLButton>("map_btn");
+ mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this));
+
+ //mShareBtn = getChild<LLButton>("share_btn");
+ //mShareBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShareButtonClicked, this));
+
+ mOverflowBtn = getChild<LLButton>("overflow_btn");
+
mTabContainer = getChild<LLTabContainer>("Places Tabs");
if (mTabContainer)
{
@@ -108,13 +114,9 @@ BOOL LLPanelPlaces::postBuild()
}
// *TODO: Assign the action to an appropriate event.
- childSetAction("overflow_btn", boost::bind(&LLPanelPlaces::toggleMediaPanel, this), this);
+ mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this));
}
- //childSetAction("share_btn", boost::bind(&LLPanelPlaces::onShareButtonClicked, this), this);
- childSetAction("teleport_btn", boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this), this);
- childSetAction("map_btn", boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this), this);
-
return TRUE;
}
@@ -124,19 +126,23 @@ void LLPanelPlaces::onOpen(const LLSD& key)
return;
mPlaceInfoType = key["type"].asString();
-
+ mPosGlobal.setZero();
togglePlaceInfoPanel(TRUE);
+ updateVerbs();
if (mPlaceInfoType == "agent")
{
- // We don't need to teleport to the current location so disable the button
- getChild<LLButton>("teleport_btn")->setEnabled(FALSE);
- getChild<LLButton>("map_btn")->setEnabled(TRUE);
-
mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE);
- mPlaceInfo->displayParcelInfo(gAgent.getPositionAgent(),
- gAgent.getRegion()->getRegionID(),
- gAgent.getPositionGlobal());
+ mPlaceInfo->displayAgentParcelInfo();
+
+ mPosGlobal = gAgent.getPositionGlobal();
+ }
+ else if (mPlaceInfoType == "create_landmark")
+ {
+ mPlaceInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
+ mPlaceInfo->displayAgentParcelInfo();
+
+ mPosGlobal = gAgent.getPositionGlobal();
}
else if (mPlaceInfoType == "landmark")
{
@@ -144,27 +150,19 @@ void LLPanelPlaces::onOpen(const LLSD& key)
LLInventoryItem* item = gInventory.getItem(item_uuid);
if (!item)
return;
+
+ setItem(item);
+ }
+ else if (mPlaceInfoType == "remote_place")
+ {
+ mPosGlobal = LLVector3d(key["x"].asReal(),
+ key["y"].asReal(),
+ key["z"].asReal());
- mPlaceInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
- mPlaceInfo->displayItemInfo(item);
-
- LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID());
- 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;
- landmark->getGlobalPos(pos_global);
- mPlaceInfo->displayParcelInfo(landmark->getRegionPos(),
- region_id,
- pos_global);
+ mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE);
+ mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal),
+ LLUUID(),
+ mPosGlobal);
}
else if (mPlaceInfoType == "teleport_history")
{
@@ -175,18 +173,47 @@ void LLPanelPlaces::onOpen(const LLSD& key)
LLVector3d pos_global = hist_items[index].mGlobalPos;
- F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
- F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
-
- LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]);
-
mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
- mPlaceInfo->displayParcelInfo(pos_local,
+ mPlaceInfo->displayParcelInfo(get_pos_local_from_global(pos_global),
hist_items[index].mRegionID,
pos_global);
}
}
+void LLPanelPlaces::setItem(LLInventoryItem* item)
+{
+ mItem = item;
+
+ // If the item is a link get a linked item
+ if (mItem->getType() == LLAssetType::AT_LINK)
+ {
+ mItem = gInventory.getItem(mItem->getAssetUUID());
+ if (mItem.isNull())
+ return;
+ }
+
+ mPlaceInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
+ mPlaceInfo->displayItemInfo(mItem);
+
+ LLLandmark* lm = gLandmarkList.getAsset(mItem->getAssetUUID(),
+ boost::bind(&LLPanelPlaces::onLandmarkLoaded, this, _1));
+ if (lm)
+ {
+ onLandmarkLoaded(lm);
+ }
+}
+
+void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark)
+{
+ LLUUID region_id;
+ landmark->getRegionID(region_id);
+ LLVector3d pos_global;
+ landmark->getGlobalPos(pos_global);
+ mPlaceInfo->displayParcelInfo(landmark->getRegionPos(),
+ region_id,
+ pos_global);
+}
+
void LLPanelPlaces::onFilterEdit(const std::string& search_string)
{
if (mFilterSubString != search_string)
@@ -212,12 +239,12 @@ void LLPanelPlaces::onTabSelected()
mActivePanel->updateVerbs();
}
+/*
void LLPanelPlaces::onShareButtonClicked()
{
// TODO: Launch the "Things" Share wizard
}
-/*
void LLPanelPlaces::onAddLandmarkButtonClicked()
{
LLFloaterReg::showInstance("add_landmark");
@@ -231,24 +258,64 @@ void LLPanelPlaces::onCopySLURLButtonClicked()
void LLPanelPlaces::onTeleportButtonClicked()
{
- mActivePanel->onTeleport();
+ if (mPlaceInfo->getVisible())
+ {
+ if (mPlaceInfoType == "landmark")
+ {
+ LLSD payload;
+ payload["asset_id"] = mItem->getAssetUUID();
+ LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload);
+ }
+ else if (mPlaceInfoType == "remote_place")
+ {
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if (!mPosGlobal.isExactlyZero() && worldmap_instance)
+ {
+ gAgent.teleportViaLocation(mPosGlobal);
+ worldmap_instance->trackLocation(mPosGlobal);
+ }
+ }
+ }
+ else
+ {
+ mActivePanel->onTeleport();
+ }
}
void LLPanelPlaces::onShowOnMapButtonClicked()
{
- if (mPlaceInfoType == "agent")
+ if (mPlaceInfo->getVisible())
{
- LLVector3d global_pos = gAgent.getPositionGlobal();
- if (!global_pos.isExactlyZero())
- {
- LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
- if(instance)
- {
- instance->trackLocation(global_pos);
- LLFloaterReg::showInstance("world_map", "center");
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if(!worldmap_instance)
+ return;
- }
+ if (mPlaceInfoType == "agent" ||
+ mPlaceInfoType == "create_landmark" ||
+ mPlaceInfoType == "remote_place")
+ {
+ if (!mPosGlobal.isExactlyZero())
+ {
+ worldmap_instance->trackLocation(mPosGlobal);
+ LLFloaterReg::showInstance("world_map", "center");
}
+ }
+ else if (mPlaceInfoType == "landmark")
+ {
+ LLLandmark* landmark = gLandmarkList.getAsset(mItem->getAssetUUID());
+ if (!landmark)
+ return;
+
+ LLVector3d landmark_global_pos;
+ if (!landmark->getGlobalPos(landmark_global_pos))
+ return;
+
+ if (!landmark_global_pos.isExactlyZero())
+ {
+ worldmap_instance->trackLocation(landmark_global_pos);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+ }
}
else
{
@@ -259,6 +326,11 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
void LLPanelPlaces::onBackButtonClicked()
{
togglePlaceInfoPanel(FALSE);
+
+ // Resetting mPlaceInfoType when Place Info panel is closed.
+ mPlaceInfoType = LLStringUtil::null;
+
+ updateVerbs();
}
void LLPanelPlaces::toggleMediaPanel()
@@ -268,6 +340,7 @@ void LLPanelPlaces::toggleMediaPanel()
mPlaceInfo->toggleMediaPanel(!mPlaceInfo->isMediaPanelVisible());
}
+
void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
if (!mPlaceInfo)
@@ -276,9 +349,6 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
mPlaceInfo->setVisible(visible);
mFilterEditor->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)
{
@@ -331,10 +401,48 @@ void LLPanelPlaces::changed(U32 mask)
void LLPanelPlaces::onAgentParcelChange()
{
- if (mPlaceInfo->getVisible() && mPlaceInfoType == "agent")
+ if (mPlaceInfo->getVisible() && (mPlaceInfoType == "agent" || mPlaceInfoType == "create_landmark"))
+ {
+ LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", mPlaceInfoType));
+ }
+ else
+ {
+ updateVerbs();
+ }
+}
+
+void LLPanelPlaces::updateVerbs()
+{
+ bool is_place_info_visible = mPlaceInfo->getVisible();
+ bool is_agent_place_info_visible = mPlaceInfoType == "agent";
+ if (is_place_info_visible)
+ {
+ if (is_agent_place_info_visible || mPlaceInfoType == "create_landmark")
+ {
+ // We don't need to teleport to the current location so disable the button
+ mTeleportBtn->setEnabled(FALSE);
+ }
+ else if (mPlaceInfoType == "landmark" || mPlaceInfoType == "remote_place")
+ {
+ mTeleportBtn->setEnabled(TRUE);
+ }
+
+ mShowOnMapBtn->setEnabled(TRUE);
+ }
+ else
{
- // Using timer to delay obtaining agent's coordinates
- // not to get the coordinates of previous parcel.
- new LLParcelUpdateTimer(.5);
+ mActivePanel->updateVerbs();
}
+
+ // Enable overflow button only when showing the information about agent's current location.
+ mOverflowBtn->setEnabled(is_place_info_visible && is_agent_place_info_visible);
}
+
+const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global)
+{
+ F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
+ F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
+
+ LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]);
+ return pos_local;
+}
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index e2ba4f39cd..c100ace8cc 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -41,6 +41,8 @@
#include "llinventorymodel.h"
#include "llpanelplaceinfo.h"
+class LLInventoryItem;
+class LLLandmark;
class LLPanelPlacesTab;
class LLFilterEditor;
class LLTabContainer;
@@ -55,38 +57,49 @@ public:
/*virtual*/ void changed(U32 mask);
/*virtual*/ void onOpen(const LLSD& key);
+ void setItem(LLInventoryItem* item);
+
+private:
+ void onLandmarkLoaded(LLLandmark* landmark);
void onFilterEdit(const std::string& search_string);
void onTabSelected();
+
//void onAddLandmarkButtonClicked();
//void onCopySLURLButtonClicked();
- void onShareButtonClicked();
+ //void onShareButtonClicked();
void onTeleportButtonClicked();
void onShowOnMapButtonClicked();
void onBackButtonClicked();
+
void toggleMediaPanel();
void togglePlaceInfoPanel(BOOL visible);
+
void onAgentParcelChange();
+ void updateVerbs();
-private:
- LLFilterEditor* mFilterEditor;
- LLPanelPlacesTab* mActivePanel;
- LLTabContainer* mTabContainer;
- LLPanelPlaceInfo* mPlaceInfo;
- std::string mFilterSubString;
-
- // 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();
- };
+ LLFilterEditor* mFilterEditor;
+ LLPanelPlacesTab* mActivePanel;
+ LLTabContainer* mTabContainer;
+ LLPanelPlaceInfo* mPlaceInfo;
+
+ //LLButton* mShareBtn;
+ LLButton* mTeleportBtn;
+ LLButton* mShowOnMapBtn;
+ LLButton* mOverflowBtn;
+
+ // Pointer to a landmark item or to a linked landmark
+ LLPointer<LLInventoryItem> mItem;
+
+ // Absolute position of the location for teleport, may not
+ // be available (hence zero)
+ LLVector3d mPosGlobal;
+
+ // Search string for filtering landmarks and teleport
+ // history locations
+ std::string mFilterSubString;
+
+ // Information type currently shown in Place Information panel
+ std::string mPlaceInfoType;
};
#endif //LL_LLPANELPLACES_H
diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp
index e5b1f04064..7c0a7b0cc4 100644
--- a/indra/newview/llpanelplacestab.cpp
+++ b/indra/newview/llpanelplacestab.cpp
@@ -41,6 +41,14 @@
#include "llslurl.h"
#include "llworldmap.h"
+bool LLPanelPlacesTab::isTabVisible()
+{
+ LLUICtrl* parent = getParentUICtrl();
+ if (!parent) return false;
+ if (!parent->getVisible()) return false;
+ return true;
+}
+
void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel)
{
//mShareBtn = panel->getChild<LLButton>("share_btn");
diff --git a/indra/newview/llpanelplacestab.h b/indra/newview/llpanelplacestab.h
index c098302d1a..1c70869414 100644
--- a/indra/newview/llpanelplacestab.h
+++ b/indra/newview/llpanelplacestab.h
@@ -49,6 +49,8 @@ public:
virtual void onTeleport() = 0;
//virtual void onCopySLURL() = 0;
+ bool isTabVisible(); // Check if parent TabContainer is visible.
+
void setPanelPlacesButtons(LLPanelPlaces* panel);
void onRegionResponse(const LLVector3d& landmark_global_pos,
U64 region_handle,
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 77edae261b..51cd05376a 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -143,6 +143,9 @@ void LLTeleportHistoryPanel::onCopySLURL()
// virtual
void LLTeleportHistoryPanel::updateVerbs()
{
+ if (!isTabVisible())
+ return;
+
S32 index = 0;
S32 cur_item = 0;
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 78091ef05b..5dca12e06b 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -37,31 +37,36 @@
#include "lltextbox.h"
#include "llscreenchannel.h"
+#include "llviewercontrol.h"
+
#include <algorithm>
using namespace LLNotificationsUI;
-#define TOAST_MARGIN 5
-#define BOTTOMPANEL_MARGIN 35
-#define NAVBAR_MARGIN 60
-
+bool LLScreenChannel::mWasStartUpToastShown = false;
//--------------------------------------------------------------------------
LLScreenChannel::LLScreenChannel(): mUnreadToastsPanel(NULL),
mToastAlignment(NA_BOTTOM),
mStoreToasts(true),
+ mHiddenToastsNum(0),
mOverflowToastHidden(false),
mIsHovering(false),
mControlHovering(false)
{
setFollows(FOLLOWS_RIGHT | FOLLOWS_BOTTOM | FOLLOWS_TOP);
+
+ //TODO: load as a resource string
+ mOverflowFormatString = "You have %d more notification";
+
+ setMouseOpaque( false );
}
-void LLScreenChannel::init(S32 channel_position, LLView* root_view)
+void LLScreenChannel::init(S32 channel_left, S32 channel_right)
{
- root_view->addChild(this);
- setRect( LLRect(channel_position, root_view->getRect().getHeight() - NAVBAR_MARGIN,
- channel_position, root_view->getRect().mBottom + BOTTOMPANEL_MARGIN));
+ S32 channel_top = getRootView()->getRect().getHeight() - gSavedSettings.getS32("NavBarMargin");
+ S32 channel_bottom = getRootView()->getRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
+ setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
}
@@ -79,7 +84,7 @@ void LLScreenChannel::reshape(S32 width, S32 height, BOOL called_from_parent)
}
//--------------------------------------------------------------------------
-LLToast* LLScreenChannel::addToast(LLUUID id, LLPanel* panel)
+LLToast* LLScreenChannel::addToast(LLUUID id, LLPanel* panel, bool is_not_tip)
{
ToastElem new_toast_elem(id, panel);
@@ -92,7 +97,29 @@ LLToast* LLScreenChannel::addToast(LLUUID id, LLPanel* panel)
{
new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));
}
- showToasts();
+
+ // don't show toasts until StartUp toast will fade, but show alerts
+ if(!mWasStartUpToastShown && mToastAlignment != NA_CENTRE)
+ {
+ new_toast_elem.toast->stopTimer();
+ // Count and store only non tip notifications
+ if(is_not_tip)
+ {
+ mHiddenToastsNum++;
+ storeToast(new_toast_elem);
+ }
+ else
+ {
+ // destroy tip toasts at once
+ new_toast_elem.toast->close();
+ }
+ // remove toast from channel
+ mToastList.pop_back();
+ }
+ else
+ {
+ showToasts();
+ }
return new_toast_elem.toast;
}
@@ -213,10 +240,20 @@ void LLScreenChannel::showToastsBottom()
}
toast_rect = (*it).toast->getRect();
- toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+TOAST_MARGIN, toast_rect.getWidth() ,toast_rect.getHeight());
+ toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());
(*it).toast->setRect(toast_rect);
- if((*it).toast->getRect().mTop > getRect().getHeight())
+ bool stop_showing_toasts = (*it).toast->getRect().mTop > getRect().getHeight();
+
+ if(!stop_showing_toasts)
+ {
+ if( it != mToastList.rend()-1)
+ {
+ stop_showing_toasts = ((*it).toast->getRect().mTop + gSavedSettings.getS32("OverflowToastHeight") + gSavedSettings.getS32("ToastMargin")) > getRect().getHeight();
+ }
+ }
+
+ if(stop_showing_toasts)
break;
(*it).toast->setVisible(TRUE);
@@ -243,7 +280,7 @@ void LLScreenChannel::showToastsCentre()
for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
{
toast_rect = (*it).toast->getRect();
- toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + TOAST_MARGIN, toast_rect.getWidth() ,toast_rect.getHeight());
+ toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());
(*it).toast->setRect(toast_rect);
(*it).toast->setVisible(TRUE);
@@ -256,7 +293,7 @@ void LLScreenChannel::showToastsTop()
}
//--------------------------------------------------------------------------
-void LLScreenChannel::createOverflowToast(S32 bottom)
+void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer)
{
LLRect toast_rect;
mUnreadToastsPanel = new LLToast(NULL);
@@ -266,21 +303,29 @@ void LLScreenChannel::createOverflowToast(S32 bottom)
mUnreadToastsPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this));
- LLTextBox* text_box = mUnreadToastsPanel->getChild<LLTextBox>("text");
+ LLTextBox* text_box = mUnreadToastsPanel->getChild<LLTextBox>("toast_text");
LLIconCtrl* icon = mUnreadToastsPanel->getChild<LLIconCtrl>("icon");
+ std::string text = llformat(mOverflowFormatString.c_str(),mHiddenToastsNum);
+ if(mHiddenToastsNum == 1)
+ {
+ text += ".";
+ }
+ else
+ {
+ text += "s.";
+ }
- std::string toastsNumStr = llformat("%d", mHiddenToastsNum);
- std::string text = "You have " + toastsNumStr + " new notifications.";
+ toast_rect = mUnreadToastsPanel->getRect();
+ mUnreadToastsPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true);
+ toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight());
+ mUnreadToastsPanel->setRect(toast_rect);
+ mUnreadToastsPanel->setAndStartTimer(timer ? timer : gSavedSettings.getS32("NotificationToastTime"));
+ getRootView()->addChild(mUnreadToastsPanel);
- text_box->setText(text);
+ text_box->setValue(text);
text_box->setVisible(TRUE);
icon->setVisible(TRUE);
- toast_rect = mUnreadToastsPanel->getRect();
- toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+TOAST_MARGIN, toast_rect.getWidth() ,toast_rect.getHeight());
- mUnreadToastsPanel->setRect(toast_rect);
- mUnreadToastsPanel->setAndStartTimer(5);
- getRootView()->addChild(mUnreadToastsPanel);
mUnreadToastsPanel->setVisible(TRUE);
}
@@ -288,6 +333,7 @@ void LLScreenChannel::createOverflowToast(S32 bottom)
void LLScreenChannel::onOverflowToastHide()
{
mOverflowToastHidden = true;
+ onCommit();
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index 5a9946f772..f05c205e2a 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -54,14 +54,15 @@ typedef enum e_notification_toast_alignment
*/
class LLScreenChannel : public LLUICtrl
{
+ friend class LLChannelManager;
public:
LLScreenChannel();
virtual ~LLScreenChannel();
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- LLToast* addToast(LLUUID id, LLPanel* panel);
- void init(S32 channel_position, LLView* root_view);
+ LLToast* addToast(LLUUID id, LLPanel* panel, bool is_not_tip = true);
+ void init(S32 channel_left, S32 channel_right);
void killToastByNotificationID(LLUUID id);
void modifyToastByNotificationID(LLUUID id, LLPanel* panel);
@@ -79,8 +80,15 @@ public:
void showToasts();
+ S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;}
+ void setNumberOfHiddenToasts(S32 num) { mHiddenToastsNum = num;}
+
+ static void setStartUpToastShown() { mWasStartUpToastShown = true; }
+
e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
+ void setOverflowFormatString ( std::string str) { mOverflowFormatString = str; }
+
private:
struct ToastElem
{
@@ -117,9 +125,10 @@ private:
void showToastsCentre();
void showToastsTop();
- void createOverflowToast(S32 bottom);
+ void createOverflowToast(S32 bottom, F32 timer = 0);
void onOverflowToastHide();
+ static bool mWasStartUpToastShown;
bool mControlHovering;
bool mIsHovering;
bool mStoreToasts;
@@ -130,6 +139,8 @@ private:
std::vector<ToastElem> mStoredToastList;
e_notification_toast_alignment mToastAlignment;
std::map<LLToast*, bool> mToastEventStack;
+
+ std::string mOverflowFormatString;
};
}
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index abcff7cfb1..2688399139 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -63,24 +63,11 @@ LLSideTray* LLSideTray::sInstance = 0;
class LLSideTrayInfoPanel: public LLPanel
{
-protected:
- LLSideTrayInfoPanel(){}
+
public:
- static LLSideTrayInfoPanel* createInstance(const string& image, const string& name,const string& description)
- {
- LLSideTrayInfoPanel* panel = new LLSideTrayInfoPanel();
- LLUICtrlFactory::getInstance()->buildPanel(panel,"panel_sidetray_tab_info.xml");
- if(panel)
- panel->setData(image, name,description);
- panel->setBorderVisible(true);
- return panel;
-
- }
- void setData(const string& image, const string& name,const string& description)
+ LLSideTrayInfoPanel():LLPanel()
{
- getChild<LLTextBox>("tab_name",false,false)->setValue(name);
- getChild<LLTextBox>("tab_description",false,false)->setValue(description);
- getChild<LLIconCtrl>("tab_icon",false,false)->setValue(image);
+ setBorderVisible(true);
}
BOOL handleHover(S32 x, S32 y, MASK mask)
@@ -91,12 +78,19 @@ public:
BOOL handleMouseUp(S32 x, S32 y, MASK mask)
{
+ std::string name = getName();
onCommit();
+ LLSideTray::getInstance()->selectTabByName(name);
return LLPanel::handleMouseUp(x,y,mask);
}
+ void reshape (S32 width, S32 height, BOOL called_from_parent )
+ {
+ return LLPanel::reshape(width, height, called_from_parent);
+ }
};
+static LLRegisterPanelClassWrapper<LLSideTrayInfoPanel> t_people("panel_sidetray_home_info");
LLSideTray* LLSideTray::getInstance()
{
@@ -113,7 +107,7 @@ bool LLSideTray::instanceCreated ()
return sInstance!=0;
}
-LLSideTrayTab::LLSideTrayTab(const Params& params):mAccordionCtrl(0)
+LLSideTrayTab::LLSideTrayTab(const Params& params):mMainPanel(0)
{
mImagePath = params.image_path;
@@ -124,30 +118,12 @@ LLSideTrayTab::~LLSideTrayTab()
{
}
-void LLSideTrayTab::addPanel(LLPanel* panel)
-{
- //addChild(panel,false);
-}
-
bool LLSideTrayTab::addChild(LLView* view, S32 tab_group)
{
- if(mAccordionCtrl == 0)
- {
- mAccordionCtrl = new LLAccordionCtrl();
- mAccordionCtrl->setVisible(TRUE);
- LLPanel::addChild(mAccordionCtrl,tab_group);
- }
-
-
- bool res = true;
- if(TAB_PANEL_CAPTION_NAME != view->getName())//skip our caption panel
- {
- mAccordionCtrl->addCollapsibleCtrl(view);
- }
- else
- res = LLPanel::addChild(view,tab_group);
-
- return res;
+ if(mMainPanel == 0 && TAB_PANEL_CAPTION_NAME != view->getName())//skip our caption panel
+ mMainPanel = view;
+ return LLPanel::addChild(view,tab_group);
+ //return res;
}
@@ -185,17 +161,18 @@ void LLSideTrayTab::arrange(S32 width, S32 height )
offset = title_panel->getRect().getHeight();
}
- LLRect sRect = mAccordionCtrl->getRect();
+ LLRect sRect = mMainPanel->getRect();
sRect.setLeftTopAndSize( splitter_margin, height - offset - splitter_margin, width - 2*splitter_margin, height - offset - 2*splitter_margin);
- mAccordionCtrl->setRect(sRect);
+ mMainPanel->reshape(sRect.getWidth(),sRect.getHeight());
+ mMainPanel->setRect(sRect);
+
+
- mAccordionCtrl->setMaxWidth(sRect.getWidth());
- mAccordionCtrl->arrange();
}
void LLSideTrayTab::reshape (S32 width, S32 height, BOOL called_from_parent )
{
- if(!mAccordionCtrl)
+ if(!mMainPanel)
return;
S32 offset = 0;
@@ -210,12 +187,12 @@ void LLSideTrayTab::reshape (S32 width, S32 height, BOOL called_from_parent )
- LLRect sRect = mAccordionCtrl->getRect();
+ LLRect sRect = mMainPanel->getRect();
sRect.setLeftTopAndSize( splitter_margin, height - offset - splitter_margin, width - 2*splitter_margin, height - offset - 2*splitter_margin);
- mAccordionCtrl->setMaxWidth(sRect.getWidth());
- mAccordionCtrl->reshape(sRect.getWidth(), sRect.getHeight());
+ //mMainPanel->setMaxWidth(sRect.getWidth());
+ mMainPanel->reshape(sRect.getWidth(), sRect.getHeight());
- mAccordionCtrl->setRect(sRect);
+ mMainPanel->setRect(sRect);
}
@@ -231,7 +208,9 @@ void LLSideTrayTab::draw()
void LLSideTrayTab::onOpen (const LLSD& key)
{
- mAccordionCtrl->onOpen(key);
+ LLPanel* panel = dynamic_cast<LLPanel*>(mMainPanel);
+ if(panel)
+ panel->onOpen(key);
}
LLSideTrayTab* LLSideTrayTab::createInstance ()
@@ -251,7 +230,6 @@ LLSideTray::LLSideTray(Params& params)
,mCollapsed(false)
,mCollapseButton(0)
,mMaxBarWidth(params.rect.width)
- ,mHomeTab(0)
{
mCollapsed=params.collapsed;
}
@@ -261,10 +239,8 @@ BOOL LLSideTray::postBuild()
{
createButtons();
- createHomeTab();
-
arrange();
- selectTabByName("home_tab");
+ selectTabByName("sidebar_home");
if(mCollapsed)
collapseSideBar();
@@ -333,8 +309,6 @@ bool LLSideTray::selectTabByIndex(size_t index)
bool LLSideTray::selectTabByName (const std::string& name)
{
LLSideTrayTab* side_bar = getTab(name);
- if(side_bar == 0 && name == "home_tab")
- side_bar = mHomeTab;
if(side_bar == NULL || side_bar == mActiveTab)
return false;
@@ -416,9 +390,10 @@ void LLSideTray::createButtons ()
mCollapseButton = createButton(EXPANDED_NAME,"",boost::bind(&LLSideTray::onToggleCollapse, this));
//create buttons for tabs
- child_vector_const_iter_t child_it;
+ child_vector_const_iter_t child_it = mTabs.begin();
+ ++child_it;
- for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
+ for ( ; child_it != mTabs.end(); ++child_it)
{
LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(*child_it);
if(sidebar_tab == NULL)
@@ -445,7 +420,7 @@ void LLSideTray::onToggleCollapse()
if(mCollapsed)
{
expandSideBar();
- selectTabByName("home_tab");
+ selectTabByName("sidebar_home");
}
else
collapseSideBar();
@@ -517,10 +492,6 @@ void LLSideTray::arrange ()
sidebar_tab->setRect(ctrl_rect);
sidebar_tab->arrange(mMaxBarWidth,getRect().getHeight());
}
-
- mHomeTab->setRect(ctrl_rect);
- mHomeTab->arrange(mMaxBarWidth,getRect().getHeight());
-
}
void LLSideTray::collapseSideBar ()
@@ -619,19 +590,16 @@ void LLSideTray::reshape (S32 width, S32 height, BOOL called_from_parent)
sidebar_tab->setRect(ctrl_rect);
}
-
- mHomeTab->reshape(mMaxBarWidth,getRect().getHeight());
- ctrl_rect.setLeftTopAndSize(sidetray_params.default_button_width,getRect().getHeight(),mMaxBarWidth,getRect().getHeight());
- mHomeTab->setRect(ctrl_rect);
-
-
}
/**
* Activate tab with "panel_name" panel
- * if no such tab - return false, otherwise true
+ * if no such tab - return false, otherwise true.
+ * TODO* In some cases a pointer to a panel of
+ * a specific class may be needed so this method
+ * would need to use templates.
*/
-bool LLSideTray::showPanel (const std::string& panel_name, const LLSD& params)
+LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& params)
{
//arrange tabs
child_vector_const_iter_t child_it;
@@ -644,51 +612,12 @@ bool LLSideTray::showPanel (const std::string& panel_name, const LLSD& params)
LLPanel* panel = dynamic_cast<LLPanel*>(view);
if(panel)
panel->onOpen(params);
- return true;
+ return panel;
}
}
- return false;
+ return NULL;
}
-void LLSideTray::createHomeTab()
-{
- mHomeTab = LLSideTrayTab::createInstance();
- child_vector_iter_t child_it;
- for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
- {
- LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(*child_it);
- if(sidebar_tab == NULL)
- continue;
-
- LLPanel* panel = LLSideTrayInfoPanel::createInstance(sidebar_tab->mImagePath,sidebar_tab->getTabTitle(),sidebar_tab->getDescription());
-
- panel->setCommitCallback(boost::bind(&LLSideTray::onTabButtonClick, this, sidebar_tab->getName()));
-
- LLAccordionCtrlTab::Params panel_params;
- panel_params.display_children(true);
- panel_params.collapsible(false);
- panel_params.header_visible(false);
- panel_params.can_resize(false);
- panel_params.min_height(200);
- panel_params.padding_left(10);
- panel_params.padding_right(10);
- panel_params.padding_top(5);
- panel_params.padding_bottom(5);
- panel_params.name(sidebar_tab->getTabTitle());
-
- LLAccordionCtrlTab* ctrl = LLUICtrlFactory::create<LLAccordionCtrlTab>(panel_params);
-
-
- ctrl->setPanel(panel);
- ctrl->postBuild();
- mHomeTab->addChild(ctrl,0);
- }
-
- mHomeTab->setBackgroundVisible(true);
- mHomeTab->postBuild();
-
- LLUICtrl::addChild(mHomeTab, 0);
-}
static const S32 fake_offset = 132;
static const S32 fake_top_offset = 78;
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index 7b1f4aee04..99e84f8141 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -65,7 +65,6 @@ protected:
public:
virtual ~LLSideTrayTab();
- void addPanel (LLPanel* panel);
/*virtual*/ BOOL postBuild ();
/*virtual*/ bool addChild (LLView* view, S32 tab_group);
@@ -87,7 +86,7 @@ private:
std::string mImagePath;
std::string mDescription;
- LLAccordionCtrl* mAccordionCtrl;
+ LLView* mMainPanel;
};
@@ -163,9 +162,9 @@ public:
/**
* Activate tab with "panel_name" panel
- * if no such tab - return false, otherwise true
+ * if no such tab - return NULL, otherwise a pointer to the panel
*/
- bool showPanel (const std::string& panel_name, const LLSD& params);
+ LLPanel* showPanel (const std::string& panel_name, const LLSD& params);
/*
* collapse SideBar, hiding visible tab and moving tab buttons
@@ -209,7 +208,6 @@ protected:
void createButtons ();
LLButton* createButton (const std::string& name,const std::string& image,LLUICtrl::commit_callback_t callback);
- void createHomeTab ();
void arrange ();
void reflectCollapseChange();
@@ -223,7 +221,6 @@ private:
std::map<std::string,LLButton*> mTabButtons;
child_vector_t mTabs;
- LLSideTrayTab* mHomeTab;
LLSideTrayTab* mActiveTab;
LLButton* mCollapseButton;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index d0432e7961..3410a1eb68 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -871,8 +871,6 @@ bool idle_startup()
gDirUtilp->setLindenUserDir(firstname, lastname);
LLFile::mkdir(gDirUtilp->getLindenUserDir());
- LLLocationHistory::getInstance()->load();
-
// Set PerAccountSettingsFile to the default value.
gSavedSettings.setString("PerAccountSettingsFile",
gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,
@@ -2517,6 +2515,8 @@ bool idle_startup()
// reset timers now that we are running "logged in" logic
LLFastTimer::reset();
+ LLLocationHistory::getInstance()->load();
+
return TRUE;
}
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 9144f9c3e0..6f5b25214e 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -104,6 +104,7 @@ bool LLToast::timerHasExpired()
if (mTimer.getStarted())
{
F32 elapsed_time = mTimer.getElapsedTimeF32();
+ // after 4 seconds a toast should start fade
if (elapsed_time > 4)
{
setBackgroundOpaque(FALSE);
@@ -119,7 +120,7 @@ bool LLToast::timerHasExpired()
//--------------------------------------------------------------------------
void LLToast::hide()
{
- setVisible(FALSE); //TODO: store in Chiclet's history
+ setVisible(FALSE);
mIsViewed = false;
mTimer.stop();
mOnFade(this, LLSD());
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 2e2ac5b36c..018664f3d1 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -68,6 +68,7 @@ public:
void setAndStartTimer(F32 period);
//
void resetTimer() { mTimer.start(); }
+ void stopTimer() { mTimer.stop(); }
void close() { die(); }
virtual void draw();
virtual void setVisible(BOOL show);
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 83c25ddc77..f5ed7f8710 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -51,6 +51,8 @@
#include "llglheaders.h"
#include "llagent.h"
#include "llavatariconctrl.h"
+#include "llfloaterinventory.h"
+#include "llinventorytype.h"
LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)
: LLToastPanel(notification),
@@ -64,6 +66,8 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
llwarns << "Group notice for unkown group: " << payload["group_id"].asUUID() << llendl;
}
+ static const LLUIColor textColor = LLUIColorTable::instance().getColor("GroupNotifyTextColor");
+
//group icon
LLIconCtrl* pGroupIcon = getChild<LLIconCtrl>("group_icon", TRUE);
pGroupIcon->setValue(groupData.mInsigniaID);
@@ -76,11 +80,36 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
pTitleText->setValue(from.str());
//message body
+ const std::string& subject = payload["subject"].asString();
const std::string& message = payload["message"].asString();
+
LLTextEditor* pMessageText = getChild< LLTextEditor>("message", TRUE, FALSE);
+ pMessageText->setValue("");
pMessageText->setEnabled(FALSE);
pMessageText->setTakesFocus(FALSE);
- pMessageText->setValue(message);
+
+ static const LLStyleSP headerstyle(new LLStyle(true, textColor,
+ "SansSerifBig"));
+ static const LLStyleSP datestyle(new LLStyle(true, textColor, "serif"));
+
+ pMessageText->appendStyledText(subject + "\n",false,false,headerstyle);
+
+ std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],["
+ +LLTrans::getString("UTCTimeDay")+"] ["
+ +LLTrans::getString("UTCTimeMth")+"] ["
+ +LLTrans::getString("UTCTimeYr")+"] ["
+ +LLTrans::getString("UTCTimeHr")+"]:["
+ +LLTrans::getString("UTCTimeMin")+"]:["
+ +LLTrans::getString("UTCTimeSec")+"] ["
+ +LLTrans::getString("UTCTimeTimezone")+"]";
+ const LLDate timeStamp = notification->getDate();
+ LLDate notice_date = timeStamp.notNull() ? timeStamp : LLDate::now();
+ LLSD substitution;
+ substitution["datetime"] = (S32) notice_date.secondsSinceEpoch();
+ LLStringUtil::format(timeStr, substitution);
+ pMessageText->appendStyledText(timeStr, false, false, datestyle);
+ pMessageText->appendColoredText(std::string("\n\n") + message, false,
+ false, textColor);
//attachment
BOOL hasInventory = payload["inventory_offer"].isDefined();
@@ -91,6 +120,13 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
mInventoryOffer = new LLOfferInfo(payload["inventory_offer"]);
childSetActionTextbox("attachment", boost::bind(
&LLToastGroupNotifyPanel::onClickAttachment, this));
+
+ //attachment icon
+ LLIconCtrl* pAttachIcon = getChild<LLIconCtrl>("attachment_icon", TRUE);
+ LLUIImagePtr attachIconImg = get_item_icon(mInventoryOffer->mType,
+ LLInventoryType::IT_TEXTURE,
+ 0, FALSE);
+ pAttachIcon->setValue(attachIconImg->getName());
}
//ok button
@@ -128,10 +164,43 @@ void LLToastGroupNotifyPanel::onClickOk()
void LLToastGroupNotifyPanel::onClickAttachment()
{
- mInventoryOffer->forceResponse(IOR_ACCEPT);
+ if (mInventoryOffer != NULL) {
+ mInventoryOffer->forceResponse(IOR_ACCEPT);
- mInventoryOffer = NULL;
+ LLTextBox * pAttachLink = getChild<LLTextBox> ("attachment", TRUE,
+ FALSE);
+ static const LLUIColor textColor = LLUIColorTable::instance().getColor(
+ "GroupNotifyDimmedTextColor");
+ pAttachLink->setColor(textColor);
- LLTextBox * pAttachLink = getChild<LLTextBox>("attachment", TRUE, FALSE);
- pAttachLink->setVisible(FALSE);
+ LLIconCtrl* pAttachIcon =
+ getChild<LLIconCtrl> ("attachment_icon", TRUE);
+ pAttachIcon->setEnabled(FALSE);
+
+ //if attachment isn't openable - notify about saving
+ if (!isAttachmentOpenable(mInventoryOffer->mType)) {
+ LLNotifications::instance().add("AttachmentSaved");
+ }
+
+ mInventoryOffer = NULL;
+ }
}
+
+//static
+bool LLToastGroupNotifyPanel::isAttachmentOpenable(LLAssetType::EType type)
+{
+ switch(type)
+ {
+ case LLAssetType::AT_LANDMARK:
+ case LLAssetType::AT_FAVORITE:
+ case LLAssetType::AT_NOTECARD:
+ case LLAssetType::AT_IMAGE_JPEG:
+ case LLAssetType::AT_IMAGE_TGA:
+ case LLAssetType::AT_TEXTURE:
+ case LLAssetType::AT_TEXTURE_TGA:
+ return true;
+ default:
+ return false;
+ }
+}
+
diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h
index f00f840e94..ba98531251 100644
--- a/indra/newview/lltoastgroupnotifypanel.h
+++ b/indra/newview/lltoastgroupnotifypanel.h
@@ -66,6 +66,7 @@ protected:
void onClickOk();
void onClickAttachment();
private:
+ static bool isAttachmentOpenable(LLAssetType::EType);
LLButton* mSaveInventoryBtn;
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index dd37d41ff5..72812d0bb9 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1606,6 +1606,8 @@ void LLToolDragAndDrop::commitGiveInventoryItem(const LLUUID& to_agent,
gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args);
}
+ // add buddy to recent people list
+ LLRecentPeople::instance().add(to_agent);
}
void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent,
@@ -1730,6 +1732,9 @@ void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent,
llinfos << "LLToolDragAndDrop::commitGiveInventoryCategory() - "
<< cat->getUUID() << llendl;
+ // add buddy to recent people list
+ LLRecentPeople::instance().add(to_agent);
+
// Test out how many items are being given.
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index acb7f927b6..9fb6d1c874 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -43,6 +43,7 @@
#include "llfloaterurldisplay.h"
#include "llfloaterworldmap.h"
#include "llpanellogin.h"
+#include "llsidetray.h"
#include "llslurl.h"
#include "llstartup.h" // gStartupState
#include "llurlsimstring.h"
@@ -202,8 +203,9 @@ bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mous
S32 z = 0;
LLURLSimString::parse(sim_string, &region_name, &x, &y, &z);
- LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD());
- if(url_displayp) url_displayp->setName(region_name);
+ // LLFloaterURLDisplay functionality moved to LLPanelPlaces in Side Tray.
+ //LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD());
+ //if(url_displayp) url_displayp->setName(region_name);
// Request a region handle by name
LLWorldMap::getInstance()->sendNamedRegionRequest(region_name,
@@ -274,12 +276,11 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::str
local_pos.mV[VY] = (F32)local_y;
local_pos.mV[VZ] = (F32)z;
-
+ LLVector3d global_pos = from_region_handle(region_handle);
+ global_pos += LLVector3d(local_pos);
if (teleport)
- {
- LLVector3d global_pos = from_region_handle(region_handle);
- global_pos += LLVector3d(local_pos);
+ {
gAgent.teleportViaLocation(global_pos);
LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
if(instance)
@@ -289,18 +290,28 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::str
}
else
{
- // display informational floater, allow user to click teleport btn
- LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD());
- if(url_displayp)
- {
- url_displayp->displayParcelInfo(region_handle, local_pos);
- if(snapshot_id.notNull())
- {
- url_displayp->setSnapshotDisplay(snapshot_id);
- }
- std::string locationString = llformat("%s %d, %d, %d", region_name.c_str(), x, y, z);
- url_displayp->setLocationString(locationString);
- }
+ LLSD key;
+ key["type"] = "remote_place";
+ key["x"] = global_pos.mdV[VX];
+ key["y"] = global_pos.mdV[VY];
+ key["z"] = global_pos.mdV[VZ];
+
+ LLSideTray::getInstance()->showPanel("panel_places", key);
+
+ // LLFloaterURLDisplay functionality moved to LLPanelPlaces in Side Tray.
+
+// // display informational floater, allow user to click teleport btn
+// LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD());
+// if(url_displayp)
+// {
+// url_displayp->displayParcelInfo(region_handle, local_pos);
+// if(snapshot_id.notNull())
+// {
+// url_displayp->setSnapshotDisplay(snapshot_id);
+// }
+// std::string locationString = llformat("%s %d, %d, %d", region_name.c_str(), x, y, z);
+// url_displayp->setLocationString(locationString);
+// }
}
}
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index 62ed861c86..4155a87e14 100644
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -46,7 +46,7 @@
#include "llviewermessage.h" // send_guid_sound_trigger
#include "llviewernetwork.h"
#include "llagent.h"
-#include "llbottomtray.h"
+#include "llnearbychatbar.h"
// Globals
LLViewerGestureList gGestureList;
@@ -136,7 +136,7 @@ void LLViewerGesture::doTrigger( BOOL send_chat )
{
// Don't play nodding animation, since that might not blend
// with the gesture animation.
- LLBottomTray::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
+ LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
}
}
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index 63234c2990..4e0c4023fd 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 "llbottomtray.h"
+#include "llnearbychatbar.h"
#include "llviewercontrol.h"
#include "llfocusmgr.h"
#include "llmorphview.h"
@@ -500,7 +500,7 @@ void stop_moving( EKeystate s )
void start_chat( EKeystate s )
{
// start chat
- LLBottomTray::startChat(NULL);
+ LLNearbyChatBar::startChat(NULL);
}
void start_gesture( EKeystate s )
@@ -508,15 +508,15 @@ void start_gesture( EKeystate s )
if (KEYSTATE_UP == s &&
!(gFocusMgr.getKeyboardFocus() && gFocusMgr.getKeyboardFocus()->acceptsTextInput()))
{
- if (LLBottomTray::getInstance()->getCurrentChat().empty())
+ if (LLNearbyChatBar::getInstance()->getCurrentChat().empty())
{
// No existing chat in chat editor, insert '/'
- LLBottomTray::getInstance()->startChat("/");
+ LLNearbyChatBar::startChat("/");
}
else
{
// Don't overwrite existing text in chat editor
- LLBottomTray::getInstance()->startChat(NULL);
+ LLNearbyChatBar::startChat(NULL);
}
}
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index e06e180ed5..7071b65228 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -132,6 +132,7 @@
#include "llfloatermemleak.h"
#include "llfasttimerview.h"
#include "llavataractions.h"
+#include "lllandmarkactions.h"
#include "llmemoryview.h"
#include "llgivemoney.h"
#include "llgroupmgr.h"
@@ -5270,24 +5271,6 @@ class LLWorldSetBusy : public view_listener_t
}
};
-bool can_create_landmark()
-{
- BOOL can = FALSE;
-
- LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (agent_parcel)
-{
-
- if (agent_parcel->getAllowLandmark()
- || LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
- {
- can = TRUE;
- }
- }
-
- return can;
-}
-
class LLWorldCreateLandmark : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -6675,9 +6658,7 @@ class LLWorldEnableCreateLandmark : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = can_create_landmark();
-
- return new_value;
+ return !LLLandmarkActions::landmarkAlreadyExists();
}
};
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 74ded99124..25c00bb816 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -209,6 +209,10 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
LLUUID fid;
LLMessageSystem* msg = gMessageSystem;
const LLSD& payload = notification["payload"];
+
+ // add friend to recent people list
+ LLRecentPeople::instance().add(payload["from_id"]);
+
switch(option)
{
case 0:
@@ -1180,6 +1184,9 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
{
opener = open_agent_offer;
}
+
+ // add buddy to recent people list
+ LLRecentPeople::instance().add(mFromID);
}
break;
case IM_TASK_INVENTORY_OFFERED:
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 65f341627a..3aefa84295 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -765,13 +765,17 @@ BOOL LLViewerParcelMgr::canHearSound(const LLVector3d &pos_global) const
BOOL LLViewerParcelMgr::inAgentParcel(const LLVector3d &pos_global) const
{
LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(pos_global);
- if (region != gAgent.getRegion())
+ LLViewerRegion* agent_region = gAgent.getRegion();
+ if (!region || !agent_region)
+ return FALSE;
+
+ if (region != agent_region)
{
// Can't be in the agent parcel if you're not in the same region.
return FALSE;
}
- LLVector3 pos_region = gAgent.getRegion()->getPosRegionFromGlobal(pos_global);
+ LLVector3 pos_region = agent_region->getPosRegionFromGlobal(pos_global);
S32 row = S32(pos_region.mV[VY] / PARCEL_GRID_STEP_METERS);
S32 column = S32(pos_region.mV[VX] / PARCEL_GRID_STEP_METERS);
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 902b59c732..0fadba1364 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -47,11 +47,13 @@
#include "llfloateravatarinfo.h"
#include "llfloaterworldmap.h"
#include "llnotify.h"
+#include "llpanelplaces.h"
#include "llpreview.h"
#include "llpreviewtexture.h"
#include "llpreviewnotecard.h"
#include "llpreviewlandmark.h"
#include "llscrollbar.h"
+#include "llsidetray.h"
#include "lltooldraganddrop.h"
#include "lltrans.h"
#include "llviewercontrol.h"
@@ -1365,11 +1367,22 @@ void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item, llwchar wc
{
if (!item)
return;
- LLPreviewLandmark* preview = LLFloaterReg::showTypedInstance<LLPreviewLandmark>("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES);
- if (preview)
+
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = item->getUUID();
+
+ LLPanelPlaces *panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->showPanel("panel_places", key));
+ if (panel)
{
- preview->setItem( item );
+ panel->setItem(item);
}
+
+// LLPreviewLandmark* preview = LLFloaterReg::showTypedInstance<LLPreviewLandmark>("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES);
+// if (preview)
+// {
+// preview->setItem( item );
+// }
}
void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item, llwchar wc )
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index a949830dcf..533889b2f7 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -878,7 +878,10 @@ void LLViewerFetchedTexture::init(bool firstinit)
LLViewerFetchedTexture::~LLViewerFetchedTexture()
{
- if (mHasFetcher)
+ //*NOTE getTextureFetch can return NULL when Viewer is shutting down.
+ // This is due to LLWearableList is singleton and is destroyed after
+ // LLAppViewer::cleanup() was called. (see ticket EXT-177)
+ if (mHasFetcher && LLAppViewer::getTextureFetch())
{
LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 3e86f48cc5..f312cc0f63 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -184,6 +184,7 @@
#include "llviewernetwork.h"
#include "llpostprocess.h"
#include "llbottomtray.h"
+#include "llnearbychatbar.h"
#include "llnotificationmanager.h"
@@ -1559,10 +1560,12 @@ void LLViewerWindow::initWorldUI()
getRootView()->sendChildToFront(gSnapshotFloaterView);
// new bottom panel
+ getRootView()->addChild(LLBottomTray::getInstance());
+ // Make sure Bottom Tray is behind Side Tray regardless "addChild" order.
+ getRootView()->sendChildToBack(LLBottomTray::getInstance());
LLRect rc = LLBottomTray::getInstance()->getRect();
rc.mLeft = 0;
rc.mRight = mRootView->getRect().getWidth();
- mRootView->addChild(LLBottomTray::getInstance());
LLBottomTray::getInstance()->reshape(rc.getWidth(),rc.getHeight(),FALSE);
LLBottomTray::getInstance()->setRect(rc);
@@ -1646,12 +1649,10 @@ void LLViewerWindow::initWorldUI()
getRootView()->sendChildToFront(gMenuHolder);
//Channel Manager
- LLNotificationsUI::LLChannelManager * channel_manager
- = LLNotificationsUI::LLChannelManager::getInstance();
+ LLNotificationsUI::LLChannelManager* channel_manager = LLNotificationsUI::LLChannelManager::getInstance();
getRootView()->addChild(channel_manager);
//Notification Manager
- LLNotificationsUI::LLNotificationManager* notify_manager =
- LLNotificationsUI::LLNotificationManager::getInstance();
+ LLNotificationsUI::LLNotificationManager* notify_manager = LLNotificationsUI::LLNotificationManager::getInstance();
getRootView()->addChild(notify_manager);
}
@@ -2175,7 +2176,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();
if( keyboard_focus )
{
- LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getChatBox() : NULL;
+ LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getNearbyChatBar()->getChatBox() : NULL;
// arrow keys move avatar while chatting hack
if (chat_editor && chat_editor->hasFocus())
{
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index fc639fbb21..f1d4520370 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -67,6 +67,9 @@
#include "llfloaterfriends.h" //VIVOX, inorder to refresh communicate panel
#include "llfloaterchat.h" // for LLFloaterChat::addChat()
+// for Talk Button's state updating
+#include "llnearbychatbar.h"
+
// for base64 decoding
#include "apr_base64.h"
@@ -5783,6 +5786,7 @@ bool LLVoiceClient::getMuteMic() const
void LLVoiceClient::setUserPTTState(bool ptt)
{
mUserPTTState = ptt;
+ LLNearbyChatBar::getInstance()->setPTTState(ptt);
}
bool LLVoiceClient::getUserPTTState()
@@ -5793,6 +5797,7 @@ bool LLVoiceClient::getUserPTTState()
void LLVoiceClient::toggleUserPTTState(void)
{
mUserPTTState = !mUserPTTState;
+ LLNearbyChatBar::getInstance()->setPTTState(mUserPTTState);
}
void LLVoiceClient::setVoiceEnabled(bool enabled)
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 179c790aed..d55f9fa42f 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -304,7 +304,10 @@
value="0.3344 0.5456 0.5159 1" />
<color
name="GroupNotifyTextColor"
- value="0 0.12 0.24 1" />
+ reference="White"/>
+ <color
+ name="GroupNotifyDimmedTextColor"
+ reference="DkGray"/>
<color
name="GroupOverTierColor"
value="0.43 0.06 0.06 1" />
@@ -493,10 +496,10 @@
value="1 0.82 0.46 1" />
<color
name="NotifyCautionWarnColor"
- reference="Black" />
+ reference="White" />
<color
name="NotifyTextColor"
- reference="Black" />
+ reference="White" />
<color
name="ObjectChatColor"
reference="LtGray" />
diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
index 3052571b1e..2d67e3d5a9 100644
--- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
@@ -28,5 +28,21 @@
color="1 1 1 1" enabled="true" image_name="closebox.tga"
name="close_btn"/>
</panel>
- <chat_items_container bottom="0" width="250" height="320" follows="left|right|top|bottom" name="chat_history" />
+ <text_editor
+ bg_readonly_color="ChatHistoryBgColor"
+ bg_writeable_color="ChatHistoryBgColor"
+ follows="left|top|right|bottom"
+ font="SansSerif"
+ layout="topleft"
+ height="320"
+ max_length="2147483647"
+ name="Chat History Editor"
+ read_only="true"
+ text_color="ChatHistoryTextColor"
+ text_readonly_color="ChatHistoryTextColor"
+ bottom="0"
+ track_bottom="true"
+ width="250"
+ word_wrap="true" />
+
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_navbar.xml b/indra/newview/skins/default/xui/en/menu_navbar.xml
index 78dff0bd4a..013136a593 100644
--- a/indra/newview/skins/default/xui/en/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/en/menu_navbar.xml
@@ -23,6 +23,9 @@
<menu_item_call.on_click
function="Navbar.Action"
parameter="landmark" />
+ <menu_item_call.on_enable
+ function="Navbar.EnableMenuItem"
+ parameter="can_landmark" />
</menu_item_call>
<menu_item_separator
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index e922e3b743..fe1baf22d0 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -181,22 +181,10 @@
function="World.Chat" />
</menu_item_call>
<menu_item_check
- label="Local Chat"
- layout="topleft"
- name="Chat History"
- shortcut="control|H">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="chat" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="chat" />
- </menu_item_check>
- <menu_item_check
label="Nearby Chat"
layout="topleft"
name="Nearby Chat"
- shortcut="control|N">
+ shortcut="control|H">
<menu_item_check.on_check
function="Floater.Visible"
parameter="nearby_chat" />
@@ -204,29 +192,6 @@
function="Floater.Toggle"
parameter="nearby_chat" />
</menu_item_check>
- <menu_item_check
- label="Communicate"
- layout="topleft"
- name="Instant Message"
- shortcut="control|T">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="communicate" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="communicate" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Media Remote Ctrl"
- layout="topleft"
- name="Preferences"
- shortcut="control|alt|M">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="media_remote_ctrl" />
- </menu_item_call>
<menu_item_separator
layout="topleft" />
<menu_item_check
@@ -251,6 +216,29 @@
function="Floater.Toggle"
parameter="mute" />
</menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="(Legacy) Communicate"
+ layout="topleft"
+ name="Instant Message"
+ shortcut="control|T">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="communicate" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="communicate" />
+ </menu_item_check>
+ <menu_item_call
+ label="(Temp) Media Remote Ctrl"
+ layout="topleft"
+ name="Preferences"
+ shortcut="control|alt|M">
+ <menu_item_call.on_click
+ function="Floater.Toggle"
+ parameter="media_remote_ctrl" />
+ </menu_item_call>
</menu>
<menu
label="World"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index c89eed37ab..17bb961308 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4191,6 +4191,7 @@ Are you sure you want to quit?
name="okcancelignore"
notext="Don&apos;t Quit"
yestext="Quit"/>
+ <unique/>
</notification>
<notification
@@ -6465,6 +6466,10 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block
yestext="Create group for L$100"/>
</notification>
+ <notification icon="notifytip.tga"
+ name="AttachmentSaved" type="notifytip">
+ Attachment has been saved.
+ </notification>
<global name="UnsupportedCPU">
- Your CPU speed does not meet the minimum requirements.
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index bbef5a8892..d42943d225 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -39,105 +39,12 @@
layout="topleft"
left="5"
min_height="28"
- width="250"
+ width="500"
top="0"
- min_width="100">
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|right"
- height="20"
- layout="topleft"
- left="0"
- name="chat_box"
- right="-39"
- top="3"
- width="250" />
- <button follows="right" width="36" top="3" left="214" resize="false"
- label="Hx" height="20">
- <button.commit_callback function="Floater.Toggle" parameter="chat"/>
- </button>
- </layout_panel>
- <icon
- auto_resize="false"
- color="0 0 0 0"
- follows="left|right"
- height="10"
- image_name="spacer24.tga"
- layout="topleft"
- left="0"
- top="0"
- width="5"
- min_width="5" />
- <view_border
- auto_resize="false"
- bevel_style="in"
- follows="left|right"
- height="28"
- layout="topleft"
- left="270"
- top="0"
- width="1" />
- <icon
- auto_resize="false"
- color="0 0 0 0"
- follows="left|right"
- height="10"
- image_name="spacer24.tga"
- layout="topleft"
- left="0"
- top="0"
- width="5"
- min_width="5" />
- <layout_panel
- auto_resize="false"
- follows="right"
- height="28"
- layout="topleft"
- min_height="28"
- width="100"
- top="0"
- min_width="100">
- <chiclet_talk
- follows="right"
- height="20"
- layout="topleft"
- left="0"
- name="talk"
- top="3"
- width="100" />
- </layout_panel>
- <icon
- auto_resize="false"
- color="0 0 0 0"
- follows="left|right"
- height="10"
- image_name="spacer24.tga"
- layout="topleft"
- left="0"
- name="DUMMY"
- top="0"
- width="5"
- min_width="5"/>
- <layout_panel
- auto_resize="false"
- follows="right"
- height="28"
- layout="topleft"
- min_height="28"
- width="90"
- top="0"
- min_width="90">
- <gesture_combo_box
- bottom="22"
- follows="right"
- height="20"
- label="Gestures"
- layout="topleft"
- name="Gesture"
- top="3"
- width="90" />
- </layout_panel>
+ min_width="305"
+ name="chat_bar"
+ user_resize="false"
+ filename="panel_nearby_chat_bar.xml"/>
<icon
auto_resize="false"
color="0 0 0 0"
@@ -159,7 +66,8 @@
min_height="28"
width="90"
top_delta="-10"
- min_width="90">
+ min_width="90"
+ user_resize="false">
<button
bottom="22"
follows="right"
@@ -190,7 +98,7 @@
top="0"
name="chiclet_list_panel"
width="150"
- min_width="70">
+ user_resize="false">
<chiclet_panel
follows="left|right"
height="25"
@@ -222,14 +130,15 @@
name="im_well_panel"
width="40"
top="0"
- min_width="40" >
+ min_width="40"
+ user_resize="false">
<chiclet_notification
follows="right"
height="25"
layout="topleft"
left="0"
name="im_well"
- top="1"
+ top="2"
width="40">
<button
image_selected="im_notifications.tga"
@@ -285,14 +194,15 @@
top="0"
name="sys_well_panel"
width="48"
- min_width="48">
+ min_width="48"
+ user_resize="false">
<chiclet_notification
follows="right"
height="25"
layout="topleft"
left="0"
name="sys_well"
- top="1"
+ top="2"
width="48">
<button
image_selected="bottom_tray_sys_notifications.tga"
diff --git a/indra/newview/skins/default/xui/en/panel_chat_item.xml b/indra/newview/skins/default/xui/en/panel_chat_item.xml
index b628ee3aa1..713c3a41a2 100644
--- a/indra/newview/skins/default/xui/en/panel_chat_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_chat_item.xml
@@ -15,7 +15,7 @@
color="1 1 1 1" enabled="true" name="avatar_icon"
/>
<text
- width="160" top="25" left="40" height="20" follows="left|right|top"
+ width="130" top="25" left="40" height="20" follows="left|right|top"
font="SansSerifBigBold" text_color="white" word_wrap="true"
mouse_opaque="true" name="sender_name" >
Jerry Knight
diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml
index 1757197372..a39a681f83 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml
@@ -9,21 +9,23 @@
top="5" left="5" mouse_opaque="true" name="group_icon"/>
<text type="string" length="1" follows="left|top|right|bottom"
font="SansSerifBigBold" height="20" layout="topleft" left="60" name="title"
- text_color="white" top="20" width="300">
+ text_color="GroupNotifyTextColor" top="20" width="300">
Sender Name / Group Name
</text>
</panel>
<text_editor type="string" length="1" bg_readonly_color="0 0 0 0"
follows="left|top|right|bottom" height="70" hide_scrollbar="true"
hide_border="true" layout="topleft" top="55" left="25" name="message"
- text_color="white" text_readonly_color="white" width="300" word_wrap="true">
+ text_color="GroupNotifyTextColor" text_readonly_color="GroupNotifyTextColor" width="300" word_wrap="true">
Message
Body
</text_editor>
+ <icon follows="left|top|right|bottom" height="16" width="16"
+ layout="topleft" top="135" left="25" mouse_opaque="true" name="attachment_icon" />
<text font="SansSerif" font.style="UNDERLINE" font_shadow="hard"
type="string" length="1" follows="left|top|right|bottom" layout="topleft"
- left="25" top="135" height="15" width="300" name="attachment"
- text_color="white">
+ left="45" top="135" height="15" width="280" name="attachment"
+ text_color="GroupNotifyTextColor">
Attachment
</text>
<button label="OK" layout="topleft" top="170" left="140" height="20"
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
new file mode 100644
index 0000000000..8b19f9a515
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ default_tab_group="1"
+ follows="left|bottom|right"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="chat_bar"
+ top="24"
+ width="500">
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|right"
+ height="20"
+ label="Click here to chat."
+ layout="topleft"
+ left_delta="7"
+ left="0"
+ name="chat_box"
+ tool_tip="Press Enter to say, Ctrl-Enter to shout."
+ top="3"
+ width="250" />
+ <button
+ follows="right"
+ width="45"
+ top="3"
+ layout="topleft"
+ left_pad="5"
+ label="Log"
+ height="20">
+ <button.commit_callback function="Floater.Toggle" parameter="nearby_chat"/>
+ </button>
+ <chiclet_talk
+ follows="right"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ name="talk"
+ top="3"
+ width="100" />
+ <gesture_combo_box
+ follows="right"
+ height="20"
+ label="Gestures"
+ layout="topleft"
+ name="Gesture"
+ left_pad="5"
+ top="3"
+ width="90" />
+</panel>
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 686dc931d3..1a06e2bb06 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
@@ -9,7 +9,7 @@
left="0"
name="picture_item"
top="80"
- width="310">
+ width="245">
<texture_picker
allow_no_texture="true"
default_image_name="None"
@@ -22,32 +22,31 @@
name="picture"
tab_stop="false"
top="7"
- width="90" />
+ width="70" />
<text
- follows="right"
- font="SansSerifBold"
+ follows="top|left|right"
+ font="SansSerif"
height="20"
layout="topleft"
- left="100"
+ left="80"
name="picture_name"
text_color="black"
top="5"
use_ellipses="true"
- width="170"/>
+ width="150"/>
<text
- follows="right"
- font="SansSerif"
+ follows="top|left|right"
+ font="SansSerifSmall"
height="40"
layout="topleft"
- left="100"
name="picture_descr"
text_color="white"
top="25"
use_ellipses="true"
- width="170"
+ width="150"
word_wrap="true" />
<button
- follows="right"
+ follows="top|right"
height="20"
image_disabled="navbar_bg_button.tga"
image_disabled_selected="navbar_bg_button.tga"
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 b746fcf84b..096b60adb1 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml
@@ -8,6 +8,26 @@
collapsed="true"
>
<sidetray_tab
+ name="sidebar_home"
+ tab_title="Home"
+ description="Home."
+ image="icn_voice-groupfocus.tga"
+ mouse_opaque="false"
+ background_opaque="false"
+ background_visible="true"
+ bg_opaque_color="0.5 0.5 0.5 1.0"
+ >
+ <panel
+ name="panel_home"
+ filename="panel_sidetray_home_tab.xml"
+ width="355"
+ height="465"
+ label="home"
+ border="true"
+ />
+ </sidetray_tab>
+
+ <sidetray_tab
name="sidebar_people"
tab_title="People"
description="Find your friends, contacts and people nearby."
@@ -17,15 +37,6 @@
background_visible="true"
bg_opaque_color="0.5 0.5 0.5 1.0"
>
- <accordion_tab
- name="people_accordion"
- title="People"
- collapsable="true"
- min_width="200"
- min_height="200"
- expanded="true"
- header_visible="false"
- >
<panel
class="panel_people"
name="panel_people"
@@ -35,7 +46,6 @@
label="People"
border="true"
/>
- </accordion_tab>
</sidetray_tab>
<!-- *TODO Vadim: isn't the sidetray_tab "label" attribute redundant since we have "tab_title" ? -->
<sidetray_tab
@@ -48,14 +58,6 @@
background_visible="true"
bg_opaque_color="0.5 0.5 0.5 1.0"
>
- <accordion_tab
- name="places_accordian"
- title="Places"
- collapsable="true"
- min_width="355"
- min_height="200"
- header_visible="false"
- >
<panel
class="panel_places"
name="panel_places"
@@ -63,7 +65,6 @@
label="Places"
border="true"
/>
- </accordion_tab>
</sidetray_tab>
<sidetray_tab
@@ -75,14 +76,6 @@
background_visible="true"
bg_opaque_color="0.5 0.5 0.5 1.0"
>
- <accordion_tab
- name="me_accordion"
- title="Me"
- collapsable="false"
- min_width="200"
- min_height="200"
- header_visible="false"
- >
<panel
class="panel_me_profile"
name="panel_me_profile"
@@ -90,7 +83,6 @@
label="Me"
border="true"
/>
- </accordion_tab>
</sidetray_tab>
<!--
@@ -107,7 +99,7 @@
name="group_accordion"
title="Group General"
expanded="true"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
header_visible="true"
@@ -187,7 +179,7 @@
<accordion_tab
name="floater_preview_animation"
title="Preview Animation"
- collapsable="true"
+ collapsible="true"
expanded="false"
min_width="200"
min_height="200"
@@ -206,7 +198,7 @@
<accordion_tab
name="floater_preview_gesture"
title="Preview Gesture"
- collapsable="true"
+ collapsible="true"
expanded="false"
min_width="200"
min_height="200"
@@ -225,7 +217,7 @@
<accordion_tab
name="floater_preview_existing_landmark"
title="Preview Existing Landmark"
- collapsable="true"
+ collapsible="true"
expanded="false"
min_width="200"
min_height="200"
@@ -244,7 +236,7 @@
<accordion_tab
name="floater_preview_sound"
title="Preview Sound"
- collapsable="true"
+ collapsible="true"
expanded="false"
min_width="200"
min_height="200"
@@ -263,7 +255,7 @@
<accordion_tab
name="floater_preview_url"
title="Preview URL"
- collapsable="true"
+ collapsible="true"
expanded="false"
min_width="200"
min_height="200"
@@ -282,7 +274,7 @@
<accordion_tab
name="floater_URL_entry"
title="URL Entry"
- collapsable="true"
+ collapsible="true"
expanded="false"
min_width="200"
min_height="200"
@@ -313,7 +305,7 @@
<accordion_tab
name="panel_region_covenant"
title="Region Covenant"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -332,7 +324,7 @@
<accordion_tab
name="panel_region_debug"
title="Region Debug"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -351,7 +343,7 @@
<accordion_tab
name="panel_region_estate"
title="Region Estate"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -370,7 +362,7 @@
<accordion_tab
name="panel_region_general"
title="Region General"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -389,7 +381,7 @@
<accordion_tab
name="panel_region_terrain"
title="Region Terrain"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -408,7 +400,7 @@
<accordion_tab
name="panel_region_texture"
title="Region Texture"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -427,7 +419,7 @@
<accordion_tab
name="floater_region_info"
title="Region Info"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -458,7 +450,7 @@
<accordion_tab
name="floater_tools"
title="Tools"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -477,7 +469,7 @@
<accordion_tab
name="floater_bulk_perms"
title="Bulk Perms"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -496,7 +488,7 @@
<accordion_tab
name="floater_build_options"
title="Build Options"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -528,7 +520,7 @@
<accordion_tab
name="floater_gesture"
title="Gestures"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -548,7 +540,7 @@
<accordion_tab
name="floater_buy_contents"
title="Buy Contents"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -567,7 +559,7 @@
<accordion_tab
name="floater_buy_object"
title="Buy Object"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -586,7 +578,7 @@
<accordion_tab
name="floater_inventory_view_finder"
title="Inventory View Finder"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -605,7 +597,7 @@
<accordion_tab
name="floater_mute"
title="Mute"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -624,7 +616,7 @@
<accordion_tab
name="floater_sell_land"
title="Sell Land"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
@@ -643,7 +635,7 @@
<accordion_tab
name="floater_telehub"
title="Telehub"
- collapsable="true"
+ collapsible="true"
min_width="200"
min_height="200"
expanded="false"
diff --git a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
new file mode 100644
index 0000000000..a85662603d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- All our XML is utf-8 encoded. -->
+
+<panel
+ name="home_tab"
+ title="home_tab"
+ visible="true"
+ width="300"
+ height="420"
+ background_opaque="false"
+ background_visible="true"
+ bevel_style="in"
+ follows="left|top|right|bottom">
+ <panel
+ left="10" width="280" height="130"
+ background_visible="true"
+ background_opaque="false"
+ bg_alpha_color="0.3 0.3 0.3 1.0"
+ name="sidebar_people"
+ follows="left|top|right"
+ class="panel_sidetray_home_info">
+ <text
+ top="-10" width="200" left="5" height="30" follows="left|right|top"
+ font="SansSerifHugeBold" text_color="white" word_wrap="true"
+ mouse_opaque="false" name="tab_name" >
+ People
+ </text>
+ <icon
+ top="-10" right="-10" width="20" height="20" follows="top|right"
+ color="1 1 1 1" enabled="true" image_name="icn_voice-groupfocus.tga"
+ mouse_opaque="false" name="tab_icon"/>
+ <text
+ top="-40" left="10" right="-10" height="120" follows="left|right|bottom"
+ font="SansSerifBig" text_color="white" word_wrap="true"
+ mouse_opaque="false" name="tab_description" >
+ Find your friends, contacts and people nearby.
+ </text>
+ </panel>
+ <panel
+ left="10" width="280" height="130"
+ background_visible="true"
+ background_opaque="false"
+ bg_alpha_color="0.3 0.3 0.3 1.0"
+ name="sidebar_places"
+ follows="left|top|right"
+ class="panel_sidetray_home_info">
+ <text
+ top="-10" width="200" left="5" height="30" follows="left|right|top"
+ font="SansSerifHugeBold" text_color="white" word_wrap="true"
+ mouse_opaque="false" name="tab_name" >
+ Places
+ </text>
+ <icon
+ top="-10" right="-10" width="20" height="20" follows="top|right"
+ color="1 1 1 1" enabled="true" image_name="inv_item_landmark.tga"
+ mouse_opaque="false" name="tab_icon"/>
+ <text
+ top="-40" left="10" right="-10" height="120" follows="left|right|bottom|top"
+ font="SansSerifBig" text_color="white" word_wrap="true"
+ mouse_opaque="false" name="tab_description" >
+ Find your friends, contacts and people nearby.
+ </text>
+ </panel>
+ <panel
+ left="10" width="280" height="130"
+ background_visible="true"
+ background_opaque="false"
+ bg_alpha_color="0.3 0.3 0.3 1.0"
+ name="sidebar_me"
+ follows="left|top|right"
+ class="panel_sidetray_home_info">
+ <text
+ top="-10" width="200" left="5" height="30" follows="left|right|top"
+ font="SansSerifHugeBold" text_color="white" word_wrap="true"
+ mouse_opaque="false" name="tab_name" >
+ Me
+ </text>
+ <icon
+ top="-10" right="-10" width="20" height="20" follows="top|right"
+ color="1 1 1 1" enabled="true" image_name="icn_voice-pvtfocus.tga"
+ mouse_opaque="false" name="tab_icon"/>
+ <text
+ top="-40" left="10" right="-10" height="120" follows="left|right|bottom"
+ font="SansSerifBig" text_color="white" word_wrap="true"
+ mouse_opaque="false" name="tab_description" >
+ Change your profile, your look and quick links to your outfits.
+ </text>
+ </panel>
+</panel>
+ \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml
index 8952ea1307..ba4915e074 100644
--- a/indra/newview/skins/default/xui/en/panel_toast.xml
+++ b/indra/newview/skins/default/xui/en/panel_toast.xml
@@ -17,16 +17,16 @@
bg_alpha_color="0.3 0.3 0.3 1.0">
<text
- type="string"
visible="false"
follows="left|top|right|bottom"
font="SansSerifBold"
height="40"
layout="topleft"
left="60"
- name="text"
+ name="toast_text"
+ word_wrap="true"
text_color="white"
- top="30"
+ top="20"
width="290">
Toast text;
</text>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 149da313a2..e5665b0194 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -652,6 +652,7 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh
<string name="Stage">Stage</string>
<string name="Other">Other</string>
<string name="Any">Any</string>
+ <string name="You">You</string>
<!-- puncutations -->
<string name=":">:</string>
@@ -785,4 +786,6 @@ If you continue to receive this message, contact customer support.
<string name="UTCTimeMin">min,datetime,utc</string>
<string name="UTCTimeSec">second,datetime,utc</string>
<string name="UTCTimeTimezone">timezone,datetime,utc</string>
+
+
</strings>
diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml
index efb9a89c6a..eb9bb99b20 100644
--- a/indra/newview/skins/default/xui/en/widgets/location_input.xml
+++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml
@@ -10,16 +10,13 @@
add_landmark_image_enabled="Favorite_Star_Active"
add_landmark_image_disabled="Favorite_Star_Off"
hover_glow_amount="0.15"
- add_landmark_width="20"
- add_landmark_height="20"
add_landmark_hpad="2"
allow_text_entry="true"
- arrow_image="Combobox_Selected"
list_position="below"
show_text_as_tentative="false"
max_chars="20"
follows="left|top"
- background="TextField_Off">
+ >
<info_button name="Place Information"
label=""
tool_tip="About current location"
diff --git a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
index 7004de8475..b33acf81cc 100644
--- a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
@@ -3,6 +3,5 @@
thumb_outline_color="SliderThumbOutlineColor"
thumb_center_color="SliderThumbCenterColor"
thumb_image="SliderThumb_Off"
- hover_glow_amount="0.15"
track_image="SliderTrack_Horiz"
track_highlight_image="SliderTrack_Horiz" />