diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llui/llaccordionctrltab.cpp | 28 | ||||
-rw-r--r-- | indra/llui/llaccordionctrltab.h | 6 | ||||
-rw-r--r-- | indra/newview/llcofwearables.cpp | 8 | ||||
-rw-r--r-- | indra/newview/llinventoryitemslist.cpp | 55 | ||||
-rw-r--r-- | indra/newview/llinventoryitemslist.h | 17 | ||||
-rw-r--r-- | indra/newview/llinventoryobserver.cpp | 69 | ||||
-rw-r--r-- | indra/newview/llinventoryobserver.h | 13 | ||||
-rw-r--r-- | indra/newview/lloutfitslist.cpp | 119 | ||||
-rw-r--r-- | indra/newview/lloutfitslist.h | 17 | ||||
-rw-r--r-- | indra/newview/llpaneloutfitsinventory.cpp | 30 | ||||
-rw-r--r-- | indra/newview/llwearableitemslist.cpp | 84 | ||||
-rw-r--r-- | indra/newview/llwearableitemslist.h | 30 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml | 62 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_outfit_edit.xml | 24 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_people.xml | 1 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/strings.xml | 14 |
16 files changed, 487 insertions, 90 deletions
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 3c706ce90e..596da782ce 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -436,6 +436,34 @@ void LLAccordionCtrlTab::setAccordionView(LLView* panel) addChild(panel,0); } +void LLAccordionCtrlTab::setTitle(const std::string& title) +{ + LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME); + if (header) + { + header->setTitle(title); + } +} + +boost::signals2::connection LLAccordionCtrlTab::setFocusReceivedCallback(const focus_signal_t::slot_type& cb) +{ + LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME); + if (header) + { + return header->setFocusReceivedCallback(cb); + } + return boost::signals2::connection(); +} + +boost::signals2::connection LLAccordionCtrlTab::setFocusLostCallback(const focus_signal_t::slot_type& cb) +{ + LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME); + if (header) + { + return header->setFocusLostCallback(cb); + } + return boost::signals2::connection(); +} LLView* LLAccordionCtrlTab::findContainerView() { diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index fb19d17e99..de254ed3eb 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -113,6 +113,12 @@ public: void setAccordionView(LLView* panel); LLView* getAccordionView() { return mContainerPanel; }; + // Set text in LLAccordionCtrlTabHeader + void setTitle(const std::string& title); + + boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb); + boost::signals2::connection setFocusLostCallback(const focus_signal_t::slot_type& cb); + bool getCollapsible() {return mCollapsible;}; void setCollapsible(bool collapsible) {mCollapsible = collapsible;}; diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index a2a1dd504a..b8222ebb18 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -204,10 +204,10 @@ void LLCOFWearables::addClothingTypesDummies(const LLAppearanceMgr::wearables_by U32 size = clothing_by_type[type].size(); if (size) continue; - //*TODO create dummy item panel - - //*TODO add dummy item panel -> mClothing->addItem(dummy_item_panel, item->getUUID(), ADD_BOTTOM, false); - + EWearableType w_type = static_cast<EWearableType>(type); + LLPanelInventoryListItemBase* item_panel = LLPanelDummyClothingListItem::create(w_type); + if(!item_panel) continue; + mClothing->addItem(item_panel, LLUUID::null, ADD_BOTTOM, false); addWearableTypeSeparator(mClothing); } } diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index 3d8cb6dfe8..8dfdb0788a 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -65,14 +65,8 @@ LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInven void LLPanelInventoryListItemBase::updateItem() { - if (mItemIcon.notNull()) - mIcon->setImage(mItemIcon); - - LLTextUtil::textboxSetHighlightedVal( - mTitle, - LLStyle::Params(), - mItem->getName(), - mHighlightedText); + setIconImage(mIconImage); + setTitle(mItem->getName(), mHighlightedText); } void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/) @@ -122,9 +116,10 @@ void LLPanelInventoryListItemBase::setShowWidget(LLUICtrl* ctrl, bool show) BOOL LLPanelInventoryListItemBase::postBuild() { - // Inheritors need to call base implementation - mIcon = getChild<LLIconCtrl>("item_icon"); - mTitle = getChild<LLTextBox>("item_name"); + setIconCtrl(getChild<LLIconCtrl>("item_icon")); + setTitleCtrl(getChild<LLTextBox>("item_name")); + + mIconImage = get_item_icon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE); updateItem(); @@ -156,13 +151,12 @@ void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask) LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item) : LLPanel() , mItem(item) -, mIcon(NULL) -, mTitle(NULL) +, mIconCtrl(NULL) +, mTitleCtrl(NULL) , mWidgetSpacing(WIDGET_SPACING) , mLeftWidgetsWidth(0) , mRightWidgetsWidth(0) { - mItemIcon = get_item_icon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE); } void LLPanelInventoryListItemBase::init() @@ -197,6 +191,24 @@ void LLPanelInventoryListItemBase::reshapeWidgets() 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) +{ + LLTextUtil::textboxSetHighlightedVal( + mTitleCtrl, + LLStyle::Params(), + title, + highlit_text); +} + void LLPanelInventoryListItemBase::reshapeLeftWidgets() { S32 widget_left = 0; @@ -246,16 +258,16 @@ void LLPanelInventoryListItemBase::reshapeRightWidgets() void LLPanelInventoryListItemBase::reshapeMiddleWidgets() { - LLRect icon_rect(mIcon->getRect()); + LLRect icon_rect(mIconCtrl->getRect()); icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop, icon_rect.getWidth(), icon_rect.getHeight()); - mIcon->setShape(icon_rect); + mIconCtrl->setShape(icon_rect); S32 name_left = icon_rect.mRight + getWidgetSpacing(); S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing(); - LLRect name_rect(mTitle->getRect()); + LLRect name_rect(mTitleCtrl->getRect()); name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom); - mTitle->setShape(name_rect); + mTitleCtrl->setShape(name_rect); } //////////////////////////////////////////////////////////////////////////////// @@ -356,17 +368,18 @@ void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item) if (!item) { llwarns << "No inventory item. Couldn't create flat list item." << llendl; - llassert(!"No inventory item. Couldn't create flat list item."); + llassert(item != NULL); } LLPanelInventoryListItemBase *list_item = LLPanelInventoryListItemBase::create(item); if (!list_item) return; - if (!addItem(list_item, item->getUUID())) + bool is_item_added = addItem(list_item, item->getUUID()); + if (!is_item_added) { llwarns << "Couldn't add flat list item." << llendl; - llassert(!"Couldn't add flat list item."); + llassert(is_item_added); } } diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 15f04c79a9..152aafbd7e 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -125,6 +125,11 @@ protected: */ virtual void init(); + /** 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; } @@ -139,6 +144,12 @@ protected: */ 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); + private: /** reshape left side widgets @@ -155,10 +166,10 @@ private: LLViewerInventoryItem* mItem; - LLIconCtrl* mIcon; - LLTextBox* mTitle; + LLIconCtrl* mIconCtrl; + LLTextBox* mTitleCtrl; - LLUIImagePtr mItemIcon; + LLUIImagePtr mIconImage; std::string mHighlightedText; widget_array_t mLeftSideWidgets; diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index e4a7b17966..86147d65e6 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -669,36 +669,87 @@ void LLInventoryCategoriesObserver::changed(U32 mask) if (!category) continue; - S32 version = category->getVersion(); - if (version != (*iter).second.mVersion) + const S32 version = category->getVersion(); + const S32 expected_num_descendents = category->getDescendentCount(); + if ((version == LLViewerInventoryCategory::VERSION_UNKNOWN) || + (expected_num_descendents == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)) { - // Update category version in map. - (*iter).second.mVersion = version; - (*iter).second.mCallback(); + continue; + } + + // Check number of known descendents to find out whether it has changed. + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf((*iter).first, cats, items); + if (!cats || !items) + { + llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl; + // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean + // that the cat just doesn't have any items or subfolders). + // Unrecoverable, so just skip this category. + + llassert(cats != NULL && items != NULL); + } + const S32 current_num_known_descendents = cats->count() + items->count(); + + LLCategoryData cat_data = (*iter).second; + + // If category version or descendents count has changed + // update category data in mCategoryMap and fire a callback. + if (version != cat_data.mVersion || current_num_known_descendents != cat_data.mDescendentsCount) + { + cat_data.mVersion = version; + cat_data.mDescendentsCount = current_num_known_descendents; + + cat_data.mCallback(); } } } -void LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb) +bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb) { S32 version; + S32 current_num_known_descendents; + bool can_be_added = true; + LLViewerInventoryCategory* category = gInventory.getCategory(cat_id); if (category) { // Inventory category version is used to find out if some changes // to a category have been made. version = category->getVersion(); + + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(cat_id, cats, items); + if (!cats || !items) + { + llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl; + // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean + // that the cat just doesn't have any items or subfolders). + // Unrecoverable, so just return "false" meaning that the category can't be observed. + can_be_added = false; + + llassert(cats != NULL && items != NULL); + } + current_num_known_descendents = cats->count() + items->count(); } else { // If category could not be retrieved it might mean that // inventory is unusable at the moment so the category is - // stored with VERSION_UNKNOWN and it may be updated later. + // stored with VERSION_UNKNOWN and DESCENDENT_COUNT_UNKNOWN, + // it may be updated later. version = LLViewerInventoryCategory::VERSION_UNKNOWN; + current_num_known_descendents = LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN; + } + + if (can_be_added) + { + mCategoryMap.insert(category_map_value_t(cat_id, LLCategoryData(cb, version, current_num_known_descendents))); } - version = category->getVersion(); - mCategoryMap.insert(category_map_value_t(cat_id, LLCategoryData(cb, version))); + return can_be_added; } void LLInventoryCategoriesObserver::removeCategory(const LLUUID& cat_id) diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index e63b67d2ad..036e6ca40d 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -276,19 +276,28 @@ public: LLInventoryCategoriesObserver() {}; virtual void changed(U32 mask); - void addCategory(const LLUUID& cat_id, callback_t cb); + /** + * Add cat_id to the list of observed categories with a + * callback fired on category being changed. + * + * @return "true" if category was added, "false" if it could + * not be found. + */ + bool addCategory(const LLUUID& cat_id, callback_t cb); void removeCategory(const LLUUID& cat_id); protected: struct LLCategoryData { - LLCategoryData(callback_t cb, S32 version) + LLCategoryData(callback_t cb, S32 version, S32 num_descendents) : mCallback(cb) , mVersion(version) + , mDescendentsCount(num_descendents) {} callback_t mCallback; S32 mVersion; + S32 mDescendentsCount; }; typedef std::map<LLUUID, LLCategoryData> category_map_t; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 1215272685..b103ec45d0 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -41,6 +41,7 @@ #include "llaccordionctrl.h" #include "llaccordionctrltab.h" +#include "llappearancemgr.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "llwearableitemslist.h" @@ -51,6 +52,7 @@ LLOutfitsList::LLOutfitsList() : LLPanel() , mAccordion(NULL) , mListCommands(NULL) + , mSelectedList(NULL) { mCategoriesObserver = new LLInventoryCategoriesObserver(); gInventory.addObserver(mCategoriesObserver); @@ -135,30 +137,37 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) { const LLUUID cat_id = (*iter); LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); - if (!cat) - continue; + if (!cat) continue; std::string name = cat->getName(); static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode(); - - accordionXmlNode->setAttributeString("name", name); - accordionXmlNode->setAttributeString("title", name); LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL); + tab->setName(name); + tab->setTitle(name); + // *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated. tab->setDisplayChildren(false); mAccordion->addCollapsibleCtrl(tab); + // Start observing the new outfit category. + LLWearableItemsList* list = tab->getChild<LLWearableItemsList>("wearable_items_list"); + if (!mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id))) + { + // Remove accordion tab if category could not be added to observer. + mAccordion->removeCollapsibleCtrl(tab); + continue; + } + // Map the new tab with outfit category UUID. mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab)); - // Start observing the new outfit category. - LLWearableItemsList* list = tab->getChild<LLWearableItemsList>("wearable_items_list"); - mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id)); + // Setting tab focus callback to monitor currently selected outfit. + tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id)); - // Setting drop down callback to monitor currently selected outfit. - tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::onTabExpandedCollapsed, this, list)); + // Setting list commit callback to monitor currently selected wearable item. + list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1)); // Fetch the new outfit contents. cat->fetch(); @@ -178,10 +187,18 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) // 1. Remove outfit accordion tab from accordion. mAccordion->removeCollapsibleCtrl(outfits_iter->second); + const LLUUID& outfit_id = outfits_iter->first; + // 2. Remove outfit category from observer to stop monitoring its changes. - mCategoriesObserver->removeCategory(outfits_iter->first); + mCategoriesObserver->removeCategory(outfit_id); - // 3. Remove category UUID to accordion tab mapping. + // 3. Reset selection if selected outfit is being removed. + if (mSelectedOutfitUUID == outfit_id) + { + changeOutfitSelection(NULL, LLUUID()); + } + + // 4. Remove category UUID to accordion tab mapping. mOutfitsMap.erase(outfits_iter); } } @@ -199,40 +216,30 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) mAccordion->arrange(); } -void LLOutfitsList::updateOutfitTab(const LLUUID& category_id) +void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl) { - outfits_map_t::iterator outfits_iter = mOutfitsMap.find(category_id); - if (outfits_iter != mOutfitsMap.end()) - { - LLViewerInventoryCategory *cat = gInventory.getCategory(category_id); - if (!cat) - return; + LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl); + if (!list) return; - std::string name = cat->getName(); + LLViewerInventoryItem *item = gInventory.getItem(list->getSelectedUUID()); + if (!item) return; - // Update tab name with the new category name. - LLAccordionCtrlTab* tab = outfits_iter->second; - if (tab) - { - tab->setName(name); - } - - // Update tab title with the new category name using textbox - // in accordion tab header. - LLTextBox* tab_title = tab->findChild<LLTextBox>("dd_textbox"); - if (tab_title) - { - tab_title->setText(name); - } - } + changeOutfitSelection(list, item->getParentUUID()); } -void LLOutfitsList::onTabExpandedCollapsed(LLWearableItemsList* list) +void LLOutfitsList::performAction(std::string action) { - if (!list) - return; + LLViewerInventoryCategory* cat = gInventory.getCategory(mSelectedOutfitUUID); + if (!cat) return; - // TODO: Add outfit selection handling. + if ("replaceoutfit" == action) + { + LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, FALSE ); + } + else if ("addtooutfit" == action) + { + LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE ); + } } void LLOutfitsList::setFilterSubString(const std::string& string) @@ -240,7 +247,6 @@ void LLOutfitsList::setFilterSubString(const std::string& string) mFilterSubString = string; } - ////////////////////////////////////////////////////////////////////////// // Private methods ////////////////////////////////////////////////////////////////////////// @@ -283,4 +289,37 @@ void LLOutfitsList::computeDifference( LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved); } +void LLOutfitsList::updateOutfitTab(const LLUUID& category_id) +{ + outfits_map_t::iterator outfits_iter = mOutfitsMap.find(category_id); + if (outfits_iter != mOutfitsMap.end()) + { + LLViewerInventoryCategory *cat = gInventory.getCategory(category_id); + if (!cat) return; + + std::string name = cat->getName(); + + // Update tab name with the new category name. + LLAccordionCtrlTab* tab = outfits_iter->second; + if (tab) + { + tab->setName(name); + tab->setTitle(name); + } + } +} + +void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) +{ + // Reset selection in previously selected tab + // if a new one is selected. + if (list && mSelectedList && mSelectedList != list) + { + mSelectedList->resetSelection(); + } + + mSelectedList = list; + mSelectedOutfitUUID = category_id; +} + // EOF diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 2d103ea356..d86cf5a703 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -65,10 +65,9 @@ public: void refreshList(const LLUUID& category_id); - // Update tab displaying outfit identified by category_id. - void updateOutfitTab(const LLUUID& category_id); + void onSelectionChange(LLUICtrl* ctrl); - void onTabExpandedCollapsed(LLWearableItemsList* list); + void performAction(std::string action); void setFilterSubString(const std::string& string); @@ -85,12 +84,24 @@ private: */ void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved); + /** + * Updates tab displaying outfit identified by category_id. + */ + void updateOutfitTab(const LLUUID& category_id); + + /** + * Resets previous selection and stores newly selected list and outfit id. + */ + void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id); LLInventoryCategoriesObserver* mCategoriesObserver; LLAccordionCtrl* mAccordion; LLPanel* mListCommands; + LLWearableItemsList* mSelectedList; + LLUUID mSelectedOutfitUUID; + std::string mFilterSubString; typedef std::map<LLUUID, LLAccordionCtrlTab*> outfits_map_t; diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 789e85b46f..80964938f5 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -188,19 +188,37 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string) void LLPanelOutfitsInventory::onWearButtonClick() { - LLFolderViewEventListener* listenerp = getCorrectListenerForAction(); - if (listenerp) + // TODO: Remove if/else, add common interface + // for "My Outfits" and "Wearing" tabs. + if (!isCOFPanelActive()) + { + mMyOutfitsPanel->performAction("replaceoutfit"); + } + else { - listenerp->performAction(NULL, "replaceoutfit"); + LLFolderViewEventListener* listenerp = getCorrectListenerForAction(); + if (listenerp) + { + listenerp->performAction(NULL, "replaceoutfit"); + } } } void LLPanelOutfitsInventory::onAdd() { - LLFolderViewEventListener* listenerp = getCorrectListenerForAction(); - if (listenerp) + // TODO: Remove if/else, add common interface + // for "My Outfits" and "Wearing" tabs. + if (!isCOFPanelActive()) + { + mMyOutfitsPanel->performAction("addtooutfit"); + } + else { - listenerp->performAction(NULL, "addtooutfit"); + LLFolderViewEventListener* listenerp = getCorrectListenerForAction(); + if (listenerp) + { + listenerp->performAction(NULL, "addtooutfit"); + } } } diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index b8fab63be9..56b2791993 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -33,8 +33,11 @@ #include "llwearableitemslist.h" +#include "lliconctrl.h" + #include "llinventoryfunctions.h" #include "llinventorymodel.h" +#include "lltransutil.h" class LLFindOutfitItems : public LLInventoryCollectFunctor { @@ -212,6 +215,87 @@ void LLPanelBodyPartsListItem::setShowEditButton(bool show) ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +LLPanelDummyClothingListItem* LLPanelDummyClothingListItem::create(EWearableType w_type) +{ + LLPanelDummyClothingListItem* list_item = new LLPanelDummyClothingListItem(w_type); + list_item->init(); + return list_item; +} + +void LLPanelDummyClothingListItem::updateItem() +{ + std::string title = wearableTypeToString(mWearableType); + setTitle(title, LLStringUtil::null); +} + +BOOL LLPanelDummyClothingListItem::postBuild() +{ + LLIconCtrl* icon = getChild<LLIconCtrl>("item_icon"); + setIconCtrl(icon); + setTitleCtrl(getChild<LLTextBox>("item_name")); + + addWidgetToRightSide("btn_add"); + + setIconImage(get_item_icon(LLAssetType::AT_CLOTHING, LLInventoryType::IT_NONE, mWearableType, FALSE)); + updateItem(); + + // Make it look loke clothing item - reserve space for 'delete' button + setLeftWidgetsWidth(icon->getRect().mLeft); + + setWidgetsVisible(false); + reshapeWidgets(); + + return TRUE; +} + +LLPanelDummyClothingListItem::LLPanelDummyClothingListItem(EWearableType w_type) + : LLPanelWearableListItem(NULL) + , mWearableType(w_type) +{ +} + +void LLPanelDummyClothingListItem::init() +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_dummy_clothing_list_item.xml"); +} + +typedef std::map<EWearableType, std::string> clothing_to_string_map_t; + +clothing_to_string_map_t init_clothing_string_map() +{ + clothing_to_string_map_t w_map; + w_map.insert(std::make_pair(WT_SHIRT, "shirt_not_worn")); + w_map.insert(std::make_pair(WT_PANTS, "pants_not_worn")); + w_map.insert(std::make_pair(WT_SHOES, "shoes_not_worn")); + w_map.insert(std::make_pair(WT_SOCKS, "socks_not_worn")); + w_map.insert(std::make_pair(WT_JACKET, "jacket_not_worn")); + w_map.insert(std::make_pair(WT_GLOVES, "gloves_not_worn")); + w_map.insert(std::make_pair(WT_UNDERSHIRT, "undershirt_not_worn")); + w_map.insert(std::make_pair(WT_UNDERPANTS, "underpants_not_worn")); + w_map.insert(std::make_pair(WT_SKIRT, "skirt_not_worn")); + w_map.insert(std::make_pair(WT_ALPHA, "alpha_not_worn")); + w_map.insert(std::make_pair(WT_TATTOO, "tattoo_not_worn")); + return w_map; +} + +std::string LLPanelDummyClothingListItem::wearableTypeToString(EWearableType w_type) +{ + static const clothing_to_string_map_t w_map = init_clothing_string_map(); + static const std::string invalid_str = LLTrans::getString("invalid_not_worn"); + + std::string type_str = invalid_str; + clothing_to_string_map_t::const_iterator it = w_map.find(w_type); + if(w_map.end() != it) + { + type_str = LLTrans::getString(it->second); + } + return type_str; +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list"); LLWearableItemsList::Params::Params() diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index ae43b3f673..c4a415dfbf 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -81,7 +81,6 @@ public: virtual ~LLPanelClothingListItem(); - /*virtual*/ void init(); /*virtual*/ BOOL postBuild(); /** @@ -96,6 +95,8 @@ public: protected: LLPanelClothingListItem(LLViewerInventoryItem* item); + + /*virtual*/ void init(); }; class LLPanelBodyPartsListItem : public LLPanelWearableListItem @@ -107,7 +108,6 @@ public: virtual ~LLPanelBodyPartsListItem(); - /*virtual*/ void init(); /*virtual*/ BOOL postBuild(); /** @@ -118,6 +118,32 @@ public: protected: LLPanelBodyPartsListItem(LLViewerInventoryItem* item); + + /*virtual*/ void init(); +}; + +/** + * @class LLPanelDummyClothingListItem + * + * A dummy item panel - displays grayed clothing icon, grayed title '<clothing> not worn' and 'add' button + */ +class LLPanelDummyClothingListItem : public LLPanelWearableListItem +{ +public: + static LLPanelDummyClothingListItem* create(EWearableType w_type); + + /*virtual*/ void updateItem(); + /*virtual*/ BOOL postBuild(); + +protected: + LLPanelDummyClothingListItem(EWearableType w_type); + + /*virtual*/ void init(); + + static std::string wearableTypeToString(EWearableType w_type); + +private: + EWearableType mWearableType; }; /** diff --git a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml new file mode 100644 index 0000000000..dbbfa8f2e2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="top|right|left" + height="20" + layout="topleft" + left="0" + name="dummy_clothing_item" + top="0" + width="380"> + <icon + follows="top|right|left" + height="20" + image_name="ListItem_Over" + layout="topleft" + left="0" + name="hovered_icon" + top="0" + visible="false" + width="380" /> + <icon + height="20" + follows="top|right|left" + image_name="ListItem_Select" + layout="topleft" + left="0" + name="selected_icon" + top="0" + visible="false" + width="380" /> + <icon + height="16" + color="0.75 0.75 0.75 1" + follows="top|left" + image_name="Inv_Object" + layout="topleft" + left="20" + name="item_icon" + top="2" + width="16" /> + <text + follows="left|right" + height="16" + layout="topleft" + left_pad="5" + allow_html="false" + use_ellipses="true" + name="item_name" + text_color="LtGray_50" + top="4" + value="..." + width="359" /> + <button + name="btn_add" + layout="topleft" + follows="top|right" + label="+" + top="0" + left="0" + height="20" + width="20" + tab_stop="false" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index 73181392c9..a9f588698a 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -234,6 +234,14 @@ name="move_further_btn" top="1" width="31" /> + <icon + follows="bottom|left" + height="25" + image_name="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="dummy_icon" + width="105" /> <button follows="bottom|right" height="25" @@ -440,6 +448,22 @@ name="add_to_outfit_btn" top="1" width="31" /> + <icon + follows="bottom|left" + height="25" + image_name="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="dummy_middle_icon" + width="140" /> + <icon + follows="bottom|left" + height="25" + image_name="Toolbar_Right_Off" + layout="topleft" + left_pad="1" + name="dummy_right_icon" + width="31" /> </panel> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 066ea3be6e..7e212c9383 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -490,6 +490,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M label="Share" layout="topleft" name="share_btn" + tool_tip="Share an inventory item" width="62" /> <button follows="bottom|left" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 74dc23853d..f544449d02 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -1802,6 +1802,20 @@ Clears (deletes) the media and all params from the given face. <string name="alpha">Alpha</string> <string name="tattoo">Tattoo</string> <string name="invalid">invalid</string> + + <!-- Not Worn Wearable Types --> + <string name="shirt_not_worn">Shirt not worn</string> + <string name="pants_not_worn">Pants not worn</string> + <string name="shoes_not_worn">Shoes not worn</string> + <string name="socks_not_worn">Socks not worn</string> + <string name="jacket_not_worn">Jacket not worn</string> + <string name="gloves_not_worn">Gloves not worn</string> + <string name="undershirt_not_worn">Undershirt not worn</string> + <string name="underpants_not_worn">Underpants not worn</string> + <string name="skirt_not_worn">Skirt not worn</string> + <string name="alpha_not_worn">Alpha not worn</string> + <string name="tattoo_not_worn">Tattoo not worn</string> + <string name="invalid_not_worn">invalid</string> <!-- Wearable List--> <string name="NewWearable">New [WEARABLE_ITEM]</string> |