SL-19105 WIP Single-folder inventory view

master
Maxim Nikolenko 2023-02-17 15:47:03 +02:00
parent 4bc9331ddd
commit 734b1b5d42
22 changed files with 761 additions and 171 deletions

View File

@ -246,6 +246,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

@ -113,6 +113,7 @@ LLFolderViewItem::Params::Params()
icon_width("icon_width", 0),
text_pad("text_pad", 0),
text_pad_right("text_pad_right", 0),
single_folder_mode("single_folder_mode", false),
arrow_size("arrow_size", 0),
max_folder_item_overlap("max_folder_item_overlap", 0)
{ }
@ -151,6 +152,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mTextPad(p.text_pad),
mTextPadRight(p.text_pad_right),
mArrowSize(p.arrow_size),
mSingleFolderMode(p.single_folder_mode),
mMaxFolderItemOverlap(p.max_folder_item_overlap)
{
if (!sColorSetInitialized)
@ -899,7 +901,10 @@ void LLFolderViewItem::draw()
getViewModelItem()->update();
drawOpenFolderArrow(default_params, sFgColor);
if(!mSingleFolderMode)
{
drawOpenFolderArrow(default_params, sFgColor);
}
drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
@ -1830,7 +1835,14 @@ void LLFolderViewFolder::toggleOpen()
// Force a folder open or closed
void LLFolderViewFolder::setOpen(BOOL openitem)
{
setOpenArrangeRecursively(openitem);
if(mSingleFolderMode)
{
getViewModelItem()->navigateToFolder();
}
else
{
setOpenArrangeRecursively(openitem);
}
}
void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
@ -2033,7 +2045,8 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
}
if( !handled )
{
if(mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)
if((mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)
&& !mSingleFolderMode)
{
toggleOpen();
handled = TRUE;
@ -2051,6 +2064,11 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
{
BOOL handled = FALSE;
if(mSingleFolderMode)
{
getViewModelItem()->navigateToFolder();
return TRUE;
}
if( isOpen() )
{
handled = childrenHandleDoubleClick( x, y, mask ) != NULL;

View File

@ -72,6 +72,7 @@ public:
text_pad_right,
arrow_size,
max_folder_item_overlap;
Optional<bool> single_folder_mode;
Params();
};
@ -121,6 +122,7 @@ protected:
mIsMouseOverTitle,
mAllowWear,
mAllowDrop,
mSingleFolderMode,
mSelectPending,
mIsItemCut;

View File

@ -159,6 +159,8 @@ public:
virtual void openItem( void ) = 0;
virtual void closeItem( void ) = 0;
virtual void selectItem(void) = 0;
virtual void navigateToFolder() = 0;
virtual BOOL isItemWearable() const { return FALSE; }

View File

@ -111,6 +111,7 @@ public:
virtual void previewItem( void );
virtual void selectItem(void) { }
virtual void showProperties(void);
virtual void navigateToFolder() {}
// Methods used in sorting (see LLConversationSort::operator())
EConversationType const getType() const { return mConvType; }

View File

@ -138,6 +138,12 @@ 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));
}
// Used by LLFolderBridge as callback for directory fetching recursion
class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
{
@ -407,6 +413,25 @@ void LLInvFVBridge::showProperties()
}
}
void LLInvFVBridge::navigateToFolder()
{
LLInventorySingleFolderPanel* panel = dynamic_cast<LLInventorySingleFolderPanel*>(mInventoryPanel.get());
if (!panel)
{
return;
}
LLInventoryModel* model = getInventoryModel();
if (!model)
{
return;
}
if (mUUID.isNull())
{
return;
}
panel->changeFolderRoot(mUUID);
}
void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
{
// Deactivate gestures when moving them into Trash
@ -921,8 +946,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
addDeleteContextMenuOptions(items, disabled_items);
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
if (active_panel && (active_panel->getName() != "All Items"))
if (!isPanelActive("All Items") && !isPanelActive("single_folder_inv"))
{
items.push_back(std::string("Show in Main Panel"));
}
@ -1013,7 +1037,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"));
}
@ -4141,14 +4165,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"));
@ -4369,6 +4393,20 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
disabled_items.push_back(std::string("New folder from selected"));
}
items.push_back(std::string("open_in_new_window"));
if ((flags & FIRST_SELECTED_ITEM) == 0)
{
disabled_items.push_back(std::string("open_in_new_window"));
}
if(isPanelActive("single_folder_inv"))
{
items.push_back(std::string("open_in_current_window"));
if ((flags & FIRST_SELECTED_ITEM) == 0)
{
disabled_items.push_back(std::string("open_in_current_window"));
}
}
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory)
{

View File

@ -107,6 +107,7 @@ public:
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
virtual void openItem() {}
virtual void closeItem() {}
virtual void navigateToFolder();
virtual void showProperties();
virtual BOOL isItemRenameable() const { return TRUE; }
virtual BOOL isMultiPreviewAllowed() { return TRUE; }

View File

@ -81,7 +81,8 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
mCurrentGeneration(0),
mFirstRequiredGeneration(0),
mFirstSuccessGeneration(0),
mSearchType(SEARCHTYPE_NAME)
mSearchType(SEARCHTYPE_NAME),
mSingleFolderMode(false)
{
// copy mFilterOps into mDefaultFilterOps
markDefault();
@ -1626,7 +1627,7 @@ bool LLInventoryFilter::areDateLimitsSet()
bool LLInventoryFilter::showAllResults() const
{
return hasFilterString();
return hasFilterString() && !mSingleFolderMode;
}

View File

@ -239,6 +239,8 @@ public:
const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; }
bool hasFilterString() const;
void setSingleFolderMode(bool is_single_folder) { mSingleFolderMode = is_single_folder; }
void setFilterPermissions(PermissionMask perms);
PermissionMask getFilterPermissions() const;
@ -361,6 +363,8 @@ private:
std::vector<std::string> mFilterTokens;
std::string mExactToken;
bool mSingleFolderMode;
};
#endif

