diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llcofwearables.cpp | 7 | ||||
-rw-r--r-- | indra/newview/lloutfitslist.cpp | 93 | ||||
-rw-r--r-- | indra/newview/lloutfitslist.h | 10 | ||||
-rw-r--r-- | indra/newview/llpaneloutfitedit.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llpaneloutfitsinventory.cpp | 9 | ||||
-rw-r--r-- | indra/newview/llsidepanelinventory.cpp | 8 | ||||
-rw-r--r-- | indra/newview/llsidepanelinventory.h | 1 | ||||
-rw-r--r-- | indra/newview/llwearableitemslist.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llwearableitemslist.h | 6 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_outfit_edit.xml | 24 |
10 files changed, 128 insertions, 39 deletions
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 1926682a39..1fab5c7683 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -374,7 +374,12 @@ void LLCOFWearables::refresh() value_it_end = values.end(); value_it != value_it_end; ++value_it) { - list->selectItemByValue(*value_it); + // value_it may be null because of dummy items + // Dummy items have no ID + if(value_it->asUUID().notNull()) + { + list->selectItemByValue(*value_it); + } } } } diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 67442dd573..6c2566813f 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -148,10 +148,27 @@ private: void onTakeOff() { - const LLUUID& selected_outfit_id = getSelectedOutfitID(); - if (selected_outfit_id.notNull()) + // Take off selected items if there are any + if (mOutfitList->hasItemSelected()) + { + uuid_vec_t selected_uuids; + mOutfitList->getSelectedItemsUUIDs(selected_uuids); + + for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it) + { + if (get_is_item_worn(*it)) + { + LLAppearanceMgr::instance().removeItemFromAvatar(*it); + } + } + } + else // or take off the whole selected outfit if no items specified. { - LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id); + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.notNull()) + { + LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id); + } } } @@ -474,7 +491,7 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) } // Handle removed tabs. - for (uuid_vec_t::const_iterator iter=vremoved.begin(); iter != vremoved.end(); iter++) + for (uuid_vec_t::const_iterator iter=vremoved.begin(); iter != vremoved.end(); ++iter) { outfits_map_t::iterator outfits_iter = mOutfitsMap.find((*iter)); if (outfits_iter != mOutfitsMap.end()) @@ -626,7 +643,10 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata) } if (command_name == "take_off") { - return LLAppearanceMgr::getInstance()->getBaseOutfitUUID() == mSelectedOutfitUUID; + // Enable "Take Off" only if a worn item or base outfit is selected. + return ( !hasItemSelected() + && LLAppearanceMgr::getInstance()->getBaseOutfitUUID() == mSelectedOutfitUUID ) + || hasWornItemSelected(); } return false; } @@ -638,6 +658,22 @@ void LLOutfitsList::showGearMenu(LLView* spawning_view) mGearMenu->show(spawning_view); } +void LLOutfitsList::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const +{ + // Collect selected items from all selected lists. + for (wearables_lists_map_t::const_iterator iter = mSelectedListsMap.begin(); + iter != mSelectedListsMap.end(); + ++iter) + { + uuid_vec_t uuids; + (*iter).second->getSelectedUUIDs(uuids); + + S32 prev_size = selected_uuids.size(); + selected_uuids.resize(prev_size + uuids.size()); + std::copy(uuids.begin(), uuids.end(), selected_uuids.begin() + prev_size); + } +} + boost::signals2::connection LLOutfitsList::setSelectionChangeCallback(selection_change_callback_t cb) { return mSelectionChangeSignal.connect(cb); @@ -878,7 +914,7 @@ void LLOutfitsList::applyFilterToTab( { // hide tab if its title doesn't pass filter // and it has no visible items - tab->setVisible(list->wasLasFilterSuccessfull()); + tab->setVisible(list->hasMatchedItems()); // remove title highlighting because it might // have been previously highlighted by less restrictive filter @@ -894,6 +930,18 @@ void LLOutfitsList::applyFilterToTab( } } +bool LLOutfitsList::hasWornItemSelected() +{ + uuid_vec_t selected_uuids; + getSelectedItemsUUIDs(selected_uuids); + + for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it) + { + if (get_is_item_worn(*it)) return true; + } + return false; +} + void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) { LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); @@ -912,6 +960,26 @@ void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const } } +void LLOutfitsList::wearSelectedItems() +{ + uuid_vec_t selected_uuids; + getSelectedItemsUUIDs(selected_uuids); + + if(selected_uuids.empty()) + { + return; + } + + uuid_vec_t::const_iterator it; + // Wear items from all selected lists(if possible- add, else replace) + for (it = selected_uuids.begin(); it != selected_uuids.end()-1; ++it) + { + LLAppearanceMgr::getInstance()->wearItemOnAvatar(*it, false, false); + } + // call update only when wearing last item + LLAppearanceMgr::getInstance()->wearItemOnAvatar(*it, true, false); +} + void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y) { LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl); @@ -919,18 +987,7 @@ void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y) uuid_vec_t selected_uuids; - // Collect selected items from all selected lists. - for (wearables_lists_map_t::iterator iter = mSelectedListsMap.begin(); - iter != mSelectedListsMap.end(); - ++iter) - { - uuid_vec_t uuids; - (*iter).second->getSelectedUUIDs(uuids); - - S32 prev_size = selected_uuids.size(); - selected_uuids.resize(prev_size + uuids.size()); - std::copy(uuids.begin(), uuids.end(), selected_uuids.begin() + prev_size); - } + getSelectedItemsUUIDs(selected_uuids); LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y); } diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index d207624792..26722f2a96 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -103,8 +103,13 @@ public: const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; } + void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const; + boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb); + // Collects selected items from all selected lists and wears them(if possible- adds, else replaces) + void wearSelectedItems(); + /** * Returns true if there is a selection inside currently selected outfit */ @@ -173,6 +178,11 @@ private: */ void applyFilterToTab(const LLUUID& category_id, LLAccordionCtrlTab* tab, const std::string& filter_substring); + /** + * Returns true if there are any worn items among currently selected, otherwise false. + */ + bool hasWornItemSelected(); + void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); void onCOFChanged(); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 54776ca2f7..1544717873 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -387,6 +387,7 @@ BOOL LLPanelOutfitEdit::postBuild() mWearableItemsList = getChild<LLInventoryItemsList>("list_view"); mWearableItemsList->setCommitOnSelectionChange(true); mWearableItemsList->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onInventorySelectionChange, this)); + mWearableItemsList->setDoubleClickCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this)); mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this)); return TRUE; @@ -404,6 +405,10 @@ void LLPanelOutfitEdit::onOpen(const LLSD& key) displayCurrentOutfit(); mInitialized = true; } + + showAddWearablesPanel(false); + mWearableItemsList->resetSelection(); + mInventoryItemsPanel->clearSelection(); } void LLPanelOutfitEdit::moveWearable(bool closer_to_body) diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 2f1cad8a75..076e6485a8 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -169,7 +169,14 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string) void LLPanelOutfitsInventory::onWearButtonClick() { - mMyOutfitsPanel->performAction("replaceoutfit"); + if (mMyOutfitsPanel->hasItemSelected()) + { + mMyOutfitsPanel->wearSelectedItems(); + } + else + { + mMyOutfitsPanel->performAction("replaceoutfit"); + } } bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD& response) diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 63b6fe5ef0..de59af49da 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -71,8 +71,8 @@ BOOL LLSidepanelInventory::postBuild() mShareBtn = mInventoryPanel->getChild<LLButton>("share_btn"); mShareBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShareButtonClicked, this)); - LLButton* shop_btn = mInventoryPanel->getChild<LLButton>("shop_btn"); - shop_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShopButtonClicked, this)); + mShopBtn = mInventoryPanel->getChild<LLButton>("shop_btn"); + mShopBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShopButtonClicked, this)); mWearBtn = mInventoryPanel->getChild<LLButton>("wear_btn"); mWearBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onWearButtonClicked, this)); @@ -265,6 +265,7 @@ void LLSidepanelInventory::updateVerbs() mPlayBtn->setEnabled(FALSE); mTeleportBtn->setVisible(FALSE); mTeleportBtn->setEnabled(FALSE); + mShopBtn->setVisible(TRUE); mShareBtn->setEnabled(canShare()); @@ -283,16 +284,19 @@ void LLSidepanelInventory::updateVerbs() case LLInventoryType::IT_ATTACHMENT: mWearBtn->setVisible(TRUE); mWearBtn->setEnabled(TRUE); + mShopBtn->setVisible(FALSE); break; case LLInventoryType::IT_SOUND: case LLInventoryType::IT_GESTURE: case LLInventoryType::IT_ANIMATION: mPlayBtn->setVisible(TRUE); mPlayBtn->setEnabled(TRUE); + mShopBtn->setVisible(FALSE); break; case LLInventoryType::IT_LANDMARK: mTeleportBtn->setVisible(TRUE); mTeleportBtn->setEnabled(TRUE); + mShopBtn->setVisible(FALSE); break; default: break; diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 13275d14c0..951fdd630c 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -94,6 +94,7 @@ private: LLButton* mPlayBtn; LLButton* mTeleportBtn; LLButton* mOverflowBtn; + LLButton* mShopBtn; }; diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 2b2615ed24..6bb3e7fb64 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -393,9 +393,9 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB return item_type_order1 < item_type_order2; } - if (item_type_order1 & TLO_NOT_CLOTHING) + if (item_type_order1 & TLO_SORTABLE_BY_NAME) { - // If both items are of the same asset type except AT_CLOTHING + // If both items are of the same asset type except AT_CLOTHING and AT_BODYPART // we can compare them by name. return LLWearableItemNameComparator::doCompare(wearable_item1, wearable_item2); } diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index eb82418454..d16a2a89c8 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -299,12 +299,12 @@ protected: private: enum ETypeListOrder { - TLO_ATTACHMENT = 0x01, - TLO_CLOTHING = 0x02, + TLO_CLOTHING = 0x01, + TLO_ATTACHMENT = 0x02, TLO_BODYPART = 0x04, TLO_UNKNOWN = 0x08, - TLO_NOT_CLOTHING = TLO_ATTACHMENT | TLO_BODYPART | TLO_UNKNOWN + TLO_SORTABLE_BY_NAME = TLO_ATTACHMENT | TLO_UNKNOWN }; static LLWearableItemTypeNameComparator::ETypeListOrder getTypeListOrder(LLAssetType::EType item_type); 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 10dea659af..362fdd606a 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -382,20 +382,20 @@ It is calculated as border_size + 2*UIResizeBarOverlap <icon follows="bottom|left|right" height="25" - image_name="Toolbar_Right_Off" + image_name="Toolbar_Middle_Off" layout="topleft" left_pad="1" name="dummy_right_icon" - width="246" /> + width="250" /> <button follows="bottom|right" height="25" - image_hover_unselected="Toolbar_Middle_Over" + image_hover_unselected="Toolbar_Right_Over" image_overlay="Shop" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" + image_selected="Toolbar_Right_Selected" + image_unselected="Toolbar_Right_Off" layout="topleft" - left_pad="0" + left_pad="1" name="shop_btn_1" top="1" width="31" /> @@ -468,21 +468,21 @@ It is calculated as border_size + 2*UIResizeBarOverlap <icon follows="bottom|left|right" height="25" - image_name="Toolbar_Right_Off" + image_name="Toolbar_Middle_Off" layout="topleft" left_pad="1" name="dummy_right_icon" - width="153" > + width="154" > </icon> <button follows="bottom|right" height="25" - image_hover_unselected="Toolbar_Middle_Over" + image_hover_unselected="Toolbar_Right_Over" image_overlay="Shop" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" + image_selected="Toolbar_Right_Selected" + image_unselected="Toolbar_Right_Off" layout="topleft" - left_pad="0" + left_pad="1" name="shop_btn_2" top="1" width="31" /> |