diff options
Diffstat (limited to 'indra')
32 files changed, 686 insertions, 381 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e632cbaaf2..e7e89d9701 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -90,6 +90,7 @@ set(viewer_SOURCE_FILES llbox.cpp llbreadcrumbview.cpp llcallbacklist.cpp + llcallfloater.cpp llcallingcard.cpp llcapabilitylistener.cpp llcaphttpsender.cpp @@ -588,6 +589,7 @@ set(viewer_HEADER_FILES llbox.h llbreadcrumbview.h llcallbacklist.h + llcallfloater.h llcallingcard.h llcapabilitylistener.h llcapabilityprovider.h diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 327d80ba34..8f3eba98a6 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -234,6 +234,7 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) // Check if cache already contains image_id for that avatar if (!updateFromCache()) { + LLIconCtrl::setValue(mDefaultIconName); app->addObserver(mAvatarId, this); app->sendAvatarPropertiesRequest(mAvatarId); } diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index bb03f47f46..7f3f869e5d 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -363,37 +363,6 @@ void LLAvatarList::computeDifference( vadded.erase(it, vadded.end()); } -static std::string format_secs(S32 secs) -{ - // *TODO: reinventing the wheel? - // *TODO: i18n - static const int LL_AL_MIN = 60; - static const int LL_AL_HOUR = LL_AL_MIN * 60; - static const int LL_AL_DAY = LL_AL_HOUR * 24; - static const int LL_AL_WEEK = LL_AL_DAY * 7; - static const int LL_AL_MONTH = LL_AL_DAY * 31; - static const int LL_AL_YEAR = LL_AL_DAY * 365; - - std::string s; - - if (secs >= LL_AL_YEAR) - s = llformat("%dy", secs / LL_AL_YEAR); - else if (secs >= LL_AL_MONTH) - s = llformat("%dmon", secs / LL_AL_MONTH); - else if (secs >= LL_AL_WEEK) - s = llformat("%dw", secs / LL_AL_WEEK); - else if (secs >= LL_AL_DAY) - s = llformat("%dd", secs / LL_AL_DAY); - else if (secs >= LL_AL_HOUR) - s = llformat("%dh", secs / LL_AL_HOUR); - else if (secs >= LL_AL_MIN) - s = llformat("%dm", secs / LL_AL_MIN); - else - s = llformat("%ds", secs); - - return s; -} - // Refresh shown time of our last interaction with all listed avatars. void LLAvatarList::updateLastInteractionTimes() { @@ -407,7 +376,7 @@ void LLAvatarList::updateLastInteractionTimes() LLAvatarListItem* item = static_cast<LLAvatarListItem*>(*it); S32 secs_since = now - (S32) LLRecentPeople::instance().getDate(item->getAvatarId()).secondsSinceEpoch(); if (secs_since >= 0) - item->setLastInteractionTime(format_secs(secs_since)); + item->setLastInteractionTime(secs_since); } } diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index c670a65bcc..efc9538fa6 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -198,9 +198,9 @@ void LLAvatarListItem::showLastInteractionTime(bool show) mAvatarName->setRect(name_rect); } -void LLAvatarListItem::setLastInteractionTime(const std::string& val) +void LLAvatarListItem::setLastInteractionTime(U32 secs_since) { - mLastInteractionTime->setValue(val); + mLastInteractionTime->setValue(formatSeconds(secs_since)); } void LLAvatarListItem::setShowInfoBtn(bool show) @@ -326,3 +326,51 @@ void LLAvatarListItem::reshapeAvatarName() mAvatarName->reshape(width, height); } + +// Convert given number of seconds to a string like "23 minutes", "15 hours" or "3 years", +// taking i18n into account. The format string to use is taken from the panel XML. +std::string LLAvatarListItem::formatSeconds(U32 secs) +{ + static const U32 LL_ALI_MIN = 60; + static const U32 LL_ALI_HOUR = LL_ALI_MIN * 60; + static const U32 LL_ALI_DAY = LL_ALI_HOUR * 24; + static const U32 LL_ALI_WEEK = LL_ALI_DAY * 7; + static const U32 LL_ALI_MONTH = LL_ALI_DAY * 30; + static const U32 LL_ALI_YEAR = LL_ALI_DAY * 365; + + std::string fmt; + U32 count = 0; + + if (secs >= LL_ALI_YEAR) + { + fmt = "FormatYears"; count = secs / LL_ALI_YEAR; + } + else if (secs >= LL_ALI_MONTH) + { + fmt = "FormatMonths"; count = secs / LL_ALI_MONTH; + } + else if (secs >= LL_ALI_WEEK) + { + fmt = "FormatWeeks"; count = secs / LL_ALI_WEEK; + } + else if (secs >= LL_ALI_DAY) + { + fmt = "FormatDays"; count = secs / LL_ALI_DAY; + } + else if (secs >= LL_ALI_HOUR) + { + fmt = "FormatHours"; count = secs / LL_ALI_HOUR; + } + else if (secs >= LL_ALI_MIN) + { + fmt = "FormatMinutes"; count = secs / LL_ALI_MIN; + } + else + { + fmt = "FormatSeconds"; count = secs; + } + + LLStringUtil::format_map_t args; + args["[COUNT]"] = llformat("%u", count); + return getString(fmt, args); +} diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 9d48101a44..341f5a6bcf 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -63,7 +63,7 @@ public: void setOnline(bool online); void setName(const std::string& name); void setAvatarId(const LLUUID& id, bool ignore_status_changes = false); - void setLastInteractionTime(const std::string& val); + void setLastInteractionTime(U32 secs_since); //Show/hide profile/info btn, translating speaker indicator and avatar name coordinates accordingly void setShowProfileBtn(bool show); void setShowInfoBtn(bool show); @@ -94,6 +94,8 @@ private: void onNameCache(const std::string& first_name, const std::string& last_name); + std::string formatSeconds(U32 secs); + LLAvatarIconCtrl* mAvatarIcon; LLTextBox* mAvatarName; LLTextBox* mLastInteractionTime; diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp new file mode 100644 index 0000000000..f566806b29 --- /dev/null +++ b/indra/newview/llcallfloater.cpp @@ -0,0 +1,76 @@ +/** + * @file llcallfloater.cpp + * @author Mike Antipov + * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...). + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llcallfloater.h" + +#include "llavatarlist.h" +#include "llbottomtray.h" +#include "llparticipantlist.h" +#include "llspeakers.h" + + +LLCallFloater::LLCallFloater(const LLSD& key) +: LLDockableFloater(NULL, key) +, mSpeakerManager(NULL) +, mPaticipants(NULL) +, mAvatarList(NULL) +{ + +} + +LLCallFloater::~LLCallFloater() +{ + delete mPaticipants; + mPaticipants = NULL; +} + +// virtual +BOOL LLCallFloater::postBuild() +{ + LLDockableFloater::postBuild(); + mAvatarList = getChild<LLAvatarList>("speakers_list"); + + mSpeakerManager = LLLocalSpeakerMgr::getInstance(); + mPaticipants = new LLParticipantList(mSpeakerManager, mAvatarList, false); + + LLView *anchor_panel = LLBottomTray::getInstance()->getChild<LLView>("speak_panel"); + + setDockControl(new LLDockControl( + anchor_panel, this, + getDockTongue(), LLDockControl::TOP)); + + return TRUE; +} +//EOF diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h new file mode 100644 index 0000000000..8c4a204943 --- /dev/null +++ b/indra/newview/llcallfloater.h @@ -0,0 +1,71 @@ +/** + * @file llcallfloater.h + * @author Mike Antipov + * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...). + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLCALLFLOATER_H +#define LL_LLCALLFLOATER_H + +#include "lldockablefloater.h" + +class LLAvatarList; +class LLParticipantList; +class LLSpeakerMgr; + +/** + * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron on the Speak button. + * It can be torn-off and freely positioned onscreen. + * + * When the Resident is engaged in Nearby Voice Chat, the Voice Control Panel provides control over + * the Resident's own microphone input volume, the audible volume of each of the other participants, + * the Resident's own Voice Morphing settings (if she has subscribed to enable the feature), and Voice Recording. + * + * When the Resident is engaged in Group Voice Chat, the Voice Control Panel also provides an + * 'End Call' button to allow the Resident to leave that voice channel. + */ +class LLCallFloater : public LLDockableFloater +{ +public: + LLCallFloater(const LLSD& key); + ~LLCallFloater(); + + /*virtual*/ BOOL postBuild(); + + +private: + LLSpeakerMgr* mSpeakerManager; + LLParticipantList* mPaticipants; + LLAvatarList* mAvatarList; +}; + + +#endif //LL_LLCALLFLOATER_H + diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 2c9b38b82a..caf9c08057 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -199,7 +199,7 @@ public: userName->setValue(SL); } - setTimeField(chat.mTimeStr); + setTimeField(chat); LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon"); @@ -267,11 +267,29 @@ protected: } private: - void setTimeField(const std::string& time_value) + std::string appendTime(const LLChat& chat)
+ {
+ time_t utc_time;
+ utc_time = time_corrected();
+ std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
+ +LLTrans::getString("TimeMin")+"] ";
+
+ LLSD substitution;
+
+ substitution["datetime"] = (S32) utc_time;
+ LLStringUtil::format (timeStr, substitution);
+
+ return timeStr;
+ }
+ + void setTimeField(const LLChat& chat) { LLTextBox* time_box = getChild<LLTextBox>("time_box"); LLRect rect_before = time_box->getRect(); + + std::string time_value = appendTime(chat); + time_box->setValue(time_value); // set necessary textbox width to fit all text @@ -386,7 +404,11 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_ p.left_pad = mLeftWidgetPad; p.right_pad = mRightWidgetPad; - if (mLastFromName == chat.mFromName) + LLDate new_message_time = LLDate::now(); + + if (mLastFromName == chat.mFromName && + mLastMessageTime.notNull() && + (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0 ) { view = getSeparator(); p.top_pad = mTopSeparatorPad; @@ -414,6 +436,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_ appendWidget(p, header_text, false); mLastFromName = chat.mFromName; + mLastMessageTime = new_message_time; } //Handle IRC styled /me messages. std::string prefix = chat.mText.substr(0, 4); diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index ef5839ff2f..d2cfa53d8b 100644 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -114,6 +114,7 @@ class LLChatHistory : public LLTextEditor private: std::string mLastFromName; + LLDate mLastMessageTime; std::string mMessageHeaderFilename; std::string mMessageSeparatorFilename; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 8a6935b71b..4acb9fd480 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -44,27 +44,12 @@ #include "llviewercontrol.h" #include "llagentdata.h" -/* -static const S32 BORDER_MARGIN = 2; -static const S32 PARENT_BORDER_MARGIN = 0; - -static const S32 HORIZONTAL_MULTIPLE = 8; -static const S32 VERTICAL_MULTIPLE = 16; -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; - -#define MAX_CHAT_HISTORY 100 -*/ - -static const S32 msg_left_offset = 30; +static const S32 msg_left_offset = 10; static const S32 msg_right_offset = 10; -static const S32 msg_height_pad = 2; - -//static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container"); +static const S32 msg_height_pad = 5; //******************************************************************************************************************* -//LLChatItemCtrl +//LLNearbyChatToastPanel //******************************************************************************************************************* LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance() @@ -79,22 +64,22 @@ void LLNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_p { LLPanel::reshape(width, height,called_from_parent); - // *NOTE: we must check if child items exist because reshape is called from the - // LLView::initFromParams BEFORE postBuild is called and child controls are not exist yet - LLPanel* caption = findChild<LLPanel>("msg_caption", false); - LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text" ,false); - if(caption && msg_text) - { - LLRect caption_rect = caption->getRect(); - caption_rect.setLeftTopAndSize( 2, height, width - 4, caption_rect.getHeight()); - caption->reshape( width - 4, caption_rect.getHeight(), 1); - caption->setRect(caption_rect); - - LLRect msg_text_rect = msg_text->getRect(); - 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); - } + LLUICtrl* msg_text = getChild<LLUICtrl>("msg_text", false); + LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false); + + LLRect msg_text_rect = msg_text->getRect(); + LLRect avatar_rect = icon->getRect(); + + avatar_rect.setLeftTopAndSize(2,height-2,avatar_rect.getWidth(),avatar_rect.getHeight()); + icon->setRect(avatar_rect); + + + msg_text_rect.setLeftTopAndSize( avatar_rect.mRight + msg_left_offset, + height - msg_height_pad, + width - avatar_rect.mRight - msg_left_offset - msg_right_offset, + height - 2*msg_height_pad); + msg_text->reshape( msg_text_rect.getWidth(), msg_text_rect.getHeight(), 1); + msg_text->setRect(msg_text_rect); } BOOL LLNearbyChatToastPanel::postBuild() @@ -102,37 +87,63 @@ BOOL LLNearbyChatToastPanel::postBuild() return LLPanel::postBuild(); } - -std::string LLNearbyChatToastPanel::appendTime() +void LLNearbyChatToastPanel::addMessage(LLSD& notification) { - time_t utc_time; - utc_time = time_corrected(); - std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" - +LLTrans::getString("TimeMin")+"] "; + std::string messageText = notification["message"].asString(); // UTF-8 line of text - LLSD substitution; + LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); - substitution["datetime"] = (S32) utc_time; - LLStringUtil::format (timeStr, substitution); + std::string color_name = notification["text_color"].asString(); + + LLColor4 textColor = LLUIColorTable::instance().getColor(color_name); + textColor.mV[VALPHA] =notification["color_alpha"].asReal(); + + S32 font_size = notification["font_size"].asInteger(); - return timeStr; -} + LLFontGL* messageFont; + switch(font_size) + { + case 0: messageFont = LLFontGL::getFontSansSerifSmall(); break; + default: + case 1: messageFont = LLFontGL::getFontSansSerif(); break; + case 2: messageFont = LLFontGL::getFontSansSerifBig(); break; + } + //append text + { + LLStyle::Params style_params; + style_params.color(textColor); + std::string font_name = LLFontGL::nameFromFont(messageFont); + std::string font_style_size = LLFontGL::sizeFromFont(messageFont); + style_params.font.name(font_name); + style_params.font.size(font_style_size); + int chat_type = notification["chat_type"].asInteger(); + + if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC) + { + messageText = messageText.substr(3); + style_params.font.style = "ITALIC"; + } + else if( chat_type == CHAT_TYPE_SHOUT) + { + style_params.font.style = "BOLD"; + } + else if( chat_type == CHAT_TYPE_WHISPER) + { + style_params.font.style = "ITALIC"; + } + msg_text->appendText(messageText, TRUE, style_params); + } + + snapToMessageHeight(); -void LLNearbyChatToastPanel::addText (const std::string& message , const LLStyle::Params& input_params) -{ - LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); - msg_text->addText(message , input_params); - mMessages.push_back(message); } void LLNearbyChatToastPanel::init(LLSD& notification) { - LLPanel* caption = getChild<LLPanel>("msg_caption", false); - - mText = notification["message"].asString(); // UTF-8 line of text - mFromName = notification["from"].asString(); // agent or object name + std::string messageText = notification["message"].asString(); // UTF-8 line of text + std::string fromName = notification["from"].asString(); // agent or object name mFromID = notification["from_id"].asUUID(); // agent id or object id int sType = notification["source"].asInteger(); @@ -140,192 +151,121 @@ void LLNearbyChatToastPanel::init(LLSD& notification) std::string color_name = notification["text_color"].asString(); - mTextColor = LLUIColorTable::instance().getColor(color_name); - mTextColor.mV[VALPHA] =notification["color_alpha"].asReal(); + LLColor4 textColor = LLUIColorTable::instance().getColor(color_name); + textColor.mV[VALPHA] =notification["color_alpha"].asReal(); S32 font_size = notification["font_size"].asInteger(); + + LLFontGL* messageFont; switch(font_size) { - case 0: - mFont = LLFontGL::getFontSansSerifSmall(); - break; + case 0: messageFont = LLFontGL::getFontSansSerifSmall(); break; default: - case 1: - mFont = LLFontGL::getFontSansSerif(); - break; - case 2: - mFont = LLFontGL::getFontSansSerifBig(); - break; + case 1: messageFont = LLFontGL::getFontSansSerif(); break; + case 2: messageFont = LLFontGL::getFontSansSerifBig(); break; } - LLStyle::Params style_params; - style_params.color(mTextColor); -// style_params.font(mFont); - std::string font_name = LLFontGL::nameFromFont(mFont); - std::string font_style_size = LLFontGL::sizeFromFont(mFont); - style_params.font.name(font_name); - style_params.font.size(font_style_size); + LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); + + msg_text->setText(std::string("")); std::string str_sender; if(gAgentID != mFromID) - str_sender = mFromName; + str_sender = fromName; else - str_sender = LLTrans::getString("You");; + str_sender = LLTrans::getString("You"); - caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender , style_params); - - LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); + str_sender+=" "; + //append user name + { + LLStyle::Params style_params_name; + + LLColor4 userNameColor = LLUIColorTable::instance().getColor("ChatToastAgentNameColor"); + + style_params_name.color(userNameColor); + + std::string font_name = LLFontGL::nameFromFont(messageFont); + std::string font_style_size = LLFontGL::sizeFromFont(messageFont); + style_params_name.font.name(font_name); + style_params_name.font.size(font_style_size); + + msg_text->appendText(str_sender, FALSE, style_params_name); + + } - if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC) + //append text { - if (mFromName.size() > 0) + LLStyle::Params style_params; + style_params.color(textColor); + std::string font_name = LLFontGL::nameFromFont(messageFont); + std::string font_style_size = LLFontGL::sizeFromFont(messageFont); + style_params.font.name(font_name); + style_params.font.size(font_style_size); + + int chat_type = notification["chat_type"].asInteger(); + + if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC) { + messageText = messageText.substr(3); style_params.font.style = "ITALIC"; - - msg_text->setText(mFromName, style_params); } - mText = mText.substr(3); - style_params.font.style = "ITALIC"; -#define INFINITE_REFLOW_BUG 0 -#if INFINITE_REFLOW_BUG - // This causes LLTextBase::reflow() to infinite loop until the viewer - // runs out of memory, throws a bad_alloc exception from std::vector - // in mLineInfoList, and the main loop catches it and continues. - // It appears to be caused by addText() adding a line separator in the - // middle of a line. See EXT-2579, EXT-1949 - msg_text->addText(mText,style_params); -#else - msg_text->appendText(mText, FALSE, style_params); -#endif - } - else - { - msg_text->setText(mText, style_params); + else if( chat_type == CHAT_TYPE_SHOUT) + { + style_params.font.style = "BOLD"; + } + else if( chat_type == CHAT_TYPE_WHISPER) + { + style_params.font.style = "ITALIC"; + } + msg_text->appendText(messageText, FALSE, style_params); } - - LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); - if(mSourceType != CHAT_SOURCE_AGENT) - msg_inspector->setVisible(false); - - mMessages.clear(); - - snapToMessageHeight (); + snapToMessageHeight(); mIsDirty = true;//will set Avatar Icon in draw } -void LLNearbyChatToastPanel::setMessage (const LLChat& chat_msg) -{ - LLSD notification; - notification["message"] = chat_msg.mText; - notification["from"] = chat_msg.mFromName; - notification["from_id"] = chat_msg.mFromID; - notification["time"] = chat_msg.mTime; - notification["source"] = (S32)chat_msg.mSourceType; - notification["chat_type"] = (S32)chat_msg.mChatType; - notification["chat_style"] = (S32)chat_msg.mChatStyle; - - std::string r_color_name="White"; - F32 r_color_alpha = 1.0f; - LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha); - - notification["text_color"] = r_color_name; - notification["color_alpha"] = r_color_alpha; - - notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ; - init(notification); - -} - void LLNearbyChatToastPanel::snapToMessageHeight () { LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); - S32 new_height = text_box->getTextPixelHeight() + msg_height_pad; + S32 new_height = llmax (text_box->getTextPixelHeight() + 2*text_box->getVPad() + 2*msg_height_pad, 25); + LLRect panel_rect = getRect(); - S32 caption_height = 0; - LLPanel* caption = getChild<LLPanel>("msg_caption", false); - caption_height = caption->getRect().getHeight(); - - panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), caption_height + new_height); + panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), new_height); - reshape( getRect().getWidth(), caption_height + new_height, 1); + reshape( getRect().getWidth(), getRect().getHeight(), 1); setRect(panel_rect); } - -void LLNearbyChatToastPanel::setWidth(S32 width) -{ - LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); - 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); - - LLStyle::Params style_params; - style_params.color(mTextColor); - style_params.font(mFont); - - - if(mText.length()) - msg_text->setText(mText, style_params); - - for(size_t i=0;i<mMessages.size();++i) - msg_text->addText(mMessages[i] , style_params); - - setRect(LLRect(getRect().mLeft, getRect().mTop, getRect().mLeft + width , getRect().mBottom)); - snapToMessageHeight (); -} - void LLNearbyChatToastPanel::onMouseLeave (S32 x, S32 y, MASK mask) { - LLPanel* caption = getChild<LLPanel>("msg_caption", false); - LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); - msg_inspector->setVisible(false); } void LLNearbyChatToastPanel::onMouseEnter (S32 x, S32 y, MASK mask) { if(mSourceType != CHAT_SOURCE_AGENT) return; - LLPanel* caption = getChild<LLPanel>("msg_caption", false); - LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); - msg_inspector->setVisible(true); } BOOL LLNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask) { if(mSourceType != CHAT_SOURCE_AGENT) return LLPanel::handleMouseDown(x,y,mask); - LLPanel* caption = getChild<LLPanel>("msg_caption", false); - LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); - S32 local_x = x - msg_inspector->getRect().mLeft - caption->getRect().mLeft; - S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom; - if(msg_inspector->pointInView(local_x, local_y)) - { - LLFloaterReg::showInstance("inspect_avatar", LLSD().insert("avatar_id", mFromID)); - } - else - { - LLFloaterReg::showInstance("nearby_chat",LLSD()); - } + LLFloaterReg::showInstance("nearby_chat",LLSD()); return LLPanel::handleMouseDown(x,y,mask); } void LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e) { - LLPanel* caption = getChild<LLPanel>("msg_caption", false); - - LLUICtrl* icon = caption->getChild<LLUICtrl>("avatar_icon", false); - LLUICtrl* name = caption->getChild<LLUICtrl>("sender_name", false); - - icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH); - name->setVisible(e == CHATITEMHEADER_SHOW_ONLY_NAME || e==CHATITEMHEADER_SHOW_BOTH); + LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false); + if(icon) + icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH); } @@ -339,11 +279,10 @@ bool LLNearbyChatToastPanel::canAddText () BOOL LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask) { - LLPanel* caption = getChild<LLPanel>("msg_caption", false); - LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon", false); + LLUICtrl* avatar_icon = getChild<LLUICtrl>("avatar_icon", false); - S32 local_x = x - avatar_icon->getRect().mLeft - caption->getRect().mLeft; - S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom; + S32 local_x = x - avatar_icon->getRect().mLeft; + S32 local_y = y - avatar_icon->getRect().mBottom; //eat message for avatar icon if msg was from object if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT) @@ -354,9 +293,7 @@ void LLNearbyChatToastPanel::draw() { if(mIsDirty) { - LLPanel* caption = findChild<LLPanel>("msg_caption", false); - if(caption) - caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(mFromID); + getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(mFromID); mIsDirty = false; } LLToastPanelBase::draw(); diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h index a65bfedd09..0a85c52401 100644 --- a/indra/newview/llchatitemscontainerctrl.h +++ b/indra/newview/llchatitemscontainerctrl.h @@ -59,9 +59,8 @@ public: const LLUUID& getFromID() const { return mFromID;} - void addText (const std::string& message , const LLStyle::Params& input_params = LLStyle::Params()); - void setMessage (const LLChat& msg); - void setWidth (S32 width); + //void addText (const std::string& message , const LLStyle::Params& input_params = LLStyle::Params()); + //void setMessage (const LLChat& msg); void snapToMessageHeight (); bool canAddText (); @@ -78,22 +77,16 @@ public: BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); virtual void init(LLSD& data); + virtual void addMessage(LLSD& data); virtual void draw(); -private: - - std::string appendTime (); + const LLUUID& messageID() const { return mFromID;} private: - std::string mText; // UTF-8 line of text - std::string mFromName; // agent or object name LLUUID mFromID; // agent id or object id EChatSourceType mSourceType; - LLColor4 mTextColor; - LLFontGL* mFont; - + - std::vector<std::string> mMessages; bool mIsDirty; }; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index ee93a9349a..310eaaec27 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -529,7 +529,6 @@ void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* //in disconnected state IM input editor should be disabled self->mInputEditor->setEnabled(!gDisconnected); } - self->mChatHistory->setCursorAndScrollToEnd(); } // static diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 74a75d0369..b0b6db682c 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -52,8 +52,6 @@ using namespace LLNotificationsUI; LLToastPanelBase* createToastPanel() { LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance(); - static S32 chat_item_width = 304; - item->setWidth(chat_item_width); return item; } @@ -169,6 +167,29 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification) //look in pool. if there is any message if(mStopProcessing) return; + + /* + find last toast and check ID + */ + + if(m_active_toasts.size()) + { + LLUUID fromID = notification["from_id"].asUUID(); // agent id or object id + LLToast* toast = m_active_toasts[0]; + LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel()); + + if(panel && panel->messageID() == fromID && panel->canAddText()) + { + panel->addMessage(notification); + toast->reshapeToPanel(); + toast->resetTimer(); + + arrangeToasts(); + return; + } + } + + if(m_toast_pool.empty()) { diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index da7922d657..020c25c8ac 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1544,9 +1544,6 @@ void LLPanelGroupMembersSubTab::updateMembers() mPendingMemberUpdate = FALSE; // Rebuild the members list. - mMembersList->deleteAllItems(); - - lldebugs << "LLPanelGroupMembersSubTab::updateMembers()" << llendl; LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); if (!gdatap) @@ -1563,7 +1560,12 @@ void LLPanelGroupMembersSubTab::updateMembers() { return; } - + + //cleanup list only for first iretation + if(mMemberProgress == gdatap->mMembers.begin()) + mMembersList->deleteAllItems(); + + LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); S32 i = 0; diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index fa6d16cfb1..78b4d29b16 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -120,6 +120,7 @@ LLPanelIMControlPanel::LLPanelIMControlPanel() LLPanelIMControlPanel::~LLPanelIMControlPanel() { + LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this); } BOOL LLPanelIMControlPanel::postBuild() @@ -169,7 +170,9 @@ void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id) LLIMModel& im_model = LLIMModel::instance(); + LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this); mAvatarID = im_model.getOtherParticipantID(session_id); + LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this); // Disable "Add friend" button for friends. childSetEnabled("add_friend_btn", !LLAvatarActions::isFriend(mAvatarID)); @@ -198,6 +201,12 @@ void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id) } } +//virtual +void LLPanelIMControlPanel::changed(U32 mask) +{ + childSetEnabled("add_friend_btn", !LLAvatarActions::isFriend(mAvatarID)); +} + void LLPanelIMControlPanel::nameUpdatedCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group) { if ( id == mAvatarID ) diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index 7bfc432ef2..a590232a0b 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -35,6 +35,7 @@ #include "llpanel.h" #include "llvoicechannel.h" +#include "llcallingcard.h" class LLSpeakerMgr; class LLAvatarList; @@ -66,7 +67,7 @@ private: }; -class LLPanelIMControlPanel : public LLPanelChatControlPanel +class LLPanelIMControlPanel : public LLPanelChatControlPanel, LLFriendObserver { public: LLPanelIMControlPanel(); @@ -76,6 +77,9 @@ public: void setSessionId(const LLUUID& session_id); + // LLFriendObserver trigger + virtual void changed(U32 mask); + protected: void nameUpdatedCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index e6b6ec64bd..73d903ed36 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -73,6 +73,8 @@ static const std::string FRIENDS_TAB_NAME = "friends_panel"; static const std::string GROUP_TAB_NAME = "groups_panel"; static const std::string RECENT_TAB_NAME = "recent_panel"; +static const std::string COLLAPSED_BY_USER = "collapsed_by_user"; + /** Comparator for comparing avatar items by last interaction date */ class LLAvatarItemRecentComparator : public LLAvatarItemComparator { @@ -467,7 +469,7 @@ LLPanelPeople::~LLPanelPeople() } -void LLPanelPeople::onFriendsAccordionExpandedCollapsed(const LLSD& param, LLAvatarList* avatar_list) +void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list) { if(!avatar_list) { @@ -477,6 +479,7 @@ void LLPanelPeople::onFriendsAccordionExpandedCollapsed(const LLSD& param, LLAva bool expanded = param.asBoolean(); + setAccordionCollapsedByUser(ctrl, !expanded); if(!expanded) { avatar_list->resetSelection(); @@ -550,11 +553,11 @@ BOOL LLPanelPeople::postBuild() LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>("tab_all"); accordion_tab->setDropDownStateChangedCallback( - boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _2, mAllFriendList)); + boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mAllFriendList)); accordion_tab = getChild<LLAccordionCtrlTab>("tab_online"); accordion_tab->setDropDownStateChangedCallback( - boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _2, mOnlineFriendList)); + boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mOnlineFriendList)); buttonSetAction("view_profile_btn", boost::bind(&LLPanelPeople::onViewProfileButtonClicked, this)); buttonSetAction("group_info_btn", boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this)); @@ -931,6 +934,9 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string) mRecentList->setNameFilter(mFilterSubString); mGroupList->setNameFilter(mFilterSubString); + setAccordionCollapsedByUser("tab_online", false); + setAccordionCollapsedByUser("tab_all", false); + showFriendsAccordionsIfNeeded(); } @@ -1309,8 +1315,12 @@ void LLPanelPeople::showAccordion(const std::string name, bool show) tab->setVisible(show); if(show) { - // expand accordion - tab->changeOpenClose(false); + // don't expand accordion if it was collapsed by user + if(!isAccordionCollapsedByUser(tab)) + { + // expand accordion + tab->changeOpenClose(false); + } } } @@ -1342,3 +1352,44 @@ void LLPanelPeople::onFriendListRefreshComplete(LLUICtrl*ctrl, const LLSD& param LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion"); accordion->arrange(); } + +void LLPanelPeople::setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed) +{ + if(!acc_tab) + { + llwarns << "Invalid parameter" << llendl; + return; + } + + LLSD param = acc_tab->getValue(); + param[COLLAPSED_BY_USER] = collapsed; + acc_tab->setValue(param); +} + +void LLPanelPeople::setAccordionCollapsedByUser(const std::string& name, bool collapsed) +{ + setAccordionCollapsedByUser(getChild<LLUICtrl>(name), collapsed); +} + +bool LLPanelPeople::isAccordionCollapsedByUser(LLUICtrl* acc_tab) +{ + if(!acc_tab) + { + llwarns << "Invalid parameter" << llendl; + return false; + } + + LLSD param = acc_tab->getValue(); + if(!param.has(COLLAPSED_BY_USER)) + { + return false; + } + return param[COLLAPSED_BY_USER].asBoolean(); +} + +bool LLPanelPeople::isAccordionCollapsedByUser(const std::string& name) +{ + return isAccordionCollapsedByUser(getChild<LLUICtrl>(name)); +} + +// EOF diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index d9dd76f3ac..5ac5bcc1d7 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -127,7 +127,7 @@ private: const std::vector<LLUUID>& ids, void*); - void onFriendsAccordionExpandedCollapsed(const LLSD& param, LLAvatarList* avatar_list); + void onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list); void showAccordion(const std::string name, bool show); @@ -135,6 +135,11 @@ private: void onFriendListRefreshComplete(LLUICtrl*ctrl, const LLSD& param); + void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed); + void setAccordionCollapsedByUser(const std::string& name, bool collapsed); + bool isAccordionCollapsedByUser(LLUICtrl* acc_tab); + bool isAccordionCollapsedByUser(const std::string& name); + LLFilterEditor* mFilterEditor; LLTabContainer* mTabContainer; LLAvatarList* mOnlineFriendList; diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index b82b994540..327048d4f3 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -52,6 +52,8 @@ // Used to limit time spent for items list update per frame. static const U32 ADD_LIMIT = 50; +static const std::string COLLAPSED_BY_USER = "collapsed_by_user"; + class LLTeleportHistoryFlatItem : public LLPanel { public: @@ -254,6 +256,10 @@ BOOL LLTeleportHistoryPanel::postBuild() LLAccordionCtrlTab* tab = (LLAccordionCtrlTab*)*iter; tab->setRightMouseDownCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionTabRightClick, this, _1, _2, _3, _4)); tab->setDisplayChildren(false); + tab->setDropDownStateChangedCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionExpand, this, _1, _2)); + + // All accordion tabs are collapsed initially + setAccordionCollapsedByUser(tab, true); mItemContainers.put(tab); @@ -270,10 +276,18 @@ BOOL LLTeleportHistoryPanel::postBuild() // Open first 2 accordion tabs if (mItemContainers.size() > 1) - mItemContainers.get(mItemContainers.size() - 1)->setDisplayChildren(true); + { + LLAccordionCtrlTab* tab = mItemContainers.get(mItemContainers.size() - 1); + tab->setDisplayChildren(true); + setAccordionCollapsedByUser(tab, false); + } if (mItemContainers.size() > 2) - mItemContainers.get(mItemContainers.size() - 2)->setDisplayChildren(true); + { + LLAccordionCtrlTab* tab = mItemContainers.get(mItemContainers.size() - 2); + tab->setDisplayChildren(true); + setAccordionCollapsedByUser(tab, false); + } } getChild<LLPanel>("bottom_panel")->childSetAction("gear_btn",boost::bind(&LLTeleportHistoryPanel::onGearButtonClicked, this)); @@ -491,6 +505,18 @@ void LLTeleportHistoryPanel::refresh() LLAccordionCtrlTab* tab = mItemContainers.get(mItemContainers.size() - 1 - tab_idx); tab->setVisible(true); + // Expand all accordion tabs when filtering + if(!mFilterSubString.empty()) + { + tab->setDisplayChildren(true); + } + // Restore each tab's expand state when not filtering + else + { + bool collapsed = isAccordionCollapsedByUser(tab); + tab->setDisplayChildren(!collapsed); + } + curr_flat_view = getFlatListViewFromTab(tab); } @@ -775,3 +801,26 @@ void LLTeleportHistoryPanel::onGearButtonClicked() LLMenuGL::showPopup(this, menu, menu_x, menu_y); } +void LLTeleportHistoryPanel::setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed) +{ + LLSD param = acc_tab->getValue(); + param[COLLAPSED_BY_USER] = collapsed; + acc_tab->setValue(param); +} + +bool LLTeleportHistoryPanel::isAccordionCollapsedByUser(LLUICtrl* acc_tab) +{ + LLSD param = acc_tab->getValue(); + if(!param.has("acc_collapsed")) + { + return false; + } + return param[COLLAPSED_BY_USER].asBoolean(); +} + +void LLTeleportHistoryPanel::onAccordionExpand(LLUICtrl* ctrl, const LLSD& param) +{ + bool expanded = param.asBoolean(); + // Save accordion tab state to restore it in refresh() + setAccordionCollapsedByUser(ctrl, !expanded); +} diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index a31ff34cb6..f646fea355 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -98,6 +98,10 @@ private: LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *); void onGearButtonClicked(); + void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed); + bool isAccordionCollapsedByUser(LLUICtrl* acc_tab); + void onAccordionExpand(LLUICtrl* ctrl, const LLSD& param); + LLTeleportHistoryStorage* mTeleportHistory; LLAccordionCtrl* mHistoryAccordion; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 4ee9cba69c..a5440c3687 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -47,10 +47,11 @@ #if LL_MSVC #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally #endif -LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list): +LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list, bool use_context_menu/* = true*/): mSpeakerMgr(data_source), mAvatarList(avatar_list), mSortOrder(E_SORT_BY_NAME) +, mParticipantListMenu(NULL) { mSpeakerAddListener = new SpeakerAddListener(*this); mSpeakerRemoveListener = new SpeakerRemoveListener(*this); @@ -68,8 +69,11 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av // Set onAvatarListDoubleClicked as default on_return action. mAvatarList->setReturnCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList)); - mParticipantListMenu = new LLParticipantListMenu(*this); - mAvatarList->setContextMenu(mParticipantListMenu); + if (use_context_menu) + { + mParticipantListMenu = new LLParticipantListMenu(*this); + mAvatarList->setContextMenu(mParticipantListMenu); + } //Lets fill avatarList with existing speakers LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index 5e26c39fc8..ce61dd9b96 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -43,7 +43,7 @@ class LLParticipantList { LOG_CLASS(LLParticipantList); public: - LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list); + LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list, bool use_context_menu = true); ~LLParticipantList(); void setSpeakingIndicatorsVisible(BOOL visible); diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp index 54f776ca6a..5edc4804ca 100644 --- a/indra/newview/llspeakbutton.cpp +++ b/indra/newview/llspeakbutton.cpp @@ -32,19 +32,14 @@ #include "llviewerprecompiledheaders.h" // must be first include -#include "llagent.h" -#include "llbottomtray.h" +#include "llbutton.h" #include "llfloaterreg.h" -#include "llvoiceclient.h" -#include "llvoicecontrolpanel.h" -#include "lltransientfloatermgr.h" -#include "llavatariconctrl.h" -#include "llbutton.h" -#include "llpanel.h" -#include "lltextbox.h" +#include "llagent.h" +#include "llbottomtray.h" +#include "llcallfloater.h" #include "lloutputmonitorctrl.h" -#include "llgroupmgr.h" +#include "lltransientfloatermgr.h" #include "llspeakbutton.h" @@ -72,7 +67,6 @@ void LLSpeakButton::draw() LLSpeakButton::LLSpeakButton(const Params& p) : LLUICtrl(p) -, mPrivateCallPanel(NULL) , mOutputMonitor(NULL) , mSpeakBtn(NULL) , mShowBtn(NULL) @@ -102,8 +96,8 @@ LLSpeakButton::LLSpeakButton(const Params& p) addChild(mShowBtn); LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn); - mShowBtn->setClickedCallback(boost::bind(&LLSpeakButton::onClick_ShowBtn, this)); - mShowBtn->setToggleState(FALSE); +// mShowBtn->setClickedCallback(boost::bind(&LLSpeakButton::onClick_ShowBtn, this)); +// mShowBtn->setToggleState(FALSE); static const S32 MONITOR_RIGHT_PAD = 2; @@ -175,42 +169,3 @@ void LLSpeakButton::onMouseUp_SpeakBtn() gVoiceClient->inputUserControlState(down); } -void LLSpeakButton::onClick_ShowBtn() -{ - if(!mShowBtn->getToggleState()) - { - mPrivateCallPanel->onClickClose(mPrivateCallPanel); - delete mPrivateCallPanel; - mPrivateCallPanel = NULL; - mShowBtn->setToggleState(FALSE); - return; - } - - S32 x = mSpeakBtn->getRect().mLeft; - S32 y = 0; - - localPointToScreen(x, y, &x, &y); - - mPrivateCallPanel = new LLVoiceControlPanel; - getRootView()->addChild(mPrivateCallPanel); - - y = LLBottomTray::getInstance()->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight(); - - LLRect rect; - rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight()); - mPrivateCallPanel->setRect(rect); - - - LLAvatarListItem* item = new LLAvatarListItem(); - item->showLastInteractionTime(false); - item->showInfoBtn(true); - item->showSpeakingIndicator(true); - item->reshape(mPrivateCallPanel->getRect().getWidth(), item->getRect().getHeight(), FALSE); - - mPrivateCallPanel->addItem(item); - mPrivateCallPanel->setVisible(TRUE); - mPrivateCallPanel->setFrontmost(TRUE); - - mShowBtn->setToggleState(TRUE); -} - diff --git a/indra/newview/llspeakbutton.h b/indra/newview/llspeakbutton.h index 424ee5357a..6660b50240 100644 --- a/indra/newview/llspeakbutton.h +++ b/indra/newview/llspeakbutton.h @@ -36,7 +36,7 @@ #include "llinitparam.h" #include "lluictrl.h" -class LLVoiceControlPanel; +class LLCallFloater; class LLButton; class LLOutputMonitorCtrl; @@ -86,12 +86,10 @@ protected: void onMouseDown_SpeakBtn(); void onMouseUp_SpeakBtn(); - void onClick_ShowBtn(); - private: LLButton* mSpeakBtn; LLButton* mShowBtn; - LLVoiceControlPanel* mPrivateCallPanel; + LLHandle<LLFloater> mPrivateCallPanel; LLOutputMonitorCtrl* mOutputMonitor; }; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 642df92379..227f6c4971 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -38,6 +38,7 @@ #include "llviewerfloaterreg.h" #include "llcompilequeue.h" +#include "llcallfloater.h" #include "llfloaterabout.h" #include "llfloateractivespeakers.h" #include "llfloateranimpreview.h" @@ -174,7 +175,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>); LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloaterContainer>); - LLFloaterReg::add("script_floater", "floater_script.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLScriptFloater>); LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>); LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>); LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>); @@ -234,6 +234,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("script_debug", "floater_script_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebug>); LLFloaterReg::add("script_debug_output", "floater_script_debug_panel.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebugOutput>); + LLFloaterReg::add("script_floater", "floater_script.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLScriptFloater>); LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater); LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>); LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>); @@ -248,6 +249,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload"); LLFloaterReg::add("voice_call", "floater_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCall>); + LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>); LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>); LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>); diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index 639585de55..a3495b9588 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -52,7 +52,7 @@ public: STATE_CONNECTED } EState; - typedef boost::function<void(const EState& old_state, const EState& new_state)> state_changed_callback_t; + typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state)> state_changed_signal_t; // on current channel changed signal typedef boost::function<void(const LLUUID& session_id)> channel_changed_callback_t; @@ -78,7 +78,8 @@ public: virtual BOOL callStarted(); const std::string& getSessionName() const { return mSessionName; } - void setStateChangedCallback(state_changed_callback_t callback) { mStateChangedCallback = callback; } + boost::signals2::connection setStateChangedCallback(const state_changed_signal_t::slot_type& callback) + { return mStateChangedCallback.connect(callback); } const LLUUID getSessionID() { return mSessionID; } EState getState() { return mState; } @@ -124,7 +125,7 @@ protected: static BOOL sSuspended; private: - state_changed_callback_t mStateChangedCallback; + state_changed_signal_t mStateChangedCallback; }; class LLVoiceChannelGroup : public LLVoiceChannel diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index eb8ec00bb9..295f4259fd 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -81,7 +81,7 @@ <color name="AgentChatColor" - reference="LtGray" /> + reference="White" /> <color name="AlertBoxColor" value="0.24 0.24 0.24 1" /> @@ -669,7 +669,7 @@ reference="LtGray" /> <color name="UserChatColor" - reference="LtGray" /> + reference="White" /> <color name="llOwnerSayChatColor" reference="LtGray" /> @@ -684,5 +684,8 @@ <color name="SysWellItemSelected" value="0.3 0.3 0.3 1.0" /> + <color + name="ChatToastAgentNameColor" + value="1.0 0.3 1.0 1.0" /> </colors> diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml new file mode 100644 index 0000000000..2f13b51a9f --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="true" + height="300" + layout="topleft" + name="floater_voice_controls" + title="Voice Controls" + save_visibility="true" + single_instance="true" + width="282"> + <panel + bevel_style="in" + follows="left|right|top" + height="73" + layout="topleft" + left="0" + name="control_panel" + width="285"> + <panel + height="20" + layout="topleft" + left="10" + name="my_panel" + width="262"> + <avatar_icon + enabled="false" + follows="left|top" + height="20" + image_name="icon_avatar_online.tga" + layout="topleft" + left="0" + name="user_icon" + top="0" + width="20" /> + <text + follows="top|left" + font="SansSerifSmallBold" + height="16" + layout="topleft" + left_pad="10" + name="user_text" + text_color="white" + top="4" + value="Mya Avatar:" + width="80" /> + </panel> + <layout_stack + bottom="10" + clip="false" + follows="left|right|top" + height="24" + layout="bottomleft" + orientation="horizontal" + width="262"> + <layout_panel + follows="left" + layout="topleft" + min_width="24" + top="0" + user_resize="false" + width="24"> + <icon + height="24" + image_name="Microphone_On" + layout="topleft" + name="Microphone_On" + top="0" + width="24" /> + </layout_panel> + <layout_panel + layout="topleft" + top="0" + user_resize="false" + width="258"> + <slider_bar + control_name="AudioLevelMic" + follows="left|right|top" + height="24" + increment="0.05" + layout="topleft" + left="0" + max_val="2" + name="volume_slider_bar" + tool_tip="Master Volume" + top="0" + value="0.75" + width="258" /> + </layout_panel> + </layout_stack> + </panel> + <avatar_list + follows="all" + height="197" + ignore_online_status="true" + layout="topleft" + left="0" + multi_select="true" + name="speakers_list" + width="282" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index 2eaa3a94ee..45f9d9c7b6 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -7,6 +7,18 @@ name="avatar_list_item" top="0" width="320"> + <!-- + Strings used to localize last interaction time. + See last_interaction textbox below. + --> + <string name="FormatSeconds">[COUNT]s</string> + <string name="FormatMinutes">[COUNT]m</string> + <string name="FormatHours">[COUNT]h</string> + <string name="FormatDays">[COUNT]d</string> + <string name="FormatWeeks">[COUNT]w</string> + <string name="FormatMonths">[COUNT]mon</string> + <string name="FormatYears">[COUNT]y</string> + <icon follows="top|right|left" height="24" diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index da8006d545..ec3f7ea7c5 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -72,7 +72,13 @@ left="0" name="talk" top="4" - width="100" /> + width="100"> + <show_button> + <show_button.init_callback + function="Button.SetDockableFloaterToggle" + parameter="voice_controls" /> + </show_button> + </talk_button> </layout_panel> <icon auto_resize="false" 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 2b29796f0a..34c6e02684 100644 --- a/indra/newview/skins/default/xui/en/panel_chat_item.xml +++ b/indra/newview/skins/default/xui/en/panel_chat_item.xml @@ -2,70 +2,26 @@ <!-- All our XML is utf-8 encoded. --> <panel name="instant_message" - width="300" + width="315" height="180" follows="all"> - <panel - width="290" - height="24" - background_visible="true" - background_opaque="false" - bg_alpha_color="Black" - left="5" - name="msg_caption"> - <avatar_icon - follows="left" - height="18" - image_name="Generic_Person" - layout="topleft" - left="3" - mouse_opaque="true" - name="avatar_icon" - top="3" - width="18" /> - <text - font.style="BOLD" - height="12" - layout="topleft" - left_pad="5" - top="7" - text_color="white" - word_wrap="false" - use_ellipses="true" - mouse_opaque="true" - name="sender_name" - width="150"> - Jerry Knight - </text> - <!-- <icon top="22" left="215" width="15" height="15" follows="top|right" - image_name="icn_voice-pvtfocus.tga" visible="false" name="msg_inspector" />--> - <!--<icon top="22" left="215" width="10" height="10" follows="top|right" - image_name="speaking_indicator.tga" name="msg_icon"/>--> - <text - font="SansSerifSmall" - follows="right|top" - halign="right" - height="13" - layout="topleft" - right="-10" - left="205" - mouse_opaque="true" - name="msg_time" - top="8" - value="23:30" - width="50" - word_wrap="true" /> - </panel> + <avatar_icon + follows="left|top" + height="18" + image_name="Generic_Person" + layout="topleft" + left="3" + mouse_opaque="true" + name="avatar_icon" + top="3" + width="18" /> <text_chat - top="-35" - left="10" - right="-10" + top="5" + left="30" height="120" - follows="left|right|bottom" text_color="white" word_wrap="true" mouse_opaque="true" name="msg_text"> - To be or not to be, that is the question. Tis a far far better thing I do than I have ever done. Tis a far far better place I go, than I have ever been. </text_chat> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml index ca84c9147b..4f0d155876 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -27,6 +27,7 @@ There are no picks/classifieds here </text> <accordion + fit_parent="true" follows="all" height="465" layout="topleft" |