View File

@ -183,6 +183,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.OpenNewFolderWindow", boost::bind(&LLInventoryPanel::openSingleViewInventory, this, _2));
}
LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
@ -1643,6 +1644,11 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata)
}
}
void LLInventoryPanel::openSingleViewInventory(const LLSD& userdata)
{
LLPanelMainInventory::newFolderWindow(LLFolderBridge::sSelf.get()->getUUID());
}
void LLInventoryPanel::purgeSelectedItems()
{
if (!mFolderRoot.get()) return;
@ -2033,6 +2039,138 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
}
static LLDefaultChildRegistry::Register<LLInventorySingleFolderPanel> t_single_folder_inventory_panel("single_folder_inventory_panel");
LLInventorySingleFolderPanel::LLInventorySingleFolderPanel(const Params& params)
: LLInventoryPanel(params)
{
getFilter().setSingleFolderMode(true);
mCommitCallbackRegistrar.add("Inventory.OpenSelectedFolder", boost::bind(&LLInventorySingleFolderPanel::openInCurrentWindow, this, _2));
}
LLInventorySingleFolderPanel::~LLInventorySingleFolderPanel()
{
}
void LLInventorySingleFolderPanel::setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
{
if (mFolderRoot.get())
{
mFolderRoot.get()->setSelectCallback(cb);
mSelectionCallback = cb;
}
}
void LLInventorySingleFolderPanel::initFromParams(const Params& p)
{
Params fav_params(p);
fav_params.start_folder.id = gInventory.getRootFolderID();
LLInventoryPanel::initFromParams(p);
changeFolderRoot(gInventory.getRootFolderID());
}
void LLInventorySingleFolderPanel::openInCurrentWindow(const LLSD& userdata)
{
changeFolderRoot(LLFolderBridge::sSelf.get()->getUUID());
}
void LLInventorySingleFolderPanel::changeFolderRoot(const LLUUID& new_id)
{
if(mFolderID.notNull())
{
mBackwardFolders.push_back(mFolderID);
}
mFolderID = new_id;
updateSingleFolderRoot();
}
void LLInventorySingleFolderPanel::onForwardFolder()
{
if(!mForwardFolders.empty() && (mFolderID != mForwardFolders.back()))
{
mBackwardFolders.push_back(mFolderID);
mFolderID = mForwardFolders.back();
mForwardFolders.pop_back();
updateSingleFolderRoot();
}
}
void LLInventorySingleFolderPanel::onBackwardFolder()
{
if(!mBackwardFolders.empty() && (mFolderID != mBackwardFolders.back()))
{
mForwardFolders.push_back(mFolderID);
mFolderID = mBackwardFolders.back();
mBackwardFolders.pop_back();
updateSingleFolderRoot();
}
}
void LLInventorySingleFolderPanel::clearNavigationHistory()
{
mForwardFolders.clear();
mBackwardFolders.clear();
}
boost::signals2::connection LLInventorySingleFolderPanel::setRootChangedCallback(root_changed_callback_t cb)
{
return mRootChangedSignal.connect(cb);
}
void LLInventorySingleFolderPanel::updateSingleFolderRoot()
{
if (mFolderID != getRootFolderID())
{
mRootChangedSignal();
LLUUID root_id = mFolderID;
if (mFolderRoot.get())
{
removeItemID(getRootFolderID());
mFolderRoot.get()->destroyView();
}
mCommitCallbackRegistrar.pushScope();
{
LLFolderView* folder_view = createFolderRoot(root_id);
folder_view->setChildrenInited(false);
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);
buildNewViews(mFolderID);
mFolderRoot.get()->setShowEmptyMessage(false);
}
}
/************************************************************************/
/* Asset Pre-Filtered Inventory Panel related class */
/************************************************************************/

