SL-12475 add Inventory Favorites tab

master
maxim_productengine 2020-01-27 17:54:02 +02:00
parent 08ac091dbd
commit 92499ce1b4
11 changed files with 225 additions and 24 deletions

View File

@ -238,6 +238,8 @@ public:
void dumpSelectionInformation();
virtual S32 notify(const LLSD& info) ;
void setShowEmptyMessage(bool show_msg) { mShowEmptyMessage = show_msg; }
bool useLabelSuffix() { return mUseLabelSuffix; }
virtual void updateMenu();

View File

@ -392,6 +392,17 @@
<key>Value</key>
<string></string>
</map>
<key>FavoritesFolder</key>
<map>
<key>Comment</key>
<string>User's chosen folder which will be shown in the Favorites tab (UUID)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string></string>
</map>
<key>SnapshotBaseDir</key>
<map>
<key>Comment</key>

View File

@ -134,6 +134,35 @@ bool isMarketplaceSendAction(const std::string& action)
return ("send_to_marketplace" == action);
}
bool isPanelActive(const std::string& panel_name)
{
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
return (active_panel && (active_panel->getName() == panel_name));
}
bool isParentSystemFolder(const LLInventoryModel* model, const LLUUID& folder_id)
{
if (!model || folder_id.isNull()) return false;
LLViewerInventoryCategory* cat = model->getCategory(folder_id);
if (cat)
{
if (cat->getPreferredType() == LLFolderType::FT_ROOT_INVENTORY)
{
return false;
}
if (LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
{
return true;
}
else
{
return isParentSystemFolder(model, cat->getParentUUID());
}
}
return false;
}
// Used by LLFolderBridge as callback for directory fetching recursion
class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
{
@ -884,8 +913,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Properties"));
}
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
if (active_panel && (active_panel->getName() != "All Items"))
if (!isPanelActive("All Items"))
{
items.push_back(std::string("Show in Main Panel"));
}
@ -976,7 +1004,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items,
items.push_back(std::string("Delete"));
if (!isItemRemovable())
if (!isItemRemovable() || isPanelActive("Favorite Items"))
{
disabled_items.push_back(std::string("Delete"));
}
@ -3997,6 +4025,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("New Clothes"));
disabled_items.push_back(std::string("New Body Parts"));
disabled_items.push_back(std::string("upload_def"));
disabled_items.push_back(std::string("Set Favorites folder"));
}
if (favorites == mUUID)
{
@ -4024,6 +4053,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("New Clothes"));
disabled_items.push_back(std::string("New Body Parts"));
disabled_items.push_back(std::string("upload_def"));
disabled_items.push_back(std::string("Set Favorites folder"));
}
if (marketplace_listings_id == mUUID)
{
@ -4032,14 +4062,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("Cut"));
disabled_items.push_back(std::string("Delete"));
}
if (isPanelActive("Favorite Items"))
{
disabled_items.push_back(std::string("Delete"));
}
if(trash_id == mUUID)
{
bool is_recent_panel = false;
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
if (active_panel && (active_panel->getName() == "Recent Items"))
{
is_recent_panel = true;
}
bool is_recent_panel = isPanelActive("Recent Items");
// This is the trash.
items.push_back(std::string("Empty Trash"));
@ -4087,6 +4117,11 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
items.push_back(std::string("New Clothes"));
items.push_back(std::string("New Body Parts"));
items.push_back(std::string("upload_def"));
if (!LLFolderType::lookupIsProtectedType(getPreferredType()) && !isParentSystemFolder(model, mUUID))
{
items.push_back(std::string("Set Favorites folder"));
}
}
}
getClipboardEntries(false, items, disabled_items, flags);

View File

@ -542,6 +542,11 @@ const LLUUID LLInventoryModel::findUserDefinedCategoryUUIDForType(LLFolderType::
cat_id = LLUUID(gSavedPerAccountSettings.getString("AnimationUploadFolder"));
break;
}
case LLFolderType::FT_FAVORITE:
{
cat_id = LLUUID(gSavedPerAccountSettings.getString("FavoritesFolder"));
break;
}
default:
break;
}

