From f2d46651b92d949a63d2b3a5dd774dce6a6752c7 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 15 Feb 2023 23:56:49 +0200 Subject: SL-19108 WIP Managing inventory thumbnail #2 --- indra/newview/llfloaterchangeitemthumbnail.cpp | 249 ++++++++++++++++++++- indra/newview/llfloaterchangeitemthumbnail.h | 62 ++++- indra/newview/llinventorybridge.cpp | 8 +- indra/newview/llsidepaneliteminfo.cpp | 2 +- .../xui/en/floater_change_item_thumbnail.xml | 48 ++-- 5 files changed, 352 insertions(+), 17 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 7590fc35d1..05b9b89dd3 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -28,14 +28,261 @@ #include "llfloaterchangeitemthumbnail.h" +#include "llbutton.h" +#include "lliconctrl.h" +#include "llinventoryicon.h" +#include "llinventorymodel.h" +#include "llinventoryobserver.h" #include "lllineeditor.h" +#include "lltextbox.h" +#include "llthumbnailctrl.h" +#include "llviewerobjectlist.h" LLFloaterChangeItemThumbnail::LLFloaterChangeItemThumbnail(const LLSD& key) - : LLPreview(key) + : LLFloater(key) + , mObserverInitialized(false) + , mTooltipState(TOOLTIP_NONE) { } LLFloaterChangeItemThumbnail::~LLFloaterChangeItemThumbnail() { + gInventory.removeObserver(this); + removeVOInventoryListener(); } + +BOOL LLFloaterChangeItemThumbnail::postBuild() +{ + mItemNameText = getChild("item_name"); + mItemTypeIcon = getChild("item_type_icon"); + mThumbnailCtrl = getChild("item_thumbnail"); + mToolTipTextBox = getChild("tooltip_text"); + + LLSD tooltip_text; + mToolTipTextBox->setValue(tooltip_text); + + LLButton *upload_local = getChild("upload_local"); + upload_local->setClickedCallback(onUploadLocal, (void*)this); + upload_local->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_UPLOAD_LOCAL)); + upload_local->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_UPLOAD_LOCAL)); + + LLButton *upload_snapshot = getChild("upload_snapshot"); + upload_snapshot->setClickedCallback(onUploadSnapshot, (void*)this); + upload_snapshot->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_UPLOAD_SNAPSHOT)); + upload_snapshot->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_UPLOAD_SNAPSHOT)); + + LLButton *use_texture = getChild("use_texture"); + use_texture->setClickedCallback(onUseTexture, (void*)this); + use_texture->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_USE_TEXTURE)); + use_texture->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_USE_TEXTURE)); + + mCopyToClipboardBtn = getChild("copy_to_clipboard"); + mCopyToClipboardBtn->setClickedCallback(onCopyToClipboard, (void*)this); + mCopyToClipboardBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_COPY_TO_CLIPBOARD)); + mCopyToClipboardBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_COPY_TO_CLIPBOARD)); + + mPasteFromClipboardBtn = getChild("paste_from_clipboard"); + mPasteFromClipboardBtn->setClickedCallback(onPasteFromClipboard, (void*)this); + mPasteFromClipboardBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_COPY_FROM_CLIPBOARD)); + mPasteFromClipboardBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_COPY_FROM_CLIPBOARD)); + + mRemoveImageBtn = getChild("remove_image"); + mRemoveImageBtn->setClickedCallback(onRemove, (void*)this); + mRemoveImageBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_REMOVE)); + mRemoveImageBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_REMOVE)); + + return LLFloater::postBuild(); +} + +void LLFloaterChangeItemThumbnail::onOpen(const LLSD& key) +{ + if (!key.has("item_id") && !key.isUUID()) + { + closeFloater(); + } + + if (key.isUUID()) + { + mItemId = key.asUUID(); + } + else + { + mItemId = key["item_id"].asUUID(); + mTaskId = key["task_id"].asUUID(); + } + + refreshFromInventory(); +} + +void LLFloaterChangeItemThumbnail::changed(U32 mask) +{ + //LLInventoryObserver + + if (mTaskId.notNull() || mItemId.isNull()) + { + // Task inventory or not set up yet + return; + } + + const std::set& mChangedItemIDs = gInventory.getChangedIDs(); + std::set::const_iterator it; + + for (it = mChangedItemIDs.begin(); it != mChangedItemIDs.end(); it++) + { + // set dirty for 'item profile panel' only if changed item is the item for which 'item profile panel' is shown (STORM-288) + if (*it == mItemId) + { + // if there's a change we're interested in. + if ((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0) + { + refreshFromInventory(); + } + } + } +} + +void LLFloaterChangeItemThumbnail::inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data) +{ + //LLVOInventoryListener + refreshFromInventory(); +} + +void LLFloaterChangeItemThumbnail::refreshFromInventory() +{ + LLViewerInventoryItem* item = NULL; + if (mTaskId.isNull()) + { + // it is in agent inventory + if (!mObserverInitialized) + { + gInventory.addObserver(this); + mObserverInitialized = true; + } + + item = gInventory.getItem(mItemId); + } + else + { + LLViewerObject* object = gObjectList.findObject(mTaskId); + if (object) + { + if (!mObserverInitialized) + { + registerVOInventoryListener(object, NULL); + mObserverInitialized = false; + } + + item = static_cast(object->getInventoryObject(mItemId)); + } + else + { + closeFloater(); + } + } + + if (item) + { + // This floater probably shouldn't be be possible to open + // for imcomplete items + llassert(item->isFinished()); + + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + bool in_trash = (item->getUUID() == trash_id) || gInventory.isObjectDescendentOf(item->getUUID(), trash_id); + if (in_trash) + { + // Close properties when moving to trash + // Aren't supposed to view properties from trash + closeFloater(); + } + else + { + refreshFromItem(item); + } + } + else + { + closeFloater(); + } +} + +void LLFloaterChangeItemThumbnail::refreshFromItem(LLViewerInventoryItem* item) +{ + LLUIImagePtr icon_img = LLInventoryIcon::getIcon(item->getType(), item->getInventoryType(), item->getFlags(), FALSE); + mItemTypeIcon->setImage(icon_img); + mItemNameText->setValue(item->getName()); + + LLUUID thumbnail_id = item->getThumbnailUUID(); + mThumbnailCtrl->setValue(thumbnail_id); + + mCopyToClipboardBtn->setEnabled(thumbnail_id.notNull()); + mRemoveImageBtn->setEnabled(thumbnail_id.notNull() && (item->getActualType() != LLAssetType::AT_TEXTURE) || (item->getAssetUUID() != thumbnail_id)); +} + +void LLFloaterChangeItemThumbnail::startObjectInventoryObserver() +{ + +} + +void LLFloaterChangeItemThumbnail::stopObjectInventoryObserver() +{ + +} + +void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onUploadSnapshot(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onUseTexture(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onRemove(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onButtonMouseEnter(LLUICtrl* button, const LLSD& param, EToolTipState state) +{ + mTooltipState = state; + + std::string tooltip_text; + std::string tooltip_name = "tooltip_" + button->getName(); + if (hasString(tooltip_name)) + { + tooltip_text = getString(tooltip_name); + } + + mToolTipTextBox->setValue(tooltip_text); +} + +void LLFloaterChangeItemThumbnail::onButtonMouseLeave(LLUICtrl* button, const LLSD& param, EToolTipState state) +{ + if (mTooltipState == state) + { + mTooltipState = TOOLTIP_NONE; + LLSD tooltip_text; + mToolTipTextBox->setValue(tooltip_text); + } +} + diff --git a/indra/newview/llfloaterchangeitemthumbnail.h b/indra/newview/llfloaterchangeitemthumbnail.h index 94792f07b6..a219adb6f5 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.h +++ b/indra/newview/llfloaterchangeitemthumbnail.h @@ -28,11 +28,71 @@ #define LL_LLFLOATERCHANGEITEMTHUMBNAIL_H #include "llfloater.h" +#include "llinventoryobserver.h" +#include "llvoinventorylistener.h" -class LLFloaterChangeItemThumbnail : public LLFloater +class LLButton; +class LLIconCtrl; +class LLTextBox; +class LLThumbnailCtrl; +class LLUICtrl; +class LLViewerInventoryItem; + +class LLFloaterChangeItemThumbnail : public LLFloater, public LLInventoryObserver, public LLVOInventoryListener { public: LLFloaterChangeItemThumbnail(const LLSD& key); ~LLFloaterChangeItemThumbnail(); + + BOOL postBuild() override; + void onOpen(const LLSD& key) override; + + void changed(U32 mask) override; + void inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data) override; + +private: + + void refreshFromInventory(); + void refreshFromItem(LLViewerInventoryItem* item); + + void startObjectInventoryObserver(); + void stopObjectInventoryObserver(); + + static void onUploadLocal(void*); + static void onUploadSnapshot(void*); + static void onUseTexture(void*); + static void onCopyToClipboard(void*); + static void onPasteFromClipboard(void*); + static void onRemove(void*); + + enum EToolTipState + { + TOOLTIP_NONE, + TOOLTIP_UPLOAD_LOCAL, + TOOLTIP_UPLOAD_SNAPSHOT, + TOOLTIP_USE_TEXTURE, + TOOLTIP_COPY_TO_CLIPBOARD, + TOOLTIP_COPY_FROM_CLIPBOARD, + TOOLTIP_REMOVE, + }; + + void onButtonMouseEnter(LLUICtrl* button, const LLSD& param, EToolTipState state); + void onButtonMouseLeave(LLUICtrl* button, const LLSD& param, EToolTipState state); + + bool mObserverInitialized; + EToolTipState mTooltipState; + LLUUID mItemId; + LLUUID mTaskId; + + LLIconCtrl *mItemTypeIcon; + LLUICtrl *mItemNameText; + LLThumbnailCtrl *mThumbnailCtrl; + LLTextBox *mToolTipTextBox; + LLButton *mCopyToClipboardBtn; + LLButton *mPasteFromClipboardBtn; + LLButton *mRemoveImageBtn; }; #endif // LL_LLFLOATERCHANGEITEMTHUMBNAIL_H diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 1b36c718f5..664ba3e336 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -878,6 +878,13 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Rename")); } } + + LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID); + items.push_back(std::string("thumbnail")); + if (!inv_item || !inv_item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) + { + disabled_items.push_back(std::string("thumbnail")); + } if (show_asset_id) { @@ -885,7 +892,6 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, bool is_asset_knowable = false; - LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID); if (inv_item) { is_asset_knowable = LLAssetType::lookupIsAssetIDKnowable(inv_item->getType()); diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index ccc57c63ab..7d9fb6565c 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -750,7 +750,7 @@ void LLSidepanelItemInfo::changed(U32 mask) const LLUUID& item_id = getItemID(); if (getObjectID().notNull() || item_id.isNull()) { - // Tasl inventory or not set up yet + // Task inventory or not set up yet return; } diff --git a/indra/newview/skins/default/xui/en/floater_change_item_thumbnail.xml b/indra/newview/skins/default/xui/en/floater_change_item_thumbnail.xml index c2c4c07ca1..f177ed0c0b 100644 --- a/indra/newview/skins/default/xui/en/floater_change_item_thumbnail.xml +++ b/indra/newview/skins/default/xui/en/floater_change_item_thumbnail.xml @@ -6,7 +6,33 @@ name="change_item_thumbnail" help_topic="change_item_thumbnail" title="CHANGE ITEM IMAGE" - width="320"> + width="319"> + + + Upload from computer + + + Use snapshot tool + + + Choose texture + + + Copy to clipboard + + + Paste from clipboard + + + Remove image + + + width="286" + enabled="false"/> -