View File

@ -222,6 +222,7 @@ public:
void doCreate(const LLSD& userdata);
bool beginIMSession();
void fileUploadLocation(const LLSD& userdata);
void openSingleViewInventory(const LLSD& userdata);
void purgeSelectedItems();
bool attachObject(const LLSD& userdata);
static void idle(void* user_data);
@ -263,6 +264,8 @@ public:
void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response);
void changeFolderRoot(const LLUUID& new_id) {};
protected:
void openStartFolderOrMyInventory(); // open the first level of inventory
void onItemsCompletion(); // called when selected items are complete
@ -382,6 +385,44 @@ private:
std::deque<LLUUID> mBuildViewsQueue;
};
class LLInventorySingleFolderPanel : 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);
void openInCurrentWindow(const LLSD& userdata);
void changeFolderRoot(const LLUUID& new_id);
void onForwardFolder();
void onBackwardFolder();
void clearNavigationHistory();
LLUUID getSingleFolderRoot() { return mFolderID; }
void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
typedef boost::function<void()> root_changed_callback_t;
boost::signals2::connection setRootChangedCallback(root_changed_callback_t cb);
protected:
LLInventorySingleFolderPanel(const Params& params);
~LLInventorySingleFolderPanel();
void updateSingleFolderRoot();
boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback;
friend class LLUICtrlFactory;
LLUUID mFolderID;
std::list<LLUUID> mBackwardFolders;
std::list<LLUUID> mForwardFolders;
boost::signals2::signal<void()> mRootChangedSignal;
};
/************************************************************************/
/* Asset Pre-Filtered Inventory Panel related class */
/* Exchanges filter's flexibility for speed of generation and */

View File

