summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2024-10-12 14:07:05 +0300
committerAndrey Lihatskiy <alihatskiy@productengine.com>2024-10-12 14:07:05 +0300
commit56101002a460ecd9bb7a264d55b6f8ecb9a348a0 (patch)
treeda613ed4e420551235416b8f68e0ed87204469a3
parentdcb5cf5bc21ba2e316cc2889b2c1371860b0348d (diff)
parent25b19eb6b8b8482d5f6cff0cae8665a0f7518eb1 (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
-rw-r--r--indra/llui/llfolderviewitem.cpp9
-rw-r--r--indra/newview/app_settings/settings.xml19
-rw-r--r--indra/newview/llinventorybridge.cpp12
-rw-r--r--indra/newview/llinventoryfilter.cpp5
-rw-r--r--indra/newview/llinventoryfunctions.cpp81
-rw-r--r--indra/newview/llinventoryfunctions.h3
-rw-r--r--indra/newview/llinventorygallery.cpp5
-rw-r--r--indra/newview/llinventorygallerymenu.cpp6
-rw-r--r--indra/newview/llinventorypanel.cpp7
-rw-r--r--indra/newview/lloutfitgallery.cpp163
-rw-r--r--indra/newview/lloutfitgallery.h26
-rw-r--r--indra/newview/lloutfitslist.cpp11
-rw-r--r--indra/newview/llpanelwearing.cpp2
-rw-r--r--indra/newview/llwearableitemslist.cpp15
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_settings.xml19
-rw-r--r--indra/newview/skins/default/xui/en/menu_outfit_gallery_sort.xml42
-rw-r--r--indra/newview/skins/default/xui/en/menu_outfit_gear.xml16
-rw-r--r--indra/newview/skins/default/xui/en/menu_outfit_list_sort.xml (renamed from indra/newview/skins/default/xui/en/menu_outfit_sort.xml)0
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