diff options
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'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'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> |