View File

@ -169,6 +169,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this));
mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryPanel::fileUploadLocation, this, _2));
mCommitCallbackRegistrar.add("Inventory.SetFavoritesFolder", boost::bind(&LLInventoryPanel::setFavoritesFolder, this, _2));
}
LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
@ -1344,6 +1345,11 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata)
}
}
void LLInventoryPanel::setFavoritesFolder(const LLSD& userdata)
{
gSavedPerAccountSettings.setString("FavoritesFolder", LLFolderBridge::sSelf.get()->getUUID().asString());
}
void LLInventoryPanel::purgeSelectedItems()
{
if (!mFolderRoot.get()) return;
@ -1729,6 +1735,95 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
}
static LLDefaultChildRegistry::Register<LLInventoryFavoriteItemsPanel> t_favorites_inventory_panel("favorites_inventory_panel");
LLInventoryFavoriteItemsPanel::LLInventoryFavoriteItemsPanel(const Params& params)
: LLInventoryPanel(params)
{
std::string ctrl_name = "FavoritesFolder";
if (gSavedPerAccountSettings.controlExists(ctrl_name))
{
LLPointer<LLControlVariable> cntrl_ptr = gSavedPerAccountSettings.getControl(ctrl_name);
if (cntrl_ptr.notNull())
{
mFolderChangedSignal = cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLInventoryFavoriteItemsPanel::updateFavoritesRootFolder, this));
}
}
}
void LLInventoryFavoriteItemsPanel::setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
{
if (mFolderRoot.get())
{
mFolderRoot.get()->setSelectCallback(cb);
mSelectionCallback = cb;
}
}
void LLInventoryFavoriteItemsPanel::initFromParams(const Params& p)
{
Params fav_params(p);
fav_params.start_folder.id = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_FAVORITE);
LLInventoryPanel::initFromParams(fav_params);
updateFavoritesRootFolder();
}
void LLInventoryFavoriteItemsPanel::updateFavoritesRootFolder()
{
const LLUUID& folder_id = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_FAVORITE);
bool is_favorites_set = (folder_id != gInventory.findCategoryUUIDForTypeInRoot(LLFolderType::FT_FAVORITE, true, gInventory.getRootFolderID()));
if (!is_favorites_set || folder_id != getRootFolderID())
{
LLUUID root_id = folder_id;
if (mFolderRoot.get())
{
removeItemID(getRootFolderID());
mFolderRoot.get()->destroyView();
}
mCommitCallbackRegistrar.pushScope();
{
LLFolderView* folder_view = createFolderRoot(root_id);
mFolderRoot = folder_view->getHandle();
addItemID(root_id, mFolderRoot.get());
LLRect scroller_view_rect = getRect();
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
LLScrollContainer::Params scroller_params(mParams.scroll());
scroller_params.rect(scroller_view_rect);
if (mScroller)
{
removeChild(mScroller);
delete mScroller;
mScroller = NULL;
}
mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
addChild(mScroller);
mScroller->addChild(mFolderRoot.get());
mFolderRoot.get()->setScrollContainer(mScroller);
mFolderRoot.get()->setFollowsAll();
mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox);
if (!mSelectionCallback.empty())
{
mFolderRoot.get()->setSelectCallback(mSelectionCallback);
}
}
mCommitCallbackRegistrar.popScope();
mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar);
if (is_favorites_set)
{
buildNewViews(folder_id);
}
mFolderRoot.get()->setShowEmptyMessage(!is_favorites_set);
}
}
namespace LLInitParam
{
void TypeValues<LLFolderType::EType>::declareValues()

View File

@ -205,6 +205,7 @@ public:
void doCreate(const LLSD& userdata);
bool beginIMSession();
void fileUploadLocation(const LLSD& userdata);
void setFavoritesFolder(const LLSD& userdata);
void purgeSelectedItems();
bool attachObject(const LLSD& userdata);
static void idle(void* user_data);
@ -322,4 +323,24 @@ private:
bool mViewsInitialized; // Views have been generated
};
class LLInventoryFavoriteItemsPanel : public LLInventoryPanel
{
public:
struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
{};
void initFromParams(const Params& p);
bool isSelectionRemovable() { return false; }
void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
protected:
LLInventoryFavoriteItemsPanel::LLInventoryFavoriteItemsPanel(const Params& params);
~LLInventoryFavoriteItemsPanel() { mFolderChangedSignal.disconnect(); }
void updateFavoritesRootFolder();
boost::signals2::connection mFolderChangedSignal;
boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback;
friend class LLUICtrlFactory;
};
#endif // LL_LLINVENTORYPANEL_H