@ -38,7 +38,6 @@
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventorypanel.h"
#include "llfiltereditor.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterreg.h"
@ -114,7 +113,9 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mMenuVisibility(NULL),
mMenuAddHandle(),
mNeedUploadCost(true),
mMenuViewDefault(NULL)
mMenuViewDefault(NULL),
mSingleFolderMode(false),
mFolderRootChangedConnection()
{
// Menu Callbacks (non contex menus)
mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2));
@ -240,6 +241,9 @@ BOOL LLPanelMainInventory::postBuild()
mVisibilityMenuButton = getChild<LLMenuButton>("options_visibility_btn");
mViewMenuButton = getChild<LLMenuButton>("view_btn");
mSingleFolderPanelInventory = getChild<LLInventorySingleFolderPanel>("single_folder_inv");
mFolderRootChangedConnection = mSingleFolderPanelInventory->setRootChangedCallback(boost::bind(&LLPanelMainInventory::updateTitle, this));
initListCommandsHandlers();
const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
@ -316,6 +320,11 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
menu->die();
mMenuAddHandle.markDead();
}
if (mFolderRootChangedConnection.connected())
{
mFolderRootChangedConnection.disconnect();
}
}
LLInventoryPanel* LLPanelMainInventory::getAllItemsPanel()
@ -383,10 +392,17 @@ void LLPanelMainInventory::closeAllFolders()
getPanel()->getRootFolder()->closeAllFolders();
}
S32 get_instance_num()
{
static S32 instance_num = 0;
instance_num = (instance_num + 1) % S32_MAX;
return instance_num;
}
void LLPanelMainInventory::newWindow()
{
static S32 instance_num = 0;
instance_num = (instance_num + 1) % S32_MAX;
S32 instance_num = get_instance_num();
if (!gAgentCamera.cameraMouselook())
{
@ -394,10 +410,45 @@ void LLPanelMainInventory::newWindow()
}
}
void LLPanelMainInventory::newFolderWindow(const LLUUID& folder_id)
{
S32 instance_num = get_instance_num();
LLFloaterSidePanelContainer* inventory_container = LLFloaterReg::showTypedInstance<LLFloaterSidePanelContainer>("inventory", LLSD(instance_num));
if(inventory_container)
{
LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(inventory_container->findChild<LLPanel>("main_panel", true));
if (sidepanel_inventory)
{
LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
if (main_inventory)
{
main_inventory->onViewModeClick();
if(folder_id.notNull())
{
main_inventory->setSingleFolderViewRoot(folder_id);
}
}
}
}
}
void LLPanelMainInventory::doCreate(const LLSD& userdata)
{
reset_inventory_filter();
menu_create_inventory_item(getPanel(), NULL, userdata);
if(mSingleFolderMode)
{
LLFolderViewItem* current_folder = getActivePanel()->getRootFolder();
if (current_folder)
{
LLFolderBridge* bridge = (LLFolderBridge*)current_folder->getViewModelItem();
menu_create_inventory_item(getPanel(), bridge, userdata);
}
}
else
{
menu_create_inventory_item(getPanel(), NULL, userdata);
}
}
void LLPanelMainInventory::resetFilters()
@ -527,7 +578,7 @@ void LLPanelMainInventory::onClearSearch()
}
// re-open folders that were initially open in case filter was active
if (mActivePanel && (mFilterSubString.size() || initially_active))
if (mActivePanel && (mFilterSubString.size() || initially_active) && !mSingleFolderMode)
{
mSavedFolderState->setApply(TRUE);
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@ -1173,10 +1224,15 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
void LLPanelMainInventory::initListCommandsHandlers()
{
childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
childSetAction("view_mode_btn", boost::bind(&LLPanelMainInventory::onViewModeClick, this));
childSetAction("up_btn", boost::bind(&LLPanelMainInventory::onUpFolderClicked, this));
childSetAction("back_btn", boost::bind(&LLPanelMainInventory::onBackFolderClicked, this));
childSetAction("forward_btn", boost::bind(&LLPanelMainInventory::onForwardFolderClicked, this));
mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2));
mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
mEnableCallbackRegistrar.add("Inventory.GearDefault.Visible", boost::bind(&LLPanelMainInventory::isActionVisible, this, _2));
mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_TOP_LEFT, true);
mMenuViewDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_view_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
@ -1211,6 +1267,47 @@ void LLPanelMainInventory::onAddButtonClick()
}
}
void LLPanelMainInventory::onViewModeClick()
{
mSingleFolderMode = !mSingleFolderMode;
getChild<LLPanel>("default_inventory_panel")->setVisible(!mSingleFolderMode);
getChild<LLPanel>("single_folder_inventory")->setVisible(mSingleFolderMode);
getChild<LLLayoutPanel>("nav_buttons")->setVisible(mSingleFolderMode);
getChild<LLButton>("view_mode_btn")->setImageOverlay(mSingleFolderMode ? getString("default_mode_btn") : getString("single_folder_mode_btn"));
mActivePanel = mSingleFolderMode ? getChild<LLInventoryPanel>("single_folder_inv") : (LLInventoryPanel*)getChild<LLTabContainer>("inventory filter tabs")->getCurrentPanel();
updateTitle();
}
void LLPanelMainInventory::onUpFolderClicked()
{
const LLViewerInventoryCategory* cat = gInventory.getCategory(mSingleFolderPanelInventory->getSingleFolderRoot());
if (cat)
{
if (cat->getParentUUID().notNull())
{
mSingleFolderPanelInventory->changeFolderRoot(cat->getParentUUID());
}
}
}
void LLPanelMainInventory::onBackFolderClicked()
{
mSingleFolderPanelInventory->onBackwardFolder();
}
void LLPanelMainInventory::onForwardFolderClicked()
{
mSingleFolderPanelInventory->onForwardFolder();
}
void LLPanelMainInventory::setSingleFolderViewRoot(const LLUUID& folder_id)
{
mSingleFolderPanelInventory->changeFolderRoot(folder_id);
mSingleFolderPanelInventory->clearNavigationHistory();
}
void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
{
if (menu)
@ -1254,6 +1351,27 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
return;
const std::string command_name = userdata.asString();
if (command_name == "new_single_folder_window")
{
newFolderWindow(LLUUID());
}
if ((command_name == "open_in_current_window") || (command_name == "open_in_new_window"))
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item)
{
return;
}
const LLUUID& folder_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
if((command_name == "open_in_current_window"))
{
mSingleFolderPanelInventory->changeFolderRoot(folder_id);
}
if((command_name == "open_in_new_window"))
{
newFolderWindow(folder_id);
}
}
if (command_name == "new_window")
{
newWindow();
@ -1505,10 +1623,34 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id);
return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id);
}
if (command_name == "open_folder")
{
LLFolderView* root = getActivePanel()->getRootFolder();
std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
if (selection_set.size() != 1) return FALSE;
LLFolderViewItem* current_item = *selection_set.begin();
if (!current_item) return FALSE;
const LLUUID& folder_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
return (gInventory.getCategory(folder_id) != NULL);
}
return TRUE;
}
bool LLPanelMainInventory::isActionVisible(const LLSD& userdata)
{
const std::string param_str = userdata.asString();
if (param_str == "single_folder_view")
{
return mSingleFolderMode;
}
if (param_str == "multi_folder_view")
{
return !mSingleFolderMode;
}
return true;
}
BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata)
{
U32 sort_order_mask = getActivePanel()->getSortOrder();
@ -1576,5 +1718,24 @@ bool LLPanelMainInventory::hasSettingsInventory()
return LLEnvironment::instance().isInventoryEnabled();
}
void LLPanelMainInventory::updateTitle()
{
LLFloater* inventory_floater = gFloaterView->getParentFloater(this);
if(inventory_floater)
{
if(mSingleFolderMode)
{
const LLViewerInventoryCategory* cat = gInventory.getCategory(mSingleFolderPanelInventory->getSingleFolderRoot());
if (cat)
{
inventory_floater->setTitle(cat->getName());
}
}
else
{
inventory_floater->setTitle(getString("inventory_title"));
}
}
}
// List Commands //
////////////////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@
#include "llpanel.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "lldndbutton.h"
#include "llfolderview.h"
@ -92,10 +93,16 @@ public:
void setFocusFilterEditor();
static void newWindow();
static void newFolderWindow(const LLUUID& folder_id);
void toggleFindOptions();
void resetFilters();
void onViewModeClick();
void onUpFolderClicked();
void onBackFolderClicked();
void onForwardFolderClicked();
void setSingleFolderViewRoot(const LLUUID& folder_id);
protected:
//
@ -149,7 +156,10 @@ private:
std::string mCategoryCountString;
LLComboBox* mSearchTypeCombo;
bool mSingleFolderMode;
LLInventorySingleFolderPanel* mSingleFolderPanelInventory;
boost::signals2::connection mFolderRootChangedConnection;
//////////////////////////////////////////////////////////////////////////////////
// List Commands //
@ -162,7 +172,9 @@ protected:
BOOL isActionEnabled(const LLSD& command_name);
BOOL isActionChecked(const LLSD& userdata);
void onCustomAction(const LLSD& command_name);
bool isActionVisible(const LLSD& userdata);
static bool hasSettingsInventory();
void updateTitle();
/**
* Set upload cost in "Upload" sub menu.
*/

