phoenix-firestorm/indra/newview/llinventorygallery.h

424 lines
15 KiB
C++

/**
* @file llinventorygallery.h
* @brief LLInventoryGallery class definition
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLINVENTORYGALLERY_H
#define LL_LLINVENTORYGALLERY_H
#include "llgesturemgr.h"
#include "lllistcontextmenu.h"
#include "llpanel.h"
#include "llinventoryfilter.h"
#include "llinventoryobserver.h"
#include "llinventorymodel.h"
class LLInventoryCategoriesObserver;
class LLInventoryGalleryItem;
class LLScrollContainer;
class LLTextBox;
class LLThumbnailsObserver;
class LLThumbnailCtrl;
class LLGalleryGestureObserver;
class LLInventoryGalleryContextMenu;
typedef boost::function<void()> callback_t;
class LLInventoryGallery : public LLPanel, public LLEditMenuHandler
{
public:
typedef boost::signals2::signal<void(const LLUUID&)> selection_change_signal_t;
typedef boost::function<void(const LLUUID&)> selection_change_callback_t;
typedef std::deque<LLUUID> selection_deque;
struct Params
: public LLInitParam::Block<Params, LLPanel::Params>
{
Optional<S32> row_panel_height;
Optional<S32> row_panel_width_factor;
Optional<S32> gallery_width_factor;
Optional<S32> vertical_gap;
Optional<S32> horizontal_gap;
Optional<S32> item_width;
Optional<S32> item_height;
Optional<S32> item_horizontal_gap;
Optional<S32> items_in_row;
Params();
};
static const LLInventoryGallery::Params& getDefaultParams();
LLInventoryGallery(const LLInventoryGallery::Params& params = getDefaultParams());
~LLInventoryGallery();
BOOL postBuild() override;
void initGallery();
void draw() override;
void onVisibilityChange(BOOL new_visibility) override;
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type,
void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) override;
void startDrag();
BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) override;
BOOL handleKeyHere(KEY key, MASK mask) override;
void moveUp(MASK mask);
void moveDown(MASK mask);
void moveLeft(MASK mask);
void moveRight(MASK mask);
void toggleSelectionRange(S32 start_idx, S32 end_idx);
void toggleSelectionRangeFromLast(const LLUUID target);
void onFocusLost() override;
void onFocusReceived() override;
void setFilterSubString(const std::string& string);
std::string getFilterSubString() { return mFilterSubString; }
LLInventoryFilter& getFilter() const { return *mFilter; }
bool checkAgainstFilterType(const LLUUID& object_id);
void getCurrentCategories(uuid_vec_t& vcur);
bool updateAddedItem(LLUUID item_id); // returns true if added item is visible
void updateRemovedItem(LLUUID item_id);
void updateChangedItemName(LLUUID item_id, std::string name);
void updateItemThumbnail(LLUUID item_id);
void updateWornItem(LLUUID item_id, bool is_worn);
void updateMessageVisibility();
void setRootFolder(const LLUUID cat_id);
void updateRootFolder();
LLUUID getRootFolder() { return mFolderID; }
bool isRootDirty() { return mRootDirty; }
boost::signals2::connection setRootChangedCallback(callback_t cb);
void onForwardFolder();
void onBackwardFolder();
void clearNavigationHistory();
bool isBackwardAvailable();
bool isForwardAvailable();
void setNavBackwardList(std::list<LLUUID> backward_list) { mBackwardFolders = backward_list; }
void setNavForwardList(std::list<LLUUID> forward_list) { mForwardFolders = forward_list; }
std::list<LLUUID> getNavBackwardList() { return mBackwardFolders; }
std::list<LLUUID> getNavForwardList() { return mForwardFolders; }
LLUUID getOutfitImageID(LLUUID outfit_id);
void refreshList(const LLUUID& category_id);
void onCOFChanged();
void onGesturesChanged();
void computeDifference(const LLInventoryModel::cat_array_t vcats, const LLInventoryModel::item_array_t vitems, uuid_vec_t& vadded, uuid_vec_t& vremoved);
void deselectItem(const LLUUID& category_id);
void clearSelection();
void changeItemSelection(const LLUUID& item_id, bool scroll_to_selection = false);
void addItemSelection(const LLUUID& item_id, bool scroll_to_selection = false);
bool toggleItemSelection(const LLUUID& item_id, bool scroll_to_selection = false);
void scrollToShowItem(const LLUUID& item_id);
void signalSelectionItemID(const LLUUID& category_id);
boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb);
LLUUID getFirstSelectedItemID();
void setSearchType(LLInventoryFilter::ESearchType type);
LLInventoryFilter::ESearchType getSearchType() { return mSearchType; }
bool areViewsInitialized();
bool hasDescendents(const LLUUID& cat_id);
bool hasVisibleItems();
void handleModifiedFilter();
LLScrollContainer* getScrollableContainer() { return mScrollPanel; }
LLInventoryGalleryItem* getFirstSelectedItem();
// Copy & paste (LLEditMenuHandler)
void copy() override;
BOOL canCopy() const override;
void cut() override;
BOOL canCut() const override;
void paste() override;
BOOL canPaste() const override;
// Copy & paste & delete
static void onDelete(const LLSD& notification, const LLSD& response, const selection_deque selected_ids);
void deleteSelection();
bool canDeleteSelection();
void pasteAsLink();
void setSortOrder(U32 order, bool update = false);
U32 getSortOrder() { return mSortOrder; };
void claimEditHandler();
void resetEditHandler();
static bool isItemCopyable(const LLUUID & item_id);
BOOL baseHandleDragAndDrop(LLUUID dest_id, BOOL drop, EDragAndDropType cargo_type,
void* cargo_data, EAcceptance* accept, std::string& tooltip_msg);
void showContextMenu(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& item_id);
protected:
void paste(const LLUUID& dest,
std::vector<LLUUID>& objects,
bool is_cut_mode,
const LLUUID& marketplacelistings_id);
void pasteAsLink(const LLUUID& dest,
std::vector<LLUUID>& objects,
const LLUUID& current_outfit_id,
const LLUUID& marketplacelistings_id,
const LLUUID& my_outifts_id);
bool applyFilter(LLInventoryGalleryItem* item, const std::string& filter_substring);
bool checkAgainstFilters(LLInventoryGalleryItem* item, const std::string& filter_substring);
static void onIdle(void* userdata);
void dirtyRootFolder();
LLInventoryCategoriesObserver* mCategoriesObserver;
LLThumbnailsObserver* mThumbnailsObserver;
LLGalleryGestureObserver* mGestureObserver;
LLInventoryObserver* mInventoryObserver;
selection_deque mSelectedItemIDs;
selection_deque mItemsToSelect;
LLUUID mLastInteractedUUID;
bool mIsInitialized;
bool mRootDirty;
selection_change_signal_t mSelectionChangeSignal;
boost::signals2::signal<void()> mRootChangedSignal;
LLUUID mFolderID;
std::list<LLUUID> mBackwardFolders;
std::list<LLUUID> mForwardFolders;
private:
void addToGallery(LLInventoryGalleryItem* item);
void removeFromGalleryLast(LLInventoryGalleryItem* item, bool needs_reshape = true);
void removeFromGalleryMiddle(LLInventoryGalleryItem* item);
LLPanel* addLastRow();
void removeLastRow();
void moveRowUp(int row);
void moveRowDown(int row);
void moveRow(int row, int pos);
LLPanel* addToRow(LLPanel* row_stack, LLInventoryGalleryItem* item, int pos, int hgap);
void removeFromLastRow(LLInventoryGalleryItem* item);
void reArrangeRows(S32 row_diff = 0);
bool updateRowsIfNeeded();
void updateGalleryWidth();
LLInventoryGalleryItem* buildGalleryItem(std::string name, LLUUID item_id, LLAssetType::EType type, LLUUID thumbnail_id, LLInventoryType::EType inventory_type, U32 flags, time_t creation_date, bool is_link, bool is_worn);
void buildGalleryPanel(int row_count);
void reshapeGalleryPanel(int row_count);
LLPanel* buildItemPanel(int left);
LLPanel* buildRowPanel(int left, int bottom);
void moveRowPanel(LLPanel* stack, int left, int bottom);
std::vector<LLPanel*> mRowPanels;
std::vector<LLPanel*> mItemPanels;
std::vector<LLPanel*> mUnusedRowPanels;
std::vector<LLPanel*> mUnusedItemPanels;
std::vector<LLInventoryGalleryItem*> mItems;
std::vector<LLInventoryGalleryItem*> mHiddenItems;
LLScrollContainer* mScrollPanel;
LLPanel* mGalleryPanel;
LLPanel* mLastRowPanel;
LLTextBox* mMessageTextBox;
int mRowCount;
int mItemsAddedCount;
bool mGalleryCreated;
bool mLoadThumbnailsImmediately;
bool mNeedsArrange;
/* Params */
int mRowPanelHeight;
int mVerticalGap;
int mHorizontalGap;
int mItemWidth;
int mItemHeight;
int mItemHorizontalGap;
int mItemsInRow;
int mRowPanelWidth;
int mGalleryWidth;
int mRowPanWidthFactor;
int mGalleryWidthFactor;
LLInventoryGalleryContextMenu* mInventoryGalleryMenu;
LLInventoryGalleryContextMenu* mRootGalleryMenu;
std::string mFilterSubString;
LLInventoryFilter* mFilter;
U32 mSortOrder;
typedef std::map<LLUUID, LLInventoryGalleryItem*> gallery_item_map_t;
gallery_item_map_t mItemMap;
uuid_vec_t mCOFLinkedItems;
uuid_vec_t mActiveGestures;
uuid_set_t mItemBuildQuery;
std::map<LLInventoryGalleryItem*, S32> mItemIndexMap;
std::map<S32, LLInventoryGalleryItem*> mIndexToItemMap;
LLInventoryFilter::ESearchType mSearchType;
std::string mUsername;
};
class LLInventoryGalleryItem : public LLPanel
{
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{};
enum EInventorySortGroup
{
SG_SYSTEM_FOLDER,
SG_TRASH_FOLDER,
SG_NORMAL_FOLDER,
SG_ITEM
};
LLInventoryGalleryItem(const Params& p);
virtual ~LLInventoryGalleryItem();
BOOL postBuild();
void draw();
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
BOOL handleMouseUp(S32 x, S32 y, MASK mask);
BOOL handleHover(S32 x, S32 y, MASK mask);
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
BOOL handleKeyHere(KEY key, MASK mask);
void onFocusLost();
void onFocusReceived();
LLFontGL* getTextFont();
void setItemName(std::string name);
bool isSelected() { return mSelected; }
void setSelected(bool value);
void setWorn(bool value);
void setUUID(LLUUID id) {mUUID = id;}
LLUUID getUUID() { return mUUID;}
void setAssetIDStr(std::string asset_id) {mAssetIDStr = asset_id;}
std::string getAssetIDStr() { return mAssetIDStr;}
void setDescription(std::string desc) {mDesc = desc;}
std::string getDescription() { return mDesc;}
void setCreatorName(std::string name) {mCreatorName = name;}
std::string getCreatorName() { return mCreatorName;}
void setCreationDate(time_t date) {mCreationDate = date;}
time_t getCreationDate() { return mCreationDate;}
std::string getItemName() {return mItemName;}
std::string getItemNameSuffix() {return mPermSuffix + mWornSuffix;}
bool isDefaultImage() {return mDefaultImage;}
bool isHidden() {return mHidden;}
void setHidden(bool hidden) {mHidden = hidden;}
void setType(LLAssetType::EType type, LLInventoryType::EType inventory_type, U32 flags, bool is_link);
LLAssetType::EType getAssetType() { return mType; }
void setThumbnail(LLUUID id);
void setGallery(LLInventoryGallery* gallery) { mGallery = gallery; }
void setLoadImmediately(bool val);
bool isFolder() { return mIsFolder; }
bool isLink() { return mIsLink; }
EInventorySortGroup getSortGroup() { return mSortGroup; }
void updateNameText();
private:
bool isFadeItem();
LLUUID mUUID;
LLTextBox* mNameText;
LLPanel* mTextBgPanel;
LLThumbnailCtrl* mThumbnailCtrl;
bool mSelected;
bool mWorn;
bool mDefaultImage;
bool mHidden;
bool mIsFolder;
bool mIsLink;
S32 mCutGeneration;
bool mSelectedForCut;
std::string mAssetIDStr;
std::string mDesc;
std::string mCreatorName;
time_t mCreationDate;
EInventorySortGroup mSortGroup;
LLAssetType::EType mType;
std::string mItemName;
std::string mWornSuffix;
std::string mPermSuffix;
LLInventoryGallery* mGallery;
};
class LLThumbnailsObserver : public LLInventoryObserver
{
public:
LLThumbnailsObserver(){};
virtual void changed(U32 mask);
bool addItem(const LLUUID& obj_id, callback_t cb);
void removeItem(const LLUUID& obj_id);
protected:
struct LLItemData
{
LLItemData(const LLUUID& obj_id, const LLUUID& thumbnail_id, callback_t cb)
: mItemID(obj_id)
, mCallback(cb)
, mThumbnailID(thumbnail_id)
{}
callback_t mCallback;
LLUUID mItemID;
LLUUID mThumbnailID;
};
typedef std::map<LLUUID, LLItemData> item_map_t;
typedef item_map_t::value_type item_map_value_t;
item_map_t mItemMap;
};
class LLGalleryGestureObserver : public LLGestureManagerObserver
{
public:
LLGalleryGestureObserver(LLInventoryGallery* gallery) : mGallery(gallery) {}
virtual ~LLGalleryGestureObserver() {}
virtual void changed() { mGallery->onGesturesChanged(); }
private:
LLInventoryGallery* mGallery;
};
#endif