View File

@ -184,6 +184,16 @@ BOOL LLPanelMainInventory::postBuild()
worn_filter.markDefault();
mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2));
}
mFavoriteItemsPanel = getChild<LLInventoryFavoriteItemsPanel>("Favorite Items");
if (mFavoriteItemsPanel)
{
LLInventoryFilter& recent_filter = mFavoriteItemsPanel->getFilter();
recent_filter.setEmptyLookupMessage("InventoryFavoritItemsNotSelected");
recent_filter.markDefault();
mFavoriteItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mFavoriteItemsPanel, _1, _2));
}
mSearchTypeCombo = getChild<LLComboBox>("search_type");
if(mSearchTypeCombo)
{
@ -1390,7 +1400,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
}
if (command_name == "delete")
{
return getActivePanel()->isSelectionRemovable();
return getActivePanel()->isSelectionRemovable() && (getActivePanel() != mFavoriteItemsPanel);
}
if (command_name == "save_texture")
{

View File

@ -37,6 +37,7 @@
class LLComboBox;
class LLFolderViewItem;
class LLInventoryPanel;
class LLInventoryFavoriteItemsPanel;
class LLSaveFolderState;
class LLFilterEditor;
class LLTabContainer;
@ -136,6 +137,7 @@ private:
LLHandle<LLFloater> mFinderHandle;
LLInventoryPanel* mActivePanel;
LLInventoryPanel* mWornItemsPanel;
LLInventoryFavoriteItemsPanel* mFavoriteItemsPanel;
bool mResortActivePanel;
LLSaveFolderState* mSavedFolderState;
std::string mFilterText;

View File

@ -358,6 +358,13 @@
parameter="model" />
</menu_item_call>
</menu>
<menu_item_call
label="Use as Favorites folder"
layout="topleft"
name="Set Favorites folder">
<menu_item_call.on_click
function="Inventory.SetFavoritesFolder"/>
</menu_item_call>
<menu
label="Change Type"
layout="topleft"

View File

@ -117,20 +117,32 @@
name="Recent Items"
show_item_link_overlays="true"
width="290" />
<inventory_panel
name="Worn Items"
label="WORN"
show_empty_message="false"
follows="all"
layout="topleft"
width="290"
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
border="false"
bevel_style="none"
scroll.reserve_scroll_corner="false">
</inventory_panel>
<inventory_panel
name="Worn Items"
label="WORN"
show_empty_message="false"
follows="all"
layout="topleft"
width="290"
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
border="false"
bevel_style="none"
scroll.reserve_scroll_corner="false"/>
<favorites_inventory_panel
name="Favorite Items"
label="FAVORITES"
show_empty_message="false"
follows="all"
layout="topleft"
width="290"
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
border="false"
bevel_style="none"
scroll.reserve_scroll_corner="false"/>
</tab_container>
<layout_stack
animate="false"

View File

@ -2291,6 +2291,7 @@ For AI Character: Get the closest navigable point to the point provided.
<!-- inventory -->
<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string>
<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>
<string name="InventoryFavoritItemsNotSelected">Click "Use as Favorites folder" on a folder of your choice. You can choose a different folder at any time. System folders cannot be used for Favorites.</string>
<string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string>
<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>
<string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string>