summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt3
-rw-r--r--indra/newview/llagent.cpp4
-rw-r--r--indra/newview/llavatarlistitem.cpp61
-rw-r--r--indra/newview/llavatarlistitem.h5
-rw-r--r--indra/newview/llchathistory.cpp50
-rw-r--r--indra/newview/llfloatergesture.cpp2
-rw-r--r--indra/newview/llgesturemgr.cpp10
-rw-r--r--indra/newview/llgesturemgr.h2
-rw-r--r--indra/newview/llinspecttoast.cpp9
-rw-r--r--indra/newview/llinspecttoast.h3
-rw-r--r--indra/newview/llnearbychat.cpp22
-rw-r--r--indra/newview/llnearbychatbar.cpp253
-rw-r--r--indra/newview/llnearbychatbar.h47
-rw-r--r--indra/newview/llnearbychathandler.cpp25
-rw-r--r--indra/newview/lloutputmonitorctrl.cpp65
-rw-r--r--indra/newview/lloutputmonitorctrl.h29
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp2
-rw-r--r--indra/newview/llpanelpick.cpp80
-rw-r--r--indra/newview/llpanelpick.h18
-rw-r--r--indra/newview/llscreenchannel.cpp125
-rw-r--r--indra/newview/llscreenchannel.h15
-rw-r--r--indra/newview/llspeakingindicatormanager.cpp254
-rw-r--r--indra/newview/llspeakingindicatormanager.h67
-rw-r--r--indra/newview/llvoiceclient.cpp11
-rw-r--r--indra/newview/llvoiceclient.h1
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml32
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml33
-rw-r--r--indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml30
-rw-r--r--indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml21
32 files changed, 847 insertions, 445 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 0e1d5ca80b..0bfc0db351 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -386,6 +386,7 @@ set(viewer_SOURCE_FILES
llspatialpartition.cpp
llspeakbutton.cpp
llspeakers.cpp
+ llspeakingindicatormanager.cpp
llsplitbutton.cpp
llsprite.cpp
llstartup.cpp
@@ -891,6 +892,7 @@ set(viewer_HEADER_FILES
llspatialpartition.h
llspeakbutton.h
llspeakers.h
+ llspeakingindicatormanager.h
llsplitbutton.h
llsprite.h
llstartup.h
@@ -1759,6 +1761,7 @@ if (INSTALL)
endif (INSTALL)
if (LL_TESTS)
+else (LL_TESTS)
# To add a viewer unit test, just add the test .cpp file below
# This creates a separate test project per file listed.
include(LLAddBuildTest)
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 35b28d8ec0..5ea253709c 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -514,6 +514,8 @@ void LLAgent::resetView(BOOL reset_camera, BOOL change_camera)
}
setFocusOnAvatar(TRUE, ANIMATE);
+
+ mCameraFOVZoomFactor = 0.f;
}
mHUDTargetZoom = 1.f;
@@ -3584,7 +3586,7 @@ F32 LLAgent::calcCameraFOVZoomFactor()
{
return 0.f;
}
- else if (mFocusObject.notNull() && !mFocusObject->isAvatar())
+ else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar)
{
// don't FOV zoom on mostly transparent objects
LLVector3 focus_offset = mFocusObjectOffset;
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index a2e17db3d8..1043858373 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -91,40 +91,25 @@ BOOL LLAvatarListItem::postBuild()
mProfileBtn->setVisible(false);
mProfileBtn->setClickedCallback(boost::bind(&LLAvatarListItem::onProfileBtnClick, this));
- // Remember avatar icon width including its padding from the name text box,
- // so that we can hide and show the icon again later.
if (!sStaticInitialized)
{
+ // Remember children widths including their padding from the next sibling,
+ // so that we can hide and show them again later.
initChildrenWidths(this);
sStaticInitialized = true;
}
-/*
- if(!p.buttons.profile)
- {
- delete mProfile;
- mProfile = NULL;
-
- LLRect rect;
-
- rect.setLeftTopAndSize(mName->getRect().mLeft, mName->getRect().mTop, mName->getRect().getWidth() + 30, mName->getRect().getHeight());
- mName->setRect(rect);
-
- if(mLocator)
- {
- rect.setLeftTopAndSize(mLocator->getRect().mLeft + 30, mLocator->getRect().mTop, mLocator->getRect().getWidth(), mLocator->getRect().getHeight());
- mLocator->setRect(rect);
- }
+ return TRUE;
+}
- if(mInfo)
- {
- rect.setLeftTopAndSize(mInfo->getRect().mLeft + 30, mInfo->getRect().mTop, mInfo->getRect().getWidth(), mInfo->getRect().getHeight());
- mInfo->setRect(rect);
- }
+S32 LLAvatarListItem::notifyParent(const LLSD& info)
+{
+ if (info.has("visibility_changed"))
+ {
+ updateChildren();
}
-*/
- return TRUE;
+ return 0;
}
void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask)
@@ -246,8 +231,10 @@ void LLAvatarListItem::showSpeakingIndicator(bool visible)
// Already done? Then do nothing.
if (mSpeakingIndicator->getVisible() == (BOOL)visible)
return;
- mSpeakingIndicator->setVisible(visible);
- updateChildren();
+// Disabled to not contradict with SpeakingIndicatorManager functionality. EXT-3976
+// probably this method should be totally removed.
+// mSpeakingIndicator->setVisible(visible);
+// updateChildren();
}
void LLAvatarListItem::setAvatarIconVisible(bool visible)
@@ -264,26 +251,6 @@ void LLAvatarListItem::setAvatarIconVisible(bool visible)
void LLAvatarListItem::onInfoBtnClick()
{
LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mAvatarId));
-
- /* TODO fix positioning of inspector
- localPointToScreen(mXPos, mYPos, &mXPos, &mYPos);
-
-
- LLRect rect;
-
- // *TODO Vadim: rewrite this. "+= -" looks weird.
- S32 delta = mYPos - inspector->getRect().getHeight();
- if(delta < 0)
- {
- mYPos += -delta;
- }
-
- rect.setLeftTopAndSize(mXPos, mYPos,
- inspector->getRect().getWidth(), inspector->getRect().getHeight());
- inspector->setRect(rect);
- inspector->setFrontmost(true);
- inspector->setVisible(true);
- */
}
void LLAvatarListItem::onProfileBtnClick()
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 868ee546d4..f76ffb391d 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -74,6 +74,11 @@ public:
virtual ~LLAvatarListItem();
virtual BOOL postBuild();
+
+ /**
+ * Processes notification from speaker indicator to update children when indicator's visibility is changed.
+ */
+ virtual S32 notifyParent(const LLSD& info);
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
virtual void setValue(const LLSD& value);
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 9a1572364f..2fc83c7e54 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -499,24 +499,29 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_
style_params.font.name(font_name);
style_params.font.size(font_size);
style_params.font.style(input_append_params.font.style);
-
- //whether to show colon after a name in header copy/past and in plain text mode
- bool show_colon = chat.mChatType != CHAT_TYPE_SHOUT && chat.mChatType != CHAT_TYPE_WHISPER;
+
+ std::string prefix = chat.mText.substr(0, 4);
//IRC styled /me messages.
- bool irc_me = false;
+ bool irc_me = prefix == "/me " || prefix == "/me'";
- std::string prefix = chat.mText.substr(0, 4);
- if (prefix == "/me " || prefix == "/me'")
+ // Delimiter after a name in header copy/past and in plain text mode
+ std::string delimiter = (chat.mChatType != CHAT_TYPE_SHOUT && chat.mChatType != CHAT_TYPE_WHISPER)
+ ? ": "
+ : " ";
+
+ // Don't add any delimiter after name in irc styled messages
+ if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC)
{
- irc_me = true;
+ delimiter = LLStringUtil::null;
+ style_params.font.style = "ITALIC";
}
if (use_plain_text_chat_history)
{
mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, style_params);
- if (utf8str_trim(chat.mFromName).size() != 0 && !irc_me)
+ if (utf8str_trim(chat.mFromName).size() != 0)
{
// Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text.
if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() )
@@ -524,11 +529,11 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_
LLStyle::Params link_params(style_params);
link_params.fillFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));
// Convert the name to a hotlink and add to message.
- mEditor->appendText(chat.mFromName + (show_colon ? ": " : " "), false, link_params);
+ mEditor->appendText(chat.mFromName + delimiter, false, link_params);
}
else
{
- mEditor->appendText(chat.mFromName + (show_colon ? ": " : " "), false, style_params);
+ mEditor->appendText(chat.mFromName + delimiter, false, style_params);
}
}
}
@@ -574,35 +579,22 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_
std::string header_text = "[" + chat.mTimeStr + "] ";
if (utf8str_trim(chat.mFromName).size() != 0 && chat.mFromName != SYSTEM_FROM)
- header_text += chat.mFromName + (show_colon ? ": " : " ");
+ header_text += chat.mFromName + delimiter;
mEditor->appendWidget(p, header_text, false);
mLastFromName = chat.mFromName;
mLastFromID = chat.mFromID;
mLastMessageTime = new_message_time;
}
-
- if (irc_me)
- {
- style_params.font.style = "ITALIC";
- if (chat.mFromName.size() > 0)
- mEditor->appendText(chat.mFromName, FALSE, style_params);
+ std::string message = irc_me ? chat.mText.substr(3) : chat.mText;
+ if ( message.size() > 0 && !LLStringOps::isSpace(message[message.size() - 1]) )
+ {
// Ensure that message ends with NewLine, to avoid losing of new lines
// while copy/paste from text chat. See EXT-3263.
- mEditor->appendText(chat.mText.substr(3) + NEW_LINE, FALSE, style_params);
- }
- else
- {
- std::string message(chat.mText);
- if ( message.size() > 0 && !LLStringOps::isSpace(message[message.size() - 1]) )
- {
- // Ensure that message ends with NewLine, to avoid losing of new lines
- // while copy/paste from text chat. See EXT-3263.
- message += NEW_LINE;
- }
- mEditor->appendText(message, FALSE, style_params);
+ message += NEW_LINE;
}
+ mEditor->appendText(message, FALSE, style_params);
mEditor->blockUndo();
// automatically scroll to end when receiving chat from myself
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 5072bc8c82..6a9c602db2 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -415,7 +415,7 @@ void LLFloaterGesture::onClickPlay()
LL_DEBUGS("Gesture")<<" Trying to play gesture id: "<< item_id <<LL_ENDL;
if(!LLGestureManager::instance().isGestureActive(item_id))
{
- // we need to inform server about gesture activating to be consistent with LLPreviewGesture and LLGestureComboBox.
+ // we need to inform server about gesture activating to be consistent with LLPreviewGesture and LLGestureComboList.
BOOL inform_server = TRUE;
BOOL deactivate_similar = FALSE;
LLGestureManager::instance().setGestureLoadedCallback(item_id, boost::bind(&LLFloaterGesture::playGesture, this, item_id));
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index df7aa9eabf..82293b4aa0 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -417,6 +417,16 @@ BOOL LLGestureManager::isGesturePlaying(const LLUUID& item_id)
return gesture->mPlaying;
}
+BOOL LLGestureManager::isGesturePlaying(LLMultiGesture* gesture)
+{
+ if(!gesture)
+ {
+ return FALSE;
+ }
+
+ return gesture->mPlaying;
+}
+
void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new_gesture, const LLUUID& asset_id)
{
const LLUUID& base_item_id = get_linked_uuid(item_id);
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index e80eea9ae9..c562587c6f 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -103,6 +103,8 @@ public:
BOOL isGesturePlaying(const LLUUID& item_id);
+ BOOL isGesturePlaying(LLMultiGesture* gesture);
+
const item_map_t& getActiveGestures() const { return mActive; }
// Force a gesture to be played, for example, if it is being
// previewed.
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index 0139d76f93..3ca8fa2f56 100644
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
@@ -1,6 +1,6 @@
/**
- * @file lltoast.h
- * @brief This class implements a placeholder for any notification panel.
+ * @file llinspecttoast.cpp
+ * @brief Toast inspector implementation.
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
@@ -37,6 +37,7 @@
#include "llfloaterreg.h"
#include "llscreenchannel.h"
#include "llchannelmanager.h"
+#include "lltransientfloatermgr.h"
using namespace LLNotificationsUI;
@@ -70,10 +71,12 @@ LLInspectToast::LLInspectToast(const LLSD& notification_id) :
llwarns << "Could not get requested screen channel." << llendl;
return;
}
+
+ LLTransientFloaterMgr::getInstance()->addControlView(this);
}
LLInspectToast::~LLInspectToast()
{
-
+ LLTransientFloaterMgr::getInstance()->removeControlView(this);
}
void LLInspectToast::onOpen(const LLSD& notification_id)
diff --git a/indra/newview/llinspecttoast.h b/indra/newview/llinspecttoast.h
index c4403d6196..ff547154b8 100644
--- a/indra/newview/llinspecttoast.h
+++ b/indra/newview/llinspecttoast.h
@@ -1,6 +1,5 @@
/**
- * @file lltoast.h
- * @brief This class implements a placeholder for any notification panel.
+ * @file llinspecttoast.h
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index fc0e51b76d..a7c1e73328 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -179,27 +179,7 @@ void LLNearbyChat::addMessage(const LLChat& chat,bool archive)
if (!chat.mMuted)
{
tmp_chat.mFromName = chat.mFromName;
-
- if (chat.mChatStyle == CHAT_STYLE_IRC)
- {
- LLColor4 txt_color = LLUIColorTable::instance().getColor("White");
- LLViewerChat::getChatColor(chat,txt_color);
- LLFontGL* fontp = LLViewerChat::getChatFont();
- std::string font_name = LLFontGL::nameFromFont(fontp);
- std::string font_size = LLFontGL::sizeFromFont(fontp);
- LLStyle::Params append_style_params;
- append_style_params.color(txt_color);
- append_style_params.readonly_color(txt_color);
- append_style_params.font.name(font_name);
- append_style_params.font.size(font_size);
- append_style_params.font.style = "ITALIC";
-
- mChatHistory->appendMessage(chat, use_plain_text_chat_history, append_style_params);
- }
- else
- {
- mChatHistory->appendMessage(chat, use_plain_text_chat_history);
- }
+ mChatHistory->appendMessage(chat, use_plain_text_chat_history);
}
if(archive)
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 75c2fb07d1..6cf8bcb417 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -48,13 +48,16 @@
#include "llcommandhandler.h"
#include "llviewercontrol.h"
#include "llnavigationbar.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "llrootview.h"
S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
// legacy callback glue
void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
-static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box");
+static LLDefaultChildRegistry::Register<LLGestureComboList> r("gesture_combo_list");
struct LLChatTypeTrigger {
std::string name;
@@ -66,13 +69,42 @@ static LLChatTypeTrigger sChatTypeTriggers[] = {
{ "/shout" , CHAT_TYPE_SHOUT}
};
-LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p)
- : LLComboBox(p)
- , mGestureLabelTimer()
+LLGestureComboList::Params::Params()
+: combo_button("combo_button"),
+ combo_list("combo_list")
+{
+}
+
+LLGestureComboList::LLGestureComboList(const LLGestureComboList::Params& p)
+: LLUICtrl(p)
, mLabel(p.label)
, mViewAllItemIndex(0)
{
- setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this));
+ LLButton::Params button_params = p.combo_button;
+ button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT);
+
+ mButton = LLUICtrlFactory::create<LLButton>(button_params);
+ mButton->reshape(getRect().getWidth(),getRect().getHeight());
+ mButton->setCommitCallback(boost::bind(&LLGestureComboList::onButtonCommit, this));
+
+ addChild(mButton);
+
+ LLScrollListCtrl::Params params = p.combo_list;
+ params.name("GestureComboList");
+ params.commit_callback.function(boost::bind(&LLGestureComboList::onItemSelected, this, _2));
+ params.visible(false);
+ params.commit_on_keyboard_movement(false);
+
+ mList = LLUICtrlFactory::create<LLScrollListCtrl>(params);
+
+ // *HACK: adding list as a child to NonSideTrayView to make it fully visible without
+ // making it top control (because it would cause problems).
+ gViewerWindow->getNonSideTrayView()->addChild(mList);
+ mList->setVisible(FALSE);
+
+ //****************************Gesture Part********************************/
+
+ setCommitCallback(boost::bind(&LLGestureComboList::onCommitGesture, this));
// now register us as observer since we have a place to put the results
LLGestureManager::instance().addObserver(this);
@@ -80,26 +112,139 @@ LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p)
// refresh list from current active gestures
refreshGestures();
- // This forces using of halign from xml, since LLComboBox
- // sets it to LLFontGL::LEFT, if text entry is disabled
- mButton->setHAlign(p.drop_down_button.font_halign);
+ setFocusLostCallback(boost::bind(&LLGestureComboList::hideList, this));
+}
+
+BOOL LLGestureComboList::handleKey(KEY key, MASK mask, BOOL called_from_parent)
+{
+ BOOL handled = FALSE;
+
+ if (key == KEY_ESCAPE && mask == MASK_NONE )
+ {
+ hideList();
+ handled = TRUE;
+ }
+ else
+ {
+ handled = mList->handleKey(key, mask, called_from_parent);
+ }
- // Pressing Gesture button by SPACE/ENTER key should open gestures list
- mButton->setCommitCallback(boost::bind(&LLComboBox::onButtonMouseDown, this));
+ return handled;
}
-LLGestureComboBox::~LLGestureComboBox()
+void LLGestureComboList::showList()
{
- LLGestureManager::instance().removeObserver(this);
+ LLRect rect = mList->getRect();
+ LLRect screen;
+ mButton->localRectToScreen(getRect(), &screen);
+
+ // Calculating amount of space between the navigation bar and gestures combo
+ LLNavigationBar* nb = LLNavigationBar::getInstance();
+
+ S32 x, nb_bottom;
+ nb->localPointToScreen(0, 0, &x, &nb_bottom);
+
+ S32 max_height = nb_bottom - screen.mTop;
+ mList->calcColumnWidths();
+ rect.setOriginAndSize(screen.mLeft, screen.mTop, llmax(mList->getMaxContentWidth(),mButton->getRect().getWidth()), max_height);
+
+ mList->setRect(rect);
+ mList->fitContents( llmax(mList->getMaxContentWidth(),mButton->getRect().getWidth()), max_height);
+
+ gFocusMgr.setKeyboardFocus(this);
+
+ // Show the list and push the button down
+ mButton->setToggleState(TRUE);
+ mList->setVisible(TRUE);
+}
+
+void LLGestureComboList::onButtonCommit()
+{
+ if (!mList->getVisible())
+ {
+ // highlight the last selected item from the original selection before potentially selecting a new item
+ // as visual cue to original value of combo box
+ LLScrollListItem* last_selected_item = mList->getLastSelectedItem();
+ if (last_selected_item)
+ {
+ mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item));
+ }
+
+ if (mList->getItemCount() != 0)
+ {
+ showList();
+ }
+ }
+ else
+ {
+ hideList();
+ }
+}
+
+void LLGestureComboList::hideList()
+{
+ if (mList->getVisible())
+ {
+ mButton->setToggleState(FALSE);
+ mList->setVisible(FALSE);
+ mList->mouseOverHighlightNthItem(-1);
+ gFocusMgr.setKeyboardFocus(NULL);
+ }
+}
+
+S32 LLGestureComboList::getCurrentIndex() const
+{
+ LLScrollListItem* item = mList->getFirstSelected();
+ if( item )
+ {
+ return mList->getItemIndex( item );
+ }
+ return -1;
}
-void LLGestureComboBox::refreshGestures()
+void LLGestureComboList::onItemSelected(const LLSD& data)
+{
+ const std::string name = mList->getSelectedItemLabel();
+
+ S32 cur_id = getCurrentIndex();
+ mLastSelectedIndex = cur_id;
+ if (cur_id != mList->getItemCount()-1 && cur_id != -1)
+ {
+ mButton->setLabel(name);
+ }
+
+ // hiding the list reasserts the old value stored in the text editor/dropdown button
+ hideList();
+
+ // commit does the reverse, asserting the value in the list
+ onCommit();
+}
+
+void LLGestureComboList::sortByName(bool ascending)
+{
+ mList->sortOnce(0, ascending);
+}
+
+LLSD LLGestureComboList::getValue() const
+{
+ LLScrollListItem* item = mList->getFirstSelected();
+ if( item )
+ {
+ return item->getValue();
+ }
+ else
+ {
+ return LLSD();
+ }
+}
+
+void LLGestureComboList::refreshGestures()
{
//store current selection so we can maintain it
LLSD cur_gesture = getValue();
- selectFirstItem();
- // clear
- clearRows();
+
+ mList->selectFirstItem();
+ mList->clearRows();
mGestures.clear();
LLGestureManager::item_map_t::const_iterator it;
@@ -110,7 +255,7 @@ void LLGestureComboBox::refreshGestures()
LLMultiGesture* gesture = (*it).second;
if (gesture)
{
- addSimpleElement(gesture->mName, ADD_BOTTOM, LLSD(idx));
+ mList->addSimpleElement(gesture->mName, ADD_BOTTOM, LLSD(idx));
mGestures.push_back(gesture);
idx++;
}
@@ -120,23 +265,42 @@ void LLGestureComboBox::refreshGestures()
// store index followed by the last added Gesture and add View All item at bottom
mViewAllItemIndex = idx;
- addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex));
+
+ mList->addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex));
// Insert label after sorting, at top, with separator below it
- addSeparator(ADD_TOP);
- addSimpleElement(mLabel, ADD_TOP);
+ mList->addSeparator(ADD_TOP);
+ mList->addSimpleElement(mLabel, ADD_TOP);
if (cur_gesture.isDefined())
{
- selectByValue(cur_gesture);
+ mList->selectByValue(cur_gesture);
+
}
else
{
- selectFirstItem();
+ mList->selectFirstItem();
+ }
+
+ LLCtrlListInterface* gestures = getListInterface();
+ LLMultiGesture* gesture = NULL;
+
+ if (gestures)
+ {
+ S32 index = gestures->getSelectedValue().asInteger();
+ if(index > 0)
+ gesture = mGestures.at(index);
}
+
+ if(gesture && LLGestureManager::instance().isGesturePlaying(gesture))
+ {
+ return;
+ }
+
+ mButton->setLabel(mLabel);
}
-void LLGestureComboBox::onCommitGesture()
+void LLGestureComboList::onCommitGesture()
{
LLCtrlListInterface* gestures = getListInterface();
if (gestures)
@@ -167,50 +331,11 @@ void LLGestureComboBox::onCommitGesture()
}
}
}
-
- mGestureLabelTimer.start();
- // free focus back to chat bar
- setFocus(FALSE);
}
-//virtual
-void LLGestureComboBox::draw()
+LLGestureComboList::~LLGestureComboList()
{
- // 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();
-}
-
-//virtual
-void LLGestureComboBox::showList()
-{
- LLComboBox::showList();
-
- // Calculating amount of space between the navigation bar and gestures combo
- LLNavigationBar* nb = LLNavigationBar::getInstance();
- S32 x, nb_bottom;
- nb->localPointToScreen(0, 0, &x, &nb_bottom);
-
- S32 list_bottom;
- mList->localPointToScreen(0, 0, &x, &list_bottom);
-
- S32 max_height = nb_bottom - list_bottom;
-
- LLRect rect = mList->getRect();
- // List overlapped navigation bar, downsize it
- if (rect.getHeight() > max_height)
- {
- rect.setOriginAndSize(rect.mLeft, rect.mBottom, rect.getWidth(), max_height);
- mList->setRect(rect);
- mList->reshape(rect.getWidth(), rect.getHeight());
- }
+ LLGestureManager::instance().removeObserver(this);
}
LLNearbyChatBar::LLNearbyChatBar()
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 224118e088..d9a7403611 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -42,33 +42,52 @@
#include "llspeakers.h"
-class LLGestureComboBox
- : public LLComboBox
- , public LLGestureManagerObserver
+class LLGestureComboList
+ : public LLGestureManagerObserver
+ , public LLUICtrl
{
public:
- struct Params : public LLInitParam::Block<Params, LLComboBox::Params> { };
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLButton::Params> combo_button;
+ Optional<LLScrollListCtrl::Params> combo_list;
+
+ Params();
+ };
+
protected:
- LLGestureComboBox(const Params&);
+
friend class LLUICtrlFactory;
+ LLGestureComboList(const Params&);
+ std::vector<LLMultiGesture*> mGestures;
+ std::string mLabel;
+ LLSD::Integer mViewAllItemIndex;
+
public:
- ~LLGestureComboBox();
+ ~LLGestureComboList();
+
+ LLCtrlListInterface* getListInterface() { return (LLCtrlListInterface*)mList; };
+ virtual void showList();
+ virtual void hideList();
+ virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+
+ S32 getCurrentIndex() const;
+ void onItemSelected(const LLSD& data);
+ void sortByName(bool ascending = true);
void refreshGestures();
void onCommitGesture();
- virtual void draw();
+ void onButtonCommit();
+ virtual LLSD getValue() const;
// LLGestureManagerObserver trigger
virtual void changed() { refreshGestures(); }
-protected:
-
- virtual void showList();
+private:
- LLFrameTimer mGestureLabelTimer;
- std::vector<LLMultiGesture*> mGestures;
- std::string mLabel;
- LLSD::Integer mViewAllItemIndex;
+ LLButton* mButton;
+ LLScrollListCtrl* mList;
+ S32 mLastSelectedIndex;
};
class LLNearbyChatBar
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 9e13a626b4..96442fafcc 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -180,6 +180,11 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
if(panel && panel->messageID() == fromID && panel->canAddText())
{
+ if (CHAT_STYLE_IRC == notification["chat_style"].asInteger())
+ {
+ notification["message"] = notification["from"].asString() + notification["message"].asString();
+ }
+
panel->addMessage(notification);
toast->reshapeToPanel();
toast->resetTimer();
@@ -302,7 +307,6 @@ LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& i
channel->setCreatePanelCallback(callback);
mChannel = LLChannelManager::getInstance()->addChannel(channel);
- mChannel->setOverflowFormatString("You have %d unread nearby chat messages");
}
LLNearbyChatHandler::~LLNearbyChatHandler()
@@ -332,25 +336,22 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
LLChat& tmp_chat = const_cast<LLChat&>(chat_msg);
- if (tmp_chat.mChatStyle == CHAT_STYLE_IRC)
- {
- if(!tmp_chat.mFromName.empty())
- tmp_chat.mText = tmp_chat.mFromName + tmp_chat.mText.substr(3);
- else
- tmp_chat.mText = tmp_chat.mText.substr(3);
- }
-
+ LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
{
//sometimes its usefull to have no name at all...
//if(tmp_chat.mFromName.empty() && tmp_chat.mFromID!= LLUUID::null)
// tmp_chat.mFromName = tmp_chat.mFromID.asString();
}
-
- LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
nearby_chat->addMessage(chat_msg);
if(nearby_chat->getVisible())
return;//no need in toast if chat is visible
-
+
+ // Handle irc styled messages for toast panel
+ if (tmp_chat.mChatStyle == CHAT_STYLE_IRC)
+ {
+ tmp_chat.mText = tmp_chat.mText.substr(3);
+ }
+
// arrange a channel on a screen
if(!mChannel->getVisible())
{
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 63803469dd..f816dc589d 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -77,7 +77,9 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
mImageLevel3(p.image_level_3),
mAutoUpdate(p.auto_update),
mSpeakerId(p.speaker_id),
- mIsAgentControl(false)
+ mIsAgentControl(false),
+ mIsSwitchDirty(false),
+ mShouldSwitchOn(false)
{
//static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange);
//static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red);
@@ -108,6 +110,7 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
LLOutputMonitorCtrl::~LLOutputMonitorCtrl()
{
LLMuteList::getInstance()->removeObserver(this);
+ LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
}
void LLOutputMonitorCtrl::setPower(F32 val)
@@ -117,6 +120,26 @@ void LLOutputMonitorCtrl::setPower(F32 val)
void LLOutputMonitorCtrl::draw()
{
+ // see also switchIndicator()
+ if (mIsSwitchDirty)
+ {
+ mIsSwitchDirty = false;
+ if (mShouldSwitchOn)
+ {
+ // just notify parent visibility may have changed
+ notifyParentVisibilityChanged();
+ }
+ else
+ {
+ // make itself invisible and notify parent about this
+ setVisible(FALSE);
+ notifyParentVisibilityChanged();
+
+ // no needs to render for invisible element
+ return;
+ }
+ }
+
// Copied from llmediaremotectrl.cpp
// *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then
// call directly into gVoiceClient to ask if that agent-id is muted, is
@@ -229,6 +252,7 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id)
if (speaker_id.isNull() || speaker_id == mSpeakerId) return;
mSpeakerId = speaker_id;
+ LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this);
//mute management
if (mAutoUpdate)
@@ -251,3 +275,42 @@ void LLOutputMonitorCtrl::onChange()
// check only blocking on voice. EXT-3542
setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat));
}
+
+// virtual
+void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
+{
+ // ensure indicator is visible in case it is not in visible chain
+ // to be called when parent became visible next time to notify parent that visibility is changed.
+ setVisible(TRUE);
+
+ // if parent is in visible chain apply switch_on state and notify it immediately
+ if (getParent() && getParent()->isInVisibleChain())
+ {
+ LL_DEBUGS("SpeakingIndicator") << "Indicator is in visible chain, notifying parent: " << mSpeakerId << LL_ENDL;
+ setVisible((BOOL)switch_on);
+ notifyParentVisibilityChanged();
+ }
+
+ // otherwise remember necessary state and mark itself as dirty.
+ // State will be applied i next draw when parents chain became visible.
+ else
+ {
+ LL_DEBUGS("SpeakingIndicator") << "Indicator is not in visible chain, parent won't be notified: " << mSpeakerId << LL_ENDL;
+ mIsSwitchDirty = true;
+ mShouldSwitchOn = switch_on;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE SECTION
+//////////////////////////////////////////////////////////////////////////
+void LLOutputMonitorCtrl::notifyParentVisibilityChanged()
+{
+ LL_DEBUGS("SpeakingIndicator") << "Notify parent that visibility was changed: " << mSpeakerId << " ,new_visibility: " << getVisible() << LL_ENDL;
+
+ LLSD params = LLSD().with("visibility_changed", getVisible());
+
+ notifyParent(params);
+}
+
+// EOF
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 85ea552a57..2bbfa251e9 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -36,6 +36,7 @@
#include "v4color.h"
#include "llview.h"
#include "llmutelist.h"
+#include "llspeakingindicatormanager.h"
class LLTextBox;
class LLUICtrlFactory;
@@ -45,7 +46,7 @@ class LLUICtrlFactory;
//
class LLOutputMonitorCtrl
-: public LLView, LLMuteListObserver
+: public LLView, public LLSpeakingIndicator, LLMuteListObserver
{
public:
struct Params : public LLInitParam::Block<Params, LLView::Params>
@@ -90,7 +91,29 @@ public:
//called by mute list
virtual void onChange();
+ /**
+ * Implementation of LLSpeakingIndicator interface.
+ * Behavior is implemented via changing visibility.
+ *
+ * If instance is in visible chain now (all parents are visible) it changes visibility
+ * and notify parent about this.
+ *
+ * Otherwise it marks an instance as dirty and stores necessary visibility.
+ * It will be applied in next draw and parent will be notified.
+ */
+ virtual void switchIndicator(bool switch_on);
+
private:
+
+ /**
+ * Notifies parent about changed visibility.
+ *
+ * Passes LLSD with "visibility_changed" => <current visibility> value.
+ * For now it is processed by LLAvatarListItem to update (reshape) its children.
+ * Implemented fo complete EXT-3976
+ */
+ void notifyParentVisibilityChanged();
+
//static LLColor4 sColorMuted;
//static LLColor4 sColorNormal;
//static LLColor4 sColorOverdriven;
@@ -117,6 +140,10 @@ private:
/** uuid of a speaker being monitored */
LLUUID mSpeakerId;
+
+ /** indicates if the instance is dirty and should notify parent */
+ bool mIsSwitchDirty;
+ bool mShouldSwitchOn;
};
#endif
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index b547997e7a..0cfe501fab 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -302,7 +302,7 @@ void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
{
LLPanelChatControlPanel::setSessionId(session_id);
- mGroupID = LLIMModel::getInstance()->getOtherParticipantID(session_id);
+ mGroupID = session_id;
// for group and Ad-hoc chat we need to include agent into list
if(!mParticipantList)
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 7a4dd3569d..e7615929c8 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -35,24 +35,30 @@
// profile.
#include "llviewerprecompiledheaders.h"
-#include "llpanel.h"
+
+#include "llpanelpick.h"
+
#include "message.h"
-#include "llagent.h"
-#include "llagentpicksinfo.h"
+
+#include "llparcel.h"
+
#include "llbutton.h"
+#include "llfloaterreg.h"
#include "lliconctrl.h"
#include "lllineeditor.h"
-#include "llparcel.h"
-#include "llviewerparcelmgr.h"
+#include "llpanel.h"
+#include "llscrollcontainer.h"
#include "lltexteditor.h"
+
+#include "llagent.h"
+#include "llagentpicksinfo.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llfloaterworldmap.h"
#include "lltexturectrl.h"
#include "lluiconstants.h"
+#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llworldmap.h"
-#include "llfloaterworldmap.h"
-#include "llfloaterreg.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llpanelpick.h"
#define XML_PANEL_EDIT_PICK "panel_edit_pick.xml"
@@ -93,6 +99,10 @@ LLPanelPickInfo::LLPanelPickInfo()
, mPickId(LLUUID::null)
, mParcelId(LLUUID::null)
, mRequestedId(LLUUID::null)
+ , mScrollingPanelMinHeight(0)
+ , mScrollingPanelWidth(0)
+ , mScrollingPanel(NULL)
+ , mScrollContainer(NULL)
{
}
@@ -146,9 +156,35 @@ BOOL LLPanelPickInfo::postBuild()
childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this));
childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this));
+ mScrollingPanel = getChild<LLPanel>("scroll_content_panel");
+ mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
+
+ mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight();
+ mScrollingPanelWidth = mScrollingPanel->getRect().getWidth();
+
return TRUE;
}
+void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLPanel::reshape(width, height, called_from_parent);
+
+ if (!mScrollContainer || !mScrollingPanel)
+ return;
+
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+ S32 scroll_height = mScrollContainer->getRect().getHeight();
+ if (mScrollingPanelMinHeight >= scroll_height)
+ {
+ mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight);
+ }
+ else
+ {
+ mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height);
+ }
+}
+
void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type)
{
if(APT_PICK_INFO != type)
@@ -284,7 +320,6 @@ void LLPanelPickInfo::setPickName(const std::string& name)
void LLPanelPickInfo::setPickDesc(const std::string& desc)
{
childSetValue(XML_DESC, desc);
- updateContentPanelRect();
}
void LLPanelPickInfo::setPickLocation(const std::string& location)
@@ -292,31 +327,6 @@ void LLPanelPickInfo::setPickLocation(const std::string& location)
childSetValue(XML_LOCATION, location);
}
-void LLPanelPickInfo::updateContentPanelRect()
-{
- LLTextBox* desc = getChild<LLTextBox>(XML_DESC);
-
- S32 text_height = desc->getTextPixelHeight();
- LLRect text_rect = desc->getRect();
-
- // let text-box height fit text height
- text_rect.set(text_rect.mLeft, text_rect.mTop, text_rect.mRight, text_rect.mTop - text_height);
- desc->setRect(text_rect);
- desc->reshape(text_rect.getWidth(), text_rect.getHeight());
- // force reflow
- desc->setText(desc->getText());
-
- // bottom of description text-box will be bottom of content panel
- desc->localRectToOtherView(desc->getLocalRect(), &text_rect, getChild<LLView>("profile_scroll"));
-
- LLPanel* content_panel = getChild<LLPanel>("scroll_content_panel");
- LLRect content_rect = content_panel->getRect();
- content_rect.set(content_rect.mLeft, content_rect.mTop, content_rect.mRight, text_rect.mBottom);
- // Somehow setRect moves all elements down.
- // Single reshape() updates rect and does not move anything.
- content_panel->reshape(content_rect.getWidth(), content_rect.getHeight());
-}
-
void LLPanelPickInfo::onClickMap()
{
LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index 12b5a116b4..62c3b20c0d 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -43,6 +43,7 @@
class LLIconCtrl;
class LLTextureCtrl;
+class LLScrollContainer;
class LLMessageSystem;
class LLAvatarPropertiesObserver;
@@ -69,6 +70,8 @@ public:
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
/**
@@ -140,15 +143,6 @@ protected:
virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
/**
- * Reshapes content panel to fit all elements.
- *
- * Assume that description text-box is the last element of panel.
- * Reshape text-box to fit text height and then reshape content panel to fit
- * text-box bottom. EXT-1326
- */
- void updateContentPanelRect();
-
- /**
* Callback for "Map" button, opens Map
*/
void onClickMap();
@@ -162,7 +156,11 @@ protected:
protected:
- LLTextureCtrl* mSnapshotCtrl;
+ S32 mScrollingPanelMinHeight;
+ S32 mScrollingPanelWidth;
+ LLScrollContainer* mScrollContainer;
+ LLPanel* mScrollingPanel;
+ LLTextureCtrl* mSnapshotCtrl;
LLUUID mAvatarId;
LLVector3d mPosGlobal;
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index d0a0dd877f..027f3daffb 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -59,17 +59,14 @@ bool LLScreenChannel::mWasStartUpToastShown = false;
// LLScreenChannelBase
//////////////////////
LLScreenChannelBase::LLScreenChannelBase(const LLUUID& id) :
- mOverflowToastPanel(NULL)
- ,mToastAlignment(NA_BOTTOM)
+ mToastAlignment(NA_BOTTOM)
,mCanStoreToasts(true)
,mHiddenToastsNum(0)
- ,mOverflowToastHidden(false)
,mHoveredToast(NULL)
,mControlHovering(false)
,mShowToasts(true)
{
mID = id;
- mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString");
mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2));
setMouseOpaque( false );
setVisible(FALSE);
@@ -217,11 +214,6 @@ void LLScreenChannel::addToast(const LLToast::Params& p)
ToastElem new_toast_elem(p);
- // reset HIDDEN flags for the Overflow Toast
- mOverflowToastHidden = false;
- if(mOverflowToastPanel)
- mOverflowToastPanel->setIsHidden(false);
-
new_toast_elem.toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, _1));
new_toast_elem.toast->setOnToastDestroyedCallback(boost::bind(&LLScreenChannel::onToastDestroyed, this, _1));
if(mControlHovering)
@@ -322,8 +314,6 @@ void LLScreenChannel::loadStoredToastsToChannel()
if(mStoredToastList.size() == 0)
return;
-
- mOverflowToastHidden = false;
for(it = mStoredToastList.begin(); it != mStoredToastList.end(); ++it)
{
@@ -344,8 +334,6 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id)
if( it == mStoredToastList.end() )
return;
- mOverflowToastHidden = false;
-
LLToast* toast = (*it).toast;
if(toast->getVisible())
@@ -490,7 +478,7 @@ void LLScreenChannel::showToastsBottom()
if(floater && floater->overlapsScreenChannel())
{
LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
- if(toast_rect.mTop + getOverflowToastHeight() + toast_margin > world_rect.mTop)
+ if(toast_rect.mTop > world_rect.mTop)
{
break;
}
@@ -526,7 +514,7 @@ void LLScreenChannel::showToastsBottom()
}
}
- if(it != mToastList.rend() && !mOverflowToastHidden)
+ if(it != mToastList.rend())
{
mHiddenToastsNum = 0;
for(; it != mToastList.rend(); it++)
@@ -535,7 +523,6 @@ void LLScreenChannel::showToastsBottom()
(*it).toast->setVisible(FALSE);
mHiddenToastsNum++;
}
- createOverflowToast(bottom, gSavedSettings.getS32("NotificationTipToastLifeTime"));
}
else
{
@@ -566,94 +553,6 @@ void LLScreenChannel::showToastsTop()
}
//--------------------------------------------------------------------------
-void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer)
-{
- LLRect toast_rect;
- LLToast::Params p;
- p.lifetime_secs = timer;
-
- if(!mOverflowToastPanel)
- mOverflowToastPanel = new LLToast(p);
-
- if(!mOverflowToastPanel)
- return;
-
- mOverflowToastPanel->startFading();
- mOverflowToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this));
-
- LLTextBox* text_box = mOverflowToastPanel->getChild<LLTextBox>("toast_text");
- std::string text = llformat(mOverflowFormatString.c_str(),mHiddenToastsNum);
- if(mHiddenToastsNum == 1)
- {
- text += ".";
- }
- else
- {
- text += "s.";
- }
-
- toast_rect = mOverflowToastPanel->getRect();
- mOverflowToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true);
- toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastGap"), getRect().getWidth(), toast_rect.getHeight());
- mOverflowToastPanel->setRect(toast_rect);
-
- // don't show overflow toast if there is not enough space for it.
- LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get());
- if(floater && floater->overlapsScreenChannel())
- {
- LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
- if(toast_rect.mTop > world_rect.mTop)
- {
- closeOverflowToastPanel();
- return;
- }
- }
-
- text_box->setValue(text);
- text_box->setVisible(TRUE);
-
- mOverflowToastPanel->setVisible(TRUE);
-}
-
-//--------------------------------------------------------------------------
-void LLScreenChannel::onOverflowToastHide()
-{
- mOverflowToastHidden = true;
-
- // remove all hidden toasts from channel and save interactive notifications
- for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end();)
- {
- if(!(*it).toast->getVisible())
- {
- if((*it).toast->getCanBeStored())
- {
- storeToast((*it));
- }
- else
- {
- deleteToast((*it).toast);
- }
-
- it = mToastList.erase(it);
- }
- else
- {
- ++it;
- }
- }
-}
-
-//--------------------------------------------------------------------------
-void LLScreenChannel::closeOverflowToastPanel()
-{
- if(mOverflowToastPanel != NULL)
- {
- mOverflowToastPanel->setVisible(FALSE);
- mOverflowToastPanel->stopFading();
- }
-}
-
-//--------------------------------------------------------------------------
void LLScreenChannel::createStartUpToast(S32 notif_num, F32 timer)
{
LLRect toast_rect;
@@ -698,24 +597,6 @@ F32 LLScreenChannel::getHeightRatio()
return ratio;
}
-S32 LLScreenChannel::getOverflowToastHeight()
-{
- if(mOverflowToastPanel)
- {
- return mOverflowToastPanel->getRect().getHeight();
- }
-
- static S32 height = 0;
- if(0 == height)
- {
- LLToast::Params p;
- LLToast* toast = new LLToast(p);
- height = toast->getRect().getHeight();
- delete toast;
- }
- return height;
-}
-
//--------------------------------------------------------------------------
void LLScreenChannel::updateStartUpString(S32 num)
{
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index 054f92096c..88053d87d9 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -72,8 +72,7 @@ public:
virtual void setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
virtual void setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
- virtual void setOverflowFormatString ( const std::string& str) { mOverflowFormatString = str; }
-
+
// kill or modify a toast by its ID
virtual void killToastByNotificationID(LLUUID id) {};
virtual void modifyToastNotificationByID(LLUUID id, LLSD data) {};
@@ -121,17 +120,13 @@ protected:
LLToast* mHoveredToast;
bool mCanStoreToasts;
bool mDisplayToastsAlways;
- bool mOverflowToastHidden;
// controls whether a channel shows toasts or not
bool mShowToasts;
//
EToastAlignment mToastAlignment;
EChannelAlignment mChannelAlignment;
- // attributes for the Overflow Toast
S32 mHiddenToastsNum;
- LLToast* mOverflowToastPanel;
- std::string mOverflowFormatString;
// channel's ID
LLUUID mID;
@@ -192,8 +187,6 @@ public:
void removeToastsBySessionID(LLUUID id);
// remove all storable toasts from screen and store them
void removeAndStoreAllStorableToasts();
- // close the Overflow Toast
- void closeOverflowToastPanel();
// close the StartUp Toast
void closeStartUpToast();
@@ -261,7 +254,6 @@ private:
void onToastHover(LLToast* toast, bool mouse_enter);
void onToastFade(LLToast* toast);
void onToastDestroyed(LLToast* toast);
- void onOverflowToastHide();
void onStartUpToastHide();
//
@@ -274,9 +266,6 @@ private:
void showToastsCentre();
void showToastsTop();
- // create the Overflow Toast
- void createOverflowToast(S32 bottom, F32 timer);
-
// create the StartUp Toast
void createStartUpToast(S32 notif_num, F32 timer);
@@ -285,8 +274,6 @@ private:
*/
static F32 getHeightRatio();
- S32 getOverflowToastHeight();
-
// Channel's flags
static bool mWasStartUpToastShown;
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
new file mode 100644
index 0000000000..42db6bf9c3
--- /dev/null
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -0,0 +1,254 @@
+/**
+ * @file llspeakingindicatormanager.cpp
+ * @author Mike Antipov
+ * @brief Implementation of SpeackerIndicatorManager class to process registered LLSpeackerIndicator
+ * depend on avatars are in the same voice channel.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ *
+ * Copyright (c) 2010, 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 "llspeakingindicatormanager.h"
+
+
+#include "llagentdata.h"
+#include "llvoicechannel.h"
+#include "llvoiceclient.h"
+
+/**
+ * This class intended to control visibility of avatar speaking indicators depend on whether avatars
+ * are in the same voice channel.
+ *
+ * Speaking indicator should be visible for avatars in the same voice channel. See EXT-3976.
+ *
+ * It stores passed instances of LLOutputMonitorCtrl in a multimap by avatar LLUUID.
+ * It observes changing of voice channel and changing of participant list in voice channel.
+ * When voice channel or voice participant list is changed it updates visibility of an appropriate
+ * speaking indicator.
+ *
+ * Several indicators can be registered for the same avatar.
+ */
+class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, LLVoiceClientParticipantObserver
+{
+ LOG_CLASS(SpeakingIndicatorManager);
+public:
+
+ /**
+ * Stores passed speaking indicator to control its visibility.
+ *
+ * Registered indicator is set visible if an appropriate avatar is in the same voice channel with Agent.
+ * It ignores instances of Agent's indicator.
+ *
+ * @param speaker_id LLUUID of an avatar whose speaking indicator is registered.
+ * @param speaking_indicator instance of the speaking indicator to be registered.
+ */
+ void registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator);
+
+ /**
+ * Removes passed speaking indicator from observing.
+ *
+ * @param speaker_id LLUUID of an avatar whose speaking indicator should be unregistered.
+ * @param speaking_indicator instance of the speaking indicator to be unregistered.
+ */
+ void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);
+
+private:
+ typedef std::set<LLUUID> speaker_ids_t;
+ typedef std::multimap<LLUUID, LLSpeakingIndicator*> speaking_indicators_mmap_t;
+ typedef speaking_indicators_mmap_t::value_type speaking_indicator_value_t;
+ typedef speaking_indicators_mmap_t::const_iterator indicator_const_iterator;
+ typedef std::pair<indicator_const_iterator, indicator_const_iterator> indicator_range_t;
+
+ friend class LLSingleton<SpeakingIndicatorManager>;
+ SpeakingIndicatorManager();
+ ~SpeakingIndicatorManager();
+
+ /**
+ * Callback to determine when voice channel is changed.
+ *
+ * It switches all registered speaking indicators off.
+ * To reduce overheads only switched on indicators are processed.
+ */
+ void sOnCurrentChannelChanged(const LLUUID& session_id);
+
+ /**
+ * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
+ *
+ * Switches off indicators had been switched on and switches on indicators of current participants list.
+ * There is only a few indicators in lists should be switched off/on.
+ * So, method does not calculate difference between these list it only switches off already
+ * switched on indicators and switches on indicators of voice channel participants
+ */
+ void onChange();
+
+ /**
+ * Changes state of indicators specified by LLUUIDs
+ *
+ * @param speakers_uuids - avatars' LLUUIDs whose speaking indicators should be switched
+ * @param switch_on - if TRUE specified indicator will be switched on, off otherwise.
+ */
+ void switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on);
+
+ /**
+ * Multimap with all registered speaking indicators
+ */
+ speaking_indicators_mmap_t mSpeakingIndicators;
+
+ /**
+ * LUUIDs of avatar for which we have speaking indicators switched on.
+ *
+ * Is used to switch off all previously ON indicators when voice participant list is changed.
+ *
+ * @see onChange()
+ */
+ speaker_ids_t mSwitchedIndicatorsOn;
+};
+
+//////////////////////////////////////////////////////////////////////////
+// PUBLIC SECTION
+//////////////////////////////////////////////////////////////////////////
+void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator)
+{
+ if (speaker_id == gAgentID) return;
+
+ LL_DEBUGS("SpeakingIndicator") << "Registering indicator: " << speaker_id << LL_ENDL;
+ speaking_indicator_value_t value_type(speaker_id, speaking_indicator);
+ mSpeakingIndicators.insert(value_type);
+
+ speaker_ids_t speakers_uuids;
+ BOOL is_in_same_voice = LLVoiceClient::getInstance()->findParticipantByID(speaker_id) != NULL;
+
+ speakers_uuids.insert(speaker_id);
+ switchSpeakerIndicators(speakers_uuids, is_in_same_voice);
+}
+
+void SpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator)
+{
+ speaking_indicators_mmap_t::iterator it;
+ it = mSpeakingIndicators.find(speaker_id);
+ for (;it != mSpeakingIndicators.end(); ++it)
+ {
+ if (it->second == speaking_indicator)
+ {
+ mSpeakingIndicators.erase(it);
+ break;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE SECTION
+//////////////////////////////////////////////////////////////////////////
+SpeakingIndicatorManager::SpeakingIndicatorManager()
+{
+ LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&SpeakingIndicatorManager::sOnCurrentChannelChanged, this, _1));
+ LLVoiceClient::getInstance()->addObserver(this);
+}
+
+SpeakingIndicatorManager::~SpeakingIndicatorManager()
+{
+ // Don't use LLVoiceClient::getInstance() here without check
+ // singleton MAY have already been destroyed.
+ if(LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->removeObserver(this);
+ }
+}
+
+void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
+{
+ switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE);
+ mSwitchedIndicatorsOn.clear();
+}
+
+void SpeakingIndicatorManager::onChange()
+{
+ LL_DEBUGS("SpeakingIndicator") << "Voice participant list was changed, updating indicators" << LL_ENDL;
+
+ speaker_ids_t speakers_uuids;
+ LLVoiceClient::getInstance()->getParticipantsUUIDSet(speakers_uuids);
+
+ LL_DEBUGS("SpeakingIndicator") << "Switching all OFF, count: " << mSwitchedIndicatorsOn.size() << LL_ENDL;
+ // switch all indicators off
+ switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE);
+ mSwitchedIndicatorsOn.clear();
+
+ LL_DEBUGS("SpeakingIndicator") << "Switching all ON, count: " << speakers_uuids.size() << LL_ENDL;
+ // then switch current voice participants indicators on
+ switchSpeakerIndicators(speakers_uuids, TRUE);
+}
+
+void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on)
+{
+ speaker_ids_t::const_iterator it_uuid = speakers_uuids.begin();
+ for (; it_uuid != speakers_uuids.end(); ++it_uuid)
+ {
+ LL_DEBUGS("SpeakingIndicator") << "Looking for indicator: " << *it_uuid << LL_ENDL;
+ indicator_range_t it_range = mSpeakingIndicators.equal_range(*it_uuid);
+ indicator_const_iterator it_indicator = it_range.first;
+ bool was_found = false;
+ for (; it_indicator != it_range.second; ++it_indicator)
+ {
+ was_found = true;
+ LLSpeakingIndicator* indicator = (*it_indicator).second;
+ indicator->switchIndicator(switch_on);
+ }
+
+ if (was_found)
+ {
+ LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators where found" << LL_ENDL;
+
+ if (switch_on)
+ {
+ // store switched on indicator to be able switch it off
+ mSwitchedIndicatorsOn.insert(*it_uuid);
+ }
+ }
+ else
+ {
+ LL_WARNS("SpeakingIndicator") << "indicator was not found among registered: " << *it_uuid << LL_ENDL;
+ }
+ }
+}
+
+/************************************************************************/
+/* LLSpeakingIndicatorManager namespace implementation */
+/************************************************************************/
+
+void LLSpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator)
+{
+ SpeakingIndicatorManager::instance().registerSpeakingIndicator(speaker_id, speaking_indicator);
+}
+
+void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator)
+{
+ SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator);
+}
+
+// EOF
+
diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h
new file mode 100644
index 0000000000..ce0158f7d8
--- /dev/null
+++ b/indra/newview/llspeakingindicatormanager.h
@@ -0,0 +1,67 @@
+/**
+ * @file llspeakingindicatormanager.h
+ * @author Mike Antipov
+ * @brief Interfeace of LLSpeackerIndicator class to be processed depend on avatars are in the same voice channel.
+ * Also register/unregister methods for this class are declared
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ *
+ * Copyright (c) 2010, 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_LLSPEAKINGINDICATORMANAGER_H
+#define LL_LLSPEAKINGINDICATORMANAGER_H
+
+class LLSpeakingIndicator
+{
+public:
+ virtual void switchIndicator(bool switch_on) = 0;
+};
+
+// See EXT-3976.
+namespace LLSpeakingIndicatorManager
+{
+ /**
+ * Stores passed speaking indicator to control its visibility.
+ *
+ * Registered indicator is set visible if an appropriate avatar is in the same voice channel with Agent.
+ * It ignores instances of Agent's indicator.
+ *
+ * @param speaker_id LLUUID of an avatar whose speaker indicator is registered.
+ * @param speaking_indicator instance of the speaker indicator to be registered.
+ */
+ void registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator);
+
+ /**
+ * Removes passed speaking indicator from observing.
+ *
+ * @param speaker_id LLUUID of an avatar whose speaker indicator should be unregistered.
+ * @param speaking_indicator instance of the speaker indicator to be unregistered.
+ */
+ void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);
+}
+
+#endif // LL_LLSPEAKINGINDICATORMANAGER_H
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 423c46e14c..42b8a1c2b6 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -5004,6 +5004,17 @@ LLVoiceClient::participantMap *LLVoiceClient::getParticipantList(void)
return result;
}
+void LLVoiceClient::getParticipantsUUIDSet(std::set<LLUUID>& participant_uuids)
+{
+ if (NULL == mAudioSession) return;
+
+ participantUUIDMap::const_iterator it = mAudioSession->mParticipantsByUUID.begin(),
+ it_end = mAudioSession->mParticipantsByUUID.end();
+ for (; it != it_end; ++it)
+ {
+ participant_uuids.insert((*(*it).first));
+ }
+}
LLVoiceClient::participantState *LLVoiceClient::sessionState::findParticipant(const std::string &uri)
{
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 724179847d..6231c6ba29 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -354,6 +354,7 @@ static void updatePosition(void);
participantState *findParticipantByID(const LLUUID& id);
participantMap *getParticipantList(void);
+ void getParticipantsUUIDSet(std::set<LLUUID>& participant_uuids);
typedef std::map<const std::string*, sessionState*, stringMapComparitor> sessionMap;
typedef std::set<sessionState*> sessionSet;
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index e01536f256..e20e5a85c0 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4985,7 +4985,7 @@ No valid parcel could be found.
icon="notify.tga"
name="ObjectGiveItem"
type="offer">
-An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you [OBJECTTYPE]:
+An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you this [OBJECTTYPE]:
[ITEM_SLURL]
<form name="form">
<button
@@ -5007,7 +5007,7 @@ An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you [OBJECTTYPE
icon="notify.tga"
name="ObjectGiveItemUnknownUser"
type="offer">
-An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you [OBJECTTYPE]:
+An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you this [OBJECTTYPE]:
[ITEM_SLURL]
<form name="form">
<button
@@ -5029,7 +5029,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you [O
icon="notify.tga"
name="UserGiveItem"
type="offer">
-[NAME_SLURL] has given you [OBJECTTYPE]:
+[NAME_SLURL] has given you this [OBJECTTYPE]:
[ITEM_SLURL]
<form name="form">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index ca547a79e2..4b39210f30 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -103,7 +103,7 @@
min_width="52"
name="gesture_panel"
user_resize="false">
- <gesture_combo_box
+ <gesture_combo_list
follows="left|right"
height="23"
label="Gesture"
@@ -113,10 +113,10 @@
top="5"
width="82"
tool_tip="Shows/hides gestures">
- <gesture_combo_box.drop_down_button
+ <gesture_combo_list.combo_button
pad_right="10"
use_ellipses="true" />
- </gesture_combo_box>
+ </gesture_combo_list>
</layout_panel>
<icon
auto_resize="false"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index d6de5af32d..7769189219 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -38,28 +38,27 @@
<scroll_container
color="DkGray2"
follows="all"
- height="510"
+ height="500"
layout="topleft"
left="10"
top_pad="10"
name="profile_scroll"
- reserve_scroll_corner="false"
opaque="true"
width="313">
<panel
name="scroll_content_panel"
- follows="left|top"
+ follows="left|top|right"
min_height="300"
layout="topleft"
top="0"
background_visible="false"
- height="510"
+ height="500"
left="0"
- width="295">
+ width="285">
<texture_picker
follows="left|top|right"
height="197"
- width="290"
+ width="280"
layout="topleft"
top="20"
left="10"
@@ -77,7 +76,7 @@
<text
type="string"
length="1"
- follows="left|top"
+ follows="left|top|right"
height="15"
font="SansSerifSmall"
font.style="BOLD"
@@ -86,7 +85,7 @@
top="215"
name="Name:"
text_color="white"
- width="290">
+ width="280">
Title:
</text>
<line_editor
@@ -99,11 +98,11 @@
max_length="63"
name="pick_name"
text_color="black"
- width="290" />
+ width="280" />
<text
type="string"
length="1"
- follows="left|top"
+ follows="left|top|right"
height="15"
font="SansSerifSmall"
font.style="BOLD"
@@ -112,13 +111,13 @@
top_pad="20"
name="description_label"
text_color="white"
- width="290">
+ width="280">
Description:
</text>
<text_editor
follows="left|top|right"
height="100"
- width="290"
+ width="280"
hide_scrollbar="false"
layout="topleft"
left="10"
@@ -132,27 +131,26 @@
length="1"
font="SansSerifSmall"
font.style="BOLD"
- follows="left|top"
+ follows="left|top|right"
height="15"
layout="topleft"
left="10"
name="location_label"
text_color="white"
top_pad="20"
- width="290">
+ width="280">
Location:
</text>
<text
type="string"
length="1"
- follows="left|top"
+ follows="left|top|right"
height="50"
layout="topleft"
left="10"
name="pick_location"
- right="-10"
top_pad="2"
- width="290"
+ width="280"
word_wrap="true">
loading...
</text>
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index e096715cee..0d9c2c2162 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -136,6 +136,7 @@ Maximum 200 per group daily
left_pad="3"
max_length="63"
name="create_subject"
+ prevalidate_callback="ascii"
width="220" />
<text
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
index f68202d287..9c7f38e688 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -40,31 +40,30 @@
left="10"
top_pad="10"
name="profile_scroll"
- reserve_scroll_corner="false"
width="313">
<panel
name="scroll_content_panel"
- follows="left|top"
+ follows="left|top|right"
min_height="300"
layout="topleft"
top="0"
background_visible="false"
- height="470"
+ height="400"
left="0"
- width="295">
+ width="285">
<texture_picker
enabled="false"
- follows="left|top"
+ follows="left|top|right"
height="197"
layout="topleft"
left="10"
name="pick_snapshot"
top="20"
- width="290" />
+ width="280" />
<text
follows="left|top|right"
height="35"
- width="290"
+ width="280"
layout="topleft"
font="SansSerifBig"
font.style="BOLD"
@@ -75,23 +74,29 @@
value="[name]"
use_ellipses="true" />
<text
- follows="left|top"
+ follows="left|top|right"
height="25"
layout="topleft"
left="10"
name="pick_location"
- width="290"
+ width="280"
word_wrap="true"
value="[loading...]" />
- <text
- follows="left|top|right"
- height="280"
+ <text_editor
+ bg_readonly_color="DkGray2"
+ follows="all"
+ height="100"
+ width="280"
+ hide_scrollbar="false"
layout="topleft"
left="10"
+ top_pad="2"
+ max_length="1023"
name="pick_desc"
- width="290"
+ read_only="true"
+ text_readonly_color="white"
value="[description]"
- word_wrap="true" />
+ wrap="true" />
</panel>
</scroll_container>
<panel
diff --git a/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml
deleted file mode 100644
index 4229f34c09..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<gesture_combo_box
- label="Gestures"
- list_position="below"
- max_chars="20"
- follows="right|top">
- <gesture_combo_box.combo_button name="Combobox Button"
- label=""
- hover_glow_amount="0.15"
- scale_image="true"
- image_unselected="ComboButton_Off"
- image_selected="ComboButton_Selected"
- image_disabled="ComboButton_Disabled"
- image_disabled_selected="ComboButton_Disabled_Selected" />
- <gesture_combo_box.drop_down_button name="Drop Down Button"
- label=""
- halign="center"
- hover_glow_amount="0.15"
- scale_image="true"
- image_selected="PushButton_Selected_Press"
- image_pressed="PushButton_Press"
- image_pressed_selected="PushButton_Selected_Press"
- image_unselected="PushButton_Off"
- image_disabled="PushButton_Disabled"
- image_disabled_selected="PushButton_Selected_Disabled" />
- <gesture_combo_box.combo_list bg_writeable_color="MenuDefaultBgColor"
- scroll_bar_bg_visible="false" />
- <gesture_combo_box.combo_editor name="Combo Text Entry"
- select_on_focus="true" />
-</gesture_combo_box>
diff --git a/indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml b/indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml
new file mode 100644
index 0000000000..808683864d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<gesture_combo_list
+ follows="right|top">
+ <gesture_combo_list.combo_button
+ name="Combolist Button"
+ label=""
+ layout="topleft"
+ halign="center"
+ hover_glow_amount="0.15"
+ mouse_opaque="false"
+ scale_image="true"
+ image_selected="PushButton_Selected_Press"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_unselected="PushButton_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Selected_Disabled" />
+ <gesture_combo_list.combo_list
+ bg_writeable_color="MenuDefaultBgColor"
+ scroll_bar_bg_visible="false" />
+</gesture_combo_list>