diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2023-03-29 21:30:46 +0300 |
---|---|---|
committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2023-03-29 21:39:51 +0300 |
commit | 8ed39a469b1b7337855c113f785fb64e66cf3b8f (patch) | |
tree | d861464f52d7551d362fd9451e830eb79d9e5bcf /indra | |
parent | a6b71d3b8234261f4ed3674017736d04649ea992 (diff) |
SL-19504 Allow drag and drop of textures into thumbnail floater
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llfloaterchangeitemthumbnail.cpp | 151 | ||||
-rw-r--r-- | indra/newview/llfloaterchangeitemthumbnail.h | 21 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 11 |
3 files changed, 166 insertions, 17 deletions
diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index a10de8ba23..8f6d984aa9 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -45,6 +45,7 @@ #include "llviewerfoldertype.h" #include "llviewermenufile.h" #include "llviewerobjectlist.h" +#include "llviewertexturelist.h" #include "llwindow.h" @@ -169,6 +170,53 @@ void LLFloaterChangeItemThumbnail::onOpen(const LLSD& key) refreshFromInventory(); } +void LLFloaterChangeItemThumbnail::onFocusReceived() +{ + mPasteFromClipboardBtn->setEnabled(LLClipboard::instance().hasContents()); +} + +void LLFloaterChangeItemThumbnail::onMouseEnter(S32 x, S32 y, MASK mask) +{ + mPasteFromClipboardBtn->setEnabled(LLClipboard::instance().hasContents()); +} + +BOOL LLFloaterChangeItemThumbnail::handleDragAndDrop( + S32 x, + S32 y, + MASK mask, + BOOL drop, + EDragAndDropType cargo_type, + void *cargo_data, + EAcceptance *accept, + std::string& tooltip_msg) +{ + if (cargo_type == DAD_TEXTURE) + { + LLInventoryItem *item = (LLInventoryItem *)cargo_data; + if (item->getAssetUUID().notNull()) + { + if (drop) + { + assignAndValidateAsset(item->getAssetUUID()); + } + + *accept = ACCEPT_YES_SINGLE; + } + else + { + *accept = ACCEPT_NO; + } + } + else + { + *accept = ACCEPT_NO; + } + + LL_DEBUGS("UserInput") << "dragAndDrop handled by LLFloaterChangeItemThumbnail " << getKey() << LL_ENDL; + + return TRUE; +} + void LLFloaterChangeItemThumbnail::changed(U32 mask) { //LLInventoryObserver @@ -342,9 +390,11 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) mThumbnailCtrl->setValue(thumbnail_id); mCopyToClipboardBtn->setEnabled(thumbnail_id.notNull()); + mPasteFromClipboardBtn->setEnabled(LLClipboard::instance().hasContents()); // todo: some elements might not support setting thumbnails // since they already have them + // It is unclear how system folders should function } void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata) @@ -418,7 +468,8 @@ void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata) LLInventoryObject* obj = self->getInventoryObject(); if (obj) { - LLClipboard::instance().addToClipboard(obj->getThumbnailUUID()); + LLClipboard::instance().addToClipboard(obj->getThumbnailUUID(), LLAssetType::AT_NONE); + self->mPasteFromClipboardBtn->setEnabled(true); } } @@ -440,29 +491,29 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) // no point checking snapshot? if (item->getType() == LLAssetType::AT_TEXTURE) { - asset_id = item->getAssetUUID(); + bool copy = item->getPermissions().allowCopyBy(gAgent.getID()); + bool xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + + if (copy && xfer) + { + asset_id = item->getAssetUUID(); + } + else + { + LLNotificationsUtil::add("ThumbnailInsufficientPermissions"); + return; + } } } else { - LLPointer<LLViewerFetchedTexture> texturep = LLViewerTextureManager::getFetchedTexture(potential_uuid); - if (texturep) - { - asset_id = potential_uuid; - } + // assume that this is a texture + asset_id = potential_uuid; } } if (asset_id.notNull()) { - // todo: if texture isn't loaded subscribe, or preload it in some way. - if (validateAsset(asset_id)) - { - self->setThumbnailId(asset_id); - } - else - { - LLNotificationsUtil::add("ThumbnailDimentionsLimit"); - } + self->assignAndValidateAsset(asset_id); } // else show 'buffer has no texture' warning? } @@ -489,15 +540,45 @@ void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notificatio } } -bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id) +void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id) { LLPointer<LLViewerFetchedTexture> texturep = LLViewerTextureManager::getFetchedTexture(asset_id); + if (texturep->getFullWidth() == 0 && !texturep->isFullyLoaded() && !texturep->isMissingAsset()) + { + texturep->setLoadedCallback(onImageLoaded, + MAX_DISCARD_LEVEL, // don't actually need max one, 3 or 4 should be enough + FALSE, + FALSE, + new LLHandle<LLFloater>(getHandle()), + NULL, + FALSE); + } + else + { + if (validateAsset(asset_id)) + { + setThumbnailId(asset_id); + } + else + { + LLNotificationsUtil::add("ThumbnailDimentionsLimit"); + } + } +} +bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id) +{ + LLPointer<LLViewerFetchedTexture> texturep = LLViewerTextureManager::findFetchedTexture(asset_id, TEX_LIST_STANDARD); if (!texturep) { return false; } + if (texturep->isMissingAsset()) + { + return false; + } + if (texturep->getFullWidth() != texturep->getFullHeight()) { return false; @@ -517,6 +598,42 @@ bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id) return true; } +//static +void LLFloaterChangeItemThumbnail::onImageLoaded( + BOOL success, + LLViewerFetchedTexture *src_vi, + LLImageRaw* src, + LLImageRaw* aux_src, + S32 discard_level, + BOOL final, + void* userdata) +{ + if (!userdata) return; + + if (!final && success) return; //not done yet + + LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata; + + if (success && !handle->isDead()) + { + LLFloaterChangeItemThumbnail* self = static_cast<LLFloaterChangeItemThumbnail*>(handle->get()); + if (self) + { + LLUUID asset_id = src_vi->getID(); + if (validateAsset(asset_id)) + { + self->setThumbnailId(asset_id); + } + else + { + LLNotificationsUtil::add("ThumbnailDimentionsLimit"); + } + } + } + + delete handle; +} + void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) { // show hourglass cursor when loading inventory window diff --git a/indra/newview/llfloaterchangeitemthumbnail.h b/indra/newview/llfloaterchangeitemthumbnail.h index 50c0c951d4..18cf2f7a85 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.h +++ b/indra/newview/llfloaterchangeitemthumbnail.h @@ -37,6 +37,7 @@ class LLTextBox; class LLThumbnailCtrl; class LLUICtrl; class LLViewerInventoryItem; +class LLViewerFetchedTexture; class LLFloaterChangeItemThumbnail : public LLFloater, public LLInventoryObserver, public LLVOInventoryListener { @@ -46,6 +47,18 @@ public: BOOL postBuild() override; void onOpen(const LLSD& key) override; + void onFocusReceived() override; + void onMouseEnter(S32 x, S32 y, MASK mask) 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 changed(U32 mask) override; void inventoryChanged(LLViewerObject* object, @@ -67,7 +80,15 @@ private: static void onRemove(void*); static void onRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFloater> handle); + void assignAndValidateAsset(const LLUUID &asset_id); static bool validateAsset(const LLUUID &asset_id); + static void onImageLoaded(BOOL success, + LLViewerFetchedTexture *src_vi, + LLImageRaw* src, + LLImageRaw* aux_src, + S32 discard_level, + BOOL final, + void* userdata); void showTexturePicker(const LLUUID &thumbnail_id); void onTexturePickerCommit(LLUUID id); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 0ea13e7d63..73ce5a6096 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6144,6 +6144,17 @@ Are you sure you want to delete them? </notification> <notification + icon="alertmodal.tga" + name="ThumbnailInsufficientPermissions" + type="alertmodal"> + <unique/> + Only copy and transfer free images can be assigned as thumbnails. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification icon="alertmodal.tga" name="ConfirmUnlink" type="alertmodal"> |