View File

@ -125,6 +125,7 @@ public:
virtual BOOL canOpenItem() const { return FALSE; }
virtual void closeItem() {}
virtual void selectItem() {}
virtual void navigateToFolder() {}
virtual BOOL isItemRenameable() const;
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL isItemMovable() const;

View File

@ -9703,6 +9703,7 @@ void initialize_menus()
commit.add("PayObject", boost::bind(&handle_give_money_dialog));
commit.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow));
commit.add("Inventory.NewFolderWindow", boost::bind(&LLPanelMainInventory::newFolderWindow, LLUUID()));
enable.add("EnablePayObject", boost::bind(&enable_pay_object));
enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar));

View File

@ -5,14 +5,14 @@
can_resize="true"
height="570"
help_topic="sidebar_inventory"
min_width="333"
min_width="363"
min_height="590"
name="floater_my_inventory"
save_rect="true"
save_visibility="true"
reuse_instance="true"
title="INVENTORY"
width="333" >
width="363" >
<panel
class="sidepanel_inventory"
name="main_panel"

View File

@ -401,6 +401,20 @@
parameter="model" />
</menu_item_call>
</menu>
<menu_item_call
label="Open"
layout="topleft"
name="open_in_current_window">
<menu_item_call.on_click
function="Inventory.OpenSelectedFolder"/>
</menu_item_call>
<menu_item_call
label="Open in new window"
layout="topleft"
name="open_in_new_window">
<menu_item_call.on_click
function="Inventory.OpenNewFolderWindow"/>
</menu_item_call>
<menu
label="Change Type"
layout="topleft"

