diff options
author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-10-12 14:07:05 +0300 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-10-12 14:07:05 +0300 |
commit | 56101002a460ecd9bb7a264d55b6f8ecb9a348a0 (patch) | |
tree | da613ed4e420551235416b8f68e0ed87204469a3 | |
parent | dcb5cf5bc21ba2e316cc2889b2c1371860b0348d (diff) | |
parent | 25b19eb6b8b8482d5f6cff0cae8665a0f7518eb1 (diff) |
Merge commit '25b19eb6b8' into marchcat/c-develop
# Conflicts:
# indra/newview/lloutfitgallery.cpp
# indra/newview/lloutfitslist.cpp
# indra/newview/llpanelwearing.cpp
# indra/newview/llwearableitemslist.cpp
18 files changed, 324 insertions, 117 deletions
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 21898366e7..9f49b32f50 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -788,17 +788,14 @@ void LLFolderViewItem::drawOpenFolderArrow() void LLFolderViewItem::drawFavoriteIcon(const Params& default_params, const LLUIColor& fg_color) { static LLUICachedControl<bool> draw_star("InventoryFavoritesUseStar", true); - if (!draw_star) - { - return; - } + static LLUICachedControl<bool> draw_hollow_star("InventoryFavoritesUseHollowStar", true); LLUIImage* favorite_image = NULL; - if (mIsFavorite) + if (draw_star && mIsFavorite) { favorite_image = default_params.favorite_image; } - else if (mHasFavorites && !isOpen()) + else if (draw_hollow_star && mHasFavorites && !isOpen()) { favorite_image = default_params.favorite_content_image; } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 923659e32c..213840dba2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -14336,14 +14336,14 @@ <key>Value</key> <integer>1</integer> </map> - <key>OutfitGallerySortByName</key> + <key>OutfitGallerySortOrder</key> <map> <key>Comment</key> - <string>Always sort outfits by name in Outfit Gallery</string> + <string>Gallery sorting: 0 - sort outfits by name, 1 - images frst, 2 - favorites first</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>Boolean</string> + <string>S32</string> <key>Value</key> <integer>0</integer> </map> @@ -14361,7 +14361,7 @@ <key>OutfitListFilterFullList</key> <map> <key>Comment</key> - <string>How outfit list in Avatar's floater is sorted. 0 - by name 1 - favorites to top</string> + <string> 0 - show only matches. 1 - show all items in outfit as long as outfit or item inside matches.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -16253,6 +16253,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>InventoryFavoritesUseHollowStar</key> + <map> + <key>Comment</key> + <string>Show star near folders that contain favorites</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>InventoryFavoritesColorText</key> <map> <key>Comment</key> diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 6382569fd5..b98329fd20 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -864,11 +864,13 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, { items.push_back(std::string("Remove from Favorites")); } - else if (is_agent_inventory - && gInventory.getRootFolderID() != mUUID - && !gInventory.isObjectDescendentOf(mUUID, gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH))) + else if (is_agent_inventory && !gInventory.isObjectDescendentOf(mUUID, gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH))) { items.push_back(std::string("Add to Favorites")); + if (gInventory.getRootFolderID() == mUUID) + { + disabled_items.push_back(std::string("Add to Favorites")); + } } if (obj->getIsLinkType()) @@ -2310,11 +2312,11 @@ bool LLItemBridge::isFavorite() const LLInventoryModel* model = getInventoryModel(); if(model) { - item = (LLViewerInventoryItem*)model->getItem(mUUID); + item = model->getItem(mUUID); } if (item) { - return item->getIsFavorite(); + return get_is_favorite(item); } return false; } diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 25a834d318..78bff79854 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -641,12 +641,15 @@ bool LLInventoryFilter::checkAgainstFilterFavorites(const LLUUID& object_id) con const LLInventoryObject* object = gInventory.getObject(object_id); if (!object) return true; - const bool is_favorite = object->getIsFavorite(); + if (mFilterOps.mFilterFavorites != FILTER_INCLUDE_FAVORITES) + { + bool is_favorite = get_is_favorite(object); if (is_favorite && (mFilterOps.mFilterFavorites == FILTER_EXCLUDE_FAVORITES)) return false; if (!is_favorite && (mFilterOps.mFilterFavorites == FILTER_ONLY_FAVORITES)) return false; + } return true; } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 879c562af7..9ae542f2d3 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2427,16 +2427,31 @@ public: /* virtual */ void fire(const LLUUID& inv_item_id) override { gInventory.addChangedMask(LLInventoryObserver::UPDATE_FAVORITE, mInvItemID); + + LLInventoryModel::item_array_t items; + LLInventoryModel::cat_array_t cat_array; + LLLinkedItemIDMatches matches(mInvItemID); + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), + cat_array, + items, + LLInventoryModel::INCLUDE_TRASH, + matches); + + std::set<LLUUID> link_ids; + for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it) + { + LLPointer<LLViewerInventoryItem> item = *it; + + gInventory.addChangedMask(LLInventoryObserver::UPDATE_FAVORITE, item->getUUID()); + } + gInventory.notifyObservers(); } private: LLUUID mInvItemID; }; -void set_favorite(const LLUUID& obj_id, bool favorite) -{ - LLInventoryObject* obj = gInventory.getObject(obj_id); - if (obj->getIsFavorite() != favorite) +void favorite_send(LLInventoryObject* obj, const LLUUID& obj_id, bool favorite) { LLSD val; if (favorite) @@ -2467,51 +2482,57 @@ void set_favorite(const LLUUID& obj_id, bool favorite) update_inventory_item(obj_id, updates, cb); } } -} -void toggle_favorite(const LLUUID& obj_id) +bool get_is_favorite(const LLInventoryObject* object) { - LLInventoryObject* obj = gInventory.getObject(obj_id); - if (!obj) + if (object->getIsLinkType()) { - return; + LLInventoryObject* obj = gInventory.getObject(object->getLinkedUUID()); + return obj && obj->getIsFavorite(); } - LLSD updates; - if (!obj->getIsFavorite()) - { - updates["favorite"] = LLSD().with("toggled", true); - } - else + return object->getIsFavorite(); +} + +bool get_is_favorite(const LLUUID& obj_id) +{ + LLInventoryObject* object = gInventory.getObject(obj_id); + if (object && object->getIsLinkType()) { - updates["favorite"] = LLSD(); + LLInventoryObject* obj = gInventory.getObject(object->getLinkedUUID()); + return obj && obj->getIsFavorite(); } - LLPointer<LLInventoryCallback> cb = new LLUpdateFavorite(obj_id); + return object->getIsFavorite(); +} - LLViewerInventoryCategory* view_folder = dynamic_cast<LLViewerInventoryCategory*>(obj); - if (view_folder) +void set_favorite(const LLUUID& obj_id, bool favorite) +{ + LLInventoryObject* obj = gInventory.getObject(obj_id); + + if (obj && obj->getIsLinkType()) { - update_inventory_category(obj_id, updates, cb); + obj = gInventory.getObject(obj_id); } - LLViewerInventoryItem* view_item = dynamic_cast<LLViewerInventoryItem*>(obj); - if (view_item) + + if (obj && obj->getIsFavorite() != favorite) { - update_inventory_item(obj_id, updates, cb); + favorite_send(obj, obj_id, favorite); } } -void toggle_linked_favorite(const LLUUID& obj_id) +void toggle_favorite(const LLUUID& obj_id) { - LLViewerInventoryItem* item = gInventory.getItem(obj_id); - if (!item) + LLInventoryObject* obj = gInventory.getObject(obj_id); + if (obj && obj->getIsLinkType()) { - LL_WARNS() << "Invalid item" << LL_ENDL; - return; + obj = gInventory.getObject(obj_id); } - LLUUID linked_id = item->getLinkedUUID(); - toggle_favorite(linked_id); + if (obj) + { + favorite_send(obj, obj_id, !obj->getIsFavorite()); + } } std::string get_searchable_description(LLInventoryModel* model, const LLUUID& item_id) diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 9005dc9b06..7affd2daf2 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -116,9 +116,10 @@ bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_ca std::string get_localized_folder_name(LLUUID cat_uuid); void new_folder_window(const LLUUID& folder_id); void ungroup_folder_items(const LLUUID& folder_id); +bool get_is_favorite(const LLInventoryObject* object); +bool get_is_favorite(const LLUUID& obj_id); void set_favorite(const LLUUID& obj_id, bool favorite); void toggle_favorite(const LLUUID& obj_id); -void toggle_linked_favorite(const LLUUID& obj_id); std::string get_searchable_description(LLInventoryModel* model, const LLUUID& item_id); std::string get_searchable_creator_name(LLInventoryModel* model, const LLUUID& item_id); std::string get_searchable_UUID(LLInventoryModel* model, const LLUUID& item_id); diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp index 45c5246aa5..aa6416d17d 100644 --- a/indra/newview/llinventorygallery.cpp +++ b/indra/newview/llinventorygallery.cpp @@ -938,6 +938,7 @@ bool LLInventoryGallery::updateAddedItem(LLUUID item_id) } bool res = false; + bool is_favorite = get_is_favorite(obj); LLInventoryGalleryItem* item = buildGalleryItem( name, @@ -949,7 +950,7 @@ bool LLInventoryGallery::updateAddedItem(LLUUID item_id) obj->getCreationDate(), obj->getIsLinkType(), is_worn, - obj->getIsFavorite()); + is_favorite); mItemMap.insert(LLInventoryGallery::gallery_item_map_t::value_type(item_id, item)); if (mGalleryCreated) { @@ -2369,7 +2370,7 @@ void LLInventoryGallery::refreshList(const LLUUID& category_id) return; } - updateChangedItemData(*items_iter, obj->getName(), obj->getIsFavorite()); + updateChangedItemData(*items_iter, obj->getName(), get_is_favorite(obj)); mNeedsArrange = true; } diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp index 018d2e9521..9941115e19 100644 --- a/indra/newview/llinventorygallerymenu.cpp +++ b/indra/newview/llinventorygallerymenu.cpp @@ -811,7 +811,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men if (!is_trash && !is_in_trash && gInventory.getRootFolderID() != selected_id) { - if (obj->getIsFavorite()) + if (get_is_favorite(obj)) { items.push_back(std::string("Remove from Favorites")); } @@ -868,7 +868,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men items.push_back(std::string("Cut")); if (!is_in_trash) { - if (obj->getIsFavorite()) + if (get_is_favorite(obj)) { items.push_back(std::string("Remove from Favorites")); } @@ -1063,7 +1063,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men } } - if (obj->getIsFavorite()) + if (get_is_favorite(obj)) { items.push_back(std::string("Remove from Favorites")); } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index cd36dc1ffb..52c0afbe68 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -628,10 +628,11 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve { if (view_item) { + view_item->refresh(); LLFolderViewFolder* parent = view_item->getParentFolder(); if (parent) { - parent->updateHasFavorites(view_item->isFavorite()); + parent->updateHasFavorites(get_is_favorite(model_item)); } } } @@ -664,7 +665,8 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve setSelection(item_id, false); } updateFolderLabel(model_item->getParentUUID()); - if (model_item->getIsFavorite()) + + if (get_is_favorite(model_item)) { LLFolderViewFolder* new_parent = (LLFolderViewFolder*)getItemByID(model_item->getParentUUID()); if (new_parent) @@ -2423,6 +2425,7 @@ void LLInventoryFavoritesItemsPanel::itemChanged(const LLUUID& id, U32 mask, con LLInventoryObserver::ADD | LLInventoryObserver::REMOVE)) { + // specifically exlude links and not get_is_favorite(model_item) if (model_item && model_item->getIsFavorite()) { LLFolderViewItem* view_item = getItemByID(id); diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index d6a4333e11..72f361c4d9 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -81,9 +81,16 @@ LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p) mItemsInRow(p.items_in_row), mRowPanWidthFactor(p.row_panel_width_factor), mGalleryWidthFactor(p.gallery_width_factor), - mTextureSelected(NULL) + mTextureSelected(NULL), + mSortMenu(nullptr) { updateGalleryWidth(); + + LLControlVariable* ctrl = gSavedSettings.getControl("InventoryFavoritesColorText"); + if (ctrl) + { + mSavedSettingInvFavColor = ctrl->getSignal()->connect(boost::bind(&LLOutfitGallery::handleInvFavColorChange, this)); + } } LLOutfitGallery::Params::Params() @@ -414,19 +421,28 @@ void LLOutfitGallery::updateRowsIfNeeded() bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2) { - static LLCachedControl<bool> outfit_gallery_sort_by_name(gSavedSettings, "OutfitGallerySortByName"); - if(outfit_gallery_sort_by_name || - ((item1->isDefaultImage() && item2->isDefaultImage()) || (!item1->isDefaultImage() && !item2->isDefaultImage()))) - { - std::string name1 = item1->getItemName(); - std::string name2 = item2->getItemName(); - - return (LLStringUtil::compareDict(name1, name2) < 0); - } - else + LLCachedControl<S32> sort_by_name(gSavedSettings, "OutfitGallerySortOrder", 0); + switch (sort_by_name()) { - return item2->isDefaultImage(); + case 2: + if (item1->isFavorite() != item2->isFavorite()) + { + return item1->isFavorite(); + } + break; + case 1: + if (item1->isDefaultImage() != item2->isDefaultImage()) + { + return item2->isDefaultImage(); + } + break; + default: + break; } + + std::string name1 = item1->getItemName(); + std::string name2 = item2->getItemName(); + return (LLStringUtil::compareDict(name1, name2) < 0); } void LLOutfitGallery::reArrangeRows(S32 row_diff) @@ -469,6 +485,20 @@ void LLOutfitGallery::updateGalleryWidth() mGalleryWidth = mGalleryWidthFactor * mItemsInRow - mItemHorizontalGap; } +void LLOutfitGallery::handleInvFavColorChange() +{ + for (outfit_map_t::iterator iter = mOutfitMap.begin(); + iter != mOutfitMap.end(); + ++iter) + { + if (!iter->second) continue; + LLOutfitGalleryItem* item = (LLOutfitGalleryItem*)iter->second; + + // refresh font color + item->setOutfitFavorite(item->isFavorite()); + } +} + LLPanel* LLOutfitGallery::addLastRow() { mRowCount++; @@ -1014,7 +1044,8 @@ void LLOutfitGalleryItem::draw() } } - if(mFavorite) + static LLUICachedControl<bool> draw_star("InventoryFavoritesUseStar", true); + if(mFavorite && draw_star()) { const S32 HPAD = 3; const S32 VPAD = 6; // includes padding for text and for the image @@ -1037,7 +1068,9 @@ void LLOutfitGalleryItem::setOutfitName(std::string name) void LLOutfitGalleryItem::setOutfitFavorite(bool is_favorite) { mFavorite = is_favorite; - mOutfitNameText->setReadOnlyColor(mFavorite ? sDefaultFavoriteColor.get() : sDefaultTextColor.get()); + + LLCachedControl<bool> use_color(gSavedSettings, "InventoryFavoritesColorText"); + mOutfitNameText->setReadOnlyColor((mFavorite && use_color()) ? sDefaultFavoriteColor.get() : sDefaultTextColor.get()); } void LLOutfitGalleryItem::setOutfitWorn(bool value) @@ -1046,11 +1079,13 @@ void LLOutfitGalleryItem::setOutfitWorn(bool value) LLStringUtil::format_map_t worn_string_args; std::string worn_string = getString("worn_string", worn_string_args); mOutfitWornText->setReadOnlyColor(sDefaultTextColor.get()); - mOutfitNameText->setReadOnlyColor(mFavorite ? sDefaultFavoriteColor.get() : sDefaultTextColor.get()); mOutfitWornText->setFont(value ? LLFontGL::getFontSansSerifBold() : LLFontGL::getFontSansSerifSmall()); mOutfitNameText->setFont(value ? LLFontGL::getFontSansSerifBold() : LLFontGL::getFontSansSerifSmall()); mOutfitWornText->setValue(value ? worn_string : ""); mOutfitNameText->setText(mOutfitName); // refresh LLTextViewModel to pick up font changes + + LLCachedControl<bool> use_color(gSavedSettings, "InventoryFavoritesColorText"); + mOutfitNameText->setReadOnlyColor((mFavorite && use_color()) ? sDefaultFavoriteColor.get() : sDefaultTextColor.get()); } void LLOutfitGalleryItem::setSelected(bool value) @@ -1250,17 +1285,6 @@ void LLOutfitGalleryGearMenu::onUpdateItemsVisibility() LLOutfitListGearMenuBase::onUpdateItemsVisibility(); } -void LLOutfitGalleryGearMenu::onChangeSortOrder() -{ - bool sort_by_name = !gSavedSettings.getBOOL("OutfitGallerySortByName"); - gSavedSettings.setBOOL("OutfitGallerySortByName", sort_by_name); - LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); - if (gallery) - { - gallery->reArrangeRows(); - } -} - bool LLOutfitGalleryGearMenu::hasDefaultImage() { LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); @@ -1379,7 +1403,11 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id) LLToggleableMenu* LLOutfitGallery::getSortMenu() { - return nullptr; + if (!mSortMenu) + { + mSortMenu = new LLOutfitGallerySortMenu(this); + } + return mSortMenu->getMenu(); } LLUUID LLOutfitGallery::getPhotoAssetId(const LLUUID& outfit_id) @@ -1397,3 +1425,84 @@ LLUUID LLOutfitGallery::getDefaultPhoto() return LLUUID(); } + +//////////////////// LLOutfitGallerySortMenu //////////////////// + +LLOutfitGallerySortMenu::LLOutfitGallerySortMenu(LLOutfitListBase* parent_panel) + : mPanelHandle(parent_panel->getHandle()) +{ + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + registrar.add("Sort.OnSort", { boost::bind(&LLOutfitGallerySortMenu::onSort, this, _2) }); + enable_registrar.add("Sort.OnEnable", boost::bind(&LLOutfitGallerySortMenu::onEnable, this, _2)); + + mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>( + "menu_outfit_gallery_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + llassert(mMenu); +} + + +LLToggleableMenu* LLOutfitGallerySortMenu::getMenu() +{ + return mMenu; +} + +void LLOutfitGallerySortMenu::updateItemsVisibility() +{ + onUpdateItemsVisibility(); +} + +void LLOutfitGallerySortMenu::onUpdateItemsVisibility() +{ + if (!mMenu) return; +} + +bool LLOutfitGallerySortMenu::onEnable(LLSD::String param) +{ + LLCachedControl<S32> sort_order(gSavedSettings, "OutfitGallerySortOrder", 0); + if ("favorites_to_top" == param) + { + return sort_order == 2; + } + else if ("images_to_top" == param) + { + return sort_order == 1; + } + else if ("by_name" == param) + { + return sort_order == 0; + } + + return false; +} + +void LLOutfitGallerySortMenu::onSort(LLSD::String param) +{ + S32 sort_order = gSavedSettings.getS32("OutfitGallerySortOrder"); + S32 new_sort_order = 0; + if ("favorites_to_top" == param) + { + new_sort_order = 2; + } + else if ("images_to_top" == param) + { + new_sort_order = 1; + } + else if ("by_name" == param) + { + new_sort_order = 0; + } + if (sort_order == new_sort_order) + { + new_sort_order = sort_order ? 0 : 1; + } + gSavedSettings.setS32("OutfitGallerySortOrder", new_sort_order); + + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mPanelHandle.get()); + if (gallery) + { + gallery->reArrangeRows(); + } +} + diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h index c65eb4bd19..1487aa6f5e 100644 --- a/indra/newview/lloutfitgallery.h +++ b/indra/newview/lloutfitgallery.h @@ -42,11 +42,13 @@ class LLOutfitGalleryItem; class LLOutfitListGearMenuBase; class LLOutfitGalleryGearMenu; class LLOutfitGalleryContextMenu; +class LLOutfitGallerySortMenu; class LLOutfitGallery : public LLOutfitListBase { public: friend class LLOutfitGalleryGearMenu; + friend class LLOutfitGallerySortMenu; friend class LLOutfitGalleryContextMenu; friend class LLUpdateGalleryOnPhotoLinked; @@ -135,6 +137,7 @@ private: void reArrangeRows(S32 row_diff = 0); void updateRowsIfNeeded(); void updateGalleryWidth(); + void handleInvFavColorChange(); LLOutfitGalleryItem* buildGalleryItem(std::string name, LLUUID outfit_id, bool is_favorite); LLOutfitGalleryItem* getSelectedItem() const; @@ -178,6 +181,7 @@ private: int mGalleryWidthFactor; LLListContextMenu* mOutfitGalleryMenu; + LLOutfitGallerySortMenu* mSortMenu; typedef std::map<LLUUID, LLOutfitGalleryItem*> outfit_map_t; typedef outfit_map_t::value_type outfit_map_value_t; @@ -189,6 +193,8 @@ private: LLInventoryCategoriesObserver* mOutfitsObserver; + + boost::signals2::connection mSavedSettingInvFavColor; }; class LLOutfitGalleryContextMenu : public LLOutfitContextMenu { @@ -215,8 +221,6 @@ public: protected: /*virtual*/ void onUpdateItemsVisibility(); private: - /*virtual*/ void onChangeSortOrder(); - bool hasDefaultImage(); }; @@ -253,6 +257,7 @@ public: std::string getItemName() {return mOutfitName;} bool isDefaultImage() {return mDefaultImage;} + bool isFavorite() { return mFavorite; } bool isHidden() {return mHidden;} void setHidden(bool hidden) {mHidden = hidden;} @@ -279,4 +284,21 @@ private: static LLUIColor sDefaultFavoriteColor; }; +class LLOutfitGallerySortMenu +{ +public: + LLOutfitGallerySortMenu(LLOutfitListBase* parent_panel); + + LLToggleableMenu* getMenu(); + void updateItemsVisibility(); + +private: + void onUpdateItemsVisibility(); + bool onEnable(LLSD::String param); + void onSort(LLSD::String param); + + LLToggleableMenu* mMenu; + LLHandle<LLPanel> mPanelHandle; +}; + #endif // LL_LLOUTFITGALLERYCTRL_H diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 397fabd5d3..e46f852062 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -784,7 +784,6 @@ void LLOutfitsList::onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUI } } - void LLOutfitsList::handleInvFavColorChange() { for (outfits_map_t::iterator iter = mOutfitsMap.begin(); @@ -1463,10 +1462,6 @@ bool LLOutfitListGearMenuBase::onEnable(LLSD::String param) { return LLAppearanceMgr::instance().getCanReplaceCOF(mOutfitList->getSelectedOutfitUUID()); } - if ("sort_by_image" == param) - { - return !gSavedSettings.getBOOL("OutfitGallerySortByName"); - } return mOutfitList->isActionEnabled(param); } @@ -1547,7 +1542,7 @@ LLOutfitListSortMenu::LLOutfitListSortMenu(LLOutfitListBase* parent_panel) enable_registrar.add("Sort.OnEnable", boost::bind(&LLOutfitListSortMenu::onEnable, this, _2)); mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>( - "menu_outfit_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + "menu_outfit_list_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); llassert(mMenu); } @@ -1581,10 +1576,10 @@ bool LLOutfitListSortMenu::onEnable(LLSD::String param) else if ("show_entire_outfit" == param) { LLCachedControl<bool> filter_mode(gSavedSettings, "OutfitListFilterFullList", 0); - return !filter_mode; + return filter_mode; } - return true; + return false; } diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 5646c8b80c..200eb38ac1 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -113,7 +113,7 @@ protected: boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op)); registrar.add("Wearing.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op)); - registrar.add("Wearing.Favorite", boost::bind(toggle_linked_favorite, mUUIDs.front())); + registrar.add("Wearing.Favorite", boost::bind(toggle_favorite, mUUIDs.front())); LLContextMenu* menu = createFromFile("menu_wearing_tab.xml"); updateMenuItemsVisibility(menu); diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 451befcd1c..f02adce96b 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -933,7 +933,7 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu() // Register handlers for attachments. registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op)); - registrar.add("Attachment.Favorite", boost::bind(toggle_linked_favorite, selected_id)); + registrar.add("Attachment.Favorite", boost::bind(toggle_favorite, selected_id)); registrar.add("Attachment.Touch", boost::bind(handle_attachment_touch, selected_id)); registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id)); registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2)); @@ -968,6 +968,8 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu U32 n_favorites = 0; // number of favorite items among the selected ones bool can_be_worn = true; + bool can_favorite = false; + bool can_unfavorite = false; for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { @@ -992,7 +994,8 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu LLUUID linked_id = item->getLinkedUUID(); LLViewerInventoryItem* linked_item = gInventory.getItem(linked_id); - const bool is_favorite = linked_item->getIsFavorite(); + can_favorite |= !linked_item->getIsFavorite(); + can_unfavorite |= linked_item->getIsFavorite(); if (is_worn) { @@ -1014,10 +1017,6 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu { ++n_already_worn; } - if (is_favorite) - { - ++n_favorites; - } if (can_be_worn) { @@ -1043,8 +1042,8 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu setMenuItemEnabled(menu, "create_new", LLAppearanceMgr::instance().canAddWearables(ids)); setMenuItemVisible(menu, "show_original", !standalone); setMenuItemEnabled(menu, "show_original", n_items == 1 && n_links == n_items); - setMenuItemVisible(menu, "favorites_add", n_favorites < n_items); - setMenuItemVisible(menu, "favorites_remove", n_favorites > 0); + setMenuItemVisible(menu, "favorites_add", can_favorite); + setMenuItemVisible(menu, "favorites_remove", can_unfavorite); setMenuItemVisible(menu, "take_off", mask == MASK_CLOTHING && n_worn == n_items); setMenuItemVisible(menu, "detach", mask == MASK_ATTACHMENT && n_worn == n_items); setMenuItemVisible(menu, "take_off_or_detach", mask == (MASK_ATTACHMENT|MASK_CLOTHING)); diff --git a/indra/newview/skins/default/xui/en/floater_inventory_settings.xml b/indra/newview/skins/default/xui/en/floater_inventory_settings.xml index e027d7556f..08b7a7af05 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_settings.xml @@ -4,8 +4,8 @@ can_minimize="true" can_resize="false" save_rect="true" - height="460" - width="460" + height="483" + width="483" name="inventory_settings" title="INVENTORY SETTINGS"> <icon @@ -210,11 +210,24 @@ left="60" width="300" height="18" - label="Star" + label="Star on favorite items" name="favorite_star" label_text.text_color="White" initial_value="false"/> <check_box + control_name="InventoryFavoritesUseHollowStar" + follows="left|top" + top_pad="5" + layout="topleft" + font="SansSerifMedium" + left="60" + width="150" + height="18" + label="Star on folders containing a favorite" + name="favorite_hollow_star" + label_text.text_color="White" + initial_value="false"/> + <check_box control_name="InventoryFavoritesColorText" follows="left|top" top_pad="5" diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gallery_sort.xml b/indra/newview/skins/default/xui/en/menu_outfit_gallery_sort.xml new file mode 100644 index 0000000000..aa4cd1483d --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_outfit_gallery_sort.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu + layout="topleft" + visible="false" + name="Sort Outfit"> + <menu_item_check + label="Sort favorites to top" + layout="topleft" + visible="true" + name="sort_favorites_to_top"> + <on_click + function="Sort.OnSort" + parameter="favorites_to_top" /> + <on_check + function="Sort.OnEnable" + parameter="favorites_to_top" /> + </menu_item_check> + <menu_item_check + label="Sort images to top" + layout="topleft" + visible="true" + name="sort_images_to_top"> + <on_click + function="Sort.OnSort" + parameter="images_to_top" /> + <on_check + function="Sort.OnEnable" + parameter="images_to_top" /> + </menu_item_check> + <menu_item_check + label="Sort by name" + layout="topleft" + visible="true" + name="sort_by_name"> + <on_click + function="Sort.OnSort" + parameter="by_name" /> + <on_check + function="Sort.OnEnable" + parameter="by_name" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index bd0c49309d..e333b05d3e 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -109,18 +109,6 @@ function="Gear.OnVisible" parameter="delete" /> </menu_item_call> - <menu_item_separator - name="sort_order_separator"/> - <menu_item_check - label="Show outfits with images first" - layout="topleft" - name="sort_order_by_image"> - <on_click - function="Gear.SortByImage" /> - <on_check - function="Gear.OnEnable" - parameter="sort_by_image" /> - </menu_item_check> <menu_item_separator/> <!-- copied (with minor modifications) from menu_inventory_add.xml --> <!-- *TODO: generate dynamically? --> @@ -282,12 +270,12 @@ </menu> <!-- copied from menu_inventory_add.xml --> - <menu_item_separator - name="inv_settings_separator"/> + <menu_item_separator/> <menu_item_check label="Inventory settings..." layout="topleft" + visible="true" name="inventory_settings"> <menu_item_check.on_check function="Floater.Visible" diff --git a/indra/newview/skins/default/xui/en/menu_outfit_sort.xml b/indra/newview/skins/default/xui/en/menu_outfit_list_sort.xml index 0a4d1ea877..0a4d1ea877 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_list_sort.xml |