summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llstring.cpp9
-rw-r--r--indra/llui/CMakeLists.txt2
-rw-r--r--indra/llui/lldockcontrol.cpp13
-rw-r--r--indra/llui/lldockcontrol.h3
-rw-r--r--indra/llui/llfiltereditor.cpp74
-rw-r--r--indra/llui/llfiltereditor.h30
-rw-r--r--indra/llui/llflatlistview.cpp494
-rw-r--r--indra/llui/llflatlistview.h262
-rw-r--r--indra/llui/llsearcheditor.cpp82
-rw-r--r--indra/llui/llsearcheditor.h24
-rw-r--r--indra/llui/lltabcontainer.cpp9
-rw-r--r--indra/llui/llview.h2
-rw-r--r--indra/newview/llavatarlist.cpp213
-rw-r--r--indra/newview/llavatarlist.h42
-rw-r--r--indra/newview/llavatarlistitem.cpp221
-rw-r--r--indra/newview/llavatarlistitem.h94
-rw-r--r--indra/newview/llchiclet.cpp26
-rw-r--r--indra/newview/llchiclet.h1
-rw-r--r--indra/newview/llfloatercamera.cpp18
-rw-r--r--indra/newview/llfloatercamera.h5
-rw-r--r--indra/newview/llimhandler.cpp9
-rw-r--r--indra/newview/llimview.cpp3
-rw-r--r--indra/newview/llnearbychatbar.cpp20
-rw-r--r--indra/newview/llnearbychatbar.h1
-rw-r--r--indra/newview/lloutputmonitorctrl.cpp48
-rw-r--r--indra/newview/lloutputmonitorctrl.h18
-rw-r--r--indra/newview/llpanelavatar.cpp2
-rw-r--r--indra/newview/llpanelgrouproles.cpp28
-rw-r--r--indra/newview/llpanelgrouproles.h9
-rw-r--r--indra/newview/llpanelpeople.cpp19
-rw-r--r--indra/newview/llpanelpeople.h3
-rw-r--r--indra/newview/llpanelplaceinfo.cpp122
-rw-r--r--indra/newview/llpanelplaceinfo.h21
-rw-r--r--indra/newview/llpanelplaces.cpp159
-rw-r--r--indra/newview/llpanelplaces.h31
-rw-r--r--indra/newview/llrecentpeople.cpp7
-rw-r--r--indra/newview/llrecentpeople.h7
-rw-r--r--indra/newview/llsearchcombobox.cpp1
-rw-r--r--indra/newview/lltoastimpanel.cpp5
-rw-r--r--indra/newview/lltoastimpanel.h1
-rw-r--r--indra/newview/llviewermenu.cpp4
-rw-r--r--indra/newview/llviewerwindow.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_sys_well.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml152
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml38
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml17
-rw-r--r--indra/newview/skins/default/xui/en/panel_places.xml15
-rw-r--r--indra/newview/skins/default/xui/en/panel_toast.xml4
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml1
-rw-r--r--indra/newview/skins/default/xui/en/widgets/filter_editor.xml24
-rw-r--r--indra/newview/skins/default/xui/en/widgets/flat_list_view.xml7
-rw-r--r--indra/newview/skins/default/xui/en/widgets/search_editor.xml3
53 files changed, 1694 insertions, 716 deletions
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 78e835dc95..8052da2450 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -968,8 +968,13 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
// special case to handle timezone
if (code == "%Z") {
- if (param == "utc") replacement = "GMT";
- else if (param != "local") replacement = LLStringOps::getDaylightSavings()? "PDT" : "PST";
+ if (param == "utc")
+ replacement = "GMT";
+ else if (param == "slt")
+ replacement = "SLT";
+ else if (param != "local") // *TODO Vadim: not local? then what?
+ replacement = LLStringOps::getDaylightSavings() ? "PDT" : "PST";
+
return true;
}
replacement = datetime->toHTTPDateString(code);
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index cc9362a252..fce6b759a4 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -40,6 +40,7 @@ set(llui_SOURCE_FILES
lleditmenuhandler.cpp
llf32uictrl.cpp
llfiltereditor.cpp
+ llflatlistview.cpp
llfloater.cpp
llfloaterreg.cpp
llflyoutbutton.cpp
@@ -122,6 +123,7 @@ set(llui_HEADER_FILES
lleditmenuhandler.h
llf32uictrl.h
llfiltereditor.h
+ llflatlistview.h
llfloater.h
llfloaterreg.h
llflyoutbutton.h
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index e119d387ce..d666f2be56 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -48,12 +48,25 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
{
off();
}
+
+ if (dockWidget != NULL) {
+ repositionDockable();
+ }
}
LLDockControl::~LLDockControl()
{
}
+void LLDockControl::setDock(LLView* dockWidget)
+{
+ mDockWidget = dockWidget;
+ if (mDockWidget != NULL)
+ {
+ repositionDockable();
+ }
+}
+
void LLDockControl::repositionDockable()
{
if (mEnabled)
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index ae4e53ddc9..7d8d5c7653 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -60,8 +60,7 @@ public:
public:
void on();
void off();
- void setDock(LLView* dockWidget)
- { mDockWidget = dockWidget;};
+ void setDock(LLView* dockWidget);
void repositionDockable();
void drawToungue();
protected:
diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp
index 26b5f2e182..390504234d 100644
--- a/indra/llui/llfiltereditor.cpp
+++ b/indra/llui/llfiltereditor.cpp
@@ -37,81 +37,15 @@
#include "llfiltereditor.h"
LLFilterEditor::LLFilterEditor(const LLFilterEditor::Params& p)
-: LLUICtrl(p)
+: LLSearchEditor(p)
{
- LLLineEditor::Params line_editor_p(p);
- line_editor_p.name("filter edit box");
- line_editor_p.rect(getLocalRect());
- line_editor_p.follows.flags(FOLLOWS_ALL);
- line_editor_p.text_pad_right(getRect().getHeight());
- line_editor_p.revert_on_esc(false);
- line_editor_p.keystroke_callback(boost::bind(&LLUICtrl::onCommit, this));
-
- mFilterEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_p);
- addChild(mFilterEditor);
-
- S32 btn_width = getRect().getHeight(); // button is square, and as tall as search editor
- LLRect clear_btn_rect(getRect().getWidth() - btn_width, getRect().getHeight(), getRect().getWidth(), 0);
- LLButton::Params button_params(p.clear_filter_button);
- button_params.name(std::string("clear filter"));
- button_params.rect(clear_btn_rect) ;
- button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
- button_params.tab_stop(false);
- button_params.click_callback.function(boost::bind(&LLFilterEditor::onClearFilter, this, _2));
-
- mClearFilterButton = LLUICtrlFactory::create<LLButton>(button_params);
- mFilterEditor->addChild(mClearFilterButton);
-}
-
-//virtual
-void LLFilterEditor::setValue(const LLSD& value )
-{
- mFilterEditor->setValue(value);
-}
-
-//virtual
-LLSD LLFilterEditor::getValue() const
-{
- return mFilterEditor->getValue();
-}
-
-//virtual
-BOOL LLFilterEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
-{
- return mFilterEditor->setTextArg(key, text);
}
-//virtual
-BOOL LLFilterEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
-{
- return mFilterEditor->setLabelArg(key, text);
-}
-
-//virtual
-void LLFilterEditor::setLabel( const LLStringExplicit &new_label )
-{
- mFilterEditor->setLabel(new_label);
-}
-
-//virtual
-void LLFilterEditor::clear()
-{
- if (mFilterEditor)
- {
- mFilterEditor->clear();
- }
-}
-void LLFilterEditor::draw()
+void LLFilterEditor::handleKeystroke()
{
- mClearFilterButton->setVisible(!mFilterEditor->getWText().empty());
-
- LLUICtrl::draw();
-}
+ this->LLSearchEditor::handleKeystroke();
-void LLFilterEditor::onClearFilter(const LLSD& data)
-{
- setText(LLStringUtil::null);
+ // Commit on every keystroke.
onCommit();
}
-
diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h
index fceb82af8d..c43a76b130 100644
--- a/indra/llui/llfiltereditor.h
+++ b/indra/llui/llfiltereditor.h
@@ -42,18 +42,14 @@
#ifndef LL_FILTEREDITOR_H
#define LL_FILTEREDITOR_H
-#include "lllineeditor.h"
-#include "llbutton.h"
+#include "llsearcheditor.h"
-class LLFilterEditor : public LLUICtrl
+class LLFilterEditor : public LLSearchEditor
{
public:
- struct Params : public LLInitParam::Block<Params, LLLineEditor::Params>
+ struct Params : public LLInitParam::Block<Params, LLSearchEditor::Params>
{
- Optional<LLButton::Params> clear_filter_button;
-
Params()
- : clear_filter_button("clear_filter_button")
{
name = "filter_editor";
}
@@ -62,26 +58,8 @@ public:
protected:
LLFilterEditor(const Params&);
friend class LLUICtrlFactory;
-public:
- virtual ~LLFilterEditor() {}
-
- /*virtual*/ void draw();
-
- void setText(const LLStringExplicit &new_text) { mFilterEditor->setText(new_text); }
-
- // LLUICtrl interface
- virtual void setValue(const LLSD& value );
- virtual LLSD getValue() const;
- virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
- virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
- virtual void setLabel( const LLStringExplicit &new_label );
- virtual void clear();
-
-private:
- void onClearFilter(const LLSD& data);
- LLLineEditor* mFilterEditor;
- LLButton* mClearFilterButton;
+ /*virtual*/ void handleKeystroke();
};
#endif // LL_FILTEREDITOR_H
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
new file mode 100644
index 0000000000..75334acb39
--- /dev/null
+++ b/indra/llui/llflatlistview.cpp
@@ -0,0 +1,494 @@
+/**
+ * @file llflatlistview.cpp
+ * @brief LLFlatListView base class
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llpanel.h"
+
+#include "llflatlistview.h"
+
+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);
+
+LLFlatListView::Params::Params()
+: item_pad("item_pad"),
+ allow_select("allow_select"),
+ multi_select("multi_select"),
+ keep_one_selected("keep_one_selected")
+{};
+
+void LLFlatListView::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
+{
+ LLScrollContainer::reshape(width, height, called_from_parent);
+ setItemsNoScrollWidth(width);
+ rearrangeItems();
+}
+
+bool LLFlatListView::addItem(LLPanel* item, LLSD value /* = LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/)
+{
+ if (!item) return false;
+ if (value.isUndefined()) return false;
+
+ //force uniqueness of items, easiest check but unreliable
+ if (item->getParent() == mItemsPanel) return false;
+
+ item_pair_t* new_pair = new item_pair_t(item, value);
+ switch (pos)
+ {
+ case ADD_TOP:
+ mItemPairs.push_front(new_pair);
+ //in LLView::draw() children are iterated in backorder
+ mItemsPanel->addChildInBack(item);
+ break;
+ case ADD_BOTTOM:
+ mItemPairs.push_back(new_pair);
+ mItemsPanel->addChild(item);
+ break;
+ default:
+ break;
+ }
+
+ //_4 is for MASK
+ item->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
+ item->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
+
+ rearrangeItems();
+ return true;
+}
+
+
+bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value /*= LLUUID::null*/)
+{
+ if (!after_item) return false;
+ if (!item_to_add) return false;
+ if (value.isUndefined()) return false;
+
+ if (mItemPairs.empty()) return false;
+
+ //force uniqueness of items, easiest check but unreliable
+ if (item_to_add->getParent() == mItemsPanel) return false;
+
+ item_pair_t* after_pair = getItemPair(after_item);
+ if (!after_pair) return false;
+
+ item_pair_t* new_pair = new item_pair_t(item_to_add, value);
+ if (after_pair == mItemPairs.back())
+ {
+ mItemPairs.push_back(new_pair);
+ mItemsPanel->addChild(item_to_add);
+ }
+ else
+ {
+ pairs_iterator_t it = mItemPairs.begin();
+ ++it;
+ while (it != mItemPairs.end())
+ {
+ if (*it == after_pair)
+ {
+ mItemPairs.insert(++it, new_pair);
+ mItemsPanel->addChild(item_to_add);
+ break;
+ }
+ }
+ }
+
+ //_4 is for MASK
+ item_to_add->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
+ item_to_add->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
+
+ rearrangeItems();
+ return true;
+}
+
+
+bool LLFlatListView::removeItem(LLPanel* item)
+{
+ if (!item) return false;
+ if (item->getParent() != mItemsPanel) return false;
+
+ item_pair_t* item_pair = getItemPair(item);
+ if (!item_pair) return false;
+
+ return removeItemPair(item_pair);
+}
+
+bool LLFlatListView::removeItemByValue(const LLSD& value)
+{
+ if (value.isUndefined()) return false;
+
+ item_pair_t* item_pair = getItemPair(value);
+ if (!item_pair) return false;
+
+ return removeItemPair(item_pair);
+}
+
+bool LLFlatListView::removeItemByUUID(LLUUID& uuid)
+{
+ return removeItemByValue(LLSD(uuid));
+}
+
+LLPanel* LLFlatListView::getItemByValue(LLSD& value) const
+{
+ if (value.isDefined()) return NULL;
+
+ item_pair_t* pair = getItemPair(value);
+ if (pair) return pair->first;
+ return NULL;
+}
+
+bool LLFlatListView::selectItem(LLPanel* item, bool select /*= true*/)
+{
+ if (!item) return false;
+ if (item->getParent() != mItemsPanel) return false;
+
+ item_pair_t* item_pair = getItemPair(item);
+ if (!item_pair) return false;
+
+ return selectItemPair(item_pair, select);
+}
+
+bool LLFlatListView::selectItemByValue(const LLSD& value, bool select /*= true*/)
+{
+ if (value.isUndefined()) return false;
+
+ item_pair_t* item_pair = getItemPair(value);
+ if (!item_pair) return false;
+
+ return selectItemPair(item_pair, select);
+}
+
+bool LLFlatListView::selectItemByUUID(LLUUID& uuid, bool select /* = true*/)
+{
+ return selectItemByValue(LLSD(uuid), select);
+}
+
+
+LLSD LLFlatListView::getSelectedValue() const
+{
+ if (mSelectedItemPairs.empty()) return LLSD();
+
+ item_pair_t* first_selected_pair = mSelectedItemPairs.front();
+ return first_selected_pair->second;
+}
+
+void LLFlatListView::getSelectedValues(std::vector<LLSD>& selected_values) const
+{
+ if (mSelectedItemPairs.empty()) return;
+
+ for (pairs_const_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it)
+ {
+ selected_values.push_back((*it)->second);
+ }
+}
+
+LLUUID LLFlatListView::getSelectedUUID() const
+{
+ const LLSD& value = getSelectedValue();
+ if (value.isDefined() && value.isUUID())
+ {
+ return value.asUUID();
+ }
+ else
+ {
+ return LLUUID::null;
+ }
+}
+
+void LLFlatListView::getSelectedUUIDs(std::vector<LLUUID>& selected_uuids) const
+{
+ if (mSelectedItemPairs.empty()) return;
+
+ for (pairs_const_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it)
+ {
+ selected_uuids.push_back((*it)->second.asUUID());
+ }
+}
+
+LLPanel* LLFlatListView::getSelectedItem() const
+{
+ if (mSelectedItemPairs.empty()) return NULL;
+
+ return mSelectedItemPairs.front()->first;
+}
+
+void LLFlatListView::getSelectedItems(std::vector<LLPanel*>& selected_items) const
+{
+ if (mSelectedItemPairs.empty()) return;
+
+ for (pairs_const_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it)
+ {
+ selected_items.push_back((*it)->first);
+ }
+}
+
+void LLFlatListView::resetSelection()
+{
+ if (mSelectedItemPairs.empty()) return;
+
+ for (pairs_iterator_t it= mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it)
+ {
+ item_pair_t* pair_to_deselect = *it;
+ LLPanel* item = pair_to_deselect->first;
+ item->setValue(UNSELECTED_EVENT);
+ }
+
+ mSelectedItemPairs.clear();
+}
+
+void LLFlatListView::clear()
+{
+ // do not use LLView::deleteAllChildren to avoid removing nonvisible items. drag-n-drop for ex.
+ for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
+ {
+ mItemsPanel->removeChild((*it)->first);
+ delete (*it)->first;
+ delete *it;
+ }
+ mItemPairs.clear();
+ mSelectedItemPairs.clear();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// PROTECTED STUFF
+//////////////////////////////////////////////////////////////////////////
+
+
+LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
+: LLScrollContainer(p),
+ mItemsPanel(NULL),
+ mItemPad(p.item_pad),
+ mAllowSelection(p.allow_select),
+ mMultipleSelection(p.multi_select),
+ mKeepOneItemSelected(p.keep_one_selected)
+{
+ mBorderThickness = getBorderWidth();
+
+ LLRect scroll_rect = getRect();
+ LLRect items_rect;
+
+ setItemsNoScrollWidth(scroll_rect.getWidth());
+ items_rect.setLeftTopAndSize(mBorderThickness, scroll_rect.getHeight() - mBorderThickness, mItemsNoScrollWidth, 0);
+
+ LLPanel::Params pp;
+ pp.rect(items_rect);
+ mItemsPanel = LLUICtrlFactory::create<LLPanel> (pp);
+ addChild(mItemsPanel);
+
+ //we don't need to stretch in vertical direction on reshaping by a parent
+ //no bottom following!
+ mItemsPanel->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP);
+};
+
+void LLFlatListView::rearrangeItems()
+{
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+ if (mItemPairs.empty()) return;
+
+ //calculating required height - assuming items can be of different height
+ //list should accommodate all its items
+ S32 height = 0;
+
+ pairs_iterator_t it = mItemPairs.begin();
+ for (; it != mItemPairs.end(); ++it)
+ {
+ LLPanel* item = (*it)->first;
+ height += item->getRect().getHeight();
+ }
+ height += mItemPad * (mItemPairs.size() - 1);
+
+ LLRect rc = mItemsPanel->getRect();
+ S32 width = mItemsNoScrollWidth;
+
+ // update width to avoid horizontal scrollbar
+ if (height > getRect().getHeight() - 2 * mBorderThickness)
+ width -= scrollbar_size;
+
+ //changes the bottom, end of the list goes down in the scroll container
+ rc.setLeftTopAndSize(rc.mLeft, rc.mTop, width, height);
+ mItemsPanel->setRect(rc);
+
+ //reshaping items
+ S32 item_new_top = height;
+ pairs_iterator_t it2, first_it = mItemPairs.begin();
+ for (it2 = first_it; it2 != mItemPairs.end(); ++it2)
+ {
+ LLPanel* item = (*it2)->first;
+ LLRect rc = item->getRect();
+ if(it2 != first_it)
+ {
+ item_new_top -= (rc.getHeight() + mItemPad);
+ }
+ rc.setLeftTopAndSize(rc.mLeft, item_new_top, width, rc.getHeight());
+ item->reshape(rc.getWidth(), rc.getHeight());
+ item->setRect(rc);
+ }
+}
+
+void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
+{
+ if (!item_pair) return;
+
+ bool select_item = !isSelected(item_pair);
+
+ //*TODO find a better place for that enforcing stuff
+ if (mKeepOneItemSelected && numSelected() == 1 && !select_item) return;
+
+ if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection();
+ selectItemPair(item_pair, select_item);
+}
+
+LLFlatListView::item_pair_t* LLFlatListView::getItemPair(LLPanel* item) const
+{
+ llassert(item);
+
+ for (pairs_const_iterator_t it= mItemPairs.begin(); it != mItemPairs.end(); ++it)
+ {
+ item_pair_t* item_pair = *it;
+ if (item_pair->first == item) return item_pair;
+ }
+ return NULL;
+}
+
+//compares two LLSD's
+bool llsds_are_equal(const LLSD& llsd_1, const LLSD& llsd_2)
+{
+ llassert(llsd_1.isDefined());
+ llassert(llsd_2.isDefined());
+
+ if (llsd_1.type() != llsd_2.type()) return false;
+
+ if (!llsd_1.isMap())
+ {
+ if (llsd_1.isUUID()) return llsd_1.asUUID() == llsd_2.asUUID();
+
+ //assumptions that string representaion is enough for other types
+ return llsd_1.asString() == llsd_2.asString();
+ }
+
+ if (llsd_1.size() != llsd_2.size()) return false;
+
+ LLSD::map_const_iterator llsd_1_it = llsd_1.beginMap();
+ LLSD::map_const_iterator llsd_2_it = llsd_2.beginMap();
+ for (S32 i = 0; i < llsd_1.size(); ++i)
+ {
+ if ((*llsd_1_it).first != (*llsd_2_it).first) return false;
+ if (!llsds_are_equal((*llsd_1_it).second, (*llsd_2_it).second)) return false;
+ ++llsd_1_it;
+ ++llsd_2_it;
+ }
+ return true;
+}
+
+LLFlatListView::item_pair_t* LLFlatListView::getItemPair(const LLSD& value) const
+{
+ llassert(value.isDefined());
+
+ for (pairs_const_iterator_t it= mItemPairs.begin(); it != mItemPairs.end(); ++it)
+ {
+ item_pair_t* item_pair = *it;
+ if (llsds_are_equal(item_pair->second, value)) return item_pair;
+ }
+ return NULL;
+}
+
+bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
+{
+ llassert(item_pair);
+
+ if (!mAllowSelection && select) return false;
+
+ if (isSelected(item_pair) == select) return true; //already in specified selection state
+ if (select)
+ {
+ mSelectedItemPairs.push_back(item_pair);
+ }
+ else
+ {
+ mSelectedItemPairs.remove(item_pair);
+ }
+
+ //a way of notifying panel of selection state changes
+ LLPanel* item = item_pair->first;
+ item->setValue(select ? SELECTED_EVENT : UNSELECTED_EVENT);
+ return true;
+}
+
+bool LLFlatListView::isSelected(item_pair_t* item_pair) const
+{
+ llassert(item_pair);
+
+ pairs_const_iterator_t it_end = mSelectedItemPairs.end();
+ return std::find(mSelectedItemPairs.begin(), it_end, item_pair) != it_end;
+}
+
+bool LLFlatListView::removeItemPair(item_pair_t* item_pair)
+{
+ llassert(item_pair);
+
+ bool deleted = false;
+ for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
+ {
+ item_pair_t* _item_pair = *it;
+ if (_item_pair == item_pair)
+ {
+ mItemPairs.erase(it);
+ deleted = true;
+ break;
+ }
+ }
+
+ if (!deleted) return false;
+
+ for (pairs_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it)
+ {
+ item_pair_t* selected_item_pair = *it;
+ if (selected_item_pair == item_pair)
+ {
+ it = mSelectedItemPairs.erase(it);
+ break;
+ }
+ }
+
+ mItemsPanel->removeChild(item_pair->first);
+ delete item_pair->first;
+ delete item_pair;
+
+ rearrangeItems();
+
+ return true;
+}
+
+
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
new file mode 100644
index 0000000000..bd0b419f4f
--- /dev/null
+++ b/indra/llui/llflatlistview.h
@@ -0,0 +1,262 @@
+/**
+ * @file llflatlistview.h
+ * @brief LLFlatListView base class
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLATLISTVIEW_H
+#define LL_LLFLATLISTVIEW_H
+
+#include "llscrollcontainer.h"
+
+
+class LLPanel;
+
+/**
+ * LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's.
+ * LLSD can be associated with each added item, it can keep data from an item in digested form.
+ * Associated LLSD's can be of any type (singular, a map etc.).
+ * Items (LLPanel's subclasses) can be of different height.
+ * The list is LLPanel created in itself and grows in height while new items are added.
+ *
+ * The control can manage selection of its items when the flag "allow_select" is set. Also ability to select
+ * multiple items (by using CTRL) is enabled through setting the flag "multi_select" - if selection is not allowed that flag
+ * is ignored. The option "keep_one_selected" forces at least one item to be selected at any time (only for mouse events on items)
+ * since any item of the list was selected.
+ *
+ * Examples of using this control are presented in Picks panel (Me Profile and Profile View), where this control is used to
+ * manage the list of pick items.
+ *
+ * ASSUMPTIONS AND STUFF
+ * - NULL pointers and undefined LLSD's are not accepted by any method of this class unless specified otherwise
+ * - Order of returned selected items are not guaranteed
+ * - The control assumes that all items being added are unique.
+ */
+class LLFlatListView : public LLScrollContainer
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLScrollContainer::Params>
+ {
+ /** turning on/off selection support */
+ Optional<bool> allow_select;
+
+ /** turning on/off multiple selection (works while clicking and holding CTRL)*/
+ Optional<bool> multi_select;
+
+ /** don't allow to deselect all selected items (for mouse events on items only) */
+ Optional<bool> keep_one_selected;
+
+ /** padding between items */
+ Optional<U32> item_pad;
+
+ Params();
+ };
+
+ virtual ~LLFlatListView() { clear(); };
+
+
+ /** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
+ virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+
+ /**
+ * Adds and item and LLSD value associated with it to the list at specified position
+ * @return true if the item was added, false otherwise
+ */
+ virtual bool addItem(LLPanel* item, LLSD value = LLUUID::null, EAddPosition pos = ADD_BOTTOM);
+
+ /**
+ * Insert item_to_add along with associated value to the list right after the after_item.
+ * @return true if the item was successfully added, false otherwise
+ */
+ virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value = LLUUID::null);
+
+ /**
+ * Remove specified item
+ * @return true if the item was removed, false otherwise
+ */
+ virtual bool removeItem(LLPanel* item);
+
+ /**
+ * Remove an item specified by value
+ * @return true if the item was removed, false otherwise
+ */
+ virtual bool removeItemByValue(const LLSD& value);
+
+ /**
+ * Remove an item specified by uuid
+ * @return true if the item was removed, false otherwise
+ */
+ virtual bool removeItemByUUID(LLUUID& uuid);
+
+ /**
+ * Get an item by value
+ * @return the item as LLPanel if associated with value, NULL otherwise
+ */
+ virtual LLPanel* getItemByValue(LLSD& value) const;
+
+ /**
+ * Select or deselect specified item based on select
+ * @return true if succeed, false otherwise
+ */
+ virtual bool selectItem(LLPanel* item, bool select = true);
+
+ /**
+ * Select or deselect an item by associated value based on select
+ * @return true if succeed, false otherwise
+ */
+ virtual bool selectItemByValue(const LLSD& value, bool select = true);
+
+ /**
+ * Select or deselect an item by associated uuid based on select
+ * @return true if succeed, false otherwise
+ */
+ virtual bool selectItemByUUID(LLUUID& uuid, bool select = true);
+
+
+
+ /**
+ * Get LLSD associated with the first selected item
+ */
+ virtual LLSD getSelectedValue() const;
+
+ /**
+ * Get LLSD's associated with selected items.
+ * @param selected_values std::vector being populated with LLSD associated with selected items
+ */
+ virtual void getSelectedValues(std::vector<LLSD>& selected_values) const;
+
+
+ /**
+ * Get LLUUID associated with selected item
+ * @return LLUUID if such was associated with selected item
+ */
+ virtual LLUUID getSelectedUUID() const;
+
+ /**
+ * Get LLUUIDs associated with selected items
+ * @param selected_uuids An std::vector being populated with LLUUIDs associated with selected items
+ */
+ virtual void getSelectedUUIDs(std::vector<LLUUID>& selected_uuids) const;
+
+ /** Get the top selected item */
+ virtual LLPanel* getSelectedItem() const;
+
+ /**
+ * Get selected items
+ * @param selected_items An std::vector being populated with pointers to selected items
+ */
+ virtual void getSelectedItems(std::vector<LLPanel*>& selected_items) const;
+
+
+ /** Resets selection of items */
+ virtual void resetSelection();
+
+
+ /** Turn on/off multiple selection support */
+ void setAllowMultipleSelection(bool allow) { mMultipleSelection = allow; }
+
+ /** Turn on/off selection support */
+ void setAllowSelection(bool can_select) { mAllowSelection = can_select; }
+
+
+ /** Get number of selected items in the list */
+ U32 numSelected() const {return mSelectedItemPairs.size(); }
+
+ /** Get number of items in the list */
+ U32 size() const { return mItemPairs.size(); }
+
+
+ /** Removes all items from the list */
+ virtual void clear();
+
+
+protected:
+
+ /** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
+ typedef std::pair<LLPanel*, LLSD> item_pair_t;
+
+ typedef std::list<item_pair_t*> pairs_list_t;
+ typedef pairs_list_t::iterator pairs_iterator_t;
+ typedef pairs_list_t::const_iterator pairs_const_iterator_t;
+
+
+ friend class LLUICtrlFactory;
+ LLFlatListView(const LLFlatListView::Params& p);
+
+ /** Manage selection on mouse events */
+ void onItemMouseClick(item_pair_t* item_pair, MASK mask);
+
+ /** Updates position of items */
+ virtual void rearrangeItems();
+
+ virtual item_pair_t* getItemPair(LLPanel* item) const;
+
+ virtual item_pair_t* getItemPair(const LLSD& value) const;
+
+ virtual bool selectItemPair(item_pair_t* item_pair, bool select);
+
+ virtual bool isSelected(item_pair_t* item_pair) const;
+
+ virtual bool removeItemPair(item_pair_t* item_pair);
+
+
+private:
+
+ void setItemsNoScrollWidth(S32 new_width) {mItemsNoScrollWidth = new_width - 2 * mBorderThickness;}
+
+
+private:
+
+ LLPanel* mItemsPanel;
+
+ S32 mItemsNoScrollWidth;
+
+ S32 mBorderThickness;
+
+ /** Items padding */
+ U32 mItemPad;
+
+ /** Selection support flag */
+ bool mAllowSelection;
+
+ /** Multiselection support flag, ignored if selection is not supported */
+ bool mMultipleSelection;
+
+ bool mKeepOneItemSelected;
+
+ /** All pairs of the list */
+ pairs_list_t mItemPairs;
+
+ /** Selected pairs for faster access */
+ pairs_list_t mSelectedItemPairs;
+};
+
+#endif
diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp
index fbcbb55b85..b87f645f3f 100644
--- a/indra/llui/llsearcheditor.cpp
+++ b/indra/llui/llsearcheditor.cpp
@@ -38,30 +38,68 @@
LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
: LLUICtrl(p)
+ , mSearchButton(NULL)
+ , mClearButton(NULL)
{
- S32 btn_top = p.search_button.top_pad + p.search_button.rect.height;
- S32 btn_right = p.search_button.rect.width + p.search_button.left_pad;
- LLRect search_btn_rect(p.search_button.left_pad, btn_top, btn_right, p.search_button.top_pad);
+ S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height;
+ S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad;
+ LLRect srch_btn_rect(p.search_button.left_pad, srch_btn_top, srch_btn_right, p.search_button.top_pad);
+ S32 text_pad_left = p.text_pad_left;
+ if (p.search_button_visible)
+ text_pad_left += srch_btn_rect.getWidth();
+
+ // Set up line editor.
LLLineEditor::Params line_editor_params(p);
line_editor_params.name("filter edit box");
line_editor_params.rect(getLocalRect());
line_editor_params.follows.flags(FOLLOWS_ALL);
- line_editor_params.text_pad_left(p.text_pad_left + search_btn_rect.getWidth());
+ line_editor_params.text_pad_left(text_pad_left);
+ line_editor_params.revert_on_esc(false);
line_editor_params.commit_callback.function(boost::bind(&LLUICtrl::onCommit, this));
+ line_editor_params.keystroke_callback(boost::bind(&LLSearchEditor::handleKeystroke, this));
mSearchEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_params);
addChild(mSearchEditor);
- LLButton::Params button_params(p.search_button);
- button_params.name(std::string("clear filter"));
- button_params.rect(search_btn_rect) ;
- button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
- button_params.tab_stop(false);
- button_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this));
+ if (p.search_button_visible)
+ {
+ // Set up search button.
+ LLButton::Params srch_btn_params(p.search_button);
+ srch_btn_params.name(std::string("search button"));
+ srch_btn_params.rect(srch_btn_rect) ;
+ srch_btn_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP);
+ srch_btn_params.tab_stop(false);
+ srch_btn_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this));
+
+ mSearchButton = LLUICtrlFactory::create<LLButton>(srch_btn_params);
+ mSearchEditor->addChild(mSearchButton);
+ }
+
+ if (p.clear_button_visible)
+ {
+ // Set up clear button.
+ S32 clr_btn_width = getRect().getHeight(); // button is square, and as tall as search editor
+ LLRect clear_btn_rect(getRect().getWidth() - clr_btn_width, getRect().getHeight(), getRect().getWidth(), 0);
+ LLButton::Params clr_btn_params(p.clear_button);
+ clr_btn_params.name(std::string("clear button"));
+ clr_btn_params.rect(clear_btn_rect) ;
+ clr_btn_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
+ clr_btn_params.tab_stop(false);
+ clr_btn_params.click_callback.function(boost::bind(&LLSearchEditor::onClearButtonClick, this, _2));
+
+ mClearButton = LLUICtrlFactory::create<LLButton>(clr_btn_params);
+ mSearchEditor->addChild(mClearButton);
+ }
+}
+
+//virtual
+void LLSearchEditor::draw()
+{
+ if (mClearButton)
+ mClearButton->setVisible(!mSearchEditor->getWText().empty());
- mSearchButton = LLUICtrlFactory::create<LLButton>(button_params);
- mSearchEditor->addChild(mSearchButton);
+ LLUICtrl::draw();
}
//virtual
@@ -89,6 +127,12 @@ BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit
}
//virtual
+void LLSearchEditor::setLabel( const LLStringExplicit &new_label )
+{
+ mSearchEditor->setLabel(new_label);
+}
+
+//virtual
void LLSearchEditor::clear()
{
if (mSearchEditor)
@@ -96,3 +140,17 @@ void LLSearchEditor::clear()
mSearchEditor->clear();
}
}
+
+void LLSearchEditor::onClearButtonClick(const LLSD& data)
+{
+ setText(LLStringUtil::null);
+ mSearchEditor->doDelete(); // force keystroke callback
+}
+
+void LLSearchEditor::handleKeystroke()
+{
+ if (mKeystrokeCallback)
+ {
+ mKeystrokeCallback(this, getValue());
+ }
+}
diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h
index cd2867b493..f395e7e816 100644
--- a/indra/llui/llsearcheditor.h
+++ b/indra/llui/llsearcheditor.h
@@ -50,10 +50,15 @@ class LLSearchEditor : public LLUICtrl
public:
struct Params : public LLInitParam::Block<Params, LLLineEditor::Params>
{
- Optional<LLButton::Params> search_button;
+ Optional<LLButton::Params> search_button, clear_button;
+ Optional<bool> search_button_visible, clear_button_visible;
+ Optional<commit_callback_t> keystroke_callback;
Params()
: search_button("search_button")
+ , search_button_visible("search_button_visible")
+ , clear_button("clear_button")
+ , clear_button_visible("clear_button_visible")
{
name = "search_editor";
}
@@ -66,26 +71,29 @@ protected:
public:
virtual ~LLSearchEditor() {}
+ /*virtual*/ void draw();
+
void setText(const LLStringExplicit &new_text) { mSearchEditor->setText(new_text); }
const std::string& getText() const { return mSearchEditor->getText(); }
-
// LLUICtrl interface
virtual void setValue(const LLSD& value );
virtual LLSD getValue() const;
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
+ virtual void setLabel( const LLStringExplicit &new_label );
virtual void clear();
- void setKeystrokeCallback(LLLineEditor::callback_t callback, void* user_data)
- {
- if(mSearchEditor)
- mSearchEditor->setKeystrokeCallback(callback,user_data);
- }
+ void setKeystrokeCallback( commit_callback_t cb ) { mKeystrokeCallback = cb; }
+
+protected:
+ void onClearButtonClick(const LLSD& data);
+ virtual void handleKeystroke();
-private:
+ commit_callback_t mKeystrokeCallback;
LLLineEditor* mSearchEditor;
LLButton* mSearchButton;
+ LLButton* mClearButton;
};
#endif // LL_SEARCHEDITOR_H
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index cabd0be522..3a13c91fac 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -429,7 +429,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )
{
static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
BOOL handled = FALSE;
- BOOL has_scroll_arrows = (getMaxScrollPos() > 0);
+ BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden();
if (has_scroll_arrows)
{
@@ -498,7 +498,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )
BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask )
{
BOOL handled = FALSE;
- BOOL has_scroll_arrows = (getMaxScrollPos() > 0);
+ BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden();
if (has_scroll_arrows)
{
@@ -540,7 +540,7 @@ BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask )
BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
{
BOOL handled = FALSE;
- BOOL has_scroll_arrows = (getMaxScrollPos() > 0);
+ BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden();
if (has_scroll_arrows)
{
@@ -1840,12 +1840,11 @@ void LLTabContainer::updateMaxScrollPos()
void LLTabContainer::commitHoveredButton(S32 x, S32 y)
{
- if (hasMouseCapture())
+ if (!getTabsHidden() && hasMouseCapture())
{
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
LLTabTuple* tuple = *iter;
- tuple->mButton->setVisible( TRUE );
S32 local_x = x - tuple->mButton->getRect().mLeft;
S32 local_y = y - tuple->mButton->getRect().mBottom;
if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible())
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index d80c2af568..1f7e5afaae 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -633,7 +633,7 @@ template <class T> T* LLView::getChild(const std::string& name, BOOL recurse) co
// did we find *something* with that name?
if (child)
{
- llwarns << "Found child named " << name << " but of wrong type " << typeid(child).name() << ", expecting " << typeid(T*).name() << llendl;
+ llwarns << "Found child named " << name << " but of wrong type " << typeid(*child).name() << ", expecting " << typeid(T*).name() << llendl;
}
result = getDefaultWidget<T>(name);
if (!result)
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index a121d327f7..2e64c10bb2 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -41,6 +41,9 @@
#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
+static LLDefaultChildRegistry::Register<LLAvatarListTmp> r_tmp("avatar_list_tmp");
+
+static const std::string COMMENT_TEXTBOX = "comment_text";
LLAvatarList::Params::Params()
:
@@ -302,3 +305,213 @@ void LLAvatarList::updateVolume()
icon_cell->setValue(getVolumeIcon(speaker_id));
}
}
+
+
+
+
+#include "llavatarlistitem.h"
+
+LLAvatarListTmp::Params::Params()
+:
+volume_column_width("volume_column_width", 0)
+, online_go_first("online_go_first", true)
+{
+}
+
+
+
+LLAvatarListTmp::LLAvatarListTmp(const Params& p)
+: LLFlatListView(p)
+, mHaveVolumeColumn(p.volume_column_width > 0)
+, mOnlineGoFirst(p.online_go_first)
+{
+ LLRect item_list_rect = getLocalRect();
+ item_list_rect.stretch( -getBorderWidth());
+
+ LLTextBox::Params text_p;
+ text_p.name(COMMENT_TEXTBOX);
+ text_p.border_visible(false);
+ text_p.rect(item_list_rect);
+ text_p.follows.flags(FOLLOWS_ALL);
+ addChild(LLUICtrlFactory::create<LLTextBox>(text_p));
+}
+
+// virtual
+void LLAvatarListTmp::draw()
+{
+ LLFlatListView::draw();
+ if (mHaveVolumeColumn)
+ {
+ updateVolume();
+ }
+}
+
+std::vector<LLUUID> LLAvatarListTmp::getSelectedIDs()
+{
+ LLUUID selected_id;
+ std::vector<LLUUID> avatar_ids;
+
+ getSelectedUUIDs(avatar_ids);
+
+ return avatar_ids;
+}
+
+void LLAvatarListTmp::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
+{
+ LLAvatarListItem* item = new LLAvatarListItem();
+ item->showStatus(true);
+ item->showInfoBtn(true);
+ item->showSpeakingIndicator(true);
+ item->setName(name);
+ item->setAvatarId(id);
+
+ item->childSetVisible("info_btn", false);
+
+ addItem(item, id, pos);
+
+ setCommentVisible(false);
+}
+
+BOOL LLAvatarListTmp::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
+{
+ BOOL have_names = TRUE;
+
+ // Save selection.
+ std::vector<LLUUID> selected_ids = getSelectedIDs();
+ LLUUID current_id = getSelectedUUID();
+ LLRect pos = getScrolledViewRect();
+
+ std::vector<LLUUID>::const_iterator buddy_it = all_buddies.begin();
+ clear();
+ for(; buddy_it != all_buddies.end(); ++buddy_it)
+ {
+ std::string name;
+ const LLUUID& buddy_id = *buddy_it;
+ have_names &= gCacheName->getFullName(buddy_id, name);
+ if (name_filter != LLStringUtil::null && !findInsensitive(name, name_filter))
+ continue;
+ addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+ }
+
+ // Changed item in place, need to request sort and update columns
+ // because we might have changed data in a column on which the user
+ // has already sorted. JC
+ // updateSort(); // TODO: implement sorting
+
+ // re-select items
+ // selectMultiple(selected_ids); // TODO: implement in LLFlatListView if need
+ selectItemByUUID(current_id);
+
+ scrollToShowRect(pos);
+
+
+ setCommentVisible(false);
+
+ return have_names;
+}
+
+
+const LLUUID LLAvatarListTmp::getCurrentID() const
+{
+ return getSelectedUUID();
+}
+
+void LLAvatarListTmp::setCommentText(const std::string& comment_text)
+{
+ getChild<LLTextBox>(COMMENT_TEXTBOX)->setValue(comment_text);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// PROTECTED SECTION
+//////////////////////////////////////////////////////////////////////////
+
+// virtual overridden
+bool LLAvatarListTmp::removeItemPair(item_pair_t* item_pair)
+{
+ bool removed = LLFlatListView::removeItemPair(item_pair);
+ setCommentVisible(size() == 0);
+ return removed;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE SECTION
+//////////////////////////////////////////////////////////////////////////
+
+// static
+std::string LLAvatarListTmp::getVolumeIcon(const LLUUID& id)
+{
+ //
+ // Determine icon appropriate for the current avatar volume.
+ //
+ // *TODO: remove this in favor of LLOutputMonitorCtrl
+ // when ListView widget is implemented
+ // which is capable of containing arbitrary widgets.
+ //
+ static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams<LLOutputMonitorCtrl>());
+ bool muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id);
+ F32 power = gVoiceClient->getCurrentPower(id);
+ std::string icon;
+
+ if (muted)
+ {
+ icon = default_monitor_params.image_mute.name;
+ }
+ else if (power == 0.f)
+ {
+ icon = default_monitor_params.image_off.name;
+ }
+ else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
+ {
+ S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
+ switch(icon_image_idx)
+ {
+ default:
+ case 0:
+ icon = default_monitor_params.image_on.name;
+ break;
+ case 1:
+ icon = default_monitor_params.image_level_1.name;
+ break;
+ case 2:
+ icon = default_monitor_params.image_level_2.name;
+ break;
+ }
+ }
+ else
+ {
+ // overdriven
+ icon = default_monitor_params.image_level_3.name;
+ }
+
+ return icon;
+}
+
+// Update volume column for all list rows.
+void LLAvatarListTmp::updateVolume()
+{
+ // TODO: implement via Listener
+ /*
+ item_list& items = getItemList();
+
+ for (item_list::iterator item_it = items.begin();
+ item_it != items.end();
+ ++item_it)
+ {
+ LLScrollListItem* itemp = (*item_it);
+ LLUUID speaker_id = itemp->getUUID();
+
+ LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME);
+ if (icon_cell)
+ icon_cell->setValue(getVolumeIcon(speaker_id));
+ }
+ */
+}
+
+void LLAvatarListTmp::setCommentVisible(bool visible) const
+{
+ getChildView(COMMENT_TEXTBOX)->setVisible(visible);
+}
+
+// EOF
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 8b419dbb57..639ed83ada 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -75,4 +75,46 @@ private:
bool mOnlineGoFirst;
};
+
+#include "llflatlistview.h"
+
+class LLAvatarListTmp : public LLFlatListView
+{
+ LOG_CLASS(LLAvatarListTmp);
+public:
+ struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
+ {
+ Optional<S32> volume_column_width;
+ Optional<bool> online_go_first;
+ Params();
+ };
+
+ LLAvatarListTmp(const Params&);
+ virtual ~LLAvatarListTmp() {}
+
+ /*virtual*/ void draw();
+
+ BOOL update(const std::vector<LLUUID>& all_buddies,
+ const std::string& name_filter = LLStringUtil::null);
+
+ const LLUUID getCurrentID() const;
+ void setCommentText( const std::string& comment_text);
+
+protected:
+ std::vector<LLUUID> getSelectedIDs();
+ void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+ /*virtual*/ bool removeItemPair(item_pair_t* item_pair);
+
+private:
+ static std::string getVolumeIcon(const LLUUID& id); /// determine volume icon from current avatar volume
+ void updateVolume(); // update volume for all avatars
+ void setCommentVisible(bool visible) const;
+
+ bool mHaveVolumeColumn;
+ bool mOnlineGoFirst;
+
+};
+
+
+
#endif // LL_LLAVATARLIST_H
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 253c2ee9a6..feae8202bc 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -2,9 +2,9 @@
* @file llavatarlistitem.cpp
* @avatar list item source file
*
- * $LicenseInfo:firstyear=2004&license=viewergpl$
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
*
- * Copyright (c) 2004-2009, Linden Research, Inc.
+ * Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -33,70 +33,39 @@
#include "llviewerprecompiledheaders.h"
-#include "llfloaterreg.h"
#include "llavatarlistitem.h"
-#include "llagent.h"
-
-
-//---------------------------------------------------------------------------------
-LLAvatarListItem::LLAvatarListItem(const Params& p) : LLPanel()
+#include "llfloaterreg.h"
+#include "llagent.h"
+#include "lloutputmonitorctrl.h"
+#include "llavatariconctrl.h"
+#include "llbutton.h"
+
+
+LLAvatarListItem::LLAvatarListItem()
+: LLPanel(),
+ mAvatarIcon(NULL),
+ mAvatarName(NULL),
+ mStatus(NULL),
+ mSpeakingIndicator(NULL),
+ mInfoBtn(NULL)
{
- mNeedsArrange = false;
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml");
-
- mStatus = NULL;
- mInfo = NULL;
- mProfile = NULL;
- mInspector = NULL;
-
- mAvatar = getChild<LLAvatarIconCtrl>("avatar_icon");
- //mAvatar->setValue(p.avatar_icon);
- mName = getChild<LLTextBox>("name");
- //mName->setText(p.user_name);
-
- init(p);
-
-
}
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::init(const Params& p)
+BOOL LLAvatarListItem::postBuild()
{
- mLocator = getChild<LLIconCtrl>("locator");
-
- mStatus = getChild<LLTextBox>("user_status");
-
- mInfo = getChild<LLButton>("info_btn");
- mInfo->setVisible(false);
-
- mProfile = getChild<LLButton>("profile_btn");
- mProfile->setVisible(false);
-
- if(!p.buttons.locator)
- {
- mLocator->setVisible(false);
- delete mLocator;
- mLocator = NULL;
- }
+ mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon");
+ mAvatarName = getChild<LLTextBox>("avatar_name");
+ mStatus = getChild<LLTextBox>("avatar_status");
- if(!p.buttons.status)
- {
- mStatus->setVisible(false);
- delete mStatus;
- mStatus = NULL;
- }
+ mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
+ mInfoBtn = getChild<LLButton>("info_btn");
- if(!p.buttons.info)
- {
- delete mInfo;
- mInfo = NULL;
- }
- else
- {
- mInfo->setClickedCallback(boost::bind(&LLAvatarListItem::onInfoBtnClick, this));
- }
+ mInfoBtn->setVisible(false);
+ mInfoBtn->setClickedCallback(boost::bind(&LLAvatarListItem::onInfoBtnClick, this));
+/*
if(!p.buttons.profile)
{
delete mProfile;
@@ -125,150 +94,72 @@ void LLAvatarListItem::init(const Params& p)
mInfo->setRect(rect);
}
}
-
+*/
+ return TRUE;
}
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- if(!mNeedsArrange)
- {
- LLView::reshape(width, height, called_from_parent);
- return;
- }
-
- LLRect rect;
- S32 profile_delta = 0;
- S32 width_delta = getRect().getWidth() - width;
-
- if(!mProfile)
- {
- profile_delta = 30;
- }
- else
- {
- rect.setLeftTopAndSize(mProfile->getRect().mLeft - width_delta, mProfile->getRect().mTop, mProfile->getRect().getWidth(), mProfile->getRect().getHeight());
- mProfile->setRect(rect);
- }
-
- width_delta += profile_delta;
-
- if(mInfo)
- {
- rect.setLeftTopAndSize(mInfo->getRect().mLeft - width_delta, mInfo->getRect().mTop, mInfo->getRect().getWidth(), mInfo->getRect().getHeight());
- mInfo->setRect(rect);
- }
-
- if(mLocator)
- {
- rect.setLeftTopAndSize(mLocator->getRect().mLeft - width_delta, mLocator->getRect().mTop, mLocator->getRect().getWidth(), mLocator->getRect().getHeight());
- mLocator->setRect(rect);
- }
-
- if(mStatus)
- {
- rect.setLeftTopAndSize(mStatus->getRect().mLeft - width_delta, mStatus->getRect().mTop, mStatus->getRect().getWidth(), mStatus->getRect().getHeight());
- mStatus->setRect(rect);
- }
-
- mNeedsArrange = false;
- LLView::reshape(width, height, called_from_parent);
-}
-
-//---------------------------------------------------------------------------------
-LLAvatarListItem::~LLAvatarListItem()
-{
-}
-//---------------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------------
-BOOL LLAvatarListItem::handleHover(S32 x, S32 y, MASK mask)
-{
- mYPos = y;
- mXPos = x;
-
- return true;
-}
-
-//---------------------------------------------------------------------------------
void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask)
{
- setTransparentColor( *(new LLColor4((F32)0.4, (F32)0.4, (F32)0.4)) );
+ childSetVisible("hovered_icon", true);
+ mInfoBtn->setVisible(true);
- if(mInfo)
- mInfo->setVisible(true);
-
- if(mProfile)
- mProfile->setVisible(true);
+ LLPanel::onMouseEnter(x, y, mask);
}
-//---------------------------------------------------------------------------------
void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask)
{
- if(mInfo)
- {
- if( mInfo->getRect().pointInRect(x, y) )
- return;
-
- mInfo->setVisible(false);
- }
-
- if(mProfile)
- {
- if( mProfile->getRect().pointInRect(x, y) )
- return;
-
- mProfile->setVisible(false);
- }
+ childSetVisible("hovered_icon", false);
+ mInfoBtn->setVisible(false);
- setTransparentColor( *(new LLColor4((F32)0.3, (F32)0.3, (F32)0.3)) );
+ LLPanel::onMouseLeave(x, y, mask);
}
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::setStatus(int status)
+void LLAvatarListItem::setStatus(const std::string& status)
{
+ mStatus->setValue(status);
}
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::setName(std::string name)
+void LLAvatarListItem::setName(const std::string& name)
{
+ mAvatarName->setValue(name);
+ mAvatarName->setToolTip(name);
}
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::setAvatar(LLSD& data)
+void LLAvatarListItem::setAvatarId(const LLUUID& id)
{
+ mAvatarIcon->setValue(id);
+ mSpeakingIndicator->setSpeakerId(id);
}
-//---------------------------------------------------------------------------------
void LLAvatarListItem::onInfoBtnClick()
{
- mInspector = LLFloaterReg::showInstance("inspect_avatar", gAgent.getID());
-
- if (!mInspector)
- return;
+ LLFloaterReg::showInstance("inspect_avatar", mAvatarIcon->getValue());
- LLRect rect;
+ /* TODO fix positioning of inspector
localPointToScreen(mXPos, mYPos, &mXPos, &mYPos);
+
+ LLRect rect;
// *TODO Vadim: rewrite this. "+= -" looks weird.
- S32 delta = mYPos - mInspector->getRect().getHeight();
+ S32 delta = mYPos - inspector->getRect().getHeight();
if(delta < 0)
{
mYPos += -delta;
}
-
+
rect.setLeftTopAndSize(mXPos, mYPos,
- mInspector->getRect().getWidth(), mInspector->getRect().getHeight());
- mInspector->setRect(rect);
- mInspector->setFrontmost(true);
- mInspector->setVisible(true);
-
+ inspector->getRect().getWidth(), inspector->getRect().getHeight());
+ inspector->setRect(rect);
+ inspector->setFrontmost(true);
+ inspector->setVisible(true);
+ */
}
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::onProfileBtnClick()
+void LLAvatarListItem::setValue( const LLSD& value )
{
+ if (!value.isMap()) return;;
+ if (!value.has("selected")) return;
+ childSetVisible("selected_icon", value["selected"]);
}
-//---------------------------------------------------------------------------------
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index b41e0ff209..dc5606e4c2 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -2,9 +2,9 @@
* @file llavatarlistitem.h
* @avatar list item header file
*
- * $LicenseInfo:firstyear=2004&license=viewergpl$
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
*
- * Copyright (c) 2004-2009, Linden Research, Inc.
+ * Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -30,75 +30,45 @@
* $/LicenseInfo$
*/
-#include "llavatariconctrl.h"
-#include <llview.h>
-#include <llpanel.h>
-#include <llfloater.h>
-#include <lltextbox.h>
-#include <llbutton.h>
-#include <lluuid.h>
+#ifndef LL_LLAVATARLISTITEM_H
+#define LL_LLAVATARLISTITEM_H
-//#include "llfloaterminiinspector.h"
+#include "llpanel.h"
+#include "lloutputmonitorctrl.h"
+#include "llbutton.h"
+#include "lltextbox.h"
-class LLAvatarListItem : public LLPanel
+class LLAvatarIconCtrl;
+
+class LLAvatarListItem : public LLPanel
{
public:
- struct Params : public LLInitParam::Block<Params, LLPanel::Params>
- {
- Optional<LLUUID> avatar_icon;
- Optional<std::string> user_name;
- struct avatar_list_item_buttons
- {
- bool status;
- bool info;
- bool profile;
- bool locator;
- avatar_list_item_buttons() : status(true), info(true), profile(true), locator(true)
- {};
- } buttons;
-
- Params()
- : avatar_icon("avatar_icon"),
- user_name("user_name")
- {};
- };
-
-
- LLAvatarListItem(const Params& p);
- virtual ~LLAvatarListItem();
-
- void reshape(S32 width, S32 height, BOOL called_from_parent);
-
- //interface
- void setStatus(int status);
- void setName(std::string name);
- void setAvatar(LLSD& data);
- void needsArrange( void ) {mNeedsArrange = true;}
-
+ LLAvatarListItem();
+ virtual ~LLAvatarListItem() {};
- //event handlers
- //mouse
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual BOOL postBuild();
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
- //buttons
- void onInfoBtnClick();
- void onProfileBtnClick();
+ virtual void setValue(const LLSD& value);
-private:
- LLAvatarIconCtrl* mAvatar;
- LLIconCtrl* mLocator;
- LLTextBox* mName;
- LLTextBox* mStatus;
- LLButton* mInfo;
- LLButton* mProfile;
+ void setStatus(const std::string& status);
+ void setName(const std::string& name);
+ void setAvatarId(const LLUUID& id);
+
+ void onInfoBtnClick();
- S32 mYPos;
- S32 mXPos;
+ void showSpeakingIndicator(bool show) { mSpeakingIndicator->setVisible(show); }
+ void showInfoBtn(bool show_info_btn) {mInfoBtn->setVisible(show_info_btn); }
+ void showStatus(bool show_status) {mStatus->setVisible(show_status); }
- LLFloater* mInspector;
- bool mNeedsArrange;
- //
- void init(const Params& p);
+private:
+ LLAvatarIconCtrl*mAvatarIcon;
+ LLTextBox* mAvatarName;
+ LLTextBox* mStatus;
+
+ LLOutputMonitorCtrl* mSpeakingIndicator;
+ LLButton* mInfoBtn;
};
+
+#endif //LL_LLAVATARLISTITEM_H
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index e5acf62189..42ed783f94 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -1140,6 +1140,8 @@ LLTalkButton::LLTalkButton(const Params& p)
LLOutputMonitorCtrl::Params monitor_params = p.monitor;
monitor_params.draw_border(false);
monitor_params.rect(monitor_rect);
+ monitor_params.auto_update(true);
+ monitor_params.speaker_id(gAgentID);
mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params);
mSpeakBtn->addChild(mOutputMonitor);
@@ -1151,17 +1153,6 @@ LLTalkButton::~LLTalkButton()
{
}
-void LLTalkButton::draw()
-{
- // Always provide speaking feedback. User can trigger speaking
- // with keyboard or middle-mouse shortcut.
- mOutputMonitor->setPower(gVoiceClient->getCurrentPower(gAgent.getID()));
- mOutputMonitor->setIsTalking( gVoiceClient->getUserPTTState() );
- mSpeakBtn->setToggleState( gVoiceClient->getUserPTTState() );
-
- LLUICtrl::draw();
-}
-
void LLTalkButton::setSpeakBtnToggleState(bool state)
{
mSpeakBtn->setToggleState(state);
@@ -1198,13 +1189,14 @@ void LLTalkButton::onClick_ShowBtn()
rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight());
mPrivateCallPanel->setRect(rect);
- LLAvatarListItem::Params p;
- p.buttons.status = true;
- p.buttons.info = true;
- p.buttons.profile = false;
- p.buttons.locator = true;
- mPrivateCallPanel->addItem(new LLAvatarListItem(p));
+ LLAvatarListItem* item = new LLAvatarListItem();
+ item->showStatus(true);
+ item->showInfoBtn(true);
+ item->showSpeakingIndicator(true);
+ item->reshape(mPrivateCallPanel->getRect().getWidth(), item->getRect().getHeight(), FALSE);
+
+ mPrivateCallPanel->addItem(item);
mPrivateCallPanel->setVisible(TRUE);
mPrivateCallPanel->setFrontmost(TRUE);
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 91f55915ed..52bd7dbc31 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -780,7 +780,6 @@ public:
/*virtual*/ ~LLTalkButton();
- /*virtual*/ void draw();
void setSpeakBtnToggleState(bool state);
protected:
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index 94ea20893a..f4c4f38008 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -77,21 +77,11 @@ bool LLFloaterCamera::inAvatarViewMode()
return mCurrMode == CAMERA_CTRL_MODE_AVATAR_VIEW;
}
-void LLFloaterCamera::resetFreeCameraMode()
+void LLFloaterCamera::resetCameraMode()
{
- if (mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA)
- {
- /* Camera Tool can be deselected when we are mouse wheel scrolling into Mouse Look
- In such case we are unable to determine that we will be into Mouse Look view */
- if (mPrevMode == CAMERA_CTRL_MODE_AVATAR_VIEW)
- {
- setMode(CAMERA_CTRL_MODE_ORBIT);
- }
- else
- {
- setMode(mPrevMode);
- }
- }
+ LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
+ if (!floater_camera) return;
+ floater_camera->switchMode(CAMERA_CTRL_MODE_ORBIT);
}
void LLFloaterCamera::update()
diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h
index 04554c6493..1181c443bf 100644
--- a/indra/newview/llfloatercamera.h
+++ b/indra/newview/llfloatercamera.h
@@ -62,9 +62,8 @@ public:
static void toPrevModeIfInAvatarViewMode();
- /* resets free camera mode to the previous mode */
- //*TODO remove, if it won't be used by LLToolCamera::handleDeselect()
- void resetFreeCameraMode();
+ /** resets current camera mode to orbit mode */
+ static void resetCameraMode();
/* determines actual mode and updates ui */
void update();
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 0262e40803..a47477c446 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -35,6 +35,7 @@
#include "llnotificationhandler.h"
+#include "llagentdata.h"
#include "llbottomtray.h"
#include "llviewercontrol.h"
#include "lltoastimpanel.h"
@@ -77,9 +78,15 @@ void LLIMHandler::processNotification(const LLSD& notify)
{
LLSD substitutions = notification->getSubstitutions();
+ // According to comments in LLIMMgr::addMessage(), if we get message
+ // from ourselves, the sender id is set to null. This fixes EXT-875.
+ LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
+ if (avatar_id.isNull())
+ avatar_id = gAgentID;
+
LLToastIMPanel::Params im_p;
im_p.notification = notification;
- im_p.avatar_id = substitutions["FROM_ID"].asUUID();
+ im_p.avatar_id = avatar_id;
im_p.from = substitutions["FROM"].asString();
im_p.time = substitutions["TIME"].asString();
im_p.message = substitutions["MESSAGE"].asString();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 901b3351c8..9ef98afe94 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -101,7 +101,8 @@ void toast_callback(const LLSD& msg){
args["FROM_ID"] = msg["from_id"];
args["SESSION_ID"] = msg["session_id"];
- LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLFloaterChatterBox::onOpen, LLFloaterChatterBox::getInstance(), msg["session_id"].asUUID()));
+ //LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLFloaterChatterBox::onOpen, LLFloaterChatterBox::getInstance(), msg["session_id"].asUUID()));
+ LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::toggle, msg["session_id"].asUUID()));
}
}
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index d4a9be0355..764e093bcc 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -32,6 +32,9 @@
#include "llviewerprecompiledheaders.h"
+#include "llfloaterreg.h"
+#include "lltrans.h"
+
#include "llnearbychatbar.h"
#include "llbottomtray.h"
#include "llagent.h"
@@ -45,7 +48,7 @@
S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
-// legacy calllback glue
+// legacy callback glue
void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box");
@@ -64,6 +67,7 @@ LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p)
: LLComboBox(p)
, mGestureLabelTimer()
, mLabel(p.label)
+ , mViewAllItemIndex(0)
{
setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this));
@@ -102,6 +106,11 @@ void LLGestureComboBox::refreshGestures()
}
sortByName();
+
+ // store index followed by the last added Gesture and add View All item at bottom
+ mViewAllItemIndex = idx;
+ addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex));
+
// Insert label after sorting, at top, with separator below it
addSeparator(ADD_TOP);
addSimpleElement(mLabel, ADD_TOP);
@@ -128,6 +137,15 @@ void LLGestureComboBox::onCommitGesture()
}
index = gestures->getSelectedValue().asInteger();
+
+ if (mViewAllItemIndex == index)
+ {
+ // The same behavior as Ctrl+G. EXT-823
+ LLFloaterReg::toggleInstance("gestures");
+ gestures->selectFirstItem();
+ return;
+ }
+
LLMultiGesture* gesture = mGestures.at(index);
if(gesture)
{
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 19177e37b3..f310740f42 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -63,6 +63,7 @@ protected:
LLFrameTimer mGestureLabelTimer;
std::vector<LLMultiGesture*> mGestures;
std::string mLabel;
+ LLSD::Integer mViewAllItemIndex;
};
class LLNearbyChatBar
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index d088c45710..49b48f5a8e 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -38,6 +38,8 @@
// viewer includes
#include "llvoiceclient.h"
+#include "llmutelist.h"
+#include "llagent.h"
// default options set in output_monitor.xml
static LLDefaultChildRegistry::Register<LLOutputMonitorCtrl> r("output_monitor");
@@ -58,7 +60,9 @@ LLOutputMonitorCtrl::Params::Params()
image_on("image_on"),
image_level_1("image_level_1"),
image_level_2("image_level_2"),
- image_level_3("image_level_3")
+ image_level_3("image_level_3"),
+ auto_update("auto_update"),
+ speaker_id("speaker_id")
{
draw_border = true;
name = "output_monitor";
@@ -69,14 +73,14 @@ LLOutputMonitorCtrl::Params::Params()
LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
: LLView(p),
mPower(0),
- mIsMuted(true),
- mIsTalking(false),
mImageMute(p.image_mute),
mImageOff(p.image_off),
mImageOn(p.image_on),
mImageLevel1(p.image_level_1),
mImageLevel2(p.image_level_2),
- mImageLevel3(p.image_level_3)
+ mImageLevel3(p.image_level_3),
+ mAutoUpdate(p.auto_update),
+ mSpeakerId(p.speaker_id)
{
//static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange);
//static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red);
@@ -99,10 +103,14 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
//sRectHeightRatio = output_monitor_rect_height_ratio;
mBorder = p.draw_border;
+
+ //with checking mute state
+ setSpeakerId(mSpeakerId);
}
LLOutputMonitorCtrl::~LLOutputMonitorCtrl()
{
+ LLMuteList::getInstance()->removeObserver(this);
}
void LLOutputMonitorCtrl::setPower(F32 val)
@@ -121,6 +129,12 @@ void LLOutputMonitorCtrl::draw()
const F32 LEVEL_1 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL * 2.f / 3.f;
const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
+ if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull())
+ {
+ setPower(gVoiceClient->getCurrentPower(mSpeakerId));
+ setIsTalking(gVoiceClient->getUserPTTState());
+ }
+
LLPointer<LLUIImage> icon;
if (mIsMuted)
{
@@ -205,3 +219,29 @@ void LLOutputMonitorCtrl::draw()
if(mBorder)
gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);
}
+
+void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id)
+{
+ if (speaker_id.isNull()) return;
+
+ mSpeakerId = speaker_id;
+
+ //mute management
+ if (mAutoUpdate)
+ {
+ if (speaker_id == gAgentID)
+ {
+ setIsMuted(false);
+ }
+ else
+ {
+ setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId));
+ LLMuteList::getInstance()->addObserver(this);
+ }
+ }
+}
+
+void LLOutputMonitorCtrl::onChange()
+{
+ setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId));
+}
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 98b2fe9dc6..7a7b8bc3a1 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -35,6 +35,7 @@
#include "v4color.h"
#include "llview.h"
+#include "llmutelist.h"
class LLTextBox;
class LLUICtrlFactory;
@@ -44,7 +45,7 @@ class LLUICtrlFactory;
//
class LLOutputMonitorCtrl
-: public LLView
+: public LLView, LLMuteListObserver
{
public:
struct Params : public LLInitParam::Block<Params, LLView::Params>
@@ -56,6 +57,8 @@ public:
image_level_1,
image_level_2,
image_level_3;
+ Optional<bool> auto_update;
+ Optional<LLUUID> speaker_id;
Params();
};
@@ -80,6 +83,11 @@ public:
// correct button image.
void setIsTalking(bool val) { mIsTalking = val; }
+ void setSpeakerId(const LLUUID& speaker_id);
+
+ //called by mute list
+ virtual void onChange();
+
private:
//static LLColor4 sColorMuted;
//static LLColor4 sColorNormal;
@@ -89,6 +97,8 @@ private:
//static F32 sRectWidthRatio;
//static F32 sRectHeightRatio;
+
+
F32 mPower;
bool mIsMuted;
bool mIsTalking;
@@ -98,6 +108,12 @@ private:
LLPointer<LLUIImage> mImageLevel1;
LLPointer<LLUIImage> mImageLevel2;
LLPointer<LLUIImage> mImageLevel3;
+
+ /** whether to deal with gVoiceClient directly */
+ bool mAutoUpdate;
+
+ /** uuid of a speaker being monitored */
+ LLUUID mSpeakerId;
};
#endif
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index e0b7aeb77e..b7f2f67a9a 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -446,7 +446,7 @@ void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_g
void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data)
{
- childSetValue("register_date", avatar_data->born_on);
+ childSetValue("register_date", LLAvatarPropertiesProcessor::ageFromDate(avatar_data->born_on));
childSetValue("sl_description_edit", avatar_data->about_text);
childSetValue("fl_description_edit",avatar_data->fl_about_text);
childSetValue("2nd_life_pic", avatar_data->image_id);
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 48c9c16780..378a09e315 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -36,6 +36,7 @@
#include "llagent.h"
#include "llbutton.h"
+#include "llfiltereditor.h"
#include "llfloatergroupinvite.h"
#include "llavataractions.h"
#include "lliconctrl.h"
@@ -49,7 +50,6 @@
#include "lltabcontainer.h"
#include "lltextbox.h"
#include "lltexteditor.h"
-#include "llsearcheditor.h"
#include "llviewertexturelist.h"
#include "llviewerwindow.h"
#include "llfocusmgr.h"
@@ -477,14 +477,12 @@ BOOL LLPanelGroupSubTab::postBuild()
{
// Hook up the search widgets.
bool recurse = true;
- mSearchEditor = getChild<LLSearchEditor>("filter_input", recurse);
+ mSearchEditor = getChild<LLFilterEditor>("filter_input", recurse);
if (!mSearchEditor)
return FALSE;
- mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::onClickSearch, this));
- mSearchEditor->setKeystrokeCallback(onSearchKeystroke, this);
-
+ mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2));
// Get icons for later use.
mActionIcons.clear();
@@ -517,26 +515,6 @@ void LLPanelGroupSubTab::setGroupID(const LLUUID& id)
}
}
-// static
-void LLPanelGroupSubTab::onSearchKeystroke(LLLineEditor* caller, void* user_data)
-{
- LLPanelGroupSubTab* self = static_cast<LLPanelGroupSubTab*>(user_data);
- self->handleSearchKeystroke(caller);
-
-}
-
-void LLPanelGroupSubTab::handleSearchKeystroke(LLLineEditor* caller)
-{
- setSearchFilter( caller->getText() );
-}
-
-// static
-void LLPanelGroupSubTab::onClickSearch()
-{
- setSearchFilter( mSearchEditor->getText() );
-}
-
-
void LLPanelGroupSubTab::setSearchFilter(const std::string& filter)
{
lldebugs << "LLPanelGroupSubTab::setSearchFilter() ==> '" << filter << "'" << llendl;
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 2a0f31fa0f..bd5fc1d235 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -35,6 +35,7 @@
#include "llpanelgroup.h"
+class LLFilterEditor;
class LLNameListCtrl;
class LLPanelGroupSubTab;
class LLPanelGroupMembersSubTab;
@@ -43,7 +44,6 @@ class LLPanelGroupActionsSubTab;
class LLScrollListCtrl;
class LLScrollListItem;
class LLTextEditor;
-class LLSearchEditor;
// Forward declare for friend usage.
//virtual BOOL LLPanelGroupSubTab::postBuildSubTab(LLView*);
@@ -111,11 +111,6 @@ public:
// This allows sub-tabs to collect child widgets from a higher level in the view hierarchy.
virtual BOOL postBuildSubTab(LLView* root) { return TRUE; }
- static void onSearchKeystroke(LLLineEditor* caller, void* user_data);
- void handleSearchKeystroke(LLLineEditor* caller);
-
- void onClickSearch();
-
virtual void setSearchFilter( const std::string& filter );
virtual void activate();
@@ -148,7 +143,7 @@ protected:
LLPanel* mHeader;
LLPanel* mFooter;
- LLSearchEditor* mSearchEditor;
+ LLFilterEditor* mSearchEditor;
std::string mSearchFilter;
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 42aa21c13e..309a97a9f2 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -401,6 +401,19 @@ LLPanelPeople::~LLPanelPeople()
LLView::deleteViewByHandle(mRecentViewSortMenuHandle);
}
+void onAvatarListTmpDoubleClicked(LLAvatarListTmp* list)
+{
+ LLUUID clicked_id = list->getCurrentID();
+
+ if (clicked_id.isNull())
+ return;
+
+#if 0 // SJB: Useful for testing, but not currently functional or to spec
+ LLAvatarActions::showProfile(clicked_id);
+#else // spec says open IM window
+ LLAvatarActions::startIM(clicked_id);
+#endif
+}
BOOL LLPanelPeople::postBuild()
{
@@ -417,7 +430,7 @@ BOOL LLPanelPeople::postBuild()
mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
- mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
+ mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarListTmp>("avatar_list");
mGroupList = getChild<LLGroupList>("group_list");
LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME);
@@ -432,11 +445,11 @@ BOOL LLPanelPeople::postBuild()
mOnlineFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mOnlineFriendList));
mAllFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mAllFriendList));
mNearbyList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mNearbyList));
- mRecentList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mRecentList));
+ mRecentList->setDoubleClickCallback(boost::bind(onAvatarListTmpDoubleClicked, mRecentList));
mOnlineFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mOnlineFriendList));
mAllFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mAllFriendList));
mNearbyList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mNearbyList));
- mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mRecentList));
+ mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
mGroupList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this));
mGroupList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 3358a70bac..c0c2f70614 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -40,6 +40,7 @@
class LLFilterEditor;
class LLTabContainer;
class LLAvatarList;
+class LLAvatarListTmp;
class LLGroupList;
class LLPanelPeople : public LLPanel
@@ -118,7 +119,7 @@ private:
LLAvatarList* mOnlineFriendList;
LLAvatarList* mAllFriendList;
LLAvatarList* mNearbyList;
- LLAvatarList* mRecentList;
+ LLAvatarListTmp* mRecentList;
LLGroupList* mGroupList;
LLHandle<LLView> mGroupPlusMenuHandle;
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 457109f869..7a19b8877e 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -68,7 +68,6 @@ LLPanelPlaceInfo::LLPanelPlaceInfo()
: LLPanel(),
mParcelID(),
mRequestedID(),
- mPosRegion(),
mLandmarkID(),
mMinHeight(0),
mScrollingPanel(NULL),
@@ -82,8 +81,6 @@ LLPanelPlaceInfo::~LLPanelPlaceInfo()
{
LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this);
}
-
- LLViewerParcelMgr::getInstance()->removeObserver(this);
}
BOOL LLPanelPlaceInfo::postBuild()
@@ -254,7 +251,6 @@ void LLPanelPlaceInfo::resetLocation()
mParcelID.setNull();
mRequestedID.setNull();
mLandmarkID.setNull();
- mPosRegion.clearVec();
std::string not_available = getString("not_available");
mMaturityRatingText->setValue(not_available);
mParcelOwner->setValue(not_available);
@@ -330,8 +326,6 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
getChild<LLAccordionCtrl>("advanced_info_accordion")->setVisible(is_info_type_agent);
- LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
-
switch(type)
{
case CREATE_LANDMARK:
@@ -339,15 +333,6 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
break;
case AGENT:
- if (parcel_mgr)
- {
- // If information is requested for current agent location
- // start using LLViewerParcelMgr for land selection.
- parcel_mgr->addObserver(this);
- parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
- }
-
- // Fall through to PLACE case
case PLACE:
mCurrentTitle = getString("title_place");
@@ -366,16 +351,7 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
break;
}
- if (type != AGENT && parcel_mgr != NULL)
- {
- if (!parcel_mgr->selectionEmpty())
- {
- parcel_mgr->deselectUnused();
- }
- parcel_mgr->removeObserver(this);
- }
-
- if (type != PLACE)
+ if (type != AGENT)
toggleMediaPanel(FALSE);
mInfoType = type;
@@ -442,12 +418,16 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
mSnapshotCtrl->setImageAssetID(parcel_data.snapshot_id);
}
- if( !parcel_data.name.empty())
+ if(!parcel_data.name.empty())
{
mParcelName->setText(parcel_data.name);
}
+ else
+ {
+ mParcelName->setText(LLStringUtil::null);
+ }
- if( !parcel_data.desc.empty())
+ if(!parcel_data.desc.empty())
{
mDescEditor->setText(parcel_data.desc);
}
@@ -471,21 +451,12 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
//because we deal with remote parcel response format
bool isForSale = (parcel_data.flags & DFQ_FOR_SALE)? TRUE : FALSE;
getChild<LLIconCtrl>("icon_for_sale")->setVisible(isForSale);
-
- // Just use given region position for display
- S32 region_x = llround(mPosRegion.mV[0]);
- S32 region_y = llround(mPosRegion.mV[1]);
- S32 region_z = llround(mPosRegion.mV[2]);
- // If the region position is zero, grab position from the global
- if(mPosRegion.isExactlyZero())
- {
- region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
- region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
- region_z = llround(parcel_data.global_z);
- }
+ S32 region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
+ S32 region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
+ S32 region_z = llround(parcel_data.global_z);
- std::string name;
+ std::string name = getString("not_available");
if (!parcel_data.sim_name.empty())
{
name = llformat("%s (%d, %d, %d)",
@@ -495,17 +466,23 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
if (mInfoType == CREATE_LANDMARK)
{
- mTitleEditor->setText(parcel_data.name);
+
+ if (parcel_data.name.empty())
+ {
+ mTitleEditor->setText(name);
+ }
+ else
+ {
+ mTitleEditor->setText(parcel_data.name);
+ }
+
mNotesEditor->setText(LLStringUtil::null);
}
}
-void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
- const LLUUID& region_id,
- const LLVector3d& pos_global)
+void LLPanelPlaceInfo::displayParcelInfo(const LLUUID& region_id,
+ const LLVector3d& pos_global)
{
- mPosRegion = pos_region;
-
LLViewerRegion* region = gAgent.getRegion();
if (!region)
return;
@@ -514,6 +491,10 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
std::string url = region->getCapability("RemoteParcelRequest");
if (!url.empty())
{
+ F32 region_x = (F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS);
+ F32 region_y = (F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS);
+ LLVector3 pos_region(region_x, region_y, (F32)pos_global.mdV[VZ]);
+
body["location"] = ll_sd_from_vector3(pos_region);
if (!region_id.isNull())
{
@@ -532,12 +513,10 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
}
}
-void LLPanelPlaceInfo::displayAgentParcelInfo()
+void LLPanelPlaceInfo::displaySelectedParcelInfo(LLParcel* parcel,
+ LLViewerRegion* region,
+ const LLVector3d& pos_global)
{
- mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
-
- LLParcel* parcel = mParcel->getParcel();
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
if (!region || !parcel)
return;
@@ -568,14 +547,9 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
parcel_data.name = parcel->getName();
parcel_data.sim_name = gAgent.getRegion()->getName();
parcel_data.snapshot_id = parcel->getSnapshotID();
- LLVector3d global_pos = gAgent.getPositionGlobal();
- parcel_data.global_x = global_pos.mdV[0];
- parcel_data.global_y = global_pos.mdV[1];
- parcel_data.global_z = global_pos.mdV[2];
-
- mPosRegion = gAgent.getPositionAgent();
-
- processParcelInfo(parcel_data);
+ parcel_data.global_x = pos_global.mdV[0];
+ parcel_data.global_y = pos_global.mdV[1];
+ parcel_data.global_z = pos_global.mdV[2];
std::string on = getString("on");
std::string off = getString("off");
@@ -589,7 +563,7 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
{
mVoiceText->setText(off);
}
-
+
if (!region->getBlockFly() && parcel->getAllowFly())
{
mFlyText->setText(on);
@@ -769,14 +743,9 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
}
}
- getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale);
-}
+ processParcelInfo(parcel_data);
-// virtual
-void LLPanelPlaceInfo::changed()
-{
- resetLocation();
- displayAgentParcelInfo();
+ getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale);
}
void LLPanelPlaceInfo::updateEstateName(const std::string& name)
@@ -835,7 +804,10 @@ void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type)
}
}
- if (item_value != current_value &&
+ LLStringUtil::trim(current_value);
+
+ if (!current_value.empty() &&
+ item_value != current_value &&
gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))
{
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
@@ -867,11 +839,17 @@ void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id)
if (name.empty())
{
name = mParcelName->getText();
+
+ // If no parcel exists use the region name instead.
+ if (name.empty())
+ {
+ name = mRegionName->getText();
+ }
}
LLStringUtil::replaceChar(desc, '\n', ' ');
// If no folder chosen use the "Landmarks" folder.
- LLLandmarkActions::createLandmarkHere(name, desc,
+ LLLandmarkActions::createLandmarkHere(name, desc,
folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK));
}
@@ -884,10 +862,14 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& global_pos)
pick_data.pick_id = LLUUID::generateNewID();
pick_data.creator_id = gAgentID;
- //legacy var need to be deleted
+ //legacy var needs to be deleted
pick_data.top_pick = FALSE;
pick_data.parcel_id = mParcelID;
pick_data.name = mParcelName->getText();
+ if (pick_data.name.empty())
+ {
+ pick_data.name = mRegionName->getText();
+ }
pick_data.desc = mDescEditor->getText();
pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
pick_data.pos_global = global_pos;
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 60f35cd0c1..32ae4334aa 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -42,17 +42,17 @@
#include "llpanelmedia.h"
#include "llremoteparcelrequest.h"
-#include "llviewerparcelmgr.h"
class LLButton;
class LLInventoryItem;
class LLLineEditor;
-class LLParcelSelection;
+class LLParcel;
class LLTextBox;
class LLTextEditor;
class LLTextureCtrl;
+class LLViewerRegion;
-class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver, LLParcelObserver
+class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
{
public:
enum INFO_TYPE
@@ -99,16 +99,14 @@ public:
// Displays information about a remote parcel.
// Sends a request to the server.
- void displayParcelInfo(const LLVector3& pos_region,
- const LLUUID& region_id,
+ void displayParcelInfo(const LLUUID& region_id,
const LLVector3d& pos_global);
- // Displays information about the parcel the agent is currently on
+ // Displays information about the currently selected parcel
// without sending a request to the server.
- void displayAgentParcelInfo();
-
- // Called on parcel selection change by LLViewerParcelMgr.
- /*virtual*/ void changed();
+ void displaySelectedParcelInfo(LLParcel* parcel,
+ LLViewerRegion* region,
+ const LLVector3d& pos_global);
void updateEstateName(const std::string& name);
void updateEstateOwnerName(const std::string& name);
@@ -135,7 +133,6 @@ private:
LLUUID mParcelID;
LLUUID mRequestedID;
LLUUID mLandmarkID;
- LLVector3 mPosRegion;
std::string mCurrentTitle;
S32 mMinHeight;
INFO_TYPE mInfoType;
@@ -186,8 +183,6 @@ private:
LLPanel* mScrollingPanel;
LLPanel* mInfoPanel;
LLMediaPanel* mMediaPanel;
-
- LLSafeHandle<LLParcelSelection> mParcel;
};
#endif // LL_LLPANELPLACEINFO_H
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index bc740bd865..11ddc3dd9a 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -31,10 +31,14 @@
#include "llviewerprecompiledheaders.h"
+#include "llpanelplaces.h"
+
#include "llassettype.h"
#include "llwindow.h"
+#include "llinventory.h"
#include "lllandmark.h"
+#include "llparcel.h"
#include "llfloaterreg.h"
#include "llnotifications.h"
@@ -44,10 +48,11 @@
#include "lluictrlfactory.h"
#include "llagent.h"
+#include "llfloaterworldmap.h"
+#include "llinventorymodel.h"
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
-#include "llfloaterworldmap.h"
-#include "llpanelplaces.h"
+#include "llpanelplaceinfo.h"
#include "llpanellandmarks.h"
#include "llpanelteleporthistory.h"
#include "llsidetray.h"
@@ -57,6 +62,7 @@
#include "llviewermenu.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
+#include "llviewerwindow.h"
static const S32 LANDMARK_FOLDERS_MENU_WIDTH = 250;
static const std::string AGENT_INFO_TYPE = "agent";
@@ -69,9 +75,41 @@ static const std::string TELEPORT_HISTORY_INFO_TYPE = "teleport_history";
static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
static std::string getFullFolderName(const LLViewerInventoryCategory* cat);
static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
-static const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global);
static void onSLURLBuilt(std::string& slurl);
+//Observer classes
+class LLPlacesParcelObserver : public LLParcelObserver
+{
+public:
+ LLPlacesParcelObserver(LLPanelPlaces* places_panel)
+ : mPlaces(places_panel) {}
+
+ /*virtual*/ void changed()
+ {
+ if (mPlaces)
+ mPlaces->changedParcelSelection();
+ }
+
+private:
+ LLPanelPlaces* mPlaces;
+};
+
+class LLPlacesInventoryObserver : public LLInventoryObserver
+{
+public:
+ LLPlacesInventoryObserver(LLPanelPlaces* places_panel)
+ : mPlaces(places_panel) {}
+
+ /*virtual*/ void changed(U32 mask)
+ {
+ if (mPlaces)
+ mPlaces->changedInventory(mask);
+ }
+
+private:
+ LLPanelPlaces* mPlaces;
+};
+
static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places");
LLPanelPlaces::LLPanelPlaces()
@@ -82,11 +120,14 @@ LLPanelPlaces::LLPanelPlaces()
mPlaceInfo(NULL),
mItem(NULL),
mPlaceMenu(NULL),
- mLandmarkMenu(NULL),
+ mLandmarkMenu(NULL),
mLandmarkFoldersMenuHandle(),
mPosGlobal()
{
- gInventory.addObserver(this);
+ mParcelObserver = new LLPlacesParcelObserver(this);
+ mInventoryObserver = new LLPlacesInventoryObserver(this);
+
+ gInventory.addObserver(mInventoryObserver);
LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(
boost::bind(&LLPanelPlaces::onAgentParcelChange, this));
@@ -96,10 +137,15 @@ LLPanelPlaces::LLPanelPlaces()
LLPanelPlaces::~LLPanelPlaces()
{
- if (gInventory.containsObserver(this))
- gInventory.removeObserver(this);
-
+ if (gInventory.containsObserver(mInventoryObserver))
+ gInventory.removeObserver(mInventoryObserver);
+
+ LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver);
+
LLView::deleteViewByHandle(mLandmarkFoldersMenuHandle);
+
+ delete mInventoryObserver;
+ delete mParcelObserver;
}
BOOL LLPanelPlaces::postBuild()
@@ -173,15 +219,10 @@ void LLPanelPlaces::onOpen(const LLSD& key)
if (mPlaceInfoType == AGENT_INFO_TYPE)
{
mPlaceInfo->setInfoType(LLPanelPlaceInfo::AGENT);
-
- mPosGlobal = gAgent.getPositionGlobal();
}
else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
{
mPlaceInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
- mPlaceInfo->displayAgentParcelInfo();
-
- mPosGlobal = gAgent.getPositionGlobal();
}
else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
{
@@ -189,7 +230,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
LLInventoryItem* item = gInventory.getItem(item_uuid);
if (!item)
return;
-
+
setItem(item);
}
else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
@@ -204,9 +245,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
key["z"].asReal());
mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE);
- mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal),
- LLUUID(),
- mPosGlobal);
+ mPlaceInfo->displayParcelInfo(LLUUID(), mPosGlobal);
}
else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
{
@@ -219,9 +258,30 @@ void LLPanelPlaces::onOpen(const LLSD& key)
mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
mPlaceInfo->updateLastVisitedText(hist_items[index].mDate);
- mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal),
- LLUUID(),
- mPosGlobal);
+ mPlaceInfo->displayParcelInfo(LLUUID(), mPosGlobal);
+ }
+
+ LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+ if (!parcel_mgr)
+ return;
+
+ // Start using LLViewerParcelMgr for land selection if
+ // information about nearby land is requested.
+ // Otherwise stop using land selection and deselect land.
+ if (mPlaceInfoType == AGENT_INFO_TYPE ||
+ mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
+ {
+ parcel_mgr->addObserver(mParcelObserver);
+ parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
+ }
+ else
+ {
+ parcel_mgr->removeObserver(mParcelObserver);
+
+ if (!parcel_mgr->selectionEmpty())
+ {
+ parcel_mgr->deselectLand();
+ }
}
}
@@ -259,9 +319,7 @@ void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark)
LLUUID region_id;
landmark->getRegionID(region_id);
landmark->getGlobalPos(mPosGlobal);
- mPlaceInfo->displayParcelInfo(landmark->getRegionPos(),
- region_id,
- mPosGlobal);
+ mPlaceInfo->displayParcelInfo(region_id, mPosGlobal);
}
void LLPanelPlaces::onFilterEdit(const std::string& search_string)
@@ -382,7 +440,7 @@ void LLPanelPlaces::onOverflowButtonClicked()
mPlaceInfoType == "teleport_history") && mPlaceMenu != NULL)
{
menu = mPlaceMenu;
-
+
// Enable adding a landmark only for agent current parcel and if
// there is no landmark already pointing to that parcel in agent's inventory.
menu->getChild<LLMenuItemCallGL>("landmark")->setEnabled(is_agent_place_info_visible &&
@@ -505,8 +563,40 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
}
}
-//virtual
-void LLPanelPlaces::changed(U32 mask)
+void LLPanelPlaces::changedParcelSelection()
+{
+ if (!mPlaceInfo)
+ return;
+
+ mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
+ LLParcel* parcel = mParcel->getParcel();
+ LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
+ if (!region || !parcel)
+ return;
+
+ // If agent is inside the selected parcel show agent's region<X, Y, Z>,
+ // otherwise show region<X, Y, Z> of agent's selection point.
+ if (region == gAgent.getRegion() &&
+ parcel->getLocalID() == LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID())
+ {
+ mPosGlobal = gAgent.getPositionGlobal();
+ }
+ else
+ {
+ LLVector3d pos_global = gViewerWindow->getLastPick().mPosGlobal;
+ if (!pos_global.isExactlyZero())
+ {
+ mPosGlobal = pos_global;
+ }
+ }
+
+ mPlaceInfo->resetLocation();
+ mPlaceInfo->displaySelectedParcelInfo(parcel, region, mPosGlobal);
+
+ updateVerbs();
+}
+
+void LLPanelPlaces::changedInventory(U32 mask)
{
if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance()))
return;
@@ -541,7 +631,7 @@ void LLPanelPlaces::changed(U32 mask)
// we don't need to monitor inventory changes anymore,
// so remove the observer
- gInventory.removeObserver(this);
+ gInventory.removeObserver(mInventoryObserver);
}
void LLPanelPlaces::onAgentParcelChange()
@@ -549,11 +639,7 @@ void LLPanelPlaces::onAgentParcelChange()
if (!mPlaceInfo)
return;
- if (mPlaceInfo->getVisible() && mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
- {
- onOpen(LLSD().insert("type", mPlaceInfoType));
- }
- else if (mPlaceInfo->isMediaPanelVisible())
+ if (mPlaceInfo->isMediaPanelVisible())
{
onOpen(LLSD().insert("type", AGENT_INFO_TYPE));
}
@@ -800,15 +886,6 @@ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
}
}
-static const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global)
-{
- F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
- F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
-
- LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]);
- return pos_local;
-}
-
static void onSLURLBuilt(std::string& slurl)
{
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl));
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 057c430230..54bc2b9003 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -32,33 +32,35 @@
#ifndef LL_LLPANELPLACES_H
#define LL_LLPANELPLACES_H
-#include "lltimer.h"
-
#include "llpanel.h"
-#include "llinventory.h"
-
-#include "llinventorymodel.h"
-#include "llpanelplaceinfo.h"
-
class LLInventoryItem;
+class LLFilterEditor;
class LLLandmark;
+class LLPanelPlaceInfo;
class LLPanelPlacesTab;
-class LLFilterEditor;
+class LLParcelSelection;
+class LLPlacesInventoryObserver;
+class LLPlacesParcelObserver;
class LLTabContainer;
+class LLToggleableMenu;
typedef std::pair<LLUUID, std::string> folder_pair_t;
-class LLPanelPlaces : public LLPanel, LLInventoryObserver
+class LLPanelPlaces : public LLPanel
{
public:
LLPanelPlaces();
virtual ~LLPanelPlaces();
/*virtual*/ BOOL postBuild();
- /*virtual*/ void changed(U32 mask);
/*virtual*/ void onOpen(const LLSD& key);
+ // Called on parcel selection change to update place information.
+ void changedParcelSelection();
+ // Called on agent inventory change to find out when inventory gets usable.
+ void changedInventory(U32 mask);
+
void setItem(LLInventoryItem* item);
private:
@@ -96,9 +98,12 @@ private:
LLButton* mShareBtn;
LLButton* mOverflowBtn;
+ LLPlacesInventoryObserver* mInventoryObserver;
+ LLPlacesParcelObserver* mParcelObserver;
+
// Pointer to a landmark item or to a linked landmark
LLPointer<LLInventoryItem> mItem;
-
+
// Absolute position of the location for teleport, may not
// be available (hence zero)
LLVector3d mPosGlobal;
@@ -118,11 +123,13 @@ private:
// List of folders to choose from when creating a landmark
folder_vec_t mLandmarkFoldersCache;
-
+
// If root view width or height is changed
// the pop-up menu must be updated
S32 mRootViewWidth;
S32 mRootViewHeight;
+
+ LLSafeHandle<LLParcelSelection> mParcel;
};
#endif //LL_LLPANELPLACES_H
diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
index 0c16cea004..04abe36878 100644
--- a/indra/newview/llrecentpeople.cpp
+++ b/indra/newview/llrecentpeople.cpp
@@ -43,7 +43,8 @@ bool LLRecentPeople::add(const LLUUID& id)
if (contains(id) || id == gAgent.getID())
return false;
- mList.insert(id);
+ LLDate date_added = LLDate::now();
+ mList.insert(std::make_pair(id, date_added));
mChangedSignal();
return true;
}
@@ -56,8 +57,8 @@ bool LLRecentPeople::contains(const LLUUID& id) const
void LLRecentPeople::get(std::vector<LLUUID>& result) const
{
result.clear();
- for (std::set<LLUUID>::const_iterator pos = mList.begin(); pos != mList.end(); ++pos)
- result.push_back(*pos);
+ for (recent_people_t::const_iterator pos = mList.begin(); pos != mList.end(); ++pos)
+ result.push_back((*pos).first);
}
// virtual
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index 40ac80e8bc..c18116b4e5 100644
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
@@ -41,6 +41,8 @@
#include <set>
#include <boost/signals2.hpp>
+class LLDate;
+
/**
* List of people the agent recently interacted with.
*
@@ -62,7 +64,7 @@ public:
* Add specified avatar to the list if it's not there already.
*
* @param id avatar to add.
- * @return false if the avatar is in the list already, true otherwisr
+ * @return false if the avatar is in the list already, true otherwise
*/
bool add(const LLUUID& id);
@@ -94,7 +96,8 @@ public:
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
private:
- std::set<LLUUID> mList;
+ typedef std::map<LLUUID, LLDate> recent_people_t;
+ recent_people_t mList;
signal_t mChangedSignal;
};
diff --git a/indra/newview/llsearchcombobox.cpp b/indra/newview/llsearchcombobox.cpp
index 33efae50ae..0b7621daa5 100644
--- a/indra/newview/llsearchcombobox.cpp
+++ b/indra/newview/llsearchcombobox.cpp
@@ -83,6 +83,7 @@ LLSearchComboBox::LLSearchComboBox(const Params&p)
mTextEntry->setKeystrokeCallback(boost::bind(&LLComboBox::onTextEntry, this, _1), NULL);
setSelectionCallback(boost::bind(&LLSearchComboBox::onSelectionCommit, this));
setPrearrangeCallback(boost::bind(&LLSearchComboBox::onSearchPrearrange, this, _2));
+ mSearchButton->setCommitCallback(boost::bind(&LLSearchComboBox::onTextCommit, this, _2));
}
void LLSearchComboBox::rebuildSearchHistory(const std::string& filter)
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index 913e46e05e..15d54d8b3b 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -55,6 +55,7 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
mUserName->setValue(p.from);
mTime->setValue(p.time);
mSessionID = p.session_id;
+ mNotification = p.notification;
mReplyBtn->setClickedCallback(boost::bind(&LLToastIMPanel::onClickReplyBtn, this));
@@ -75,7 +76,9 @@ LLToastIMPanel::~LLToastIMPanel()
//--------------------------------------------------------------------------
void LLToastIMPanel::onClickReplyBtn()
{
- LLIMFloater::toggle(mSessionID);
+ LLSD response = mNotification->getResponseTemplate();
+ response["respondbutton"] = true;
+ mNotification->respond(response);
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index 11f489c12f..b51ce23364 100644
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -63,6 +63,7 @@ private:
void onClickReplyBtn();
+ LLNotificationPtr mNotification;
LLUUID mSessionID;
LLAvatarIconCtrl* mAvatar;
LLTextBox* mUserName;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ac3defef01..12d5687877 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -100,7 +100,6 @@
#include "llfloaterdirectory.h"
#include "llfloaterchatterbox.h"
#include "llfloaterfonttest.h"
-#include "llfloatergesture.h"
#include "llfloatergodtools.h"
#include "llfloatergroupinvite.h"
#include "llfloatergroups.h"
@@ -183,7 +182,6 @@
#include "lluuid.h"
#include "llviewercamera.h"
#include "llviewergenericmessage.h"
-#include "llviewergesture.h"
#include "llviewertexturelist.h" // gTextureList
#include "llviewerinventory.h"
#include "llviewermenufile.h" // init_menu_file()
@@ -210,6 +208,7 @@
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llfloaternotificationsconsole.h"
+#include "llfloatercamera.h"
#include "lltexlayer.h"
#include "llappearancemgr.h"
@@ -3768,6 +3767,7 @@ void handle_reset_view()
else
{
reset_view_final( TRUE );
+ LLFloaterCamera::resetCameraMode();
}
}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index e5d0e3ebb2..f7fbe96aa7 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2364,7 +2364,7 @@ void LLViewerWindow::updateUI()
updateWorldViewRect();
- //updateBottomTrayRect();
+ updateBottomTrayRect();
LLView::sMouseHandlerMessage.clear();
diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml
index 37c6cbf391..e94ca1b30b 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory.xml
@@ -25,6 +25,8 @@
Fetched
</floater.string>
<filter_editor
+ search_button_visible="false"
+ text_pad_left="12"
follows="left|top|right"
height="16"
label="Type here to search"
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 d76ea398d5..76b2e5c811 100644
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -1,9 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater
- background_opaque="false"
- background_visible="true"
bevel_style="in"
- bg_alpha_color="0.0 0.0 0.0 0.0"
left="0"
top="0"
follows="right|bottom"
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index 3de3365539..f211ae0ad6 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -1,65 +1,89 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- All our XML is utf-8 encoded. -->
-
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- name="avatar_list_item"
- title="avatar_list_item"
- visible="true"
- width="314"
- height="30"
- left="0"
- top="100"
- follows="bottom|right|left"
- min_width="150"
- max_height="30"
-
- background_opaque="false"
- background_visible="true"
- bevel_style="in"
- bg_alpha_color="0.3 0.3 0.3 1.0">
-
- <avatar_icon
- bottom="5" left="5" width="20" height="20" follows="top|left"
- color="1 1 1 1" enabled="true" image_name="smile.png"
- mouse_opaque="true" name="avatar_icon"
- />
-
- <text
- bottom="4" left="35" width="160" height="20" follows="right|left"
- font="SansSerifBigBold" text_color="white"
- mouse_opaque="true" name="user_name" >
- Boris Linden
- </text>
-
- <text
- bottom="3" left="190" width="40" height="20" follows="right"
- font="SansSerif" text_color="0.5 0.5 0.5 1.0"
- mouse_opaque="true" name="user_status" >
- Away
- </text>
-
- <icon
- bottom="5" left="230" width="20" height="20" follows="right"
- color="1 1 1 1" enabled="true" image_name="speaking_indicator.tga"
- mouse_opaque="true" name="locator"
- />
-
- <button
- bottom="5" left="260" width="20" height="20" follows="right"
- name="info_btn" label=""
- image_unselected="avatar_info_btn.tga" image_disabled="avatar_info_btn.tga"
- image_selected="avatar_info_btn_active.tga" image_hover_selected="avatar_info_btn_active.tga"
- image_disabled_selected="avatar_info_btn.tga" font="SansSerifBigBold"
- />
-
- <button
- bottom="5" left="290" width="20" height="20" follows="right"
- name="profile_btn" label=""
- image_unselected="profile_chevron_btn.tga" image_disabled="profile_chevron_btn.tga"
- image_selected="profile_chevron_btn_active.tga" image_hover_selected="profile_chevron_btn_active.tga"
- image_disabled_selected="profile_chevron_btn.tga" font="SansSerifBigBold"
- />
-
-
-
-</panel>
+ follows="top|right|left"
+ height="24"
+ layout="topleft"
+ left="0"
+ name="avatar_list_item"
+ top="0"
+ width="320">
+ <icon
+ follows="top|right|left"
+ height="24"
+ image_name="ListItem_Over"
+ layout="topleft"
+ left="0"
+ name="hovered_icon"
+ top="0"
+ visible="false"
+ width="320" />
+ <icon
+ height="24"
+ follows="top|right|left"
+ image_name="ListItem_Select"
+ layout="topleft"
+ left="0"
+ name="selected_icon"
+ top="0"
+ visible="false"
+ width="320" />
+ <avatar_icon
+ follows="top|left"
+ height="20"
+ image_name="smile.png"
+ layout="topleft"
+ left="5"
+ mouse_opaque="true"
+ top="2"
+ width="20" />
+ <text
+ follows="left|right"
+ font="SansSerifBigBold"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ name="avatar_name"
+ text_color="white"
+ top="4"
+ use_ellipses="true"
+ value="Unknown"
+ width="180" />
+ <text
+ follows="right"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ name="avatar_status"
+ text_color="0.5 0.5 0.5 1"
+ value="Away"
+ width="50" />
+ <output_monitor
+ auto_update="true"
+ follows="right"
+ draw_border="false"
+ halign="left"
+ height="16"
+ layout="topleft"
+ left_pad="3"
+ mouse_opaque="true"
+ name="speaking_indicator"
+ top="4"
+ visible="true"
+ width="20" />
+ <button
+ follows="right"
+ font="SansSerifBigBold"
+ height="18"
+ image_disabled="Info"
+ image_disabled_selected="Info"
+ image_hover_selected="Info"
+ image_selected="Info"
+ image_unselected="Info"
+ layout="topleft"
+ left_pad="2"
+ name="info_btn"
+ picture_style="true"
+ top="2"
+ width="18" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 9ae165cbb9..7b8bd8b337 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -185,7 +185,7 @@
Select multiple Members by holding the Ctrl key and
clicking on their names.
</panel.string>
- <search_editor
+ <filter_editor
layout="topleft"
top="10"
left="4"
@@ -193,17 +193,9 @@ clicking on their names.
height="20"
follows="left|top|right"
max_length="250"
- label="Filter People"
+ label="Filter Members"
name="filter_input"
- font="SansSerif"
- background_image="TextField_Search_Off"
- text_pad_left="10"
- text_color="black">
- <search_button label=""
- top_pad="4"
- left_pad="6"
- />
- </search_editor>
+ font="SansSerif" />
<!--<line_editor
border_style="line"
border_thickness="1"
@@ -318,7 +310,7 @@ including the Everyone and Owner Roles.
name="power_partial_icon">
checkbox_enabled_false.tga
</panel.string>
- <search_editor
+ <filter_editor
layout="topleft"
top="10"
left="4"
@@ -328,15 +320,7 @@ including the Everyone and Owner Roles.
max_length="250"
label="Filter Roles"
name="filter_input"
- font="SansSerif"
- background_image="TextField_Search_Off"
- text_pad_left="10"
- text_color="black">
- <search_button label=""
- top_pad="4"
- left_pad="6"
- />
- </search_editor>
+ font="SansSerif" />
<!--<line_editor
border_style="line"
border_thickness="1"
@@ -426,7 +410,7 @@ including the Everyone and Owner Roles.
Abilities allow Members in Roles to do specific
things in this group. There&apos;s a broad variety of Abilities.
</panel.string>
- <search_editor
+ <filter_editor
layout="topleft"
top="10"
left="4"
@@ -436,15 +420,7 @@ things in this group. There&apos;s a broad variety of Abilities.
max_length="250"
label="Filter Abilities"
name="filter_input"
- font="SansSerif"
- background_image="TextField_Search_Off"
- text_pad_left="10"
- text_color="black">
- <search_button label=""
- top_pad="4"
- left_pad="6"
- />
- </search_editor>
+ font="SansSerif" />
<!--<line_editor
border_style="line"
border_thickness="1"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 0af42bfc74..3642b0fec1 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -31,7 +31,6 @@
name="groups_filter_label"
value="Filter Groups" />
<filter_editor
- background_image="TextField_Search_Off"
follows="left|top|right"
font="SansSerif"
height="23"
@@ -40,21 +39,8 @@
max_length="270"
name="filter_input"
text_color="black"
- text_pad_left="26"
top="3"
width="256" />
- <button
- follows="left|top|right"
- height="13"
- image_selected="Search"
- image_unselected="Search"
- layout="topleft"
- left="20"
- name="people_search"
- picture_style="true"
- scale_image="false"
- top="8"
- width="13" />
<tab_container
follows="left|top|right|bottom"
height="326"
@@ -303,7 +289,8 @@
layout="topleft"
name="recent_panel"
width="285">
- <avatar_list
+ <avatar_list_tmp
+ color="DkGray2"
follows="left|top|right|bottom"
height="357"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index bff28718a7..b379ad2276 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -16,7 +16,6 @@
name="teleport_history_tab_title"
value="Teleport History" />
<filter_editor
- background_image="TextField_Search_Off"
follows="left|top|right"
font="SansSerif"
height="23"
@@ -24,22 +23,8 @@
layout="topleft"
left="15"
name="Filter"
- text_color="black"
- text_pad_left="26"
top="3"
width="256" />
- <button
- follows="left|top|right"
- height="13"
- image_selected="Search"
- image_unselected="Search"
- layout="topleft"
- left="20"
- name="landmark_search"
- picture_style="true"
- scale_image="false"
- top="8"
- width="13" />
<tab_container
follows="all"
height="326"
diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml
index 441caffa28..01fd84e09d 100644
--- a/indra/newview/skins/default/xui/en/panel_toast.xml
+++ b/indra/newview/skins/default/xui/en/panel_toast.xml
@@ -11,8 +11,6 @@
left="100"
top="500"
follows="right|bottom"
- background_opaque="true"
- background_visible="true"
bevel_style="in"
can_minimize="false"
can_tear_off="false"
@@ -20,7 +18,7 @@
can_drag_on_left="false"
can_close="false"
can_dock="false"
- bg_alpha_color="0.3 0.3 0.3 1.0">
+ >
<text
visible="false"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index faed615bdd..4206b87c2b 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -1818,6 +1818,7 @@ this texture in your inventory
<string name="AnimFlagStart" value=" Start Animation : " />
<string name="Wave" value=" Wave " />
<string name="HelloAvatar" value=" Hello, avatar! " />
+ <string name="ViewAllGestures" value=" View All >>" />
<!-- inventory filter -->
<!-- use value="" because they have preceding spaces -->
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
index a34b005448..ada258fbec 100644
--- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
@@ -1,8 +1,20 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<filter_editor select_on_focus="true"
- background_image_disabled="TextField_Search_Disabled"
- background_image_focused="TextField_Search_Active">
- <clear_filter_button label=""
- image_unselected="Icon_Close_Foreground"
- image_selected="Icon_Close_Press" />
+<filter_editor
+ clear_button_visible="true"
+ search_button_visible="true"
+ text_pad_left="4"
+ select_on_focus="true"
+ background_image="TextField_Search_Off"
+ background_image_disabled="TextField_Search_Disabled"
+ background_image_focused="TextField_Search_Active" >
+ <search_button label=""
+ top_pad="4"
+ left_pad="4"
+ width="13"
+ height="13"
+ image_unselected="Search"
+ image_selected="Search" />
+ <clear_button label=""
+ image_unselected="Icon_Close_Foreground"
+ image_selected="Icon_Close_Press" />
</filter_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
new file mode 100644
index 0000000000..24d072a573
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<flat_list_view
+ allow_select="true"
+ item_pad="5"
+ keep_one_selected="true"
+ multi_select="false"
+ opaque="true" /> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
index 8643f919ec..f482ff3b89 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<search_editor
clear_button_visible="false"
+ search_button_visible="true"
text_pad_left="4"
select_on_focus="true"
background_image="TextField_Search_Off"
@@ -13,7 +14,7 @@
height="13"
image_unselected="Search"
image_selected="Search" />
- <clear_button label=""
+ <clear_button label=""
image_unselected="Icon_Close_Foreground"
image_selected="Icon_Close_Press" />
</search_editor>