View File

@ -6,15 +6,39 @@
mouse_opaque="false"
name="menu_gear_default"
visible="false">
<menu_item_call
label="Open"
layout="topleft"
name="open_in_current_window">
<on_click
function="Inventory.GearDefault.Custom.Action"
parameter="open_in_current_window" />
<on_enable
function="Inventory.GearDefault.Enable"
parameter="open_folder" />
<on_visible
function="Inventory.GearDefault.Visible"
parameter="single_folder_view" />
</menu_item_call>
<menu_item_call
label="Open in new window"
layout="topleft"
name="open_in_new_window">
<on_click
function="Inventory.GearDefault.Custom.Action"
parameter="open_in_new_window" />
<on_enable
function="Inventory.GearDefault.Enable"
parameter="open_folder" />
</menu_item_call>
<menu_item_call
label="New Folder Window"
layout="topleft"
shortcut="control|shift|J"
enabled="false"
name="new_single_folder">
<on_click
function="Inventory.GearDefault.Custom.Action"
parameter="new_window" />
parameter="new_single_folder_window" />
</menu_item_call>
<menu_item_call
label="New Inventory Window"
@ -32,6 +56,9 @@
<on_click
function="Inventory.GearDefault.Custom.Action"
parameter="close_folders" />
<on_visible
function="Inventory.GearDefault.Visible"
parameter="multi_folder_view" />
</menu_item_call>
<menu_item_separator
layout="topleft" />
@ -115,6 +142,9 @@
<on_enable
function="Inventory.GearDefault.Enable"
parameter="empty_lostnfound" />
<on_visible
function="Inventory.GearDefault.Visible"
parameter="multi_folder_view" />
</menu_item_call>
<menu_item_call
label="Empty Trash"
@ -126,5 +156,8 @@
<on_enable
function="Inventory.GearDefault.Enable"
parameter="empty_trash" />
<on_visible
function="Inventory.GearDefault.Visible"
parameter="multi_folder_view" />
</menu_item_call>
</toggleable_menu>

View File

@ -49,5 +49,8 @@
<on_check
function="Inventory.GearDefault.Check"
parameter="sort_system_folders_to_top" />
<on_visible
function="Inventory.GearDefault.Visible"
parameter="multi_folder_view" />
</menu_item_check>
</toggleable_menu>

