summaryrefslogtreecommitdiff
path: root/indra/newview/llnearbychatbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llnearbychatbar.cpp')
-rw-r--r--indra/newview/llnearbychatbar.cpp321
1 files changed, 206 insertions, 115 deletions
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 5fa97926a5..1507b7d324 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -32,6 +32,8 @@
#include "llviewerprecompiledheaders.h"
+#include "message.h"
+
#include "llfloaterreg.h"
#include "lltrans.h"
@@ -45,13 +47,17 @@
#include "llviewerstats.h"
#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;
@@ -63,43 +69,190 @@ 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);
+ addChild(mList);
+
+ //****************************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);
+ LLGestureMgr::instance().addObserver(this);
// refresh list from current active gestures
refreshGestures();
+
+ setFocusLostCallback(boost::bind(&LLGestureComboList::hideList, this));
}
-LLGestureComboBox::~LLGestureComboBox()
+BOOL LLGestureComboList::handleKeyHere(KEY key, MASK mask)
{
- LLGestureManager::instance().removeObserver(this);
+ BOOL handled = FALSE;
+
+ if (key == KEY_ESCAPE && mask == MASK_NONE )
+ {
+ hideList();
+ handled = TRUE;
+ }
+ else
+ {
+ handled = mList->handleKeyHere(key, mask);
+ }
+
+ return handled;
}
-void LLGestureComboBox::refreshGestures()
+void LLGestureComboList::showList()
+{
+ LLRect rect = mList->getRect();
+ LLRect button_rect = mButton->getRect();
+
+ // Calculating amount of space between the navigation bar and gestures combo
+ LLNavigationBar* nb = LLNavigationBar::getInstance();
+
+ S32 x, nb_bottom;
+ nb->localPointToOtherView(0, 0, &x, &nb_bottom, this);
+
+ S32 max_height = nb_bottom - button_rect.mTop;
+ mList->calcColumnWidths();
+ rect.setOriginAndSize(button_rect.mLeft, button_rect.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);
+ LLUI::addPopup(mList);
+}
+
+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);
+ LLUI::removePopup(mList);
+ gFocusMgr.setKeyboardFocus(NULL);
+ }
+}
+
+S32 LLGestureComboList::getCurrentIndex() const
+{
+ LLScrollListItem* item = mList->getFirstSelected();
+ if( item )
+ {
+ return mList->getItemIndex( item );
+ }
+ return -1;
+}
+
+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::iterator it;
+ LLGestureMgr::item_map_t::const_iterator it;
+ const LLGestureMgr::item_map_t& active_gestures = LLGestureMgr::instance().getActiveGestures();
LLSD::Integer idx(0);
- for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it)
+ for (it = active_gestures.begin(); it != active_gestures.end(); ++it)
{
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++;
}
@@ -109,23 +262,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 && LLGestureMgr::instance().isGesturePlaying(gesture))
+ {
+ return;
}
+
+ mButton->setLabel(mLabel);
}
-void LLGestureComboBox::onCommitGesture()
+void LLGestureComboList::onCommitGesture()
{
LLCtrlListInterface* gestures = getListInterface();
if (gestures)
@@ -149,38 +321,25 @@ void LLGestureComboBox::onCommitGesture()
LLMultiGesture* gesture = mGestures.at(index);
if(gesture)
{
- LLGestureManager::instance().playGesture(gesture);
+ LLGestureMgr::instance().playGesture(gesture);
if(!gesture->mReplaceText.empty())
{
LLNearbyChatBar::sendChatFromViewer(gesture->mReplaceText, CHAT_TYPE_NORMAL, FALSE);
}
}
}
-
- 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();
+ LLGestureMgr::instance().removeObserver(this);
}
LLNearbyChatBar::LLNearbyChatBar()
: LLPanel()
, mChatBox(NULL)
{
+ mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
}
//virtual
@@ -198,19 +357,10 @@ BOOL LLNearbyChatBar::postBuild()
mChatBox->setIgnoreTab(TRUE);
mChatBox->setPassDelete(TRUE);
mChatBox->setReplaceNewlinesWithSpaces(FALSE);
- mChatBox->setMaxTextLength(1023);
mChatBox->setEnableLineHistory(TRUE);
mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
mOutputMonitor->setVisible(FALSE);
- mTalkBtn = getParent()->getChild<LLTalkButton>("talk");
-
- // Speak button should be initially disabled because
- // it takes some time between logging in to world and connecting to voice channel.
- mTalkBtn->setEnabled(FALSE);
-
- // Registering Chat Bar to receive Voice client status change notifications.
- gVoiceClient->addObserver(this);
return TRUE;
}
@@ -229,16 +379,6 @@ bool LLNearbyChatBar::instanceExists()
void LLNearbyChatBar::draw()
{
- LLRect rect = getRect();
- S32 max_width = getMaxWidth();
-
- if (rect.getWidth() > max_width)
- {
- rect.setLeftTopAndSize(rect.mLeft, rect.mTop, max_width, rect.getHeight());
- reshape(rect.getWidth(), rect.getHeight(), FALSE);
- setRect(rect);
- }
-
displaySpeakingIndicator();
LLPanel::draw();
}
@@ -264,32 +404,6 @@ BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask )
return handled;
}
-S32 LLNearbyChatBar::getMinWidth() const
-{
- static S32 min_width = -1;
-
- if (min_width < 0)
- {
- const std::string& s = getString("min_width");
- min_width = !s.empty() ? atoi(s.c_str()) : 300;
- }
-
- return min_width;
-}
-
-S32 LLNearbyChatBar::getMaxWidth() const
-{
- static S32 max_width = -1;
-
- if (max_width < 0)
- {
- const std::string& s = getString("max_width");
- max_width = !s.empty() ? atoi(s.c_str()) : 510;
- }
-
- return max_width;
-}
-
BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
{
U32 in_len = in_str.length();
@@ -362,7 +476,7 @@ void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
std::string utf8_trigger = wstring_to_utf8str(raw_text);
std::string utf8_out_str(utf8_trigger);
- if (LLGestureManager::instance().matchPrefix(utf8_trigger, &utf8_out_str))
+ if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
{
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
@@ -444,7 +558,7 @@ void LLNearbyChatBar::sendChat( EChatType type )
if (0 == channel)
{
// discard returned "found" boolean
- LLGestureManager::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
+ LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
}
else
{
@@ -491,8 +605,8 @@ void LLNearbyChatBar::displaySpeakingIndicator()
LLUUID id;
id.setNull();
- mSpeakerMgr.update(TRUE);
- mSpeakerMgr.getSpeakerList(&speaker_list, FALSE);
+ mSpeakerMgr->update(TRUE);
+ mSpeakerMgr->getSpeakerList(&speaker_list, FALSE);
for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
{
@@ -664,11 +778,6 @@ LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channe
}
}
-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;
@@ -698,32 +807,14 @@ public:
{
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;
- }
-};
-void LLNearbyChatBar::onChange(EStatusType status, const std::string &channelURI, bool proximal)
-{
- // Time it takes to connect to voice channel might be pretty long,
- // so don't expect user login or STATUS_VOICE_ENABLED to be followed by STATUS_JOINED.
- BOOL enable = FALSE;
+ // Send unescaped message, see EXT-6353.
+ std::string unescaped_mesg (LLURI::unescape(tokens[1].asString()));
- switch (status)
- {
- // Do not add STATUS_VOICE_ENABLED because voice chat is
- // inactive until STATUS_JOINED
- case STATUS_JOINED:
- enable = TRUE;
- break;
- default:
- enable = FALSE;
- break;
+ send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel);
+ return true;
}
-
- mTalkBtn->setEnabled(enable);
-}
+};
// Creating the object registers with the dispatcher.
LLChatHandler gChatHandler;