summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2009-10-01 17:44:44 +0000
committerSteven Bennetts <steve@lindenlab.com>2009-10-01 17:44:44 +0000
commitf05df68656d2abdc38d86cd6746398fa90eb8614 (patch)
tree95f389551a7132b86dd96ff7c55b92674ee16756
parent090977608d3d4e1d6d26689064910221c66f6084 (diff)
merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0@1868 https://svn.aws.productengine.com/secondlife/pe/stable-2@1876 -> viewer-2.0.0-3
* Bugs: EXT-1111 EXT-915 EXT-1131 EXT-1200 EXT-1202 EXT-1201 EXT-1205 EXT-1212 EXT-1173 EXT-1229 EXT-1218 EXT-1164 EXT-996 EXT-821 EXT-1030 EXT-1031 EXT-816 * Major Bugs: EXT-1142 (timeout during login due to processing group IMs) * Changes: EXT-1216 (minimize message well)
-rw-r--r--indra/llui/CMakeLists.txt2
-rw-r--r--indra/llui/lldockablefloater.cpp18
-rw-r--r--indra/llui/lldockcontrol.cpp78
-rw-r--r--indra/llui/lldockcontrol.h10
-rw-r--r--indra/llui/llflatlistview.cpp4
-rw-r--r--indra/llui/lltexteditor.cpp43
-rw-r--r--indra/llui/lltexteditor.h10
-rw-r--r--indra/newview/llavatarlist.cpp136
-rw-r--r--indra/newview/llavatarlist.h25
-rw-r--r--indra/newview/llbottomtray.cpp5
-rw-r--r--indra/newview/llchannelmanager.cpp54
-rw-r--r--indra/newview/llchannelmanager.h16
-rw-r--r--indra/newview/llchatitemscontainerctrl.cpp392
-rw-r--r--indra/newview/llchatitemscontainerctrl.h86
-rw-r--r--indra/newview/llchatmsgbox.cpp2
-rw-r--r--indra/newview/llchiclet.cpp31
-rw-r--r--indra/newview/llchiclet.h3
-rw-r--r--indra/newview/llfavoritesbar.cpp11
-rw-r--r--indra/newview/llfavoritesbar.h2
-rw-r--r--indra/newview/llfloaterchatterbox.cpp3
-rw-r--r--indra/newview/llgrouplist.cpp49
-rw-r--r--indra/newview/llgrouplist.h24
-rw-r--r--indra/newview/llimfloater.cpp73
-rw-r--r--indra/newview/llimfloater.h6
-rw-r--r--indra/newview/llimhandler.cpp4
-rw-r--r--indra/newview/llimpanel.cpp87
-rw-r--r--indra/newview/llimpanel.h7
-rw-r--r--indra/newview/llimview.cpp246
-rw-r--r--indra/newview/llimview.h67
-rw-r--r--indra/newview/llnearbychat.cpp29
-rw-r--r--indra/newview/llnearbychat.h6
-rw-r--r--indra/newview/llnearbychathandler.cpp242
-rw-r--r--indra/newview/llnotificationalerthandler.cpp13
-rw-r--r--indra/newview/llnotificationgrouphandler.cpp5
-rw-r--r--indra/newview/llnotificationhandler.h4
-rw-r--r--indra/newview/llnotificationscripthandler.cpp11
-rw-r--r--indra/newview/llnotificationtiphandler.cpp5
-rw-r--r--indra/newview/llpanelavatar.cpp2
-rw-r--r--indra/newview/llpanelgroup.cpp15
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp2
-rw-r--r--indra/newview/llpanelpeople.cpp285
-rw-r--r--indra/newview/llpanelpeople.h27
-rw-r--r--indra/newview/llpanelpick.cpp47
-rw-r--r--indra/newview/llpanelpick.h5
-rw-r--r--indra/newview/llpanelpicks.cpp7
-rw-r--r--indra/newview/llpanelpicks.h2
-rw-r--r--indra/newview/llpanelplaces.cpp10
-rw-r--r--indra/newview/llpanelteleporthistory.cpp8
-rw-r--r--indra/newview/llscreenchannel.cpp74
-rw-r--r--indra/newview/llscreenchannel.h139
-rw-r--r--indra/newview/llsidetray.cpp10
-rw-r--r--indra/newview/llstatusbar.cpp17
-rw-r--r--indra/newview/llstatusbar.h4
-rw-r--r--indra/newview/llsyswellwindow.cpp43
-rw-r--r--indra/newview/llsyswellwindow.h6
-rw-r--r--indra/newview/lltoast.cpp19
-rw-r--r--indra/newview/lltoast.h3
-rw-r--r--indra/newview/lltoastpanel.h6
-rw-r--r--indra/newview/llviewermenu.cpp13
-rw-r--r--indra/newview/llviewermenu.h1
-rw-r--r--indra/newview/llviewerwindow.cpp6
-rw-r--r--indra/newview/skins/default/xui/en/floater_sys_well.xml12
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_notes.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_view.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history.xml2
-rw-r--r--indra/newview/skins/default/xui/en/widgets/scroll_list.xml6
-rw-r--r--indra/newview/skins/default/xui/en/widgets/search_combo_box.xml5
73 files changed, 1467 insertions, 1148 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index d7d411dee6..0a284f0088 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -85,6 +85,7 @@ set(llui_SOURCE_FILES
lltextbox.cpp
lltexteditor.cpp
lltextparser.cpp
+ lltransientfloatermgr.cpp
lltransutil.cpp
lltooltip.cpp
llui.cpp
@@ -171,6 +172,7 @@ set(llui_HEADER_FILES
lltexteditor.h
lltextparser.h
lltooltip.h
+ lltransientfloatermgr.h
lltransutil.h
lluicolortable.h
lluiconstants.h
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index 93d62fd7c2..4525f0a45b 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -71,9 +71,9 @@ void LLDockableFloater::resetInstance()
if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked())
{
sInstanceHandle.get()->setVisible(FALSE);
- }
+ }
sInstanceHandle = getHandle();
- }
+ }
}
void LLDockableFloater::setVisible(BOOL visible)
@@ -105,11 +105,11 @@ void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
mDockControl.get()->off();
}
- if (!docked && pop_on_undock)
- {
- // visually pop up a little bit to emphasize the undocking
- translate(0, UNDOCK_LEAP_HEIGHT);
- }
+ if (!docked && pop_on_undock)
+ {
+ // visually pop up a little bit to emphasize the undocking
+ translate(0, UNDOCK_LEAP_HEIGHT);
+ }
}
else
{
@@ -126,8 +126,8 @@ void LLDockableFloater::draw()
mDockControl.get()->repositionDockable();
if (isDocked())
{
- mDockControl.get()->drawToungue();
- }
+ mDockControl.get()->drawToungue();
+ }
}
LLFloater::draw();
}
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index 0b16b2554c..146c7a969a 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -35,7 +35,7 @@
#include "lldockcontrol.h"
LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
- const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback) :
+ const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue)
{
mDockAt = dockAt;
@@ -49,13 +49,13 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
off();
}
- if (!(get_rect_callback))
+ if (!(get_allowed_rect_callback))
{
- mGetRectCallback = boost::bind(&LLDockControl::getEnabledRect, this, _1);
+ mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
}
else
{
- mGetRectCallback = get_rect_callback;
+ mGetAllowedRectCallback = get_allowed_rect_callback;
}
if (dockWidget != NULL)
@@ -77,7 +77,7 @@ void LLDockControl::setDock(LLView* dockWidget)
}
}
-void LLDockControl::getEnabledRect(LLRect& rect)
+void LLDockControl::getAllowedRect(LLRect& rect)
{
rect = mDockableFloater->getRootView()->getRect();
}
@@ -86,7 +86,7 @@ void LLDockControl::repositionDockable()
{
LLRect dockRect = mDockWidget->calcScreenRect();
LLRect rootRect;
- mGetRectCallback(rootRect);
+ mGetAllowedRectCallback(rootRect);
static BOOL prev_visibility = !mDockWidget->getVisible();
// recalculate dockable position if dock position changed, dock visibility changed,
@@ -100,7 +100,7 @@ void LLDockControl::repositionDockable()
mDockableFloater->setDocked(false);
// force off() since dockable may not have dockControll at this time
off();
- }
+ }
else
{
moveDockable();
@@ -123,10 +123,10 @@ bool LLDockControl::isDockVisible()
res = mDockWidget->isInVisibleChain();
if (res)
{
- LLRect dockRect = mDockWidget->calcScreenRect();
+ LLRect dockRect = mDockWidget->calcScreenRect();
switch (mDockAt)
- {
+ {
case TOP:
// check is dock inside parent rect
LLRect dockParentRect =
@@ -149,25 +149,25 @@ void LLDockControl::moveDockable()
// calculate new dockable position
LLRect dockRect = mDockWidget->calcScreenRect();
LLRect rootRect;
- mGetRectCallback(rootRect);
+ mGetAllowedRectCallback(rootRect);
- LLRect dockableRect = mDockableFloater->calcScreenRect();
- S32 x = 0;
- S32 y = 0;
- switch (mDockAt)
- {
- case TOP:
- x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+ LLRect dockableRect = mDockableFloater->calcScreenRect();
+ S32 x = 0;
+ S32 y = 0;
+ switch (mDockAt)
+ {
+ case TOP:
+ x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
// check is dockable inside root view rect
- if (x < rootRect.mLeft)
- {
- x = rootRect.mLeft;
- }
- if (x + dockableRect.getWidth() > rootRect.mRight)
- {
- x = rootRect.mRight - dockableRect.getWidth();
- }
+ if (x < rootRect.mLeft)
+ {
+ x = rootRect.mLeft;
+ }
+ if (x + dockableRect.getWidth() > rootRect.mRight)
+ {
+ x = rootRect.mRight - dockableRect.getWidth();
+ }
// calculate dock tongue position
@@ -185,21 +185,21 @@ void LLDockControl::moveDockable()
{
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
}
- mDockTongueY = dockRect.mTop;
+ mDockTongueY = dockRect.mTop;
- break;
- }
+ break;
+ }
// move dockable
- dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
- dockableRect.getHeight());
- LLRect localDocableParentRect;
- mDockableFloater->getParent()->screenRectToLocal(dockableRect,
- &localDocableParentRect);
- mDockableFloater->setRect(localDocableParentRect);
+ dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+ dockableRect.getHeight());
+ LLRect localDocableParentRect;
+ mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+ &localDocableParentRect);
+ mDockableFloater->setRect(localDocableParentRect);
- mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
- &mDockTongueX, &mDockTongueY);
+ mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+ &mDockTongueX, &mDockTongueY);
}
@@ -207,9 +207,9 @@ void LLDockControl::on()
{
if (isDockVisible())
{
- mDockableFloater->setCanDrag(false);
- mEnabled = true;
- mRecalculateDocablePosition = true;
+ mDockableFloater->setCanDrag(false);
+ mEnabled = true;
+ mRecalculateDocablePosition = true;
}
}
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index 219ddfd092..e8ffcac0ac 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -52,11 +52,11 @@ public:
public:
// callback for a function getting a rect valid for control's position
- typedef boost::function<void (LLRect& )> get_rect_callback_t;
+ typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t;
LOG_CLASS(LLDockControl);
LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
- const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback = NULL);
+ const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL);
virtual ~LLDockControl();
public:
@@ -67,13 +67,13 @@ public:
void drawToungue();
bool isDockVisible();
- // gets a rect that bounds possible positions for a dockable control
- void getEnabledRect(LLRect& rect);
+ // gets a rect that bounds possible positions for a dockable control (EXT-1111)
+ void getAllowedRect(LLRect& rect);
private:
virtual void moveDockable();
private:
- get_rect_callback_t mGetRectCallback;
+ get_allowed_rect_callback_t mGetAllowedRectCallback;
bool mEnabled;
bool mRecalculateDocablePosition;
DocAt mDockAt;
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 9fcd386c19..e9df361472 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -39,8 +39,8 @@
static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("flat_list_view");
-const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
-const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
+const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
+const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
static const std::string COMMENT_TEXTBOX = "comment_text";
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 8d5f277b59..39f09b297f 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2001,6 +2001,8 @@ void LLTextEditor::cut()
deleteSelection( FALSE );
needsReflow();
+
+ onKeyStroke();
}
BOOL LLTextEditor::canCopy() const
@@ -2105,6 +2107,8 @@ void LLTextEditor::pasteHelper(bool is_primary)
deselect();
needsReflow();
+
+ onKeyStroke();
}
@@ -2492,6 +2496,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
if(text_may_have_changed)
{
needsReflow();
+
+ onKeyStroke();
}
needsScroll();
}
@@ -2534,6 +2540,8 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
deselect();
needsReflow();
+
+ onKeyStroke();
}
return handled;
@@ -2588,6 +2596,8 @@ void LLTextEditor::doDelete()
setCursorPos(mCursorPos + 1);
removeChar();
}
+
+ onKeyStroke();
}
needsReflow();
@@ -2634,6 +2644,8 @@ void LLTextEditor::undo()
setCursorPos(pos);
needsReflow();
+
+ onKeyStroke();
}
BOOL LLTextEditor::canRedo() const
@@ -2676,6 +2688,8 @@ void LLTextEditor::redo()
setCursorPos(pos);
needsReflow();
+
+ onKeyStroke();
}
void LLTextEditor::onFocusReceived()
@@ -4402,6 +4416,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
// Update of the preedit should be caused by some key strokes.
mKeystrokeTimer.reset();
+
+ onKeyStroke();
}
BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
@@ -4648,3 +4664,30 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
ed->addDocumentChild(mView);
}
}
+
+BOOL LLTextEditor::isDirty() const
+{
+ if(mReadOnly)
+ {
+ return FALSE;
+ }
+
+ if( mPristineCmd )
+ {
+ return ( mPristineCmd == mLastCmd );
+ }
+ else
+ {
+ return ( NULL != mLastCmd );
+ }
+}
+
+void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& callback)
+{
+ mKeystrokeSignal.connect(callback);
+}
+
+void LLTextEditor::onKeyStroke()
+{
+ mKeystrokeSignal(this);
+}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 68b8f2c3b1..a04261c4be 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -139,6 +139,10 @@ public:
virtual ~LLTextEditor();
+ typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
+
+ void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
+
void setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
// mousehandler overrides
@@ -169,7 +173,7 @@ public:
virtual void clear();
virtual void setFocus( BOOL b );
virtual BOOL acceptsTextInput() const;
- virtual BOOL isDirty() const { return isPristine(); }
+ virtual BOOL isDirty() const;
virtual void setValue(const LLSD& value);
// LLEditMenuHandler interface
@@ -503,6 +507,8 @@ private:
S32 getFirstVisibleLine() const;
+ void onKeyStroke();
+
//
// Data
//
@@ -568,6 +574,8 @@ private:
BOOL mHandleEditKeysDirectly;
LLCoordGL mLastIMEPosition; // Last position of the IME editor
+
+ keystroke_signal_t mKeystrokeSignal;
}; // end class LLTextEditor
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index ee14a2ff86..36f9780ad0 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -41,6 +41,10 @@
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
+// Maximum number of avatars that can be added to a list in one pass.
+// Used to limit time spent for avatar list update per frame.
+static const unsigned ADD_LIMIT = 50;
+
static bool findInsensitive(std::string haystack, const std::string& needle_upper)
{
LLStringUtil::toUpper(haystack);
@@ -65,6 +69,7 @@ LLAvatarList::LLAvatarList(const Params& p)
: LLFlatListView(p)
, mOnlineGoFirst(p.online_go_first)
, mContextMenu(NULL)
+, mDirty(true) // to force initial update
{
setCommitOnSelectionChange(true);
@@ -72,44 +77,40 @@ LLAvatarList::LLAvatarList(const Params& p)
setComparator(&NAME_COMPARATOR);
}
-void LLAvatarList::computeDifference(
- const std::vector<LLUUID>& vnew_unsorted,
- std::vector<LLUUID>& vadded,
- std::vector<LLUUID>& vremoved)
+// virtual
+void LLAvatarList::draw()
{
- std::vector<LLUUID> vcur;
- std::vector<LLUUID> vnew = vnew_unsorted;
+ if (mDirty)
+ refresh();
- // Convert LLSDs to LLUUIDs.
- {
- std::vector<LLSD> vcur_values;
- getValues(vcur_values);
+ LLFlatListView::draw();
+}
- for (size_t i=0; i<vcur_values.size(); i++)
- vcur.push_back(vcur_values[i].asUUID());
+void LLAvatarList::setNameFilter(const std::string& filter)
+{
+ if (mNameFilter != filter)
+ {
+ mNameFilter = filter;
+ setDirty();
}
+}
- std::sort(vcur.begin(), vcur.end());
- std::sort(vnew.begin(), vnew.end());
-
- std::vector<LLUUID>::iterator it;
- size_t maxsize = llmax(vcur.size(), vnew.size());
- vadded.resize(maxsize);
- vremoved.resize(maxsize);
-
- // what to remove
- it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
- vremoved.erase(it, vremoved.end());
-
- // what to add
- it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
- vadded.erase(it, vadded.end());
+void LLAvatarList::sortByName()
+{
+ setComparator(&NAME_COMPARATOR);
+ sort();
}
-BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
+//////////////////////////////////////////////////////////////////////////
+// PROTECTED SECTION
+//////////////////////////////////////////////////////////////////////////
+
+void LLAvatarList::refresh()
{
- BOOL have_names = TRUE;
- bool have_filter = name_filter != LLStringUtil::null;
+ bool have_names = TRUE;
+ bool add_limit_exceeded = false;
+ bool modified = false;
+ bool have_filter = !mNameFilter.empty();
// Save selection.
std::vector<LLUUID> selected_ids;
@@ -118,22 +119,36 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
// Determine what to add and what to remove.
std::vector<LLUUID> added, removed;
- LLAvatarList::computeDifference(all_buddies, added, removed);
+ LLAvatarList::computeDifference(getIDs(), added, removed);
// Handle added items.
+ unsigned nadded = 0;
for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
{
std::string name;
const LLUUID& buddy_id = *it;
- have_names &= gCacheName->getFullName(buddy_id, name);
- if (!have_filter || findInsensitive(name, name_filter))
- addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+ have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+ if (!have_filter || findInsensitive(name, mNameFilter))
+ {
+ if (nadded >= ADD_LIMIT)
+ {
+ add_limit_exceeded = true;
+ break;
+ }
+ else
+ {
+ addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+ modified = true;
+ nadded++;
+ }
+ }
}
// Handle removed items.
for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
{
removeItemByUUID(*it);
+ modified = true;
}
// Handle filter.
@@ -146,9 +161,12 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
{
std::string name;
const LLUUID& buddy_id = it->asUUID();
- have_names &= gCacheName->getFullName(buddy_id, name);
- if (!findInsensitive(name, name_filter))
+ have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+ if (!findInsensitive(name, mNameFilter))
+ {
removeItemByUUID(buddy_id);
+ modified = true;
+ }
}
}
@@ -167,18 +185,15 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
//
// Otherwise, if we have no filter then no need to update again
// because the items will update their names.
- return !have_filter || have_names;
-}
+ bool dirty = add_limit_exceeded || (have_filter && !have_names);
+ setDirty(dirty);
-void LLAvatarList::sortByName()
-{
- setComparator(&NAME_COMPARATOR);
- sort();
+ // Commit if we've added/removed items.
+ if (modified)
+ onCommit();
}
-//////////////////////////////////////////////////////////////////////////
-// PROTECTED SECTION
-//////////////////////////////////////////////////////////////////////////
+
void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
{
LLAvatarListItem* item = new LLAvatarListItem();
@@ -194,8 +209,39 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
addItem(item, id, pos);
}
+void LLAvatarList::computeDifference(
+ const std::vector<LLUUID>& vnew_unsorted,
+ std::vector<LLUUID>& vadded,
+ std::vector<LLUUID>& vremoved)
+{
+ std::vector<LLUUID> vcur;
+ std::vector<LLUUID> vnew = vnew_unsorted;
+ // Convert LLSDs to LLUUIDs.
+ {
+ std::vector<LLSD> vcur_values;
+ getValues(vcur_values);
+ for (size_t i=0; i<vcur_values.size(); i++)
+ vcur.push_back(vcur_values[i].asUUID());
+ }
+
+ std::sort(vcur.begin(), vcur.end());
+ std::sort(vnew.begin(), vnew.end());
+
+ std::vector<LLUUID>::iterator it;
+ size_t maxsize = llmax(vcur.size(), vnew.size());
+ vadded.resize(maxsize);
+ vremoved.resize(maxsize);
+
+ // what to remove
+ it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
+ vremoved.erase(it, vremoved.end());
+
+ // what to add
+ it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
+ vadded.erase(it, vadded.end());
+}
bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
{
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 8d79e073d2..ec801645fe 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -37,10 +37,22 @@
#include "llavatarlistitem.h"
+/**
+ * Generic list of avatars.
+ *
+ * Updates itself when it's dirty, using optional name filter.
+ * To initiate update, modify the UUID list and call setDirty().
+ *
+ * @see getIDs()
+ * @see setDirty()
+ * @see setNameFilter()
+ */
class LLAvatarList : public LLFlatListView
{
LOG_CLASS(LLAvatarList);
public:
+ typedef std::vector<LLUUID> uuid_vector_t;
+
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
{
Optional<S32> volume_column_width;
@@ -51,14 +63,19 @@ public:
LLAvatarList(const Params&);
virtual ~LLAvatarList() {}
- BOOL update(const std::vector<LLUUID>& all_buddies,
- const std::string& name_filter = LLStringUtil::null);
+ virtual void draw(); // from LLView
+
+ void setNameFilter(const std::string& filter);
+ void setDirty(bool val = true) { mDirty = val; }
+ uuid_vector_t& getIDs() { return mIDs; }
void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; }
void sortByName();
protected:
+ void refresh();
+
void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
void computeDifference(
const std::vector<LLUUID>& vnew,
@@ -68,6 +85,10 @@ protected:
private:
bool mOnlineGoFirst;
+ bool mDirty;
+
+ std::string mNameFilter;
+ uuid_vector_t mIDs;
LLAvatarListItem::ContextMenu* mContextMenu;
};
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 46151b469f..8771611b1c 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -133,6 +133,7 @@ LLIMChiclet* LLBottomTray::createIMChiclet(const LLUUID& session_id)
case LLIMChiclet::TYPE_IM:
return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
case LLIMChiclet::TYPE_GROUP:
+ case LLIMChiclet::TYPE_AD_HOC:
return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
case LLIMChiclet::TYPE_UNKNOWN:
break;
@@ -231,7 +232,7 @@ void LLBottomTray::showBottomTrayContextMenu(S32 x, S32 y, MASK mask)
mBottomTrayContextMenu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, mBottomTrayContextMenu, x, y);
- }
+ }
}
void LLBottomTray::showGestureButton(BOOL visible)
@@ -243,7 +244,7 @@ void LLBottomTray::showGestureButton(BOOL visible)
mGestureCombo->setVisible(visible);
if (!visible)
- {
+ {
LLFloaterReg::hideFloaterInstance("gestures");
r.mRight -= mGestureCombo->getRect().getWidth();
}
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 7ae9976338..b4b680416c 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -77,7 +77,7 @@ LLScreenChannel* LLChannelManager::createNotificationChannel()
p.channel_align = CA_RIGHT;
// Getting a Channel for our notifications
- return LLChannelManager::getInstance()->getChannel(p);
+ return dynamic_cast<LLScreenChannel*> (LLChannelManager::getInstance()->createChannel(p));
}
//--------------------------------------------------------------------------
@@ -113,7 +113,7 @@ void LLChannelManager::onLoginCompleted()
LLChannelManager::Params p;
p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
p.channel_align = CA_RIGHT;
- mStartUpChannel = getChannel(p);
+ mStartUpChannel = createChannel(p);
if(!mStartUpChannel)
{
@@ -147,22 +147,32 @@ void LLChannelManager::onStartUpToastClose()
LLScreenChannel::setStartUpToastShown();
// force NEARBY CHAT CHANNEL to repost all toasts if present
- LLScreenChannel* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
- nearby_channel->loadStoredToastsToChannel();
- nearby_channel->setCanStoreToasts(false);
+ //LLScreenChannelBase* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+ //!!!!!!!!!!!!!!
+ //FIXME
+ //nearby_channel->loadStoredToastsToChannel();
+ //nearby_channel->setCanStoreToasts(false);
}
//--------------------------------------------------------------------------
-LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
+
+LLScreenChannelBase* LLChannelManager::addChannel(LLScreenChannelBase* channel)
{
- LLScreenChannel* new_channel = NULL;
+ if(!channel)
+ return 0;
- new_channel = findChannelByID(p.id);
+ ChannelElem new_elem;
+ new_elem.id = channel->getChannelID();
+ new_elem.channel = channel;
- if(new_channel)
- return new_channel;
+ mChannelList.push_back(new_elem);
- new_channel = new LLScreenChannel(p.id);
+ return channel;
+}
+
+LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
+{
+ LLScreenChannel* new_channel = new LLScreenChannel(p.id);
if(!new_channel)
{
@@ -172,20 +182,26 @@ LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
{
new_channel->setToastAlignment(p.toast_align);
new_channel->setChannelAlignment(p.channel_align);
- new_channel->setDisplayToastsAlways(p.display_toasts_always);
-
- ChannelElem new_elem;
- new_elem.id = p.id;
- new_elem.channel = new_channel;
+ new_channel->setDisplayToastsAlways(p.display_toasts_always);
- mChannelList.push_back(new_elem);
+ addChannel(new_channel);
}
-
return new_channel;
}
+LLScreenChannelBase* LLChannelManager::getChannel(LLChannelManager::Params& p)
+{
+ LLScreenChannelBase* new_channel = findChannelByID(p.id);
+
+ if(new_channel)
+ return new_channel;
+
+ return createChannel(p);
+
+}
+
//--------------------------------------------------------------------------
-LLScreenChannel* LLChannelManager::findChannelByID(const LLUUID id)
+LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID id)
{
std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
if(it != mChannelList.end())
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index 811fa06d2b..b927d369cd 100644
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
@@ -52,8 +52,8 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
public:
struct Params
{
- LLUUID id;
- bool display_toasts_always;
+ LLUUID id;
+ bool display_toasts_always;
EToastAlignment toast_align;
EChannelAlignment channel_align;
@@ -64,7 +64,7 @@ public:
struct ChannelElem
{
LLUUID id;
- LLScreenChannel* channel;
+ LLScreenChannelBase* channel;
ChannelElem() : id(LLUUID("")), channel(NULL) { }
@@ -89,19 +89,23 @@ public:
void onStartUpToastClose();
// creates a new ScreenChannel according to the given parameters or returns existing if present
- LLScreenChannel* getChannel(LLChannelManager::Params& p);
+ LLScreenChannelBase* getChannel(LLChannelManager::Params& p);
+
+ LLScreenChannelBase* addChannel(LLScreenChannelBase* channel);
// returns a channel by its ID
- LLScreenChannel* findChannelByID(const LLUUID id);
+ LLScreenChannelBase* findChannelByID(const LLUUID id);
// creator of the Notification channel, that is used in more than one handler
- LLScreenChannel* createNotificationChannel();
+ LLScreenChannel* createNotificationChannel();
// remove channel methods
void removeChannelByID(const LLUUID id);
private:
+ LLScreenChannel* createChannel(LLChannelManager::Params& p);
+
LLScreenChannel* mStartUpChannel;
std::vector<ChannelElem> mChannelList;
};
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 6fb6552f2d..c2d7e0d935 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -44,6 +44,7 @@
#include "llviewercontrol.h"
#include "llagentdata.h"
+/*
static const S32 BORDER_MARGIN = 2;
static const S32 PARENT_BORDER_MARGIN = 0;
@@ -53,33 +54,27 @@ static const F32 MIN_AUTO_SCROLL_RATE = 120.f;
static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
-static const S32 msg_left_offset = 30;
-static const S32 msg_right_offset = 10;
-
#define MAX_CHAT_HISTORY 100
+*/
+static const S32 msg_left_offset = 30;
+static const S32 msg_right_offset = 10;
-static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container");
-
-
+//static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container");
//*******************************************************************************************************************
//LLChatItemCtrl
//*******************************************************************************************************************
-LLChatItemCtrl* LLChatItemCtrl::createInstance()
+LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance()
{
- LLChatItemCtrl* item = new LLChatItemCtrl();
+ LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel();
LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml");
+ item->setFollows(FOLLOWS_NONE);
return item;
}
-void LLChatItemCtrl::draw()
-{
- LLPanel::draw();
-}
-
-void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
+void LLNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_parent )
{
LLPanel::reshape(width, height,called_from_parent);
@@ -101,13 +96,13 @@ void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
}
}
-BOOL LLChatItemCtrl::postBuild()
+BOOL LLNearbyChatToastPanel::postBuild()
{
return LLPanel::postBuild();
}
-std::string LLChatItemCtrl::appendTime()
+std::string LLNearbyChatToastPanel::appendTime()
{
time_t utc_time;
utc_time = time_corrected();
@@ -124,48 +119,63 @@ std::string LLChatItemCtrl::appendTime()
-void LLChatItemCtrl::addText (const std::string& message)
+void LLNearbyChatToastPanel::addText (const std::string& message)
{
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
msg_text->addText(message);
mMessages.push_back(message);
}
-void LLChatItemCtrl::setMessage (const LLChat& msg)
+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
+ mFromID = notification["from_id"].asUUID(); // agent id or object id
+ int sType = notification["source"].asInteger();
+ mSourceType = (EChatSourceType)sType;
+
std::string str_sender;
-
- if(gAgentID != msg.mFromID)
- str_sender = msg.mFromName;
+ if(gAgentID != mFromID)
+ str_sender = mFromName;
else
str_sender = LLTrans::getString("You");;
caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender);
- std::string tt = appendTime();
-
- caption->getChild<LLTextBox>("msg_time", false)->setText(tt);
-
-
- caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(msg.mFromID);
+ caption->getChild<LLTextBox>("msg_time", false)->setText(appendTime());
- mOriginalMessage = msg;
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
- msg_text->setText(msg.mText);
+ msg_text->setText(mText);
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
- if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ if(mSourceType != CHAT_SOURCE_AGENT)
msg_inspector->setVisible(false);
mMessages.clear();
+ 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;
+
+ init(notification);
+
}
-void LLChatItemCtrl::snapToMessageHeight ()
+void LLNearbyChatToastPanel::snapToMessageHeight ()
{
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
S32 new_height = text_box->getTextPixelHeight();
@@ -184,14 +194,14 @@ void LLChatItemCtrl::snapToMessageHeight ()
}
-void LLChatItemCtrl::setWidth(S32 width)
+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);
- if(mOriginalMessage.mText.length())
- msg_text->setText(mOriginalMessage.mText);
+ if(mText.length())
+ msg_text->setText(mText);
for(size_t i=0;i<mMessages.size();++i)
msg_text->addText(mMessages[i]);
@@ -200,25 +210,25 @@ void LLChatItemCtrl::setWidth(S32 width)
snapToMessageHeight ();
}
-void LLChatItemCtrl::onMouseLeave (S32 x, S32 y, MASK mask)
+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 LLChatItemCtrl::onMouseEnter (S32 x, S32 y, MASK mask)
+void LLNearbyChatToastPanel::onMouseEnter (S32 x, S32 y, MASK mask)
{
- if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ 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 LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
+BOOL LLNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask)
{
- if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ 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");
@@ -226,12 +236,16 @@ BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom;
if(msg_inspector->pointInView(local_x, local_y))
{
- LLFloaterReg::showInstance("inspect_avatar", mOriginalMessage.mFromID);
+ LLFloaterReg::showInstance("inspect_avatar", mFromID);
+ }
+ else
+ {
+ LLFloaterReg::showInstance("nearby_chat",LLSD());
}
return LLPanel::handleMouseDown(x,y,mask);
}
-void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
+void LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
{
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
@@ -243,7 +257,7 @@ void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
}
-bool LLChatItemCtrl::canAddText ()
+bool LLNearbyChatToastPanel::canAddText ()
{
LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
if(!msg_text)
@@ -251,7 +265,7 @@ bool LLChatItemCtrl::canAddText ()
return msg_text->getTextLinesNum()<10;
}
-BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+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);
@@ -260,296 +274,20 @@ BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom;
//eat message for avatar icon if msg was from object
- if(avatar_icon->pointInView(local_x, local_y) && mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT)
return TRUE;
return LLPanel::handleRightMouseDown(x,y,mask);
}
-
-
-//*******************************************************************************************************************
-//LLChatItemsContainerCtrl
-//*******************************************************************************************************************
-
-LLChatItemsContainerCtrl::LLChatItemsContainerCtrl(const Params& params):LLPanel(params)
-{
- mEShowItemHeader = CHATITEMHEADER_SHOW_BOTH;
-}
-
-
-void LLChatItemsContainerCtrl::addMessage(const LLChat& msg)
-{
- /*
- if(msg.mChatType == CHAT_TYPE_DEBUG_MSG)
- return;
- */
- if(mItems.size() >= MAX_CHAT_HISTORY)
- {
- LLChatItemCtrl* item = mItems[0];
- removeChild(item);
- delete item;
- mItems.erase(mItems.begin());
- }
-
-
- if(mItems.size() > 0
- && msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID
- && (msg.mTime-mItems[mItems.size()-1]->getMessage().mTime)<60
- && mItems[mItems.size()-1]->canAddText()
- )
- {
- mItems[mItems.size()-1]->addText(msg.mText);
- mItems[mItems.size()-1]->snapToMessageHeight();
- }
- else
- {
- LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
- mItems.push_back(item);
- addChild(item,0);
- item->setWidth(getRect().getWidth() - 16);
- item->setMessage(msg);
- item->snapToMessageHeight();
-
- item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
-
- item->setVisible(true);
- }
-
- arrange(getRect().getWidth(),getRect().getHeight());
- updateLayout(getRect().getWidth(),getRect().getHeight());
- scrollToBottom();
-}
-
-void LLChatItemsContainerCtrl::scrollToBottom ()
-{
- if(mScrollbar->getVisible())
- {
- mScrollbar->setDocPos(mScrollbar->getDocPosMax());
- onScrollPosChangeCallback(0,0);
- }
-}
-
-void LLChatItemsContainerCtrl::draw()
-{
- LLLocalClipRect clip(getRect());
- LLPanel::draw();
-}
-
-void LLChatItemsContainerCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
-{
- S32 delta_width = width - getRect().getWidth();
- S32 delta_height = height - getRect().getHeight();
-
- if (delta_width || delta_height || sForceReshape)
- {
- arrange(width, height);
- }
-
- updateBoundingRect();
-}
-
-void LLChatItemsContainerCtrl::arrange (S32 width, S32 height)
+void LLNearbyChatToastPanel::draw()
{
- S32 delta_width = width - getRect().getWidth();
- if(delta_width)//width changed...too bad. now we need to reformat all items
- reformatHistoryScrollItems(width);
-
- calcRecuiredHeight();
-
- show_hide_scrollbar(width,height);
-
- updateLayout(width,height);
-}
-
-void LLChatItemsContainerCtrl::reformatHistoryScrollItems(S32 width)
-{
- for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
- {
- (*it)->setWidth(width);
- }
-}
-
-S32 LLChatItemsContainerCtrl::calcRecuiredHeight ()
-{
- S32 rec_height = 0;
-
- std::vector<LLChatItemCtrl*>::iterator it;
- for(it=mItems.begin(); it!=mItems.end(); ++it)
- {
- rec_height += (*it)->getRect().getHeight();
- }
-
- mInnerRect.setLeftTopAndSize(0,rec_height + BORDER_MARGIN*2,getRect().getWidth(),rec_height + BORDER_MARGIN);
-
- return mInnerRect.getHeight();
-}
-
-
-void LLChatItemsContainerCtrl::updateLayout (S32 width, S32 height)
-{
- S32 panel_top = height - BORDER_MARGIN ;
- S32 panel_width = width;
- if(mScrollbar->getVisible())
- {
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
- panel_top+=mScrollbar->getDocPos();
- panel_width-=scrollbar_size;
- }
-
-
- //set sizes for first panels and dragbars
- for(size_t i=0;i<mItems.size();++i)
- {
- LLRect panel_rect = mItems[i]->getRect();
- panelSetLeftTopAndSize(mItems[i],panel_rect.mLeft,panel_top,panel_width,panel_rect.getHeight());
- panel_top-=panel_rect.getHeight();
- }
-}
-
-void LLChatItemsContainerCtrl::show_hide_scrollbar (S32 width, S32 height)
-{
- calcRecuiredHeight();
- if(getRecuiredHeight() > height )
- showScrollbar(width, height);
- else
- hideScrollbar(width, height);
-}
-
-void LLChatItemsContainerCtrl::showScrollbar (S32 width, S32 height)
-{
- bool was_visible = mScrollbar->getVisible();
-
- mScrollbar->setVisible(true);
-
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
- panelSetLeftTopAndSize(mScrollbar,width-scrollbar_size
- ,height-PARENT_BORDER_MARGIN,scrollbar_size,height-2*PARENT_BORDER_MARGIN);
-
- mScrollbar->setPageSize(height);
- mScrollbar->setDocParams(mInnerRect.getHeight(),mScrollbar->getDocPos());
-
- if(was_visible)
- {
- S32 scroll_pos = llmin(mScrollbar->getDocPos(), getRecuiredHeight() - height - 1);
- mScrollbar->setDocPos(scroll_pos);
- updateLayout(width,height);
- return;
- }
-}
-
-void LLChatItemsContainerCtrl::hideScrollbar (S32 width, S32 height)
-{
- if(mScrollbar->getVisible() == false)
- return;
- mScrollbar->setVisible(false);
-
- mScrollbar->setDocPos(0);
-
- if(mItems.size()>0)
- {
- S32 panel_top = height - BORDER_MARGIN; // Top coordinate of the first panel
- S32 diff = panel_top - mItems[0]->getRect().mTop;
- shiftPanels(diff);
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLChatItemsContainerCtrl::panelSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S32 width, S32 height)
-{
- if(!panel)
- return;
- LLRect panel_rect = panel->getRect();
- panel_rect.setLeftTopAndSize( left, top, width, height);
- panel->reshape( width, height, 1);
- panel->setRect(panel_rect);
-}
-
-void LLChatItemsContainerCtrl::panelShiftVertical(LLView* panel,S32 delta)
-{
- if(!panel)
- return;
- panel->translate(0,delta);
-}
-
-void LLChatItemsContainerCtrl::shiftPanels(S32 delta)
-{
- //Arrange panels
- for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
- {
- panelShiftVertical((*it),delta);
- }
-
-}
-
-//---------------------------------------------------------------------------------
-
-void LLChatItemsContainerCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
-{
- updateLayout(getRect().getWidth(),getRect().getHeight());
-}
-
-BOOL LLChatItemsContainerCtrl::postBuild()
-{
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
- LLRect scroll_rect;
- scroll_rect.setOriginAndSize(
- getRect().getWidth() - scrollbar_size,
- 1,
- scrollbar_size,
- getRect().getHeight() - 1);
-
-
- LLScrollbar::Params sbparams;
- sbparams.name("scrollable vertical");
- sbparams.rect(scroll_rect);
- sbparams.orientation(LLScrollbar::VERTICAL);
- sbparams.doc_size(mInnerRect.getHeight());
- sbparams.doc_pos(0);
- sbparams.page_size(mInnerRect.getHeight());
- sbparams.step_size(VERTICAL_MULTIPLE);
- sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
- sbparams.change_callback(boost::bind(&LLChatItemsContainerCtrl::onScrollPosChangeCallback, this, _1, _2));
-
- mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
- LLView::addChild( mScrollbar );
- mScrollbar->setVisible( true );
- mScrollbar->setFollowsRight();
- mScrollbar->setFollowsTop();
- mScrollbar->setFollowsBottom();
-
- reformatHistoryScrollItems(getRect().getWidth());
- arrange(getRect().getWidth(),getRect().getHeight());
-
- return LLPanel::postBuild();
-}
-BOOL LLChatItemsContainerCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
-{
- return LLPanel::handleMouseDown(x,y,mask);
-}
-BOOL LLChatItemsContainerCtrl::handleKeyHere (KEY key, MASK mask)
-{
- if( mScrollbar->getVisible() && mScrollbar->handleKeyHere( key,mask ) )
- return TRUE;
- return LLPanel::handleKeyHere(key,mask);
-}
-BOOL LLChatItemsContainerCtrl::handleScrollWheel ( S32 x, S32 y, S32 clicks )
-{
- if( mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) )
- return TRUE;
- return false;
-}
-
-void LLChatItemsContainerCtrl::setHeaderVisibility(EShowItemHeader e)
-{
- if(e == mEShowItemHeader)
- return;
- mEShowItemHeader = e;
- for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
+ if(mIsDirty)
{
- (*it)->setHeaderVisibility(e);
+ LLPanel* caption = findChild<LLPanel>("msg_caption", false);
+ if(caption)
+ caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(mFromID);
+ mIsDirty = false;
}
+ LLToastPanelBase::draw();
}
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index de16cf9505..8fb045b6d9 100644
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -37,6 +37,7 @@
#include "llscrollbar.h"
#include "string"
#include "llchat.h"
+#include "lltoastpanel.h"
typedef enum e_show_item_header
{
@@ -45,20 +46,18 @@ typedef enum e_show_item_header
CHATITEMHEADER_SHOW_BOTH
} EShowItemHeader;
-class LLChatItemCtrl: public LLPanel
+class LLNearbyChatToastPanel: public LLToastPanelBase
{
protected:
- LLChatItemCtrl(){};
+ LLNearbyChatToastPanel():mIsDirty(false){};
public:
- ~LLChatItemCtrl(){}
+ ~LLNearbyChatToastPanel(){}
- static LLChatItemCtrl* createInstance();
+ static LLNearbyChatToastPanel* createInstance();
- void draw();
-
- const LLChat& getMessage() const { return mOriginalMessage;}
+ const LLUUID& getFromID() const { return mFromID;}
void addText (const std::string& message);
void setMessage (const LLChat& msg);
@@ -77,78 +76,27 @@ public:
void setHeaderVisibility(EShowItemHeader e);
BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-private:
-
- std::string appendTime ();
-
-private:
- LLChat mOriginalMessage;
-
- std::vector<std::string> mMessages;
-};
-
-class LLChatItemsContainerCtrl: public LLPanel
-{
-public:
- struct Params
- : public LLInitParam::Block<Params, LLPanel::Params>
- {
- Params(){};
- };
-
- LLChatItemsContainerCtrl(const Params& params);
-
-
- ~LLChatItemsContainerCtrl(){}
-
- void addMessage (const LLChat& msg);
-
- void draw();
-
- void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
-
- void onScrollPosChangeCallback(S32, LLScrollbar*);
-
- virtual BOOL postBuild();
-
- BOOL handleMouseDown (S32 x, S32 y, MASK mask);
- BOOL handleKeyHere (KEY key, MASK mask);
- BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
-
- void scrollToBottom ();
-
- void setHeaderVisibility(EShowItemHeader e);
- EShowItemHeader getHeaderVisibility() const { return mEShowItemHeader;};
+ virtual void init(LLSD& data);
+ virtual void draw();
private:
- void reformatHistoryScrollItems(S32 width);
- void arrange (S32 width, S32 height);
-
- S32 calcRecuiredHeight ();
- S32 getRecuiredHeight () const { return mInnerRect.getHeight(); }
-
- void updateLayout (S32 width, S32 height);
-
- void show_hide_scrollbar (S32 width, S32 height);
-
- void showScrollbar (S32 width, S32 height);
- void hideScrollbar (S32 width, S32 height);
-
- void panelSetLeftTopAndSize (LLView* panel, S32 left, S32 top, S32 width, S32 height);
- void panelShiftVertical (LLView* panel,S32 delta);
- void shiftPanels (S32 delta);
+
+ std::string appendTime ();
private:
- std::vector<LLChatItemCtrl*> mItems;
+ std::string mText; // UTF-8 line of text
+ std::string mFromName; // agent or object name
+ LLUUID mFromID; // agent id or object id
+ EChatSourceType mSourceType;
- EShowItemHeader mEShowItemHeader;
- LLRect mInnerRect;
- LLScrollbar* mScrollbar;
+ std::vector<std::string> mMessages;
+ bool mIsDirty;
};
+
#endif
diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp
index e6398dd47a..bd0c36b44a 100644
--- a/indra/newview/llchatmsgbox.cpp
+++ b/indra/newview/llchatmsgbox.cpp
@@ -102,7 +102,7 @@ void LLChatMsgBox::drawText(S32 x, S32 y, const LLWString &text, const LLColor4
// iterate through each block of text that has been added
y -= mLineSpacing;
- for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); true ;)
+ for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); it != mSeparatorOffset.end() ;)
{
// display the text for this block
S32 num_chars = *it - start;
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 20c44d5b11..98e492cada 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -49,6 +49,7 @@
#include "llvoicecontrolpanel.h"
#include "llgroupmgr.h"
#include "llnotificationmanager.h"
+#include "lltransientfloatermgr.h"
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
@@ -243,26 +244,36 @@ void LLIMChiclet::draw()
LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
{
EType type = TYPE_UNKNOWN;
- LLFloaterIMPanel* im = NULL;
if(session_id.isNull())
return type;
- if (!(im = LLIMMgr::getInstance()->findFloaterBySession(session_id)))
+ EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id);
+ if (IM_COUNT == im_type)
{
llassert_always(0 && "IM session not found"); // should never happen
return type;
}
- switch(im->getDialogType())
+ switch(im_type)
{
case IM_NOTHING_SPECIAL:
+ case IM_SESSION_P2P_INVITE:
type = TYPE_IM;
break;
case IM_SESSION_GROUP_START:
case IM_SESSION_INVITE:
- type = TYPE_GROUP;
+ if (gAgent.isInGroup(session_id))
+ {
+ type = TYPE_GROUP;
+ }
+ else
+ {
+ type = TYPE_AD_HOC;
+ }
break;
+ case IM_SESSION_CONFERENCE_START:
+ type = TYPE_AD_HOC;
default:
break;
}
@@ -285,6 +296,11 @@ LLIMP2PChiclet::Params::Params()
avatar_icon.name("avatar_icon");
avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
+
+ // *NOTE dzaporozhan
+ // Changed icon height from 25 to 24 to fix ticket EXT-794.
+ // In some cases(after changing UI scale) 25 pixel height icon was
+ // drawn incorrectly, i'm not sure why.
avatar_icon.rect(LLRect(0, 24, 25, 0));
avatar_icon.mouse_opaque(false);
@@ -458,6 +474,11 @@ LLIMGroupChiclet::Params::Params()
rect(LLRect(0, 25, 45, 0));
group_icon.name("group_icon");
+
+ // *NOTE dzaporozhan
+ // Changed icon height from 25 to 24 to fix ticket EXT-794.
+ // In some cases(after changing UI scale) 25 pixel height icon was
+ // drawn incorrectly, i'm not sure why.
group_icon.rect(LLRect(0, 24, 25, 0));
unread_notifications.name("unread");
@@ -1164,6 +1185,7 @@ LLTalkButton::LLTalkButton(const Params& p)
speak_params.rect(speak_rect);
mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
addChild(mSpeakBtn);
+ LLTransientFloaterMgr::getInstance()->addControlView(mSpeakBtn);
mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this));
mSpeakBtn->setToggleState(FALSE);
@@ -1172,6 +1194,7 @@ LLTalkButton::LLTalkButton(const Params& p)
show_params.rect(show_rect);
mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
addChild(mShowBtn);
+ LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn);
mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this));
mShowBtn->setToggleState(FALSE);
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 316348cf1d..ef47b54333 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -275,7 +275,8 @@ public:
enum EType {
TYPE_UNKNOWN,
TYPE_IM,
- TYPE_GROUP
+ TYPE_GROUP,
+ TYPE_AD_HOC
};
/*virtual*/ ~LLIMChiclet() {};
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 6b18984f88..ea947a5565 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -934,6 +934,17 @@ void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S
LLMenuGL::showPopup(fav_button, menu, x, y);
}
+BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = childrenHandleRightMouseDown( x, y, mask) != NULL;
+ if(!handled && !gMenuHolder->hasVisibleMenu())
+ {
+ show_navbar_context_menu(this,x,y);
+ handled = true;
+ }
+
+ return handled;
+}
void copy_slurl_to_clipboard_cb(std::string& slurl)
{
gClipboard.copyFromString(utf8str_to_wstring(slurl));
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 0be8de29a9..97117c3b4a 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -62,7 +62,7 @@ public:
std::string& tooltip_msg);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
-
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
// LLInventoryObserver observer trigger
virtual void changed(U32 mask);
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp
index 05ea800d0e..dea656b0e4 100644
--- a/indra/newview/llfloaterchatterbox.cpp
+++ b/indra/newview/llfloaterchatterbox.cpp
@@ -363,7 +363,8 @@ LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
{
// only LLFloaterIMPanels are called "im_floater"
LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp;
- if (im_floaterp->getVoiceChannel() == LLVoiceChannel::getCurrentVoiceChannel())
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(im_floaterp->getSessionID());
+ if (voice_channel == LLVoiceChannel::getCurrentVoiceChannel())
{
return im_floaterp;
}
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index d3b013237b..905857f393 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -73,7 +73,11 @@ LLGroupList::Params::Params()
LLGroupList::LLGroupList(const Params& p)
: LLFlatListView(p)
+ , mDirty(true) // to force initial update
{
+ // Listen for agent group changes.
+ gAgent.addListener(this, "new group");
+
mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
setCommitOnSelectionChange(true);
// TODO: implement context menu
@@ -84,17 +88,41 @@ LLGroupList::LLGroupList(const Params& p)
setComparator(&GROUP_COMPARATOR);
}
+LLGroupList::~LLGroupList()
+{
+ gAgent.removeListener(this);
+}
+
+// virtual
+void LLGroupList::draw()
+{
+ if (mDirty)
+ refresh();
+
+ LLFlatListView::draw();
+}
+
+void LLGroupList::setNameFilter(const std::string& filter)
+{
+ if (mNameFilter != filter)
+ {
+ mNameFilter = filter;
+ setDirty();
+ }
+}
+
static bool findInsensitive(std::string haystack, const std::string& needle_upper)
{
LLStringUtil::toUpper(haystack);
return haystack.find(needle_upper) != std::string::npos;
}
-BOOL LLGroupList::update(const std::string& name_filter)
+void LLGroupList::refresh()
{
const LLUUID& highlight_id = gAgent.getGroupID();
S32 count = gAgent.mGroups.count();
LLUUID id;
+ bool have_filter = !mNameFilter.empty();
clear();
@@ -102,7 +130,7 @@ BOOL LLGroupList::update(const std::string& name_filter)
{
id = gAgent.mGroups.get(i).mID;
const LLGroupData& group_data = gAgent.mGroups.get(i);
- if (name_filter != LLStringUtil::null && !findInsensitive(group_data.mName, name_filter))
+ if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
continue;
addNewItem(id, group_data.mName, group_data.mInsigniaID, highlight_id == id, ADD_BOTTOM);
}
@@ -113,13 +141,14 @@ BOOL LLGroupList::update(const std::string& name_filter)
// add "none" to list at top
{
std::string loc_none = LLTrans::getString("GroupsNone");
- if (name_filter == LLStringUtil::null || findInsensitive(loc_none, name_filter))
+ if (have_filter || findInsensitive(loc_none, mNameFilter))
addNewItem(LLUUID::null, loc_none, LLUUID::null, highlight_id.isNull(), ADD_TOP);
}
selectItemByUUID(highlight_id);
- return TRUE;
+ setDirty(false);
+ onCommit();
}
void LLGroupList::toggleIcons()
@@ -158,6 +187,18 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
// setCommentVisible(false);
}
+// virtual
+bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ // Why is "new group" sufficient?
+ if (event->desc() == "new group")
+ {
+ setDirty();
+ return true;
+ }
+
+ return false;
+}
/************************************************************************/
/* LLGroupListItem implementation */
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 7708b58de6..9c3ab88901 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -33,10 +33,19 @@
#ifndef LL_LLGROUPLIST_H
#define LL_LLGROUPLIST_H
+#include "llevent.h"
#include "llflatlistview.h"
#include "llpanel.h"
+#include "llpointer.h"
-class LLGroupList: public LLFlatListView
+/**
+ * Auto-updating list of agent groups.
+ *
+ * Can use optional group name filter.
+ *
+ * @see setNameFilter()
+ */
+class LLGroupList: public LLFlatListView, public LLOldEvents::LLSimpleListener
{
LOG_CLASS(LLGroupList);
public:
@@ -46,14 +55,23 @@ public:
};
LLGroupList(const Params& p);
- BOOL update(const std::string& name_filter = LLStringUtil::null);
+ virtual ~LLGroupList();
+
+ virtual void draw(); // from LLView
+
+ void setNameFilter(const std::string& filter);
void toggleIcons();
bool getIconsVisible() const { return mShowIcons; }
-
+
private:
+ void setDirty(bool val = true) { mDirty = val; }
+ void refresh();
void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
bool mShowIcons;
+ bool mDirty;
+ std::string mNameFilter;
};
class LLButton;
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 254e16e1fb..1c144b11b0 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -48,6 +48,7 @@
#include "lltrans.h"
#include "llviewertexteditor.h"
#include "llviewerwindow.h"
+#include "lltransientfloatermgr.h"
@@ -62,33 +63,46 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
mInputEditor(NULL),
mPositioned(false)
{
- LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
- if(session)
+ EInstantMessage type = LLIMModel::getInstance()->getType(session_id);
+ if(IM_COUNT != type)
{
- mDialog = session->mType;
- }
+ mDialog = type;
- if (mDialog == IM_NOTHING_SPECIAL)
- {
- mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
- }
- else
- {
- mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
+ if (IM_NOTHING_SPECIAL == mDialog || IM_SESSION_P2P_INVITE == mDialog)
+ {
+ mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
+ }
+ else
+ {
+ mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
+ }
}
-// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml");
LLUI::getRootView()->setFocusLostCallback(boost::bind(&LLIMFloater::focusChangeCallback, this));
mCloseSignal.connect(boost::bind(&LLIMFloater::onClose, this));
+
+ LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);
}
void LLIMFloater::onClose()
{
LLIMModel::instance().sendLeaveSession(mSessionID, mOtherParticipantUUID);
+
+ //*TODO - move to the IMModel::sendLeaveSession() for the integrity (IB)
gIMMgr->removeSession(mSessionID);
}
+void LLIMFloater::setMinimized(BOOL minimize)
+{
+ if(!isDocked())
+ {
+ setVisible(!minimize);
+ }
+
+ LLFloater::setMinimized(minimize);
+}
+
/* static */
void LLIMFloater::newIMCallback(const LLSD& data){
@@ -152,16 +166,17 @@ void LLIMFloater::sendMsg()
LLIMFloater::~LLIMFloater()
{
+ LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
}
//virtual
BOOL LLIMFloater::postBuild()
{
- LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
- if(session)
+ const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
+ if (other_party_id.notNull())
{
- mOtherParticipantUUID = session->mOtherParticipantID;
- mControlPanel->setID(session->mOtherParticipantID);
+ mOtherParticipantUUID = other_party_id;
+ mControlPanel->setID(mOtherParticipantUUID);
}
LLButton* slide_left = getChild<LLButton>("slide_left_btn");
@@ -216,17 +231,6 @@ void* LLIMFloater::createPanelGroupControl(void* userdata)
return self->mControlPanel;
}
-
-
-void LLIMFloater::focusChangeCallback()
-{
- // hide docked floater if user clicked inside in-world area
- if (isDocked())
- {
- setVisible(false);
- }
-}
-
void LLIMFloater::onSlide()
{
LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
@@ -271,13 +275,13 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
}
floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
- LLDockControl::TOP, boost::bind(&LLIMFloater::getEnabledRect, floater, _1)));
+ LLDockControl::TOP, boost::bind(&LLIMFloater::getAllowedRect, floater, _1)));
}
return floater;
}
-void LLIMFloater::getEnabledRect(LLRect& rect)
+void LLIMFloater::getAllowedRect(LLRect& rect)
{
rect = gViewerWindow->getWorldViewRect();
}
@@ -285,8 +289,10 @@ void LLIMFloater::getEnabledRect(LLRect& rect)
void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
{
// update notification channel state
- LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+ LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
+ (LLNotificationsUI::LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
LLDockableFloater::setDocked(docked, pop_on_undock);
// update notification channel state
@@ -298,8 +304,9 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
void LLIMFloater::setVisible(BOOL visible)
{
- LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+ LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
+ (LLNotificationsUI::LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
LLDockableFloater::setVisible(visible);
// update notification channel state
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 276f38e829..a183212f04 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -57,6 +57,8 @@ public:
// LLFloater overrides
/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
+ // override LLFloater's minimization according to EXT-1216
+ /*virtual*/ void setMinimized(BOOL minimize);
// Make IM conversion visible and update the message history
static LLIMFloater* show(const LLUUID& session_id);
@@ -90,8 +92,8 @@ private:
void onSlide();
static void* createPanelIMControl(void* userdata);
static void* createPanelGroupControl(void* userdata);
- void focusChangeCallback();
- void getEnabledRect(LLRect& rect);
+ // gets a rect that bounds possible positions for the LLIMFloater on a screen (EXT-1111)
+ void getAllowedRect(LLRect& rect);
LLPanelChatControlPanel* mControlPanel;
LLUUID mSessionID;
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 46067c081f..74971f3fd8 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -109,7 +109,9 @@ bool LLIMHandler::processNotification(const LLSD& notify)
p.panel = im_box;
p.can_be_stored = false;
p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
- mChannel->addToast(p);
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
// send a signal to the counter manager;
mNewNotificationSignal();
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index aa2beabf3d..abd3cd4def 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -940,7 +940,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
mHistoryEditor(NULL),
mSessionUUID(session_id),
mSessionLabel(session_label),
- mVoiceChannel(NULL),
mSessionInitialized(FALSE),
mSessionStartMsgPos(0),
mOtherParticipantUUID(other_participant_id),
@@ -956,7 +955,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
mTextIMPossible(TRUE),
mProfileButtonEnabled(TRUE),
mCallBackEnabled(TRUE),
- mSpeakers(NULL),
mSpeakerPanel(NULL),
mFirstKeystrokeTimer(),
mLastKeystrokeTimer()
@@ -967,7 +965,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
case IM_SESSION_GROUP_START:
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
xml_filename = "floater_instant_message_group.xml";
- mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
break;
case IM_SESSION_INVITE:
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
@@ -979,16 +976,13 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
{
xml_filename = "floater_instant_message_ad_hoc.xml";
}
- mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
break;
case IM_SESSION_P2P_INVITE:
xml_filename = "floater_instant_message.xml";
- mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
break;
case IM_SESSION_CONFERENCE_START:
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
xml_filename = "floater_instant_message_ad_hoc.xml";
- mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
break;
// just received text from another user
case IM_NOTHING_SPECIAL:
@@ -998,8 +992,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionUUID);
mProfileButtonEnabled = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionUUID);
mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionUUID);
-
- mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
break;
default:
llwarns << "Unknown session type" << llendl;
@@ -1007,10 +999,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
break;
}
- mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
- // All participants will be added to the list of people we've recently interacted with.
- mSpeakers->addListener(&LLRecentPeople::instance(), "add");
-
LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, NULL);
setTitle(mSessionLabel);
@@ -1058,33 +1046,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
LLFloaterIMPanel::~LLFloaterIMPanel()
{
- delete mSpeakers;
- mSpeakers = NULL;
-
- // End the text IM session if necessary
- if(gVoiceClient && mOtherParticipantUUID.notNull())
- {
- switch(mDialog)
- {
- case IM_NOTHING_SPECIAL:
- case IM_SESSION_P2P_INVITE:
- gVoiceClient->endUserIMSession(mOtherParticipantUUID);
- break;
-
- default:
- // Appease the compiler
- break;
- }
- }
-
- //kicks you out of the voice channel if it is currently active
-
- // HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
- mVoiceChannel->deactivate();
-
- delete mVoiceChannel;
- mVoiceChannel = NULL;
-
//delete focus lost callback
mFocusCallbackConnection.disconnect();
}
@@ -1152,7 +1113,8 @@ BOOL LLFloaterIMPanel::postBuild()
void* LLFloaterIMPanel::createSpeakersPanel(void* data)
{
LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)data;
- floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(floaterp->mSpeakers, TRUE);
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(floaterp->mSessionUUID);
+ floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(speaker_mgr, TRUE);
return floaterp->mSpeakerPanel;
}
@@ -1198,12 +1160,14 @@ void LLFloaterIMPanel::draw()
&& mCallBackEnabled;
// hide/show start call and end call buttons
- childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
- childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID);
+ childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
+ childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
childSetEnabled("start_call_btn", enable_connect);
childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
- LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID());
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
+ LLPointer<LLSpeaker> self_speaker = speaker_mgr->findSpeaker(gAgent.getID());
if(!mTextIMPossible)
{
mInputEditor->setEnabled(FALSE);
@@ -1227,7 +1191,7 @@ void LLFloaterIMPanel::draw()
}
// show speakers window when voice first connects
- if (mShowSpeakersOnConnect && mVoiceChannel->isActive())
+ if (mShowSpeakersOnConnect && voice_channel->isActive())
{
childSetVisible("active_speakers_panel", TRUE);
mShowSpeakersOnConnect = FALSE;
@@ -1263,11 +1227,11 @@ void LLFloaterIMPanel::draw()
else
{
// refresh volume and mute checkbox
- childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
+ childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID));
childSetValue("mute_btn", LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat));
- childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
+ childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
}
LLFloater::draw();
}
@@ -1403,12 +1367,6 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
{
mNumUnreadMessages++;
}
-
- if (source != LLUUID::null)
- {
- mSpeakers->speakerChatted(source);
- mSpeakers->setSpeakerTyping(source, FALSE);
- }
}
@@ -1589,7 +1547,7 @@ void LLFloaterIMPanel::onClickStartCall(void* userdata)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
- self->mVoiceChannel->activate();
+ LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->activate();
}
// static
@@ -1597,7 +1555,7 @@ void LLFloaterIMPanel::onClickEndCall(void* userdata)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
- self->getVoiceChannel()->deactivate();
+ LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->deactivate();
}
// static
@@ -1671,7 +1629,8 @@ void LLFloaterIMPanel::onVisibilityChange(const LLSD& new_visibility)
mNumUnreadMessages = 0;
}
- if (new_visibility.asBoolean() && mVoiceChannel->getState() == LLVoiceChannel::STATE_CONNECTED)
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID);
+ if (new_visibility.asBoolean() && voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
LLFloaterReg::showInstance("voice_call", mSessionUUID);
else
LLFloaterReg::hideInstance("voice_call", mSessionUUID);
@@ -1723,11 +1682,6 @@ void LLFloaterIMPanel::sendMsg()
mSentTypingState = TRUE;
}
-void LLFloaterIMPanel::updateSpeakersList(const LLSD& speaker_updates)
-{
- mSpeakers->updateSpeakers(speaker_updates);
-}
-
void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
{
if (
@@ -1751,15 +1705,9 @@ void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
}
}
-void LLFloaterIMPanel::setSpeakers(const LLSD& speaker_list)
-{
- mSpeakers->setSpeakers(speaker_list);
-}
-
void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
{
mSessionUUID = session_id;
- mVoiceChannel->updateSessionID(session_id);
mSessionInitialized = TRUE;
//we assume the history editor hasn't moved at all since
@@ -1790,6 +1738,7 @@ void LLFloaterIMPanel::requestAutoConnect()
void LLFloaterIMPanel::setTyping(BOOL typing)
{
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
if (typing)
{
// Every time you type something, reset this timer
@@ -1804,7 +1753,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
mSentTypingState = FALSE;
}
- mSpeakers->setSpeakerTyping(gAgent.getID(), TRUE);
+ speaker_mgr->setSpeakerTyping(gAgent.getID(), TRUE);
}
else
{
@@ -1814,7 +1763,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
sendTypingState(FALSE);
mSentTypingState = TRUE;
}
- mSpeakers->setSpeakerTyping(gAgent.getID(), FALSE);
+ speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
}
mTyping = typing;
@@ -1874,7 +1823,7 @@ void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info)
mHistoryEditor->removeTextFromEnd(chars_to_remove);
if (im_info)
{
- mSpeakers->setSpeakerTyping(im_info->mFromID, FALSE);
+ LLIMModel::getInstance()->getSpeakerManager(mSessionUUID)->setSpeakerTyping(im_info->mFromID, FALSE);
}
}
}
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index fd1134ee5e..fb9b28ad16 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -33,6 +33,7 @@
#ifndef LL_IMPANEL_H
#define LL_IMPANEL_H
+#include "llimview.h" //for LLIMModel
#include "lldockablefloater.h"
#include "lllogchat.h"
#include "lluuid.h"
@@ -245,11 +246,7 @@ public:
const LLUUID& getSessionID() const { return mSessionUUID; }
const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; }
- LLIMSpeakerMgr* getSpeakerManager() const { return mSpeakers; }
- void updateSpeakersList(const LLSD& speaker_updates);
void processSessionUpdate(const LLSD& update);
- void setSpeakers(const LLSD& speaker_list);
- LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
EInstantMessage getDialogType() const { return mDialog; }
void setDialogType(EInstantMessage dialog) { mDialog = dialog; }
@@ -305,7 +302,6 @@ private:
LLUUID mSessionUUID;
std::string mSessionLabel;
- LLVoiceChannel* mVoiceChannel;
BOOL mSessionInitialized;
LLSD mQueuedMsgsForInit;
@@ -346,7 +342,6 @@ private:
BOOL mProfileButtonEnabled;
BOOL mCallBackEnabled;
- LLIMSpeakerMgr* mSpeakers;
LLPanelActiveSpeakers* mSpeakerPanel;
// Optimization: Don't send "User is typing..." until the
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 3cf78f957b..556eb5ffd7 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -114,10 +114,84 @@ void toast_callback(const LLSD& msg){
LLIMModel::LLIMModel()
{
- addChangedCallback(toast_callback);
addChangedCallback(LLIMFloater::newIMCallback);
+ addChangedCallback(toast_callback);
+}
+
+
+LLIMModel::LLIMSession::LLIMSession( const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id )
+: mSessionID(session_id),
+ mName(name),
+ mType(type),
+ mNumUnread(0),
+ mOtherParticipantID(other_participant_id),
+ mVoiceChannel(NULL),
+ mSpeakers(NULL)
+{
+ if (IM_NOTHING_SPECIAL == type || IM_SESSION_P2P_INVITE == type)
+ {
+ mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id);
+ }
+ else
+ {
+ mVoiceChannel = new LLVoiceChannelGroup(session_id, name);
+ }
+ mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
+
+ // All participants will be added to the list of people we've recently interacted with.
+ mSpeakers->addListener(&LLRecentPeople::instance(), "add");
+}
+
+LLIMModel::LLIMSession::~LLIMSession()
+{
+ delete mSpeakers;
+ mSpeakers = NULL;
+
+ // End the text IM session if necessary
+ if(gVoiceClient && mOtherParticipantID.notNull())
+ {
+ switch(mType)
+ {
+ case IM_NOTHING_SPECIAL:
+ case IM_SESSION_P2P_INVITE:
+ gVoiceClient->endUserIMSession(mOtherParticipantID);
+ break;
+
+ default:
+ // Appease the linux compiler
+ break;
+ }
+ }
+
+ // HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
+ mVoiceChannel->deactivate();
+
+ delete mVoiceChannel;
+ mVoiceChannel = NULL;
}
+LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
+{
+ return get_if_there(LLIMModel::instance().sSessionsMap, session_id,
+ (LLIMModel::LLIMSession*) NULL);
+}
+
+void LLIMModel::updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id)
+{
+ if (new_session_id == old_session_id) return;
+
+ LLIMSession* session = findIMSession(old_session_id);
+ if (session)
+ {
+ session->mSessionID = new_session_id;
+ session->mVoiceChannel->updateSessionID(new_session_id);
+
+ //*TODO set session initialized flag here? (IB)
+
+ sSessionsMap.erase(old_session_id);
+ sSessionsMap[new_session_id] = session;
+ }
+}
void LLIMModel::testMessages()
{
@@ -153,7 +227,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage
return false;
}
- LLIMSession* session = new LLIMSession(name, type, other_participant_id);
+ LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id);
sSessionsMap[session_id] = session;
LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id);
@@ -170,12 +244,12 @@ bool LLIMModel::clearSession(LLUUID session_id)
return true;
}
+//*TODO remake it, instead of returing the list pass it as as parameter (IB)
std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
{
std::list<LLSD> return_list;
- LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
-
+ LLIMSession* session = findIMSession(session_id);
if (!session)
{
llwarns << "session " << session_id << "does not exist " << llendl;
@@ -202,13 +276,14 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
mChangedSignal(arg);
// TODO: in the future is there a more efficient way to return these
+ //of course there is - return as parameter (IB)
return return_list;
}
bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string utf8_text) {
- LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+ LLIMSession* session = findIMSession(session_id);
if (!session)
{
@@ -231,7 +306,7 @@ bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string ut
bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text) {
- LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+ LLIMSession* session = findIMSession(session_id);
if (!session)
{
@@ -260,9 +335,9 @@ bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id,
}
-const std::string& LLIMModel::getName(LLUUID session_id)
+const std::string& LLIMModel::getName(const LLUUID& session_id) const
{
- LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+ LLIMSession* session = findIMSession(session_id);
if (!session)
{
@@ -273,6 +348,66 @@ const std::string& LLIMModel::getName(LLUUID session_id)
return session->mName;
}
+const S32 LLIMModel::getNumUnread(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return -1;
+ }
+
+ return session->mNumUnread;
+}
+
+const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return LLUUID::null;
+ }
+
+ return session->mOtherParticipantID;
+}
+
+EInstantMessage LLIMModel::getType(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return IM_COUNT;
+ }
+
+ return session->mType;
+}
+
+LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id ) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return NULL;
+ }
+
+ return session->mVoiceChannel;
+}
+
+LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return NULL;
+ }
+
+ return session->mSpeakers;
+}
+
// TODO get rid of other participant ID
void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing)
@@ -316,7 +451,7 @@ void LLIMModel::sendLeaveSession(LLUUID session_id, LLUUID other_participant_id)
}
-
+//*TODO update list of messages in a LLIMSession (IB)
void LLIMModel::sendMessage(const std::string& utf8_text,
const LLUUID& im_session_id,
const LLUUID& other_participant_id,
@@ -415,9 +550,16 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(im_session_id);
if (floater) floater->addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID());
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(im_session_id);
+ if (speaker_mgr)
+ {
+ speaker_mgr->speakerChatted(gAgentID);
+ speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
+ }
}
// Add the recipient to the recent people list.
+ //*TODO should be deleted, because speaker manager updates through callback the recent list
LLRecentPeople::instance().add(other_participant_id);
}
@@ -633,10 +775,8 @@ public:
{
if ( gIMMgr)
{
- LLFloaterIMPanel* floaterp =
- gIMMgr->findFloaterBySession(mSessionID);
-
- if (floaterp)
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
{
//we've accepted our invitation
//and received a list of agents that were
@@ -650,15 +790,20 @@ public:
//but unfortunately, our base that we are receiving here
//may not be the most up to date. It was accurate at
//some point in time though.
- floaterp->setSpeakers(content);
+ speaker_mgr->setSpeakers(content);
//we now have our base of users in the session
//that was accurate at some point, but maybe not now
//so now we apply all of the udpates we've received
//in case of race conditions
- floaterp->updateSpeakersList(
- gIMMgr->getPendingAgentListUpdates(mSessionID));
+ speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
+ }
+
+ LLFloaterIMPanel* floaterp =
+ gIMMgr->findFloaterBySession(mSessionID);
+ if (floaterp)
+ {
if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
{
floaterp->requestAutoConnect();
@@ -1104,6 +1249,12 @@ void LLIMMgr::addMessage(
//no session ID...compute new one
new_session_id = computeSessionID(dialog, other_participant_id);
}
+
+ if (!LLIMModel::getInstance()->findIMSession(new_session_id))
+ {
+ LLIMModel::instance().newSession(session_id, session_name, dialog, other_participant_id);
+ }
+
floater = findFloaterBySession(new_session_id);
if (!floater)
{
@@ -1169,6 +1320,14 @@ void LLIMMgr::addMessage(
else
{
floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message
+
+ //*TODO consider moving that speaker management stuff into model (IB)
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(new_session_id);
+ if (speaker_mgr)
+ {
+ speaker_mgr->speakerChatted(gAgentID);
+ speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
+ }
}
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
@@ -1273,11 +1432,10 @@ LLUUID LLIMMgr::addP2PSession(const std::string& name,
{
LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id);
- LLFloaterIMPanel* floater = findFloaterBySession(session_id);
- if(floater)
+ LLVoiceChannelP2P* voice_channel = (LLVoiceChannelP2P*) LLIMModel::getInstance()->getSpeakerManager(session_id);
+ if (voice_channel)
{
- LLVoiceChannelP2P* voice_channelp = (LLVoiceChannelP2P*)floater->getVoiceChannel();
- voice_channelp->setSessionHandle(voice_session_handle, caller_uri);
+ voice_channel->setSessionHandle(voice_session_handle, caller_uri);
}
return session_id;
@@ -1312,6 +1470,11 @@ LLUUID LLIMMgr::addSession(
LLUUID session_id = computeSessionID(dialog,other_participant_id);
+ if (!LLIMModel::getInstance()->findIMSession(session_id))
+ {
+ LLIMModel::instance().newSession(session_id, name, dialog, other_participant_id);
+ }
+
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if(!floater)
{
@@ -1335,17 +1498,10 @@ LLUUID LLIMMgr::addSession(
noteMutedUsers(floater, ids);
}
}
- else
- {
- // *TODO: Remove this? Otherwise old communicate window opens on
- // second initiation of IM session from People panel?
- // floater->openFloater();
- }
- //mTabContainer->selectTabPanel(panel);
floater->setInputFocus(TRUE);
LLIMFloater::show(session_id);
- notifyObserverSessionAdded(floater->getSessionID(), name, other_participant_id);
- return floater->getSessionID();
+
+ return session_id;
}
// This removes the panel referenced by the uuid, and then restores
@@ -1705,7 +1861,6 @@ LLFloaterIMPanel* LLIMMgr::createFloater(
LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
LLFloaterChatterBox::getInstance()->addFloater(floater, FALSE, i_pt);
mFloaters.insert(floater->getHandle());
- LLIMModel::instance().newSession(session_id, session_label, dialog, other_participant_id);
return floater;
}
@@ -1825,24 +1980,25 @@ public:
gIMMgr->updateFloaterSessionID(
temp_session_id,
session_id);
+
+ LLIMModel::getInstance()->updateSessionID(temp_session_id, session_id);
+
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+ if (speaker_mgr)
+ {
+ speaker_mgr->setSpeakers(body);
+ speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
+ }
+
LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
if (floaterp)
{
- floaterp->setSpeakers(body);
-
- //apply updates we've possibly received previously
- floaterp->updateSpeakersList(
- gIMMgr->getPendingAgentListUpdates(session_id));
-
if ( body.has("session_info") )
{
floaterp->processSessionUpdate(body["session_info"]);
}
-
- //aply updates we've possibly received previously
- floaterp->updateSpeakersList(
- gIMMgr->getPendingAgentListUpdates(session_id));
}
+
gIMMgr->clearPendingAgentListUpdates(session_id);
}
else
@@ -1932,15 +2088,15 @@ public:
const LLSD& context,
const LLSD& input) const
{
- LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID());
- if (floaterp)
+ const LLUUID& session_id = input["body"]["session_id"].asUUID();
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+ if (speaker_mgr)
{
- floaterp->updateSpeakersList(
- input["body"]);
+ speaker_mgr->updateSpeakers(input["body"]);
}
else
{
- //we don't have a floater yet..something went wrong
+ //we don't have a speaker manager yet..something went wrong
//we are probably receiving an update here before
//a start or an acceptance of an invitation. Race condition.
gIMMgr->addPendingAgentListUpdates(
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 219af0705d..9a94d01bb2 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -34,6 +34,8 @@
#define LL_LLIMVIEW_H
#include "lldarray.h"
+#include "llfloateractivespeakers.h" //for LLIMSpeakerMgr
+#include "llimpanel.h" //for voice channels
#include "llmodaldialog.h"
#include "llinstantmessage.h"
#include "lluuid.h"
@@ -50,21 +52,40 @@ public:
struct LLIMSession
{
- LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id)
- :mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id) {}
-
+ LLIMSession(const LLUUID& session_id, const std::string& name,
+ const EInstantMessage& type, const LLUUID& other_participant_id);
+ virtual ~LLIMSession();
+
+ LLUUID mSessionID;
std::string mName;
EInstantMessage mType;
LLUUID mOtherParticipantID;
S32 mNumUnread;
std::list<LLSD> mMsgs;
+
+ LLVoiceChannel* mVoiceChannel;
+ LLIMSpeakerMgr* mSpeakers;
};
LLIMModel();
+ //*TODO make it non-static as LLIMMOdel is a singleton (IB)
static std::map<LLUUID, LLIMSession*> sSessionsMap; //mapping session_id to session
+
boost::signals2::signal<void(const LLSD&)> mChangedSignal;
+
+ /**
+ * Find an IM Session corresponding to session_id
+ * Returns NULL if the session does not exist
+ */
+ LLIMSession* findIMSession(const LLUUID& session_id) const;
+
+ /**
+ * Rebind session data to a new session id.
+ */
+ void updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id);
+
boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb );
bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id);
@@ -72,10 +93,42 @@ public:
std::list<LLSD> getMessages(LLUUID session_id, int start_index = 0);
bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text);
bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text);
- //used to get the name of the session, for use as the title
- //currently just the other avatar name
- const std::string& getName(LLUUID session_id);
-
+ //used to get the name of the session, for use as the title
+ //currently just the other avatar name
+ const std::string& getName(const LLUUID& session_id) const;
+
+ /**
+ * Get number of unread messages in a session with session_id
+ * Returns -1 if the session with session_id doesn't exist
+ */
+ const S32 getNumUnread(const LLUUID& session_id) const;
+
+ /**
+ * Get uuid of other participant in a session with session_id
+ * Returns LLUUID::null if the session doesn't exist
+ *
+ * *TODO what to do with other participants in ad-hoc and group chats?
+ */
+ const LLUUID& getOtherParticipantID(const LLUUID& session_id) const;
+
+ /**
+ * Get type of a session specified by session_id
+ * Returns EInstantMessage::IM_COUNT if the session does not exist
+ */
+ EInstantMessage getType(const LLUUID& session_id) const;
+
+ /**
+ * Get voice channel for the session specified by session_id
+ * Returns NULL if the session does not exist
+ */
+ LLVoiceChannel* getVoiceChannel(const LLUUID& session_id) const;
+
+ /**
+ * Get im speaker manager for the session specified by session_id
+ * Returns NULL if the session does not exist
+ */
+ LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const;
+
static void sendLeaveSession(LLUUID session_id, LLUUID other_participant_id);
static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
const std::vector<LLUUID>& ids, EInstantMessage dialog);
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index b53bb586f3..8430937933 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -65,6 +65,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key) :
mChatCaptionPanel(NULL),
mChatHistoryEditor(NULL)
{
+ m_isDirty = false;
}
LLNearbyChat::~LLNearbyChat()
@@ -181,7 +182,7 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat)
return text_color;
}
-void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color)
+void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& color)
{
std::string line = chat.mText;
@@ -194,25 +195,28 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons
bool prepend_newline = true;
if (gSavedSettings.getBOOL("ChatShowTimestamps"))
{
- edit->appendTime(prepend_newline);
+ mChatHistoryEditor->appendTime(prepend_newline);
prepend_newline = false;
}
// If the msg is from an agent (not yourself though),
// extract out the sender name and replace it with the hotlinked name.
+
+ std::string str_URL = chat.mURL;
+
if (chat.mSourceType == CHAT_SOURCE_AGENT &&
chat.mFromID != LLUUID::null)
{
- chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
+ str_URL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
}
// If the chat line has an associated url, link it up to the name.
- if (!chat.mURL.empty()
+ if (!str_URL.empty()
&& (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0))
{
std::string start_line = line.substr(0, chat.mFromName.length() + 1);
line = line.substr(chat.mFromName.length() + 1);
- edit->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,chat.mURL));
+ mChatHistoryEditor->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,str_URL));
prepend_newline = false;
}
@@ -225,11 +229,9 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons
else if (2 == font_size)
font_name = "sansserifbig";
- edit->appendColoredText(line, false, prepend_newline, color, font_name);
+ mChatHistoryEditor->appendColoredText(line, false, prepend_newline, color, font_name);
}
-
-
void LLNearbyChat::addMessage(const LLChat& chat)
{
LLColor4 color = nearbychat_get_text_color(chat);
@@ -254,7 +256,7 @@ void LLNearbyChat::addMessage(const LLChat& chat)
mChatHistoryEditor->setParseHighlights(TRUE);
if (!chat.mMuted)
- nearbychat_add_timestamped_line(mChatHistoryEditor, chat, color);
+ add_timestamped_line(chat, color);
}
void LLNearbyChat::onNearbySpeakers()
@@ -482,9 +484,16 @@ BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask)
void LLNearbyChat::onOpen(const LLSD& key )
{
- LLNotificationsUI::LLScreenChannel* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+ LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
if(chat_channel)
{
chat_channel->removeToastsFromChannel();
}
}
+
+void LLNearbyChat::draw ()
+{
+ LLFloater::draw();
+}
+
+
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index efa2e479e6..599e6b6859 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -76,7 +76,10 @@ public:
virtual void onOpen (const LLSD& key);
+ virtual void draw ();
+
private:
+ void add_timestamped_line(const LLChat& chat, const LLColor4& color);
void pinn_panel();
void float_panel();
@@ -86,10 +89,11 @@ private:
S32 mStart_X;
S32 mStart_Y;
- //LLResizeBar* mResizeBar[RESIZE_BAR_COUNT];
LLHandle<LLView> mPopupMenuHandle;
LLPanel* mChatCaptionPanel;
LLViewerTextEditor* mChatHistoryEditor;
+
+ bool m_isDirty;
};
#endif
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 7eb5d91e53..eb42e83994 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -41,30 +41,227 @@
#include "llviewercontrol.h"
#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
+#include "llviewerwindow.h"//for screen channel position
//add LLNearbyChatHandler to LLNotificationsUI namespace
-namespace LLNotificationsUI{
+using namespace LLNotificationsUI;
+//-----------------------------------------------------------------------------------------------
+//LLNearbyChatScreenChannel
+//-----------------------------------------------------------------------------------------------
+LLToastPanelBase* createToastPanel()
+{
+ LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance();
+ static S32 chat_item_width = 304;
+ item->setWidth(chat_item_width);
+ return item;
+}
+
+
+class LLNearbyChatScreenChannel: public LLScreenChannelBase
+{
+public:
+ LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id) { mActiveMessages = 0;};
+ void init (S32 channel_left, S32 channel_right);
+
+ void addNotification (LLSD& notification);
+ void arrangeToasts ();
+ void showToastsBottom ();
+
+ typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t;
+ void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
+
+ void onToastDestroyed (LLToast* toast);
+ void onToastFade (LLToast* toast);
+
+ // hide all toasts from screen, but not remove them from a channel
+ virtual void hideToastsFromScreen()
+ {
+ };
+ // removes all toasts from a channel
+ virtual void removeToastsFromChannel()
+ {
+ for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+ {
+ LLToast* toast = (*it);
+ toast->setVisible(FALSE);
+ toast->stopTimer();
+ m_toast_pool.push_back(toast);
+
+ }
+ m_active_toasts.clear();
+ };
+
+protected:
+ void createOverflowToast(S32 bottom, F32 timer);
+
+ create_toast_panel_callback_t m_create_toast_panel_callback_t;
+
+ bool createPoolToast();
+
+ std::vector<LLToast*> m_active_toasts;
+ std::list<LLToast*> m_toast_pool;
+
+ S32 mActiveMessages;
+};
+
+void LLNearbyChatScreenChannel::init(S32 channel_left, S32 channel_right)
+{
+ S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
+ S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom;
+ setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
+ setVisible(TRUE);
+}
+
+
+void LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
+{
+ //we don't need overflow toast in nearby chat
+}
+
+void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast)
+{
+}
+
+void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)
+{
+ //fade mean we put toast to toast pool
+ if(!toast)
+ return;
+ m_toast_pool.push_back(toast);
+
+ std::vector<LLToast*>::iterator pos = std::find(m_active_toasts.begin(),m_active_toasts.end(),toast);
+ if(pos!=m_active_toasts.end())
+ m_active_toasts.erase(pos);
+
+ arrangeToasts();
+}
+
+
+bool LLNearbyChatScreenChannel::createPoolToast()
+{
+ LLToastPanelBase* panel= m_create_toast_panel_callback_t();
+ if(!panel)
+ return false;
+
+ LLToast::Params p;
+ p.panel = panel;
+
+ LLToast* toast = new LLToast(p);
+
+
+ toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1));
+ toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1));
+
+ m_toast_pool.push_back(toast);
+ return true;
+}
+
+void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
+{
+ //look in pool. if there is any message
+
+
+ if(m_toast_pool.empty())
+ {
+ //"pool" is empty - create one more panel
+ if(!createPoolToast())//created toast will go to pool. so next call will find it
+ return;
+ addNotification(notification);
+ return;
+ }
+
+ //take 1st element from pool, (re)initialize it, put it in active toasts
+
+ LLToast* toast = m_toast_pool.back();
+
+ m_toast_pool.pop_back();
+
+
+ LLToastPanelBase* panel = dynamic_cast<LLToastPanelBase*>(toast->getPanel());
+ if(!panel)
+ return;
+ panel->init(notification);
+
+ toast->reshapeToPanel();
+ toast->resetTimer();
+
+ m_active_toasts.insert(m_active_toasts.begin(),toast);
+
+ arrangeToasts();
+}
+
+void LLNearbyChatScreenChannel::arrangeToasts()
+{
+ if(m_active_toasts.size() == 0 || mIsHovering)
+ return;
+
+ hideToastsFromScreen();
+
+ showToastsBottom();
+}
+
+void LLNearbyChatScreenChannel::showToastsBottom()
+{
+ LLRect rect = getRect();
+
+ LLRect toast_rect;
+ S32 bottom = getRect().mBottom;
+
+ for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+ {
+ LLToast* toast = (*it);
+ toast_rect = toast->getRect();
+ toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());
+
+ toast->setRect(toast_rect);
+
+ if(toast->getRect().mTop > getRect().getHeight())
+ {
+ while(it!=m_active_toasts.end())
+ {
+ (*it)->setVisible(FALSE);
+ (*it)->stopTimer();
+ m_toast_pool.push_back(*it);
+ it=m_active_toasts.erase(it);
+ }
+ break;
+ }
+ toast->setVisible(TRUE);
+ bottom = toast->getRect().mTop;
+ }
+}
+
+
+//-----------------------------------------------------------------------------------------------
+//LLNearbyChatHandler
+//-----------------------------------------------------------------------------------------------
LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
{
mType = type;
- LLChannelManager::Params p;
- p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
// Getting a Channel for our notifications
- mChannel = LLChannelManager::getInstance()->getChannel(p);
+ LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+
+ LLNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
+
+ channel->setCreatePanelCallback(callback);
+
+ mChannel = LLChannelManager::getInstance()->addChannel(channel);
mChannel->setOverflowFormatString("You have %d unread nearby chat messages");
}
+
LLNearbyChatHandler::~LLNearbyChatHandler()
{
}
+
void LLNearbyChatHandler::initChannel()
{
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
S32 channel_right_bound = nearby_chat->getRect().mRight;
- S32 channel_width = nearby_chat->getRect().mRight - 16; //HACK: 16 - ?
+ S32 channel_width = nearby_chat->getRect().mRight;
mChannel->init(channel_right_bound - channel_width, channel_right_bound);
}
@@ -77,41 +274,42 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
if(chat_msg.mText.empty())
return;//don't process empty messages
-
+
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
nearby_chat->addMessage(chat_msg);
if(nearby_chat->getVisible())
return;//no need in toast if chat is visible
-
+
// arrange a channel on a screen
if(!mChannel->getVisible())
{
initChannel();
}
-
+
LLUUID id;
id.generate();
- LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
-
- item->setMessage(chat_msg);
- //static S32 chat_item_width = nearby_chat->getRect().getWidth() - 16;
- static S32 chat_item_width = 304;
- item->setWidth(chat_item_width);
- item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
+ LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel);
- item->setVisible(true);
- LLToast::Params p;
- p.notif_id = id;
- p.panel = item;
- p.on_delete_toast = boost::bind(&LLNearbyChatHandler::onDeleteToast, this, _1);
- mChannel->addToast(p);
+ if(channel)
+ {
+ LLSD notification;
+ notification["id"] = id;
+ 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;
+
+ channel->addNotification(notification);
+ }
+
}
void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
{
}
-}
+
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 3893eaa0d4..755f1235a6 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -100,16 +100,23 @@ bool LLAlertHandler::processNotification(const LLSD& notify)
p.can_fade = false;
p.is_modal = mIsModal;
p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
- mChannel->addToast(p);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
}
else if (notify["sigtype"].asString() == "change")
{
LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
- mChannel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
}
else
{
- mChannel->killToastByNotificationID(notification->getID());
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->killToastByNotificationID(notification->getID());
}
return true;
}
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index c488d37ea5..ffa92b543c 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -89,7 +89,10 @@ bool LLGroupHandler::processNotification(const LLSD& notify)
p.notification = notification;
p.panel = notify_box;
p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
- mChannel->addToast(p);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
// send a signal to the counter manager
mNewNotificationSignal();
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 90ff5fbaac..cd4e640ec4 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -104,8 +104,8 @@ protected:
// at the moment, when a handlers creates a channel.
virtual void initChannel()=0;
- LLScreenChannel* mChannel;
- e_notification_type mType;
+ LLScreenChannelBase* mChannel;
+ e_notification_type mType;
};
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 72855ac0fd..070af432d6 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -48,7 +48,11 @@ LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
// Getting a Channel for our notifications
mChannel = LLChannelManager::getInstance()->createNotificationChannel();
mChannel->setControlHovering(true);
- mChannel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+
}
//--------------------------------------------------------------------------
@@ -92,7 +96,10 @@ bool LLScriptHandler::processNotification(const LLSD& notify)
p.notification = notification;
p.panel = notify_box;
p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
- mChannel->addToast(p);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
// send a signal to the counter manager
mNewNotificationSignal();
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index 740acb6365..5186a93569 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -93,8 +93,9 @@ bool LLTipHandler::processNotification(const LLSD& notify)
p.is_tip = true;
p.can_be_stored = false;
- mChannel->addToast(p);
-
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
}
else if (notify["sigtype"].asString() == "delete")
{
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 649697e091..7ccff73080 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -313,7 +313,7 @@ void LLPanelProfileTab::scrollToTop()
{
LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
if (scrollContainer)
- scrollContainer->goToTop();
+ scrollContainer->goToTop();
}
//////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 490c845c94..2b584910a3 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -195,7 +195,7 @@ BOOL LLPanelGroup::postBuild()
if(panel_land) mTabs.push_back(panel_land);
if(panel_general)
- panel_general->setupCtrls(this);
+ panel_general->setupCtrls(this);
return TRUE;
}
@@ -206,8 +206,8 @@ void LLPanelGroup::reposButton(const std::string& name)
if(!button)
return;
LLRect btn_rect = button->getRect();
- btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
- button->setRect(btn_rect);
+ btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
+ button->setRect(btn_rect);
}
void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent )
@@ -235,7 +235,14 @@ void LLPanelGroup::onBtnCreate()
if(!panel_general)
return;
std::string apply_mesg;
- panel_general->apply(apply_mesg);//yes yes you need to call apply to create...
+ if(panel_general->apply(apply_mesg))//yes yes you need to call apply to create...
+ return;
+ if ( !apply_mesg.empty() )
+ {
+ LLSD args;
+ args["MESSAGE"] = apply_mesg;
+ LLNotifications::instance().add("GenericAlert", args);
+ }
}
void LLPanelGroup::onBtnRefresh(void* user_data)
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 5eb7b8f5f5..2e1d971995 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -835,6 +835,7 @@ void LLPanelGroupGeneral::reset()
{
std::string empty_str = "";
mEditCharter->setText(empty_str);
+ mGroupNameEditor->setText(empty_str);
}
{
@@ -850,6 +851,7 @@ void LLPanelGroupGeneral::reset()
{
mComboMature->setEnabled(true);
mComboMature->setVisible( !gAgent.isTeen() );
+ mComboMature->selectFirstItem();
}
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 6a41b6feb9..b2a0a01005 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -60,11 +60,8 @@
#include "llvoiceclient.h"
#include "llworld.h"
-using namespace LLOldEvents;
-
#define FRIEND_LIST_UPDATE_TIMEOUT 0.5
#define NEARBY_LIST_UPDATE_INTERVAL 1
-#define RECENT_LIST_UPDATE_DELAY 1
static const std::string NEARBY_TAB_NAME = "nearby_panel";
static const std::string FRIENDS_TAB_NAME = "friends_panel";
@@ -102,7 +99,7 @@ static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people");
class LLPanelPeople::Updater
{
public:
- typedef boost::function<bool(U32)> callback_t;
+ typedef boost::function<void()> callback_t;
Updater(callback_t cb)
: mCallback(cb)
{
@@ -113,16 +110,6 @@ public:
}
/**
- * Force the list updates.
- *
- * This may start repeated updates until all names are complete.
- */
- virtual void forceUpdate()
- {
- updateList();
- }
-
- /**
* Activate/deactivate updater.
*
* This may start/stop regular updates.
@@ -130,9 +117,9 @@ public:
virtual void setActive(bool) {}
protected:
- bool updateList(U32 mask = 0)
+ void updateList()
{
- return mCallback(mask);
+ mCallback();
}
callback_t mCallback;
@@ -147,6 +134,11 @@ public:
{
mEventTimer.stop();
}
+
+ virtual BOOL tick() // from LLEventTimer
+ {
+ return FALSE;
+ }
};
/**
@@ -178,13 +170,6 @@ public:
LLAvatarTracker::instance().removeObserver(this);
}
- /*virtual*/ void forceUpdate()
- {
- // Perform updates until all names are loaded.
- if (!updateList(LLFriendObserver::ADD))
- changed(LLFriendObserver::ADD);
- }
-
/*virtual*/ void changed(U32 mask)
{
// events can arrive quickly in bulk - we need not process EVERY one of them -
@@ -198,12 +183,12 @@ public:
/*virtual*/ BOOL tick()
{
- if (updateList(mMask))
- {
- // Got all names, stop updates.
- mEventTimer.stop();
- mMask = 0;
- }
+ if (mMask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
+ updateList();
+
+ // Stop updates.
+ mEventTimer.stop();
+ mMask = 0;
return FALSE;
}
@@ -329,68 +314,9 @@ class LLRecentListUpdater : public LLAvatarListUpdater, public boost::signals2::
public:
LLRecentListUpdater(callback_t cb)
- : LLAvatarListUpdater(cb, RECENT_LIST_UPDATE_DELAY)
- {
- LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::onRecentPeopleChanged, this));
- }
-
-private:
- /*virtual*/ void forceUpdate()
- {
- onRecentPeopleChanged();
- }
-
- /*virtual*/ BOOL tick()
- {
- // Update the list until we get all the names.
- if (updateList())
- {
- // Got all names, stop updates.
- mEventTimer.stop();
- }
-
- return FALSE;
- }
-
- void onRecentPeopleChanged()
- {
- if (!updateList())
- {
- // Some names are incomplete, schedule another update.
- mEventTimer.start();
- }
- }
-};
-
-/**
- * Updates the group list on events from LLAgent.
- */
-class LLGroupListUpdater : public LLPanelPeople::Updater, public LLSimpleListener
-{
- LOG_CLASS(LLGroupListUpdater);
-
-public:
- LLGroupListUpdater(callback_t cb)
- : LLPanelPeople::Updater(cb)
- {
- gAgent.addListener(this, "new group");
- }
-
- ~LLGroupListUpdater()
+ : LLAvatarListUpdater(cb, 0)
{
- gAgent.removeListener(this);
- }
-
- /*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- // Why is "new group" sufficient?
- if (event->desc() == "new group")
- {
- updateList();
- return true;
- }
-
- return false;
+ LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::updateList, this));
}
};
@@ -404,12 +330,12 @@ LLPanelPeople::LLPanelPeople()
mOnlineFriendList(NULL),
mAllFriendList(NULL),
mNearbyList(NULL),
- mRecentList(NULL)
+ mRecentList(NULL),
+ mGroupList(NULL)
{
- mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::onFriendListUpdate,this, _1));
+ mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList, this));
mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this));
mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList, this));
- mGroupListUpdater = new LLGroupListUpdater (boost::bind(&LLPanelPeople::updateGroupList, this));
}
LLPanelPeople::~LLPanelPeople()
@@ -417,7 +343,6 @@ LLPanelPeople::~LLPanelPeople()
delete mNearbyListUpdater;
delete mFriendListUpdater;
delete mRecentListUpdater;
- delete mGroupListUpdater;
LLView::deleteViewByHandle(mGroupPlusMenuHandle);
LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);
@@ -512,7 +437,7 @@ BOOL LLPanelPeople::postBuild()
buttonSetAction("share_btn", boost::bind(&LLPanelPeople::onShareButtonClicked, this));
getChild<LLPanel>(NEARBY_TAB_NAME)->childSetAction("nearby_view_sort_btn",boost::bind(&LLPanelPeople::onNearbyViewSortButtonClicked, this));
- getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked, this));
+ getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked, this));
getChild<LLPanel>(FRIENDS_TAB_NAME)->childSetAction("friends_viewsort_btn",boost::bind(&LLPanelPeople::onFriendsViewSortButtonClicked, this));
getChild<LLPanel>(GROUP_TAB_NAME)->childSetAction("groups_viewsort_btn",boost::bind(&LLPanelPeople::onGroupsViewSortButtonClicked, this));
@@ -547,137 +472,71 @@ BOOL LLPanelPeople::postBuild()
if(recent_view_sort)
mRecentViewSortMenuHandle = recent_view_sort->getHandle();
-
-
- // Perform initial update.
- mFriendListUpdater->forceUpdate();
- mNearbyListUpdater->forceUpdate();
- mGroupListUpdater->forceUpdate();
- mRecentListUpdater->forceUpdate();
-
// call this method in case some list is empty and buttons can be in inconsistent state
updateButtons();
return TRUE;
}
-void LLPanelPeople::applyFilterToTab(const std::string& tab_name)
-{
- if (tab_name == FRIENDS_TAB_NAME) // this tab has two lists
- filterFriendList();
- else if (tab_name == NEARBY_TAB_NAME)
- filterNearbyList();
- else if (tab_name == RECENT_TAB_NAME)
- filterRecentList();
- else if (tab_name == GROUP_TAB_NAME)
- updateGroupList();
-}
-
-bool LLPanelPeople::updateFriendList(U32 changed_mask)
+void LLPanelPeople::updateFriendList()
{
- // Refresh names.
- if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
- {
- // get all buddies we know about
- const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
- LLAvatarTracker::buddy_map_t all_buddies;
- av_tracker.copyBuddyList(all_buddies);
-
- // *TODO: it's suboptimal to rebuild the whole lists on online status change.
+ if (!mOnlineFriendList || !mAllFriendList)
+ return;
- // save them to the online and all friends vectors
- mOnlineFriendVec.clear();
- mAllFriendVec.clear();
+ // get all buddies we know about
+ const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
+ LLAvatarTracker::buddy_map_t all_buddies;
+ av_tracker.copyBuddyList(all_buddies);
- LLFriendCardsManager::folderid_buddies_map_t listMap;
+ // save them to the online and all friends vectors
+ LLAvatarList::uuid_vector_t& online_friendsp = mOnlineFriendList->getIDs();
+ LLAvatarList::uuid_vector_t& all_friendsp = mAllFriendList->getIDs();
- // *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
- LLFriendCardsManager::instance().collectFriendsLists(listMap);
- if (listMap.size() > 0)
- {
- lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;
- mAllFriendVec = listMap.begin()->second;
- }
- else
- {
- lldebugs << "Friends Cards were not found" << llendl;
- }
+ all_friendsp.clear();
+ online_friendsp.clear();
- LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
- for (; buddy_it != all_buddies.end(); ++buddy_it)
- {
- LLUUID buddy_id = buddy_it->first;
- if (av_tracker.isBuddyOnline(buddy_id))
- mOnlineFriendVec.push_back(buddy_id);
- }
+ LLFriendCardsManager::folderid_buddies_map_t listMap;
- return filterFriendList();
+ // *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
+ LLFriendCardsManager::instance().collectFriendsLists(listMap);
+ if (listMap.size() > 0)
+ {
+ lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;
+ all_friendsp = listMap.begin()->second;
+ }
+ else
+ {
+ lldebugs << "Friends Cards were not found" << llendl;
}
- return true;
-}
-
-bool LLPanelPeople::updateNearbyList()
-{
- LLWorld::getInstance()->getAvatars(&mNearbyVec, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
- filterNearbyList();
-
- return true;
-}
-
-bool LLPanelPeople::updateRecentList()
-{
- LLRecentPeople::instance().get(mRecentVec);
- filterRecentList();
-
- return true;
-}
-
-bool LLPanelPeople::updateGroupList()
-{
- if (!mGroupList)
- return true; // there's no point in further updates
+ LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
+ for (; buddy_it != all_buddies.end(); ++buddy_it)
+ {
+ LLUUID buddy_id = buddy_it->first;
+ if (av_tracker.isBuddyOnline(buddy_id))
+ online_friendsp.push_back(buddy_id);
+ }
- bool have_names = mGroupList->update(mFilterSubString);
- updateButtons();
- return have_names;
+ mOnlineFriendList->setDirty();
+ mAllFriendList->setDirty();
}
-bool LLPanelPeople::filterFriendList()
+void LLPanelPeople::updateNearbyList()
{
- if (!mOnlineFriendList || !mAllFriendList)
- return true; // there's no point in further updates
-
- // We must always update Friends list to clear the latest removed friend.
- bool have_names =
- mOnlineFriendList->update(mOnlineFriendVec, mFilterSubString) &
- mAllFriendList->update(mAllFriendVec, mFilterSubString);
-
-
- updateButtons();
- return have_names;
-}
+ if (!mNearbyList)
+ return;
-bool LLPanelPeople::filterNearbyList()
-{
- bool have_names = mNearbyList->update(mNearbyVec, mFilterSubString);
- updateButtons();
- return have_names;
+ LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+ mNearbyList->setDirty();
}
-bool LLPanelPeople::filterRecentList()
+void LLPanelPeople::updateRecentList()
{
if (!mRecentList)
- return true;
-
- if (mRecentVec.size() > 0)
- {
- bool updated = mRecentList->update(mRecentVec, mFilterSubString);
- updateButtons();
- return updated;
- }
+ return;
- return true;
+ LLRecentPeople::instance().get(mRecentList->getIDs());
+ mRecentList->setDirty();
}
void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
@@ -846,16 +705,19 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
LLStringUtil::toUpper(mFilterSubString);
LLStringUtil::trimHead(mFilterSubString);
- // Apply new filter to current tab.
- applyFilterToTab(getActiveTabName());
+ // Apply new filter.
+ mNearbyList->setNameFilter(mFilterSubString);
+ mOnlineFriendList->setNameFilter(mFilterSubString);
+ mAllFriendList->setNameFilter(mFilterSubString);
+ mRecentList->setNameFilter(mFilterSubString);
+ mGroupList->setNameFilter(mFilterSubString);
}
void LLPanelPeople::onTabSelected(const LLSD& param)
{
std::string tab_name = getChild<LLPanel>(param.asString())->getName();
mNearbyListUpdater->setActive(tab_name == NEARBY_TAB_NAME);
- applyFilterToTab(tab_name);
- // No need to call updateButtons() because applyFilterToTab() does that.
+ updateButtons();
if (GROUP_TAB_NAME == tab_name)
mFilterEditor->setLabel(getString("groups_filter_label"));
@@ -960,17 +822,6 @@ void LLPanelPeople::onAvatarPicked(
LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
}
-bool LLPanelPeople::onFriendListUpdate(U32 changed_mask)
-{
- bool have_names = updateFriendList(changed_mask);
-
- // Update online status in the Recent tab.
- // *TODO: isn't it too much to update the whole list?
-// updateRecentList(); // mantipov: seems online status should be supported by LLAvatarListItem itself.
-
- return have_names;
-}
-
void LLPanelPeople::onGroupPlusButtonClicked()
{
LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 8cd3cc7feb..de27814388 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -58,15 +58,10 @@ public:
private:
// methods indirectly called by the updaters
- bool updateFriendList(U32 changed_mask);
- bool updateNearbyList();
- bool updateRecentList();
- bool updateGroupList();
-
- bool filterFriendList();
- bool filterNearbyList();
- bool filterRecentList();
- void applyFilterToTab(const std::string& tab_name);
+ void updateFriendList();
+ void updateNearbyList();
+ void updateRecentList();
+
void updateButtons();
const std::string& getActiveTabName() const;
LLUUID getCurrentItemID() const;
@@ -110,7 +105,6 @@ private:
void onRecentViewSortMenuItemClicked(const LLSD& userdata);
// misc callbacks
- bool onFriendListUpdate(U32 changed_mask);
static void onAvatarPicked(
const std::vector<std::string>& names,
const std::vector<LLUUID>& ids,
@@ -135,21 +129,8 @@ private:
Updater* mFriendListUpdater;
Updater* mNearbyListUpdater;
Updater* mRecentListUpdater;
- Updater* mGroupListUpdater;
std::string mFilterSubString;
-
- // The vectors below contain up-to date avatar lists
- // for the corresponding tabs.
- // When the user enters a filter, it gets applied
- // to all the vectors and the result is shown in the tabs.
- // We don't need to have such a vector for the groups tab
- // since re-fetching the groups list is always fast.
- typedef std::vector<LLUUID> uuid_vector_t;
- uuid_vector_t mNearbyVec;
- uuid_vector_t mOnlineFriendVec;
- uuid_vector_t mAllFriendVec;
- uuid_vector_t mRecentVec;
};
#endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 42185d28e5..5df3d4f1d6 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -39,8 +39,10 @@
#include "message.h"
#include "llagent.h"
#include "llbutton.h"
+#include "lllineeditor.h"
#include "llparcel.h"
#include "llviewerparcelmgr.h"
+#include "lltexteditor.h"
#include "lltexturectrl.h"
#include "lluiconstants.h"
#include "llworldmap.h"
@@ -73,7 +75,8 @@ LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */)
mPickId(LLUUID::null),
mCreatorId(LLUUID::null),
mDataReceived(FALSE),
- mIsPickNew(false)
+ mIsPickNew(false),
+ mLocationChanged(false)
{
if (edit_mode)
{
@@ -123,6 +126,16 @@ BOOL LLPanelPick::postBuild()
if (mEditMode)
{
+ enableSaveButton(FALSE);
+
+ mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1));
+
+ LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
+ line_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1), NULL);
+
+ LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
+ text_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1));
+
childSetAction("cancel_btn", boost::bind(&LLPanelPick::onClickCancel, this));
childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPick::onClickSet, this));
childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPick::onClickSave, this));
@@ -287,6 +300,26 @@ void LLPanelPick::setEditMode( BOOL edit_mode )
updateButtons();
}
+void LLPanelPick::onPickChanged(LLUICtrl* ctrl)
+{
+ if(mLocationChanged)
+ {
+ // Pick was enabled in onClickSet
+ return;
+ }
+
+ if( mSnapshotCtrl->isDirty()
+ || getChild<LLLineEditor>("pick_name")->isDirty()
+ || getChild<LLTextEditor>("pick_desc")->isDirty() )
+ {
+ enableSaveButton(TRUE);
+ }
+ else
+ {
+ enableSaveButton(FALSE);
+ }
+}
+
//////////////////////////////////////////////////////////////////////////
// PROTECTED AREA
//////////////////////////////////////////////////////////////////////////
@@ -466,6 +499,9 @@ void LLPanelPick::onClickSet()
mSimName = parcel->getName();
}
setPickLocation(createLocationText(std::string(""), SET_LOCATION_NOTICE, mSimName, mPosGlobal));
+
+ mLocationChanged = true;
+ enableSaveButton(TRUE);
}
// static
@@ -552,3 +588,12 @@ void LLPanelPick::processParcelInfo(const LLParcelData& parcel_data)
//*NOTE we don't removeObserver(...) ourselves cause LLRemoveParcelProcessor does it for us
}
+
+void LLPanelPick::enableSaveButton(bool enable)
+{
+ if(!mEditMode)
+ {
+ return;
+ }
+ childSetEnabled(XML_BTN_SAVE, enable);
+}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index 7ce58b59af..82cba72bc4 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -74,6 +74,8 @@ public:
// switches the panel to either View or Edit mode
void setEditMode(BOOL edit_mode);
+ void onPickChanged(LLUICtrl* ctrl);
+
// because this panel works in two modes (edit/view) we are
// free from managing two panel for editing and viewing picks and so
// are free from controlling switching between them in the parent panel (e.g. Me Profile)
@@ -128,6 +130,8 @@ protected:
void onClickSave();
void onClickCancel();
+ void enableSaveButton(bool enable);
+
protected:
BOOL mEditMode;
LLTextureCtrl* mSnapshotCtrl;
@@ -146,6 +150,7 @@ protected:
std::string mLocation;
commit_callback_t mBackCb;
+ bool mLocationChanged;
};
#endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 93317e613f..e74afba25a 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -126,8 +126,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
mPicksList->addItem(picture, pick_value);
picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1));
- picture->setRightMouseDownCallback(boost::bind(&LLPanelPicks::onRightMouseDownItem, this, _1, _2, _3, _4));
- picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
+ picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
}
@@ -260,8 +259,10 @@ void LLPanelPicks::onClickMap()
}
-void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
+void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
{
+ updateButtons();
+
if (mPopupMenu)
{
mPopupMenu->buildDrawLabels();
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 27a21305b3..7ebdc3089c 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -100,7 +100,7 @@ private:
void updateButtons();
virtual void onDoubleClickItem(LLUICtrl* item);
- virtual void onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
+ virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
LLPanelProfile* getProfilePanel();
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 4e070df7eb..80ecc95afb 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -337,7 +337,7 @@ void LLPanelPlaces::onFilterEdit(const std::string& search_string)
LLStringUtil::trimHead(mFilterSubString);
if (mActivePanel)
- mActivePanel->onSearchEdit(mFilterSubString);
+ mActivePanel->onSearchEdit(mFilterSubString);
}
}
@@ -386,7 +386,7 @@ void LLPanelPlaces::onTeleportButtonClicked()
else
{
if (mActivePanel)
- mActivePanel->onTeleport();
+ mActivePanel->onTeleport();
}
}
@@ -432,7 +432,7 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
else
{
if (mActivePanel)
- mActivePanel->onShowOnMap();
+ mActivePanel->onShowOnMap();
}
}
@@ -510,7 +510,7 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
addChild(mPickPanel);
mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- }
+ }
togglePickPanel(TRUE);
@@ -733,7 +733,7 @@ void LLPanelPlaces::updateVerbs()
else
{
if (mActivePanel)
- mActivePanel->updateVerbs();
+ mActivePanel->updateVerbs();
}
}
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index f6672d9c8b..32cccc4ac0 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -306,12 +306,12 @@ void LLTeleportHistoryPanel::showTeleportHistory()
if (curr_tab <= tabs_cnt - 4)
{
- curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
+ curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
}
else if (curr_tab == tabs_cnt - 3) // 6 day and older, low boundary is 1 month
{
curr_date = LLDate::now();
- curr_date.split(&curr_year, &curr_month, &curr_day);
+ curr_date.split(&curr_year, &curr_month, &curr_day);
curr_month--;
if (0 == curr_month)
{
@@ -376,7 +376,7 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
S32 tabs_cnt = mItemContainers.size();
for (S32 n = 0; n < tabs_cnt; n++)
- {
+ {
LLAccordionCtrlTab* tab = mItemContainers.get(n);
if (!tab->getVisible())
@@ -390,7 +390,7 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
continue;
flv->resetSelection(true);
- }
+ }
updateVerbs();
}
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 082bba027f..06bdf64b19 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -55,36 +55,30 @@ using namespace LLNotificationsUI;
bool LLScreenChannel::mWasStartUpToastShown = false;
//--------------------------------------------------------------------------
-LLScreenChannel::LLScreenChannel(LLUUID& id): mOverflowToastPanel(NULL), mStartUpToastPanel(NULL),
- mToastAlignment(NA_BOTTOM), mCanStoreToasts(true),
- mHiddenToastsNum(0), mOverflowToastHidden(false),
- mIsHovering(false), mControlHovering(false),
- mShowToasts(true)
+//////////////////////
+// LLScreenChannelBase
+//////////////////////
+LLScreenChannelBase::LLScreenChannelBase(const LLUUID& id) :
+ mOverflowToastPanel(NULL)
+ ,mToastAlignment(NA_BOTTOM)
+ ,mCanStoreToasts(true)
+ ,mHiddenToastsNum(0)
+ ,mOverflowToastHidden(false)
+ ,mIsHovering(false)
+ ,mControlHovering(false)
+ ,mShowToasts(false)
{
mID = id;
mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString");
- mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannel::updatePositionAndSize, this, _1, _2));
+ mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2));
setMouseOpaque( false );
setVisible(FALSE);
}
-
-//--------------------------------------------------------------------------
-void LLScreenChannel::init(S32 channel_left, S32 channel_right)
-{
- S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
- S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
- setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
- setVisible(TRUE);
-}
-
-//--------------------------------------------------------------------------
-LLScreenChannel::~LLScreenChannel()
+LLScreenChannelBase::~LLScreenChannelBase()
{
mWorldViewRectConnection.disconnect();
}
-
-//--------------------------------------------------------------------------
-void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
+void LLScreenChannelBase::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
{
S32 top_delta = old_world_rect.mTop - new_world_rect.mTop;
S32 right_delta = old_world_rect.mRight - new_world_rect.mRight;
@@ -105,6 +99,42 @@ void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_wo
}
setRect(this_rect);
redrawToasts();
+
+}
+
+void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
+{
+ S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
+ S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
+ setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
+ setVisible(TRUE);
+}
+
+//--------------------------------------------------------------------------
+//////////////////////
+// LLScreenChannel
+//////////////////////
+//--------------------------------------------------------------------------
+LLScreenChannel::LLScreenChannel(LLUUID& id): LLScreenChannelBase(id)
+{
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::init(S32 channel_left, S32 channel_right)
+{
+ LLScreenChannelBase::init(channel_left, channel_right);
+}
+
+//--------------------------------------------------------------------------
+LLScreenChannel::~LLScreenChannel()
+{
+
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
+{
+ LLScreenChannelBase::updatePositionAndSize(old_world_rect, new_world_rect);
}
//--------------------------------------------------------------------------
@@ -561,7 +591,7 @@ void LLScreenChannel::removeAndStoreAllStorableToasts()
else
{
++it;
- }
+ }
}
redrawToasts();
}
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index f1ef6bd64d..459c28ac7c 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -55,10 +55,95 @@ typedef enum e_channel_alignment
CA_RIGHT,
} EChannelAlignment;
+class LLScreenChannelBase : public LLUICtrl
+{
+ friend class LLChannelManager;
+public:
+ LLScreenChannelBase(const LLUUID& id);
+ ~LLScreenChannelBase();
+
+ // Channel's outfit-functions
+ // update channel's size and position in the World View
+ virtual void updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
+ // initialization of channel's shape and position
+ virtual void init(S32 channel_left, S32 channel_right);
+
+
+ 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) {};
+
+ // hide all toasts from screen, but not remove them from a channel
+ virtual void hideToastsFromScreen() {};
+ // removes all toasts from a channel
+ virtual void removeToastsFromChannel() {};
+
+ // show all toasts in a channel
+ virtual void redrawToasts() {};
+
+ virtual void closeOverflowToastPanel() {};
+ virtual void hideOverflowToastPanel() {};
+
+
+ // Channel's behavior-functions
+ // set whether a channel will control hovering inside itself or not
+ virtual void setControlHovering(bool control) { mControlHovering = control; }
+ // set Hovering flag for a channel
+ virtual void setHovering(bool hovering) { mIsHovering = hovering; }
+
+ void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
+
+ void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
+ bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
+
+ // get number of hidden notifications from a channel
+ S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;}
+
+
+ void setShowToasts(bool show) { mShowToasts = show; }
+ bool getShowToasts() { return mShowToasts; }
+
+ // get toast allignment preset for a channel
+ e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
+
+ // get ID of a channel
+ LLUUID getChannelID() { return mID; }
+
+protected:
+ // Channel's flags
+ bool mControlHovering;
+ bool mIsHovering;
+ 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;
+
+ // store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
+ boost::signals2::connection mWorldViewRectConnection;
+};
+
+
/**
* Screen channel manages toasts visibility and positioning on the screen.
*/
-class LLScreenChannel : public LLUICtrl
+class LLScreenChannel : public LLScreenChannelBase
{
friend class LLChannelManager;
public:
@@ -70,12 +155,6 @@ public:
void updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
// initialization of channel's shape and position
void init(S32 channel_left, S32 channel_right);
- // set allignment of toasts inside a channel
- void setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
- // set allignment of channel inside a world view
- void setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
- // set a template for a string in the OverflowToast
- void setOverflowFormatString ( std::string str) { mOverflowFormatString = str; }
// Operating with toasts
// add a toast to a channel
@@ -104,37 +183,17 @@ public:
// close the StartUp Toast
void closeStartUpToast();
- // Channel's behavior-functions
- // set whether a channel will control hovering inside itself or not
- void setControlHovering(bool control) { mControlHovering = control; }
- // set Hovering flag for a channel
- void setHovering(bool hovering) { mIsHovering = hovering; }
- // set whether a channel will store faded toasts or not
- void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
- // tell all channels that the StartUp toast was shown and allow them showing of toasts
- static void setStartUpToastShown() { mWasStartUpToastShown = true; }
// get StartUp Toast's state
static bool getStartUpToastShown() { return mWasStartUpToastShown; }
- // set mode for dislaying of toasts
- void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
- // get mode for dislaying of toasts
- bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
- // tell a channel to show toasts or not
- void setShowToasts(bool show) { mShowToasts = show; }
- // determine whether channel shows toasts or not
- bool getShowToasts() { return mShowToasts; }
+ // tell all channels that the StartUp toast was shown and allow them showing of toasts
+ static void setStartUpToastShown() { mWasStartUpToastShown = true; }
// let a channel update its ShowToast flag
void updateShowToastsState();
+
// Channel's other interface functions functions
- // get number of hidden notifications from a channel
- S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;}
// update number of notifications in the StartUp Toast
void updateStartUpString(S32 num);
- // get toast allignment preset for a channel
- e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
- // get ID of a channel
- LLUUID getChannelID() { return mID; }
// Channel's signals
// signal on storing of faded toasts event
@@ -201,30 +260,10 @@ private:
// Channel's flags
static bool mWasStartUpToastShown;
- bool mControlHovering;
- bool mIsHovering;
- 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;
// attributes for the StartUp Toast
LLToast* mStartUpToastPanel;
- // channel's ID
- LLUUID mID;
-
- // store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
- boost::signals2::connection mWorldViewRectConnection;
std::vector<ToastElem> mToastList;
std::vector<ToastElem> mStoredToastList;
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 381e63f020..2be0aa40d2 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -48,6 +48,7 @@
#include "lliconctrl.h"//for Home tab icon
#include "llsidetraypanelcontainer.h"
#include "llwindow.h"//for SetCursor
+#include "lltransientfloatermgr.h"
//#include "llscrollcontainer.h"
@@ -248,6 +249,7 @@ LLSideTray::LLSideTray(Params& params)
// register handler function to process data from the xml.
// panel_name should be specified via "parameter" attribute.
commit.add("SideTray.ShowPanel", boost::bind(&LLSideTray::showPanel, this, _2, LLUUID::null));
+ LLTransientFloaterMgr::getInstance()->addControlView(this);
}
@@ -448,13 +450,17 @@ void LLSideTray::reflectCollapseChange()
setPanelRect();
if(mCollapsed)
+ {
gFloaterView->setSnapOffsetRight(0);
+ setFocus(FALSE);
+ }
else
+ {
gFloaterView->setSnapOffsetRight(mMaxBarWidth);
+ setFocus(TRUE);
+ }
gFloaterView->refresh();
-
- setFocus( FALSE );
}
void LLSideTray::arrange ()
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index d7df258750..b0930cd86d 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -225,22 +225,14 @@ void LLStatusBar::draw()
BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- if (mHideNavbarContextMenu)
- {
- mHideNavbarContextMenu->buildDrawLabels();
- mHideNavbarContextMenu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, mHideNavbarContextMenu, x, y);
- }
-
+ show_navbar_context_menu(this,x,y);
return TRUE;
}
BOOL LLStatusBar::postBuild()
{
- mHideNavbarContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- gMenuHolder->addChild(mHideNavbarContextMenu);
- gMenuBarView->setRightMouseDownCallback(boost::bind(&LLStatusBar::onMainMenuRightClicked, this, _1, _2, _3, _4));
+ gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3));
return TRUE;
}
@@ -560,11 +552,6 @@ void LLStatusBar::setupDate()
}
}
-void LLStatusBar::onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
-{
- handleRightMouseDown(x, y, mask);
-}
-
// static
void LLStatusBar::onClickStatGraph(void* data)
{
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 81a69e9590..d5629e6f1e 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -91,7 +91,6 @@ private:
// simple method to setup the part that holds the date
void setupDate();
- void onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask);
static void onCommitSearch(LLUICtrl*, void* data);
static void onClickSearch(void* data);
static void onClickStatGraph(void* data);
@@ -111,8 +110,7 @@ private:
S32 mSquareMetersCommitted;
LLFrameTimer* mBalanceTimer;
LLFrameTimer* mHealthTimer;
- LLMenuGL* mHideNavbarContextMenu;
-
+
static std::vector<std::string> sDays;
static std::vector<std::string> sMonths;
static const U32 MAX_DATE_STRING_LENGTH;
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index c1eecf4c12..2206e79c6f 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -109,6 +109,14 @@ BOOL LLSysWellWindow::postBuild()
}
//---------------------------------------------------------------------------------
+void LLSysWellWindow::setMinimized(BOOL minimize)
+{
+ setVisible(!minimize);
+
+ LLFloater::setMinimized(minimize);
+}
+
+//---------------------------------------------------------------------------------
void LLSysWellWindow::connectListUpdaterToSignal(std::string notification_type)
{
LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
@@ -155,10 +163,10 @@ void LLSysWellWindow::addItem(LLSysWellItem::Params p)
{
handleItemAdded(IT_NOTIFICATION);
- reshapeWindow();
+ reshapeWindow();
- new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
- new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
+ new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
+ new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
}
else
{
@@ -226,11 +234,11 @@ void LLSysWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
//---------------------------------------------------------------------------------
void LLSysWellWindow::initChannel()
{
- LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
+ LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
- if(channel)
+ mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
+ if(mChannel)
{
- mChannel = channel;
mChannel->setOnStoreToastCallback(boost::bind(&LLSysWellWindow::onStoreToast, this, _1, _2));
}
else
@@ -240,7 +248,7 @@ void LLSysWellWindow::initChannel()
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::getEnabledRect(LLRect& rect)
+void LLSysWellWindow::getAllowedRect(LLRect& rect)
{
rect = gViewerWindow->getWorldViewRect();
}
@@ -252,7 +260,7 @@ void LLSysWellWindow::toggleWindow()
{
setDockControl(new LLDockControl(
LLBottomTray::getInstance()->getSysWell(), this,
- getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getEnabledRect, this, _1)));
+ getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getAllowedRect, this, _1)));
}
if(!getVisible())
@@ -404,20 +412,18 @@ bool LLSysWellWindow::isWindowEmpty()
//---------------------------------------------------------------------------------
//virtual
-void LLSysWellWindow::sessionAdded(const LLUUID& sessionId,
- const std::string& name, const LLUUID& otherParticipantId)
+void LLSysWellWindow::sessionAdded(const LLUUID& session_id,
+ const std::string& name, const LLUUID& other_participant_id)
{
- if (mMessageList->getItemByValue(get_session_value(sessionId)) == NULL)
+ //*TODO get rid of get_session_value, session_id's are unique, cause performance degradation with lots chiclets (IB)
+ if (mMessageList->getItemByValue(get_session_value(session_id)) == NULL)
{
- S32 chicletCounter = 0;
- LLIMModel::LLIMSession* session = get_if_there(LLIMModel::sSessionsMap,
- sessionId, (LLIMModel::LLIMSession*) NULL);
- if (session != NULL)
+ S32 chicletCounter = LLIMModel::getInstance()->getNumUnread(session_id);
+ if (chicletCounter > -1)
{
- chicletCounter = session->mNumUnread;
+ addIMRow(session_id, chicletCounter, name, other_participant_id);
+ reshapeWindow();
}
- addIMRow(sessionId, chicletCounter, name, otherParticipantId);
- reshapeWindow();
}
}
@@ -491,6 +497,7 @@ LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID&
switch (im_chiclet_type)
{
case LLIMChiclet::TYPE_GROUP:
+ case LLIMChiclet::TYPE_AD_HOC:
mChiclet = getChild<LLIMChiclet>("group_chiclet");
childSetVisible("p2p_chiclet", false);
break;
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 37a2690a82..203b949715 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -68,6 +68,8 @@ public:
void toggleWindow();
/*virtual*/ BOOL canClose() { return FALSE; }
/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
+ // override LLFloater's minimization according to EXT-1216
+ /*virtual*/ void setMinimized(BOOL minimize);
// Handlers
void onItemClick(LLSysWellItem* item);
@@ -86,8 +88,8 @@ private:
IT_INSTANT_MESSAGE
}EItemType;
- // gets a rect valid for SysWellWindow's position on a screen (EXT-1111)
- void getEnabledRect(LLRect& rect);
+ // gets a rect that bounds possible positions for the SysWellWindow on a screen (EXT-1111)
+ void getAllowedRect(LLRect& rect);
// connect counter and list updaters to the corresponding signals
void connectListUpdaterToSignal(std::string notification_type);
// init Window's channel
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 97a15759bf..ecaf4fb150 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -167,15 +167,30 @@ void LLToast::tick()
}
//--------------------------------------------------------------------------
-void LLToast::insertPanel(LLPanel* panel)
+
+void LLToast::reshapeToPanel()
{
- LLRect panel_rect, toast_rect;
+ LLPanel* panel = getPanel();
+ if(!panel)
+ return;
+
+ LLRect panel_rect;
panel_rect = panel->getRect();
reshape(panel_rect.getWidth(), panel_rect.getHeight());
panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight());
panel->setRect(panel_rect);
+
+ LLRect toast_rect = getRect();
+ toast_rect.setLeftTopAndSize(toast_rect.mLeft,toast_rect.mTop,panel_rect.getWidth(), panel_rect.getHeight());
+ setRect(toast_rect);
+
+}
+
+void LLToast::insertPanel(LLPanel* panel)
+{
addChild(panel);
+ reshapeToPanel();
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 9248747c43..2166351fd0 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -99,6 +99,9 @@ public:
// Operating with toasts
// insert a panel to a toast
void insertPanel(LLPanel* panel);
+
+ void reshapeToPanel();
+
// get toast's panel
LLPanel* getPanel() { return mPanel; }
// enable/disable Toast's Hide button
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index bc9888f4b4..418373e8c6 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -39,6 +39,12 @@
#include <string>
+class LLToastPanelBase: public LLPanel
+{
+public:
+ virtual void init(LLSD& data){};
+};
+
/**
* Base class for all panels that can be added to the toast.
* All toast panels should contain necessary logic for representing certain notification
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 671a62962b..12253455a3 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7666,6 +7666,19 @@ class LLHelpShowFirstTimeTip : public view_listener_t
}
};
+void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y)
+{
+ static LLMenuGL* show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml",
+ gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if(gMenuHolder->hasVisibleMenu())
+ {
+ gMenuHolder->hideMenus();
+ }
+ show_navbar_context_menu->buildDrawLabels();
+ show_navbar_context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y);
+}
+
void initialize_menus()
{
// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index cf482266d6..dd6aac2dd3 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -52,6 +52,7 @@ void show_debug_menus(); // checks for if menus should be shown first.
void toggle_debug_menus(void*);
void show_context_menu( S32 x, S32 y, MASK mask );
void show_build_mode_context_menu(S32 x, S32 y, MASK mask);
+void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y);
BOOL enable_save_into_inventory(void*);
void handle_reset_view();
void handle_cut(void*);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index d23f10f880..4a0efbaddc 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3223,9 +3223,9 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans
// assume that pickAsync put the results in the back of the mPicks list
if(mPicks.size() != 0)
{
- mLastPick = mPicks.back();
- mLastPick.fetchResults();
- mPicks.pop_back();
+ mLastPick = mPicks.back();
+ mLastPick.fetchResults();
+ mPicks.pop_back();
}
else
{
diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml
index 30406cad63..aef5707fd4 100644
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -12,7 +12,7 @@
width="320"
min_width="320"
height="23"
- can_minimize="false"
+ can_minimize="true"
can_tear_off="false"
can_resize="false"
can_drag_on_left="false"
@@ -22,10 +22,10 @@
<flat_list_view
color="FloaterDefaultBackgroundColor"
follows="all"
- layout="topleft"
- name="notification_list"
- left="1"
+ layout="topleft"
+ name="notification_list"
+ left="1"
top="20"
- height="0"
- width="318"/>
+ height="0"
+ width="318"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 648c3458e0..2c77f61da6 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -128,13 +128,13 @@
function="World.SetAway" />
</menu_item_call>
<menu_item_separator
- layout="topleft"/>
+ layout="topleft"/>
<menu_item_call
label="Set Busy"
layout="topleft"
name="Set Busy">
<menu_item_call.on_click
- function="World.SetBusy"/>
+ function="World.SetBusy"/>
</menu_item_call>
</menu>
<menu_item_separator
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 90b331a39f..cd7e340ff1 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -79,7 +79,6 @@
label="Move"
layout="topleft"
name="movement_btn"
- tab_stop="false"
tool_tip="Shows/Hide Movement controls"
top="6"
width="70">
@@ -117,7 +116,6 @@
label="View"
layout="topleft"
left="0"
- tab_stop="false"
tool_tip="Shows/Hide Camera controls"
top="6"
name="camera_btn"
@@ -133,7 +131,6 @@
height="20"
width="20"
left_pad="0"
- tab_stop="false"
is_toggle="true"
picture_style="true"
image_selected="toggle_button_selected"
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index c4c8aa24c4..fb4ce436e8 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -28,7 +28,7 @@
width="25"
height="25"
label=""
- follows="top|left"
+ follows="top|right"
image_overlay="BackArrow_Off"
tab_stop="false" />
<text
@@ -41,6 +41,7 @@
text_color="white"
follows="top|left|right"
mouse_opaque="true"
+ use_ellipses="true"
name="group_name">(Loading...)</text>
<line_editor
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 683a54b366..4088d96ebf 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -35,6 +35,8 @@
follows="right"
height="20"
speak_button.font="SansSerifMedium"
+ speak_button.tab_stop="true"
+ show_button.tab_stop="true"
layout="topleft"
left_pad="5"
name="talk"
diff --git a/indra/newview/skins/default/xui/en/panel_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml
index 58ebac2a84..2056ec14d5 100644
--- a/indra/newview/skins/default/xui/en/panel_notes.xml
+++ b/indra/newview/skins/default/xui/en/panel_notes.xml
@@ -2,7 +2,7 @@
<panel
bevel_style="in"
follows="left|top|right|bottom"
- height="420"
+ height="460"
label="Notes &amp; Privacy"
layout="topleft"
left="0"
@@ -16,7 +16,7 @@
layout="topleft"
left="0"
top="0"
- height="420"
+ height="430"
width="313"
border_size="0">
<panel
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index d0bde77cf2..1bd1953397 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="left|top|right|bottom"
- height="515"
+ height="555"
label="Picks"
layout="topleft"
left="0"
@@ -11,7 +11,7 @@
<flat_list_view
color="DkGray2"
follows="left|top|right|bottom"
- height="495"
+ height="465"
layout="topleft"
left="0"
name="picks_list"
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index 56ba5970f2..02d179d503 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="all"
- height="515"
+ height="560"
label="Profile"
layout="topleft"
left="0"
@@ -25,7 +25,7 @@
<scroll_container
color="DkGray2"
follows="left|top|right|bottom"
- height="515"
+ height="500"
min_height="300"
layout="topleft"
name="profile_scroll"
@@ -265,6 +265,7 @@
left="0"
name="profile_buttons_panel"
top_pad="0"
+ height="25"
width="313">
<button
follows="bottom|left"
@@ -316,6 +317,7 @@
name="profile_me_buttons_panel"
top_pad="0"
visible="false"
+ height="25"
width="313">
<button
follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml
index cbe646f3cc..606535115d 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml
@@ -2,7 +2,7 @@
<panel
background_visible="true"
follows="all"
- height="660"
+ height="570"
layout="topleft"
min_height="350"
min_width="240"
@@ -50,7 +50,7 @@
width="25" />
<tab_container
follows="left|top|right|bottom"
- height="660"
+ height="560"
layout="topleft"
left="10"
name="tabs"
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
index a0fc986423..aa95a2baef 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -111,7 +111,7 @@
width="380">
</flat_list_view>
</accordion_tab>
-
+
<accordion_tab
can_resize="false"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
index cb876da8d8..824a815a99 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
@@ -10,9 +10,9 @@
highlighted_color="ScrollHighlightedColor"
column_padding="5"
draw_stripes="true"
+ scroll_bar_bg_visible="false"
+ scroll_bar_bg_color="black"
background_visible="false"
heading_height="23"
draw_border="false"
- draw_heading="false"
- scroll_bar_bg_visible="false"
- scroll_bar_bg_color="black" />
+ draw_heading="false" />
diff --git a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
index 6e73e997e0..e998635d20 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
@@ -12,17 +12,20 @@
<combo_editor
select_on_focus="true"
text_pad_left="20"
+ tool_tip="Search"
background_image="TextField_Search_Off"
background_image_disabled="TextField_Search_Disabled"
background_image_focused="TextField_Search_Active"/>
<combo_list
multi_select="false"
- page_lines="10" />
+ page_lines="10"
+ scroll_bar_bg_visible="true" />
<search_button label=""
top_pad="4"
left_pad="4"
width="13"
height="13"
+ tool_tip="Search"
image_unselected="Search"
image_selected="Search" />
</search_combo_box> \ No newline at end of file