View File

@ -36,6 +36,15 @@
function="Inventory.NewWindow"
parameter="" />
</menu_item_call>
<menu_item_call
label="New Folder Window"
name="new_single_folder"
shortcut="control|shift|J"
visible="false">
<menu_item_call.on_click
function="Inventory.NewFolderWindow"
parameter="" />
</menu_item_call>
<menu_item_call
label="Places..."
name="Places"

View File

@ -23,6 +23,9 @@
name="ItemcountUnknown">
Fetched [ITEM_COUNT] Items and [CATEGORY_COUNT] Folders [FILTER]
</panel.string>
<panel.string name="inventory_title">INVENTORY</panel.string>
<panel.string name="default_mode_btn">Command_AboutLand_Icon</panel.string>
<panel.string name="single_folder_mode_btn">Command_Map_Icon</panel.string>
<text
type="string"
length="1"
@ -38,157 +41,262 @@
width="300">
Items:
</text>
<combo_box
height="23"
layout="topleft"
left="3"
top="18"
name="search_type"
follows="top|left"
width="67">
<item
label="Name"
name="Name"
value="search_by_name"/>
<item
label="Creator"
name="Creator"
value="search_by_creator"/>
<item
label="Description"
name="Description"
value="search_by_description"/>
<item
label="UUID"
name="UUID"
value="search_by_UUID"/>
</combo_box>
<menu_button
follows="top|left"
tool_tip="Show search visibility options"
height="23"
image_overlay="Inv_Toolbar_SearchVisibility"
layout="topleft"
left_pad="1"
name="options_visibility_btn"
width="31" />
<filter_editor
text_pad_left="10"
<layout_stack
follows="left|top|right"
height="23"
label="Enter search text"
layout="topleft"
left_pad="1"
max_length_chars="300"
highlight_text_field="true"
name="inventory search editor"
width="99" />
<menu_button
follows="top|right"
tool_tip="Show additional options"
height="23"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="OptionsMenu_Off"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
left_pad="1"
name="options_gear_btn"
width="31" />
<menu_button
follows="top|right"
tool_tip="View/sort options"
height="23"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="Conv_toolbar_sort"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
left_pad="1"
name="view_btn"
width="31" />
<button
follows="top|right"
height="23"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="AddItem_Off"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
left_pad="1"
name="add_btn"
tool_tip="Add new item"
width="31" />
<button
follows="top|right"
tool_tip="Toggles between traditional and single-folder views"
height="23"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="Command_Map_Icon"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
left_pad="1"
enabled="false"
name="view_mode_btn"
width="31" />
<tab_container
height="25"
animate="false"
top_pad="10"
left="2"
orientation="horizontal">
<layout_panel
border="false"
bevel_style="in"
user_resize="false"
auto_resize="false"
height="25"
width="65"
name="nav_buttons"
visible="false">
<button
follows="top|left"
height="23"
image_selected="Arrow_Left"
image_pressed="Arrow_Left"
image_unselected="Arrow_Left"
scale_image="false"
layout="topleft"
left="3"
top="2"
name="back_btn"
tool_tip="Back"
width="20" />
<button
follows="top|left"
height="23"
image_selected="Arrow_Right"
image_pressed="Arrow_Right"
image_unselected="Arrow_Right"
scale_image="false"
layout="topleft"
left_pad="1"
name="forward_btn"
tool_tip="Forward"
width="20" />
<button
follows="top|left"
height="23"
image_selected="Arrow_Up"
image_pressed="Arrow_Up"
image_unselected="Arrow_Up"
scale_image="false"
layout="topleft"
left_pad="1"
name="up_btn"
tool_tip="Go up one level"
width="20" />
</layout_panel>
<layout_panel
border="false"
bevel_style="in"
user_resize="false"
height="25"
width="375"
visible="true">
<combo_box
height="23"
layout="topleft"
left="2"
top="0"
name="search_type"
tool_tip="Search by"
follows="top|left"
width="67">
<item
label="Name"
name="Name"
value="search_by_name"/>
<item
label="Creator"
name="Creator"
value="search_by_creator"/>
<item
label="Description"
name="Description"
value="search_by_description"/>
<item
label="UUID"
name="UUID"
value="search_by_UUID"/>
</combo_box>
<menu_button
follows="top|left"
tool_tip="Search visibility options"
height="23"
image_overlay="Inv_Toolbar_SearchVisibility"
layout="topleft"
left_pad="1"
name="options_visibility_btn"
width="31" />
<filter_editor
text_pad_left="10"
follows="left|top|right"
height="23"
label="Enter search text"
layout="topleft"
left_pad="1"
max_length_chars="300"
highlight_text_field="true"
name="inventory search editor"
width="150" />
<menu_button
follows="top|right"
tool_tip="Actions"
height="23"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="OptionsMenu_Off"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
left_pad="1"
name="options_gear_btn"
width="31" />
<menu_button
follows="top|right"
tool_tip="View &amp; sort options"
height="23"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="Conv_toolbar_sort"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
left_pad="1"
name="view_btn"
width="31" />
<button
follows="top|right"
height="23"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="AddItem_Off"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
left_pad="1"
name="add_btn"
tool_tip="Create new item"
width="31" />
<button
follows="top|right"
tool_tip="Switch between views"
height="23"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="Command_Map_Icon"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
left_pad="1"
name="view_mode_btn"
width="31" />
</layout_panel>
</layout_stack>
<panel
follows="all"
halign="center"
height="372"
layout="topleft"
left="7"
name="inventory filter tabs"
tab_height="30"
tab_position="top"
tab_min_width="100"
name="default_inventory_panel"
top_pad="10"
width="312">
<inventory_panel
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
border="false"
bevel_style="none"
<tab_container
follows="all"
halign="center"
height="372"
layout="topleft"
left="0"
name="inventory filter tabs"
tab_height="30"
tab_position="top"
tab_min_width="100"
top="0"
width="312">
<inventory_panel
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
border="false"
bevel_style="none"
follows="all"
height="338"
label="MY INVENTORY"
help_topic="my_inventory_tab"
layout="topleft"
left="0"
name="All Items"
sort_order_setting="InventorySortOrder"
show_item_link_overlays="true"
top="16"
width="288" />
<recent_inventory_panel
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
border="false"
bevel_style="none"
follows="all"
height="338"
label="RECENT"
help_topic="recent_inventory_tab"
layout="topleft"
left_delta="0"
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>
</tab_container>
</panel>
<panel
follows="all"
height="338"
label="MY INVENTORY"
help_topic="my_inventory_tab"
halign="center"
height="372"
layout="topleft"
left="0"
name="All Items"
sort_order_setting="InventorySortOrder"
show_item_link_overlays="true"
top="16"
width="288" />
<recent_inventory_panel
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
border="false"
bevel_style="none"
follows="all"
height="338"
label="RECENT"
help_topic="recent_inventory_tab"
layout="topleft"
left_delta="0"
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>
</tab_container>
left="7"
name="single_folder_inventory"
top_delta="0"
visible="false"
width="312">
<single_folder_inventory_panel
name="single_folder_inv"
show_empty_message="false"
follows="all"
left="0"
top="0"
top_pad="5"
height="372"
width="312"
layout="topleft"
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
border="false"
bevel_style="none"
scroll.reserve_scroll_corner="false">
<item folder_indentation="0"/>
<folder
single_folder_mode="true"
folder_indentation="0"/>
</single_folder_inventory_panel>
</panel>
</panel>

View File

@ -18,7 +18,7 @@
height="570"
visible="true"
default_tab_group="1"
width="355">
width="395">
<layout_stack
follows="left|right|top|bottom"
layout="topleft"
@ -28,14 +28,14 @@
orientation="vertical"
name="inventory_layout_stack"
height="565"
width="355">
width="395">
<layout_panel
name="main_inventory_layout_panel"
layout="topleft"
auto_resize="true"
user_resize="true"
min_dim="150"
width="355"
width="395"
follows="bottom|left|right"
height="300">
<panel
@ -48,7 +48,7 @@
top="0"
label=""
height="300"
width="355" />
width="395" />
</layout_panel>
<layout_panel
width="355"