diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/newview/llinventoryitemslist.cpp | 337 | ||||
-rw-r--r-- | indra/newview/llinventoryitemslist.h | 180 | ||||
-rw-r--r-- | indra/newview/llinventorylistitem.cpp | 388 | ||||
-rw-r--r-- | indra/newview/llinventorylistitem.h | 235 | ||||
-rw-r--r-- | indra/newview/llwearableitemslist.cpp | 20 | ||||
-rw-r--r-- | indra/newview/llwearableitemslist.h | 8 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml | 18 |
8 files changed, 659 insertions, 529 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 24811db3cb..c1b2d680be 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -260,6 +260,7 @@ set(viewer_SOURCE_FILES llinventoryfunctions.cpp llinventoryicon.cpp llinventoryitemslist.cpp + llinventorylistitem.cpp llinventorymodel.cpp llinventorymodelbackgroundfetch.cpp llinventoryobserver.cpp @@ -783,6 +784,7 @@ set(viewer_HEADER_FILES llinventoryfunctions.h llinventoryicon.h llinventoryitemslist.h + llinventorylistitem.h llinventorymodel.h llinventorymodelbackgroundfetch.h llinventoryobserver.h diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index 14de5442d6..fbb3774917 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -3,8 +3,6 @@ * @brief A list of inventory items represented by LLFlatListView. * * Class LLInventoryItemsList implements a flat list of inventory items. - * Class LLPanelInventoryListItem displays inventory item as an element - * of LLInventoryItemsList. * * $LicenseInfo:firstyear=2010&license=viewergpl$ * @@ -40,341 +38,12 @@ // llcommon #include "llcommonutils.h" -// llui -#include "lliconctrl.h" -#include "lltextutil.h" +#include "lltrans.h" #include "llcallbacklist.h" -#include "llinventoryfunctions.h" +#include "llinventorylistitem.h" #include "llinventorymodel.h" -#include "lltrans.h" - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -static const S32 WIDGET_SPACING = 3; - -LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInventoryItem* item) -{ - LLPanelInventoryListItemBase* list_item = NULL; - if (item) - { - list_item = new LLPanelInventoryListItemBase(item); - list_item->init(); - } - return list_item; -} - -void LLPanelInventoryListItemBase::draw() -{ - if (getNeedsRefresh()) - { - if (mItem) - { - updateItem(mItem->getName()); - } - setNeedsRefresh(false); - } - LLPanel::draw(); -} - -// virtual -void LLPanelInventoryListItemBase::updateItem(const std::string& name, - const LLStyle::Params& input_params) -{ - setIconImage(mIconImage); - setTitle(name, mHighlightedText, input_params); -} - -void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/) -{ - LLUICtrl* ctrl = findChild<LLUICtrl>(name); - if(ctrl) - { - addWidgetToLeftSide(ctrl, show_widget); - } -} - -void LLPanelInventoryListItemBase::addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget/* = true*/) -{ - mLeftSideWidgets.push_back(ctrl); - setShowWidget(ctrl, show_widget); -} - -void LLPanelInventoryListItemBase::addWidgetToRightSide(const std::string& name, bool show_widget/* = true*/) -{ - LLUICtrl* ctrl = findChild<LLUICtrl>(name); - if(ctrl) - { - addWidgetToRightSide(ctrl, show_widget); - } -} - -void LLPanelInventoryListItemBase::addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget/* = true*/) -{ - mRightSideWidgets.push_back(ctrl); - setShowWidget(ctrl, show_widget); -} - -void LLPanelInventoryListItemBase::setShowWidget(const std::string& name, bool show) -{ - LLUICtrl* widget = findChild<LLUICtrl>(name); - if(widget) - { - setShowWidget(widget, show); - } -} - -void LLPanelInventoryListItemBase::setShowWidget(LLUICtrl* ctrl, bool show) -{ - // Enable state determines whether widget may become visible in setWidgetsVisible() - ctrl->setEnabled(show); -} - -BOOL LLPanelInventoryListItemBase::postBuild() -{ - setIconCtrl(getChild<LLIconCtrl>("item_icon")); - setTitleCtrl(getChild<LLTextBox>("item_name")); - - if (mItem) - { - mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE); - updateItem(mItem->getName()); - } - - setNeedsRefresh(true); - - setWidgetsVisible(false); - reshapeWidgets(); - - return TRUE; -} - -void LLPanelInventoryListItemBase::setValue(const LLSD& value) -{ - if (!value.isMap()) return; - if (!value.has("selected")) return; - childSetVisible("selected_icon", value["selected"]); -} - -void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask) -{ - childSetVisible("hovered_icon", true); - LLPanel::onMouseEnter(x, y, mask); -} - -void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask) -{ - childSetVisible("hovered_icon", false); - LLPanel::onMouseLeave(x, y, mask); -} - -const std::string& LLPanelInventoryListItemBase::getItemName() const -{ - if (!mItem) - { - return LLStringUtil::null; - } - return mItem->getName(); -} - -LLAssetType::EType LLPanelInventoryListItemBase::getType() const -{ - if (!mItem) - { - return LLAssetType::AT_NONE; - } - return mItem->getType(); -} - -LLWearableType::EType LLPanelInventoryListItemBase::getWearableType() const -{ - if (!mItem) - { - return LLWearableType::WT_NONE; - } - return mItem->getWearableType(); -} - -const std::string& LLPanelInventoryListItemBase::getDescription() const -{ - if (!mItem) - { - return LLStringUtil::null; - } - return mItem->getDescription(); -} - -S32 LLPanelInventoryListItemBase::notify(const LLSD& info) -{ - S32 rv = 0; - if(info.has("match_filter")) - { - mHighlightedText = info["match_filter"].asString(); - - std::string test(mTitleCtrl->getText()); - LLStringUtil::toUpper(test); - - if(mHighlightedText.empty() || std::string::npos != test.find(mHighlightedText)) - { - rv = 0; // substring is found - } - else - { - rv = -1; - } - - setNeedsRefresh(true); - } - else - { - rv = LLPanel::notify(info); - } - return rv; -} - -LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item) -: LLPanel() -, mItem(item) -, mIconCtrl(NULL) -, mTitleCtrl(NULL) -, mWidgetSpacing(WIDGET_SPACING) -, mLeftWidgetsWidth(0) -, mRightWidgetsWidth(0) -, mNeedsRefresh(false) -{ -} - -void LLPanelInventoryListItemBase::init() -{ - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml"); -} - -class WidgetVisibilityChanger -{ -public: - WidgetVisibilityChanger(bool visible) : mVisible(visible){} - void operator()(LLUICtrl* widget) - { - // Disabled widgets never become visible. see LLPanelInventoryListItemBase::setShowWidget() - widget->setVisible(mVisible && widget->getEnabled()); - } -private: - bool mVisible; -}; - -void LLPanelInventoryListItemBase::setWidgetsVisible(bool visible) -{ - std::for_each(mLeftSideWidgets.begin(), mLeftSideWidgets.end(), WidgetVisibilityChanger(visible)); - std::for_each(mRightSideWidgets.begin(), mRightSideWidgets.end(), WidgetVisibilityChanger(visible)); -} - -void LLPanelInventoryListItemBase::reshapeWidgets() -{ - // disabled reshape left for now to reserve space for 'delete' button in LLPanelClothingListItem - /*reshapeLeftWidgets();*/ - reshapeRightWidgets(); - reshapeMiddleWidgets(); -} - -void LLPanelInventoryListItemBase::setIconImage(const LLUIImagePtr& image) -{ - if(image) - { - mIconImage = image; - mIconCtrl->setImage(mIconImage); - } -} - -void LLPanelInventoryListItemBase::setTitle(const std::string& title, - const std::string& highlit_text, - const LLStyle::Params& input_params) -{ - mTitleCtrl->setToolTip(title); - - LLTextUtil::textboxSetHighlightedVal( - mTitleCtrl, - input_params, - title, - highlit_text); -} - -BOOL LLPanelInventoryListItemBase::handleToolTip( S32 x, S32 y, MASK mask) -{ - LLRect text_box_rect = mTitleCtrl->getRect(); - if (text_box_rect.pointInRect(x, y) && - mTitleCtrl->getTextPixelWidth() <= text_box_rect.getWidth()) - { - return FALSE; - } - return LLPanel::handleToolTip(x, y, mask); -} - -void LLPanelInventoryListItemBase::reshapeLeftWidgets() -{ - S32 widget_left = 0; - mLeftWidgetsWidth = 0; - - widget_array_t::const_iterator it = mLeftSideWidgets.begin(); - const widget_array_t::const_iterator it_end = mLeftSideWidgets.end(); - for( ; it_end != it; ++it) - { - LLUICtrl* widget = *it; - if(!widget->getVisible()) - { - continue; - } - LLRect widget_rect(widget->getRect()); - widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight()); - widget->setShape(widget_rect); - - widget_left += widget_rect.getWidth() + getWidgetSpacing(); - mLeftWidgetsWidth = widget_rect.mRight; - } -} - -void LLPanelInventoryListItemBase::reshapeRightWidgets() -{ - S32 widget_right = getLocalRect().getWidth(); - S32 widget_left = widget_right; - - widget_array_t::const_reverse_iterator it = mRightSideWidgets.rbegin(); - const widget_array_t::const_reverse_iterator it_end = mRightSideWidgets.rend(); - for( ; it_end != it; ++it) - { - LLUICtrl* widget = *it; - if(!widget->getVisible()) - { - continue; - } - LLRect widget_rect(widget->getRect()); - widget_left = widget_right - widget_rect.getWidth(); - widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight()); - widget->setShape(widget_rect); - - widget_right = widget_left - getWidgetSpacing(); - } - mRightWidgetsWidth = getLocalRect().getWidth() - widget_left; -} - -void LLPanelInventoryListItemBase::reshapeMiddleWidgets() -{ - LLRect icon_rect(mIconCtrl->getRect()); - icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop, - icon_rect.getWidth(), icon_rect.getHeight()); - mIconCtrl->setShape(icon_rect); - - S32 name_left = icon_rect.mRight + getWidgetSpacing(); - S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing(); - LLRect name_rect(mTitleCtrl->getRect()); - name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom); - mTitleCtrl->setShape(name_rect); -} - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// +#include "llviewerinventory.h" LLInventoryItemsList::Params::Params() {} diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 5dc0bfe3de..71c7b6a675 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -3,8 +3,6 @@ * @brief A list of inventory items represented by LLFlatListView. * * Class LLInventoryItemsList implements a flat list of inventory items. - * Class LLPanelInventoryListItem displays inventory item as an element - * of LLInventoryItemsList. * * $LicenseInfo:firstyear=2010&license=viewergpl$ * @@ -38,189 +36,11 @@ #include "lldarray.h" -#include "llpanel.h" - // newview #include "llflatlistview.h" -#include "llviewerinventory.h" -class LLIconCtrl; -class LLTextBox; class LLViewerInventoryItem; -/** - * @class LLPanelInventoryListItemBase - * - * Base class for Inventory flat list item. Panel consists of inventory icon - * and inventory item name. - * This class is able to display widgets(buttons) on left(before icon) and right(after text-box) sides - * of panel. - * - * How to use (see LLPanelClothingListItem for example): - * - implement init() to build panel from xml - * - create new xml file, fill it with widgets you want to dynamically show/hide/reshape on left/right sides - * - redefine postBuild()(call base implementation) and add needed widgets to needed sides, - * - */ -class LLPanelInventoryListItemBase : public LLPanel -{ -public: - static LLPanelInventoryListItemBase* create(LLViewerInventoryItem* item); - - virtual void draw(); - - /** - * Let item know it need to be refreshed in next draw() - */ - void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; } - - bool getNeedsRefresh(){ return mNeedsRefresh; } - - /** - * Add widget to left side - */ - void addWidgetToLeftSide(const std::string& name, bool show_widget = true); - void addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget = true); - - /** - * Add widget to right side, widget is supposed to be child of calling panel - */ - void addWidgetToRightSide(const std::string& name, bool show_widget = true); - void addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget = true); - - /** - * Mark widgets as visible. Only visible widgets take part in reshaping children - */ - void setShowWidget(const std::string& name, bool show); - void setShowWidget(LLUICtrl* ctrl, bool show); - - /** - * Set spacing between widgets during reshape - */ - void setWidgetSpacing(S32 spacing) { mWidgetSpacing = spacing; } - - S32 getWidgetSpacing() { return mWidgetSpacing; } - - /** - * Inheritors need to call base implementation of postBuild() - */ - /*virtual*/ BOOL postBuild(); - - /** - * Handles item selection - */ - /*virtual*/ void setValue(const LLSD& value); - - /** - * Handles filter request - */ - /*virtual*/ S32 notify(const LLSD& info); - - /* Highlights item */ - /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); - /* Removes item highlight */ - /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); - - /** Get the name of a corresponding inventory item */ - const std::string& getItemName() const; - - /** Get the asset type of a corresponding inventory item */ - LLAssetType::EType getType() const; - - /** Get the wearable type of a corresponding inventory item */ - LLWearableType::EType getWearableType() const; - - /** Get the description of a corresponding inventory item */ - const std::string& getDescription() const; - - /** Get the associated inventory item */ - LLViewerInventoryItem* getItem() const { return mItem; } - - virtual ~LLPanelInventoryListItemBase(){} - -protected: - - LLPanelInventoryListItemBase(LLViewerInventoryItem* item); - - typedef std::vector<LLUICtrl*> widget_array_t; - - /** - * Use it from a factory function to build panel, do not build panel in constructor - */ - virtual void init(); - - /** - * Called after inventory item was updated, update panel widgets to reflect inventory changes. - */ - virtual void updateItem(const std::string& name, - const LLStyle::Params& input_params = LLStyle::Params()); - - /** setter for mIconCtrl */ - void setIconCtrl(LLIconCtrl* icon) { mIconCtrl = icon; } - /** setter for MTitleCtrl */ - void setTitleCtrl(LLTextBox* tb) { mTitleCtrl = tb; } - - void setLeftWidgetsWidth(S32 width) { mLeftWidgetsWidth = width; } - void setRightWidgetsWidth(S32 width) { mRightWidgetsWidth = width; } - - /** - * Set all widgets from both side visible/invisible. Only enabled widgets - * (see setShowWidget()) can become visible - */ - virtual void setWidgetsVisible(bool visible); - - /** - * Reshape all child widgets - icon, text-box and side widgets - */ - virtual void reshapeWidgets(); - - /** set wearable type icon image */ - void setIconImage(const LLUIImagePtr& image); - - /** Set item title - inventory item name usually */ - virtual void setTitle(const std::string& title, - const std::string& highlit_text, - const LLStyle::Params& input_params = LLStyle::Params()); - - /** - * Show tool tip if item name text size > panel size - */ - virtual BOOL handleToolTip( S32 x, S32 y, MASK mask); - - LLViewerInventoryItem* mItem; - -private: - - /** reshape left side widgets - * Deprecated for now. Disabled reshape left for now to reserve space for 'delete' - * button in LLPanelClothingListItem according to Neal's comment (https://codereview.productengine.com/secondlife/r/325/) - */ - void reshapeLeftWidgets(); - - /** reshape right side widgets */ - void reshapeRightWidgets(); - - /** reshape remaining widgets */ - void reshapeMiddleWidgets(); - - - LLIconCtrl* mIconCtrl; - LLTextBox* mTitleCtrl; - - LLUIImagePtr mIconImage; - std::string mHighlightedText; - - widget_array_t mLeftSideWidgets; - widget_array_t mRightSideWidgets; - S32 mWidgetSpacing; - - S32 mLeftWidgetsWidth; - S32 mRightWidgetsWidth; - bool mNeedsRefresh; -}; - -////////////////////////////////////////////////////////////////////////// - class LLInventoryItemsList : public LLFlatListViewEx { public: diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp new file mode 100644 index 0000000000..18b6de77e2 --- /dev/null +++ b/indra/newview/llinventorylistitem.cpp @@ -0,0 +1,388 @@ +/** + * @file llinventorylistitem.cpp + * @brief Inventory list item panel. + * + * Class LLPanelInventoryListItemBase displays inventory item as an element + * of LLInventoryItemsList. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llinventorylistitem.h" + +// llui +#include "lliconctrl.h" +#include "lltextbox.h" +#include "lltextutil.h" + +// newview +#include "llviewerinventory.h" + +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(&typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item"); + +static const S32 WIDGET_SPACING = 3; + +LLPanelInventoryListItemBase::Params::Params() +: default_style("default_style"), + worn_style("worn_style") +{}; + +LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInventoryItem* item) +{ + LLPanelInventoryListItemBase* list_item = NULL; + if (item) + { + list_item = new LLPanelInventoryListItemBase(item); + list_item->init(); + } + return list_item; +} + +void LLPanelInventoryListItemBase::draw() +{ + if (getNeedsRefresh()) + { + if (mItem) + { + updateItem(mItem->getName()); + } + setNeedsRefresh(false); + } + LLPanel::draw(); +} + +// virtual +void LLPanelInventoryListItemBase::updateItem(const std::string& name, + EItemState item_state) +{ + setIconImage(mIconImage); + setTitle(name, mHighlightedText, item_state); +} + +void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/) +{ + LLUICtrl* ctrl = findChild<LLUICtrl>(name); + if(ctrl) + { + addWidgetToLeftSide(ctrl, show_widget); + } +} + +void LLPanelInventoryListItemBase::addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget/* = true*/) +{ + mLeftSideWidgets.push_back(ctrl); + setShowWidget(ctrl, show_widget); +} + +void LLPanelInventoryListItemBase::addWidgetToRightSide(const std::string& name, bool show_widget/* = true*/) +{ + LLUICtrl* ctrl = findChild<LLUICtrl>(name); + if(ctrl) + { + addWidgetToRightSide(ctrl, show_widget); + } +} + +void LLPanelInventoryListItemBase::addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget/* = true*/) +{ + mRightSideWidgets.push_back(ctrl); + setShowWidget(ctrl, show_widget); +} + +void LLPanelInventoryListItemBase::setShowWidget(const std::string& name, bool show) +{ + LLUICtrl* widget = findChild<LLUICtrl>(name); + if(widget) + { + setShowWidget(widget, show); + } +} + +void LLPanelInventoryListItemBase::setShowWidget(LLUICtrl* ctrl, bool show) +{ + // Enable state determines whether widget may become visible in setWidgetsVisible() + ctrl->setEnabled(show); +} + +BOOL LLPanelInventoryListItemBase::postBuild() +{ + setIconCtrl(getChild<LLIconCtrl>("item_icon")); + setTitleCtrl(getChild<LLTextBox>("item_name")); + + if (mItem) + { + mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE); + updateItem(mItem->getName()); + } + + setNeedsRefresh(true); + + setWidgetsVisible(false); + reshapeWidgets(); + + return TRUE; +} + +void LLPanelInventoryListItemBase::setValue(const LLSD& value) +{ + if (!value.isMap()) return; + if (!value.has("selected")) return; + childSetVisible("selected_icon", value["selected"]); +} + +void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask) +{ + childSetVisible("hovered_icon", true); + LLPanel::onMouseEnter(x, y, mask); +} + +void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask) +{ + childSetVisible("hovered_icon", false); + LLPanel::onMouseLeave(x, y, mask); +} + +const std::string& LLPanelInventoryListItemBase::getItemName() const +{ + if (!mItem) + { + return LLStringUtil::null; + } + return mItem->getName(); +} + +LLAssetType::EType LLPanelInventoryListItemBase::getType() const +{ + if (!mItem) + { + return LLAssetType::AT_NONE; + } + return mItem->getType(); +} + +LLWearableType::EType LLPanelInventoryListItemBase::getWearableType() const +{ + if (!mItem) + { + return LLWearableType::WT_NONE; + } + return mItem->getWearableType(); +} + +const std::string& LLPanelInventoryListItemBase::getDescription() const +{ + if (!mItem) + { + return LLStringUtil::null; + } + return mItem->getDescription(); +} + +S32 LLPanelInventoryListItemBase::notify(const LLSD& info) +{ + S32 rv = 0; + if(info.has("match_filter")) + { + mHighlightedText = info["match_filter"].asString(); + + std::string test(mTitleCtrl->getText()); + LLStringUtil::toUpper(test); + + if(mHighlightedText.empty() || std::string::npos != test.find(mHighlightedText)) + { + rv = 0; // substring is found + } + else + { + rv = -1; + } + + setNeedsRefresh(true); + } + else + { + rv = LLPanel::notify(info); + } + return rv; +} + +LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item) +: LLPanel() +, mItem(item) +, mIconCtrl(NULL) +, mTitleCtrl(NULL) +, mWidgetSpacing(WIDGET_SPACING) +, mLeftWidgetsWidth(0) +, mRightWidgetsWidth(0) +, mNeedsRefresh(false) +{ +} + +void LLPanelInventoryListItemBase::init() +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml"); +} + +class WidgetVisibilityChanger +{ +public: + WidgetVisibilityChanger(bool visible) : mVisible(visible){} + void operator()(LLUICtrl* widget) + { + // Disabled widgets never become visible. see LLPanelInventoryListItemBase::setShowWidget() + widget->setVisible(mVisible && widget->getEnabled()); + } +private: + bool mVisible; +}; + +void LLPanelInventoryListItemBase::setWidgetsVisible(bool visible) +{ + std::for_each(mLeftSideWidgets.begin(), mLeftSideWidgets.end(), WidgetVisibilityChanger(visible)); + std::for_each(mRightSideWidgets.begin(), mRightSideWidgets.end(), WidgetVisibilityChanger(visible)); +} + +void LLPanelInventoryListItemBase::reshapeWidgets() +{ + // disabled reshape left for now to reserve space for 'delete' button in LLPanelClothingListItem + /*reshapeLeftWidgets();*/ + reshapeRightWidgets(); + reshapeMiddleWidgets(); +} + +void LLPanelInventoryListItemBase::setIconImage(const LLUIImagePtr& image) +{ + if(image) + { + mIconImage = image; + mIconCtrl->setImage(mIconImage); + } +} + +void LLPanelInventoryListItemBase::setTitle(const std::string& title, + const std::string& highlit_text, + EItemState item_state) +{ + mTitleCtrl->setToolTip(title); + + LLStyle::Params style_params; + + const LLPanelInventoryListItemBase::Params& params = LLUICtrlFactory::getDefaultParams<LLPanelInventoryListItemBase>(); + + switch(item_state) + { + case IS_DEFAULT: + style_params = params.default_style(); + break; + case IS_WORN: + style_params = params.worn_style(); + break; + default:; + } + + LLTextUtil::textboxSetHighlightedVal( + mTitleCtrl, + style_params, + title, + highlit_text); +} + +BOOL LLPanelInventoryListItemBase::handleToolTip( S32 x, S32 y, MASK mask) +{ + LLRect text_box_rect = mTitleCtrl->getRect(); + if (text_box_rect.pointInRect(x, y) && + mTitleCtrl->getTextPixelWidth() <= text_box_rect.getWidth()) + { + return FALSE; + } + return LLPanel::handleToolTip(x, y, mask); +} + +void LLPanelInventoryListItemBase::reshapeLeftWidgets() +{ + S32 widget_left = 0; + mLeftWidgetsWidth = 0; + + widget_array_t::const_iterator it = mLeftSideWidgets.begin(); + const widget_array_t::const_iterator it_end = mLeftSideWidgets.end(); + for( ; it_end != it; ++it) + { + LLUICtrl* widget = *it; + if(!widget->getVisible()) + { + continue; + } + LLRect widget_rect(widget->getRect()); + widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight()); + widget->setShape(widget_rect); + + widget_left += widget_rect.getWidth() + getWidgetSpacing(); + mLeftWidgetsWidth = widget_rect.mRight; + } +} + +void LLPanelInventoryListItemBase::reshapeRightWidgets() +{ + S32 widget_right = getLocalRect().getWidth(); + S32 widget_left = widget_right; + + widget_array_t::const_reverse_iterator it = mRightSideWidgets.rbegin(); + const widget_array_t::const_reverse_iterator it_end = mRightSideWidgets.rend(); + for( ; it_end != it; ++it) + { + LLUICtrl* widget = *it; + if(!widget->getVisible()) + { + continue; + } + LLRect widget_rect(widget->getRect()); + widget_left = widget_right - widget_rect.getWidth(); + widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight()); + widget->setShape(widget_rect); + + widget_right = widget_left - getWidgetSpacing(); + } + mRightWidgetsWidth = getLocalRect().getWidth() - widget_left; +} + +void LLPanelInventoryListItemBase::reshapeMiddleWidgets() +{ + LLRect icon_rect(mIconCtrl->getRect()); + icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop, + icon_rect.getWidth(), icon_rect.getHeight()); + mIconCtrl->setShape(icon_rect); + + S32 name_left = icon_rect.mRight + getWidgetSpacing(); + S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing(); + LLRect name_rect(mTitleCtrl->getRect()); + name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom); + mTitleCtrl->setShape(name_rect); +} + +// EOF diff --git a/indra/newview/llinventorylistitem.h b/indra/newview/llinventorylistitem.h new file mode 100644 index 0000000000..599431af3f --- /dev/null +++ b/indra/newview/llinventorylistitem.h @@ -0,0 +1,235 @@ +/** + * @file llinventorylistitem.h + * @brief Inventory list item panel. + * + * Class LLPanelInventoryListItemBase displays inventory item as an element + * of LLInventoryItemsList. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, 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_LLINVENTORYLISTITEM_H +#define LL_LLINVENTORYLISTITEM_H + +// llcommon +#include "llassettype.h" + +// llui +#include "llpanel.h" +#include "llstyle.h" + +// newview +#include "llwearabletype.h" + +class LLIconCtrl; +class LLTextBox; +class LLViewerInventoryItem; + +/** + * @class LLPanelInventoryListItemBase + * + * Base class for Inventory flat list item. Panel consists of inventory icon + * and inventory item name. + * This class is able to display widgets(buttons) on left(before icon) and right(after text-box) sides + * of panel. + * + * How to use (see LLPanelClothingListItem for example): + * - implement init() to build panel from xml + * - create new xml file, fill it with widgets you want to dynamically show/hide/reshape on left/right sides + * - redefine postBuild()(call base implementation) and add needed widgets to needed sides, + * + */ +class LLPanelInventoryListItemBase : public LLPanel +{ +public: + struct Params : public LLInitParam::Block<Params, LLPanel::Params> + { + Optional<LLStyle::Params> default_style, + worn_style; + Params(); + }; + + typedef enum e_item_state { + IS_DEFAULT, + IS_WORN, + } EItemState; + + static LLPanelInventoryListItemBase* create(LLViewerInventoryItem* item); + + virtual void draw(); + + /** + * Let item know it need to be refreshed in next draw() + */ + void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; } + + bool getNeedsRefresh(){ return mNeedsRefresh; } + + /** + * Add widget to left side + */ + void addWidgetToLeftSide(const std::string& name, bool show_widget = true); + void addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget = true); + + /** + * Add widget to right side, widget is supposed to be child of calling panel + */ + void addWidgetToRightSide(const std::string& name, bool show_widget = true); + void addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget = true); + + /** + * Mark widgets as visible. Only visible widgets take part in reshaping children + */ + void setShowWidget(const std::string& name, bool show); + void setShowWidget(LLUICtrl* ctrl, bool show); + + /** + * Set spacing between widgets during reshape + */ + void setWidgetSpacing(S32 spacing) { mWidgetSpacing = spacing; } + + S32 getWidgetSpacing() { return mWidgetSpacing; } + + /** + * Inheritors need to call base implementation of postBuild() + */ + /*virtual*/ BOOL postBuild(); + + /** + * Handles item selection + */ + /*virtual*/ void setValue(const LLSD& value); + + /** + * Handles filter request + */ + /*virtual*/ S32 notify(const LLSD& info); + + /* Highlights item */ + /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); + /* Removes item highlight */ + /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); + + /** Get the name of a corresponding inventory item */ + const std::string& getItemName() const; + + /** Get the asset type of a corresponding inventory item */ + LLAssetType::EType getType() const; + + /** Get the wearable type of a corresponding inventory item */ + LLWearableType::EType getWearableType() const; + + /** Get the description of a corresponding inventory item */ + const std::string& getDescription() const; + + /** Get the associated inventory item */ + LLViewerInventoryItem* getItem() const { return mItem; } + + virtual ~LLPanelInventoryListItemBase(){} + +protected: + + LLPanelInventoryListItemBase(LLViewerInventoryItem* item); + + typedef std::vector<LLUICtrl*> widget_array_t; + + /** + * Use it from a factory function to build panel, do not build panel in constructor + */ + virtual void init(); + + /** + * Called after inventory item was updated, update panel widgets to reflect inventory changes. + */ + virtual void updateItem(const std::string& name, + EItemState item_state = IS_DEFAULT); + + /** setter for mIconCtrl */ + void setIconCtrl(LLIconCtrl* icon) { mIconCtrl = icon; } + /** setter for MTitleCtrl */ + void setTitleCtrl(LLTextBox* tb) { mTitleCtrl = tb; } + + void setLeftWidgetsWidth(S32 width) { mLeftWidgetsWidth = width; } + void setRightWidgetsWidth(S32 width) { mRightWidgetsWidth = width; } + + /** + * Set all widgets from both side visible/invisible. Only enabled widgets + * (see setShowWidget()) can become visible + */ + virtual void setWidgetsVisible(bool visible); + + /** + * Reshape all child widgets - icon, text-box and side widgets + */ + virtual void reshapeWidgets(); + + /** set wearable type icon image */ + void setIconImage(const LLUIImagePtr& image); + + /** Set item title - inventory item name usually */ + void setTitle(const std::string& title, + const std::string& highlit_text, + EItemState item_state = IS_DEFAULT); + + /** + * Show tool tip if item name text size > panel size + */ + virtual BOOL handleToolTip( S32 x, S32 y, MASK mask); + + LLViewerInventoryItem* mItem; + +private: + + /** reshape left side widgets + * Deprecated for now. Disabled reshape left for now to reserve space for 'delete' + * button in LLPanelClothingListItem according to Neal's comment (https://codereview.productengine.com/secondlife/r/325/) + */ + void reshapeLeftWidgets(); + + /** reshape right side widgets */ + void reshapeRightWidgets(); + + /** reshape remaining widgets */ + void reshapeMiddleWidgets(); + + + LLIconCtrl* mIconCtrl; + LLTextBox* mTitleCtrl; + + LLUIImagePtr mIconImage; + std::string mHighlightedText; + + widget_array_t mLeftSideWidgets; + widget_array_t mRightSideWidgets; + S32 mWidgetSpacing; + + S32 mLeftWidgetsWidth; + S32 mRightWidgetsWidth; + bool mNeedsRefresh; +}; + +#endif //LL_LLINVENTORYLISTITEM_H diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 9c308359fa..427a0dc34d 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -34,11 +34,11 @@ #include "llwearableitemslist.h" #include "lliconctrl.h" +#include "llmenugl.h" // for LLContextMenu #include "llagentwearables.h" #include "llappearancemgr.h" #include "llinventoryfunctions.h" -#include "llmenugl.h" // for LLContextMenu #include "lltransutil.h" #include "llviewerattachmenu.h" #include "llvoavatarself.h" @@ -113,18 +113,17 @@ LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item // virtual void LLPanelWearableOutfitItem::updateItem(const std::string& name, - const LLStyle::Params& input_params) + EItemState item_state) { std::string search_label = name; - LLStyle::Params style_params = input_params; if (mItem && get_is_item_worn(mItem->getUUID())) { search_label += LLTrans::getString("worn"); - style_params.font.style("BOLD"); + item_state = IS_WORN; } - LLPanelInventoryListItemBase::updateItem(search_label, style_params); + LLPanelInventoryListItemBase::updateItem(search_label, item_state); } ////////////////////////////////////////////////////////////////////////// @@ -264,19 +263,18 @@ LLPanelAttachmentListItem* LLPanelAttachmentListItem::create(LLViewerInventoryIt return list_item; } -void LLPanelAttachmentListItem::setTitle(const std::string& title, - const std::string& highlit_text, - const LLStyle::Params& input_params) +void LLPanelAttachmentListItem::updateItem(const std::string& name, + EItemState item_state) { - std::string title_joint = title; + std::string title_joint; if (mItem && isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(mItem->getLinkedUUID())) { std::string joint = LLTrans::getString(gAgentAvatarp->getAttachedPointName(mItem->getLinkedUUID())); - title_joint = title + " (" + joint + ")"; + title_joint = name + " (" + joint + ")"; } - LLPanelDeletableWearableListItem::setTitle(title_joint, highlit_text, input_params); + LLPanelInventoryListItemBase::updateItem(title_joint, item_state); } ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 5dc06284c3..2bfb90e3ec 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -38,6 +38,7 @@ // newview #include "llinventoryitemslist.h" +#include "llinventorylistitem.h" #include "llinventorymodel.h" #include "lllistcontextmenu.h" #include "llwearabletype.h" @@ -87,7 +88,7 @@ public: * Updates item name and (worn) suffix. */ /*virtual*/ void updateItem(const std::string& name, - const LLStyle::Params& input_params = LLStyle::Params()); + EItemState item_state = IS_DEFAULT); protected: LLPanelWearableOutfitItem(LLViewerInventoryItem* item); @@ -124,9 +125,8 @@ public: virtual ~LLPanelAttachmentListItem() {}; /** Set item title. Joint name is added to the title in parenthesis */ - /*virtual*/ void setTitle(const std::string& title, - const std::string& highlit_text, - const LLStyle::Params& input_params = LLStyle::Params()); + /*virtual*/ void updateItem(const std::string& name, + EItemState item_state = IS_DEFAULT); protected: LLPanelAttachmentListItem(LLViewerInventoryItem* item) : LLPanelDeletableWearableListItem(item) {}; diff --git a/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml b/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml new file mode 100644 index 0000000000..dbe1ea2874 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<inventory_list_item + height="0" + layout="topleft" + left="0" + name="inventory_list_item" + top="0" + width="0"> + <!-- DEFAULT style for inventory list item --> + <default_style + font="SansSerifSmall" + font.style="NORMAL" /> + + <!-- style for inventory list item WORN on avatar --> + <worn_style + font="SansSerifSmall" + font.style="BOLD" /> +</inventory_list_item> |