From 1140ae3489a9e260a0abb808b4152f2d57384d67 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Thu, 29 Dec 2022 19:51:33 +0100 Subject: Add a texture inspector and show it when hovering over an inventory textory (or folder containing - among others - exactly one texture) and when hovering over notecard embedded textures --- indra/newview/llinspecttexture.cpp | 301 +++++++++++++++++++++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 indra/newview/llinspecttexture.cpp (limited to 'indra/newview/llinspecttexture.cpp') diff --git a/indra/newview/llinspecttexture.cpp b/indra/newview/llinspecttexture.cpp new file mode 100644 index 0000000000..cd288e9603 --- /dev/null +++ b/indra/newview/llinspecttexture.cpp @@ -0,0 +1,301 @@ +/** + * @file llinspecttexture.cpp + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, 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$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterreg.h" +#include "llinspect.h" +#include "llinspecttexture.h" +#include "llinventoryfunctions.h" +#include "llinventorymodel.h" +#include "lltexturectrl.h" +#include "lltrans.h" +#include "llviewertexturelist.h" + +// ============================================================================ +// LLInspectTexture class +// + +class LLInspectTexture : public LLInspect +{ + friend class LLFloaterReg; +public: + LLInspectTexture(const LLSD& sdKey); + ~LLInspectTexture(); + +public: + void onOpen(const LLSD& sdData) override; + BOOL postBuild() override; + +public: + const LLUUID& getAssetId() const { return mAssetId; } + const LLUUID& getItemId() const { return mItemId; } + +protected: + LLUUID mAssetId; + LLUUID mItemId; // Item UUID relative to gInventoryModel (or null if not displaying an inventory texture) + LLUUID mNotecardId; + LLTextureCtrl* mTextureCtrl = nullptr; + LLTextBox* mTextureName = nullptr; +}; + +LLInspectTexture::LLInspectTexture(const LLSD& sdKey) + : LLInspect(LLSD()) +{ +} + +LLInspectTexture::~LLInspectTexture() +{ +} + +void LLInspectTexture::onOpen(const LLSD& sdData) +{ + // Start fade animation + LLInspect::onOpen(sdData); + + bool fIsAsset = sdData.has("asset_id"); + bool fIsInventory = sdData.has("item_id"); + + // Skip if we're being asked to display the same thing + const LLUUID idAsset = (fIsAsset) ? sdData["asset_id"].asUUID() : LLUUID::null; + const LLUUID idItem = (fIsInventory) ? sdData["item_id"].asUUID() : LLUUID::null; + if ( (getVisible()) && ( ((fIsAsset) && (idAsset == mAssetId)) || ((fIsInventory) && (idItem == mItemId)) ) ) + { + return; + } + + // Position the inspector relative to the mouse cursor + // Similar to how tooltips are positioned [see LLToolTipMgr::createToolTip()] + if (sdData.has("pos")) + LLUI::instance().positionViewNearMouse(this, sdData["pos"]["x"].asInteger(), sdData["pos"]["y"].asInteger()); + else + LLUI::instance().positionViewNearMouse(this); + + std::string strName = sdData["name"].asString(); + if (fIsAsset) + { + mAssetId = idAsset; + mItemId = idItem; // Will be non-null in the case of a notecard + mNotecardId = sdData["notecard_id"].asUUID(); + } + else if (fIsInventory) + { + const LLViewerInventoryItem* pItem = gInventory.getItem(idItem); + if ( (pItem) && (LLAssetType::AT_TEXTURE == pItem->getType()) ) + { + if (strName.empty()) + strName = pItem->getName(); + mAssetId = pItem->getAssetUUID(); + mItemId = idItem; + } + else + { + mAssetId.setNull(); + mItemId.setNull(); + } + mNotecardId = LLUUID::null; + } + + mTextureCtrl->setImageAssetID(mAssetId); + mTextureName->setText(strName); +} + +BOOL LLInspectTexture::postBuild() +{ + mTextureCtrl = getChild("texture_ctrl"); + mTextureName = getChild("texture_name"); + + return TRUE; +} + +// ============================================================================ +// Helper functions +// + +LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p) +{ + const LLSD& sdTooltip = p.create_params; + + LLInventoryType::EType eInvType = (sdTooltip.has("inv_type")) ? (LLInventoryType::EType)sdTooltip["inv_type"].asInteger() : LLInventoryType::IT_NONE; + switch (eInvType) + { + case LLInventoryType::IT_SNAPSHOT: + case LLInventoryType::IT_TEXTURE: + return LLUICtrlFactory::create(p); + case LLInventoryType::IT_CATEGORY: + { + if (sdTooltip.has("item_id")) + { + const LLUUID idCategory = sdTooltip["item_id"].asUUID(); + + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLIsOfAssetType f(LLAssetType::AT_TEXTURE); + gInventory.getDirectDescendentsOf(idCategory, cats, items, f); + + // Exactly one texture found => show the texture tooltip + if (1 == items.size()) + { + p.create_params.getValue()["asset_id"] = items.front()->getAssetUUID(); + return LLUICtrlFactory::create(p); + } + } + + // No or more than one texture found => show default tooltip + return LLUICtrlFactory::create(p); + } + default: + return LLUICtrlFactory::create(p); + } +} + +void LLInspectTextureUtil::registerFloater() +{ + LLFloaterReg::add("inspect_texture", "inspect_texture.xml", &LLFloaterReg::build); +} + +// ============================================================================ +// LLTexturePreviewView helper class +// + +class LLTexturePreviewView : public LLView +{ +public: + LLTexturePreviewView(const LLView::Params& p); + ~LLTexturePreviewView(); + +public: + void draw() override; + +public: + void setImageFromAssetId(const LLUUID& idAsset); + void setImageFromItemId(const LLUUID& idItem); + +protected: + LLPointer m_Image; + S32 mImageBoostLevel = LLGLTexture::BOOST_NONE; + std::string mLoadingText; +}; + + +LLTexturePreviewView::LLTexturePreviewView(const LLView::Params& p) + : LLView(p) +{ + mLoadingText = LLTrans::getString("texture_loading"); +} + +LLTexturePreviewView::~LLTexturePreviewView() +{ + if (m_Image) + { + m_Image->setBoostLevel(mImageBoostLevel); + m_Image = nullptr; + } +} + +void LLTexturePreviewView::draw() +{ + if (m_Image) + { + LLRect rctClient = getLocalRect(); + + gl_rect_2d(rctClient, LLColor4::black); + rctClient.stretch(-2); + if (4 == m_Image->getComponents()) + gl_rect_2d_checkerboard(rctClient); + gl_draw_scaled_image(rctClient.mLeft, rctClient.mBottom, rctClient.getWidth(), rctClient.getHeight(), m_Image); + + bool isLoading = (!m_Image->isFullyLoaded()) && (m_Image->getDiscardLevel() > 0); + if (isLoading) + LLFontGL::getFontSansSerif()->renderUTF8(mLoadingText, 0, llfloor(rctClient.mLeft + 3), llfloor(rctClient.mTop - 25), LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW); + m_Image->addTextureStats((isLoading) ? MAX_IMAGE_AREA : (F32)(rctClient.getWidth() * rctClient.getHeight())); + } +} + +void LLTexturePreviewView::setImageFromAssetId(const LLUUID& idAsset) +{ + m_Image = LLViewerTextureManager::getFetchedTexture(idAsset, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + if (m_Image) + { + mImageBoostLevel = m_Image->getBoostLevel(); + m_Image->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + m_Image->forceToSaveRawImage(0); + if ( (!m_Image->isFullyLoaded()) && (!m_Image->hasFetcher()) ) + { + if (m_Image->isInFastCacheList()) + { + m_Image->loadFromFastCache(); + } + gTextureList.forceImmediateUpdate(m_Image); + } + } +} + +void LLTexturePreviewView::setImageFromItemId(const LLUUID& idItem) +{ + const LLViewerInventoryItem* pItem = gInventory.getItem(idItem); + setImageFromAssetId( (pItem) ? pItem->getAssetUUID() : LLUUID::null ); +} + +// ============================================================================ +// LLTextureToolTip class +// + +LLTextureToolTip::LLTextureToolTip(const LLToolTip::Params& p) + : LLToolTip(p) + , mPreviewView(nullptr) + , mPreviewSize(256) +{ + mMaxWidth = llmax(mMaxWidth, mPreviewSize); +} + +LLTextureToolTip::~LLTextureToolTip() +{ +} + +void LLTextureToolTip::initFromParams(const LLToolTip::Params& p) +{ + LLToolTip::initFromParams(p); + + // Create and add the preview control + LLView::Params p_preview; + p_preview.name = "texture_preview"; + LLRect rctPreview; + rctPreview.setOriginAndSize(mPadding, mTextBox->getRect().mTop, mPreviewSize, mPreviewSize); + p_preview.rect = rctPreview; + mPreviewView = LLUICtrlFactory::create(p_preview); + addChild(mPreviewView); + + // Parse the control params + const LLSD& sdTextureParams = p.create_params; + if (sdTextureParams.has("asset_id")) + mPreviewView->setImageFromAssetId(sdTextureParams["asset_id"].asUUID()); + else if (sdTextureParams.has("item_id")) + mPreviewView->setImageFromItemId(sdTextureParams["item_id"].asUUID()); + + snapToChildren(); +} + +// ============================================================================ -- cgit v1.3 From 6ada89ce0b9372d6a7f49ac45bad6713ad5d3355 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 1 Feb 2023 00:35:22 +0200 Subject: SL-19117 Extend texture preview to show thumbnails when present --- indra/llui/llview.cpp | 20 +++++++++------ indra/llui/llview.h | 1 + indra/newview/llinspecttexture.cpp | 49 ++++++++++++++++++++---------------- indra/newview/llinventorypanel.cpp | 12 ++++----- indra/newview/llviewertexteditor.cpp | 9 +++++-- 5 files changed, 54 insertions(+), 37 deletions(-) (limited to 'indra/newview/llinspecttexture.cpp') diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 9ba71913d0..10e4755cd3 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -877,6 +877,17 @@ LLView* LLView::childFromPoint(S32 x, S32 y, bool recur) return 0; } +F32 LLView::getTooltipTimeout() +{ + static LLCachedControl tooltip_fast_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFastDelay", 0.1f); + static LLCachedControl tooltip_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipDelay", 0.7f); + // allow "scrubbing" over ui by showing next tooltip immediately + // if previous one was still visible + return (F32)(LLToolTipMgr::instance().toolTipVisible() + ? tooltip_fast_delay + : tooltip_delay); +} + BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; @@ -886,14 +897,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask) std::string tooltip = getToolTip(); if (!tooltip.empty()) { - static LLCachedControl tooltip_fast_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFastDelay", 0.1f); - static LLCachedControl tooltip_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipDelay", 0.7f); static LLCachedControl allow_ui_tooltips(*LLUI::getInstance()->mSettingGroups["config"], "BasicUITooltips", true); - // allow "scrubbing" over ui by showing next tooltip immediately - // if previous one was still visible - F32 timeout = LLToolTipMgr::instance().toolTipVisible() - ? tooltip_fast_delay - : tooltip_delay; // Even if we don't show tooltips, consume the event, nothing below should show tooltip if (allow_ui_tooltips) @@ -901,7 +905,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask) LLToolTipMgr::instance().show(LLToolTip::Params() .message(tooltip) .sticky_rect(calcScreenRect()) - .delay_time(timeout)); + .delay_time(getTooltipTimeout())); } handled = TRUE; } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index bec45df78a..444a4c3cb5 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -243,6 +243,7 @@ public: ECursorType getHoverCursor() { return mHoverCursor; } + static F32 getTooltipTimeout(); virtual const std::string getToolTip() const { return mToolTipMsg.getString(); } void sendChildToFront(LLView* child); diff --git a/indra/newview/llinspecttexture.cpp b/indra/newview/llinspecttexture.cpp index cd288e9603..af96561c45 100644 --- a/indra/newview/llinspecttexture.cpp +++ b/indra/newview/llinspecttexture.cpp @@ -136,14 +136,17 @@ BOOL LLInspectTexture::postBuild() LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p) { - const LLSD& sdTooltip = p.create_params; + const LLSD& sdTooltip = p.create_params; + + if (sdTooltip.has("thumbnail_id")) + { + // go straight for tooltip regardless of type + return LLUICtrlFactory::create(p); + } LLInventoryType::EType eInvType = (sdTooltip.has("inv_type")) ? (LLInventoryType::EType)sdTooltip["inv_type"].asInteger() : LLInventoryType::IT_NONE; switch (eInvType) { - case LLInventoryType::IT_SNAPSHOT: - case LLInventoryType::IT_TEXTURE: - return LLUICtrlFactory::create(p); case LLInventoryType::IT_CATEGORY: { if (sdTooltip.has("item_id")) @@ -277,23 +280,27 @@ LLTextureToolTip::~LLTextureToolTip() void LLTextureToolTip::initFromParams(const LLToolTip::Params& p) { - LLToolTip::initFromParams(p); - - // Create and add the preview control - LLView::Params p_preview; - p_preview.name = "texture_preview"; - LLRect rctPreview; - rctPreview.setOriginAndSize(mPadding, mTextBox->getRect().mTop, mPreviewSize, mPreviewSize); - p_preview.rect = rctPreview; - mPreviewView = LLUICtrlFactory::create(p_preview); - addChild(mPreviewView); - - // Parse the control params - const LLSD& sdTextureParams = p.create_params; - if (sdTextureParams.has("asset_id")) - mPreviewView->setImageFromAssetId(sdTextureParams["asset_id"].asUUID()); - else if (sdTextureParams.has("item_id")) - mPreviewView->setImageFromItemId(sdTextureParams["item_id"].asUUID()); + LLToolTip::initFromParams(p); + + // Create and add the preview control + LLView::Params p_preview; + p_preview.name = "texture_preview"; + LLRect rctPreview; + rctPreview.setOriginAndSize(mPadding, mTextBox->getRect().mTop, mPreviewSize, mPreviewSize); + p_preview.rect = rctPreview; + mPreviewView = LLUICtrlFactory::create(p_preview); + addChild(mPreviewView); + + // Parse the control params + const LLSD& sdTextureParams = p.create_params; + if (sdTextureParams.has("thumbnail_id")) + { + mPreviewView->setImageFromAssetId(sdTextureParams["thumbnail_id"].asUUID()); + } + else if (sdTextureParams.has("item_id")) + { + mPreviewView->setImageFromItemId(sdTextureParams["item_id"].asUUID()); + } snapToChildren(); } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index dabe633b8c..d6f4b8f103 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1285,16 +1285,16 @@ BOOL LLInventoryPanel::handleToolTip(S32 x, S32 y, MASK mask) { if (const LLFolderViewModelItemInventory* vm_item_p = static_cast(hover_item_p->getViewModelItem())) { - // Copy/pasted from LLView::handleToolTip() - F32 nTimeout = LLToolTipMgr::instance().toolTipVisible() - ? LLUI::getInstance()->mSettingGroups["config"]->getF32("ToolTipFastDelay") - : LLUI::getInstance()->mSettingGroups["config"]->getF32("ToolTipDelay"); + LLSD params; + params["inv_type"] = vm_item_p->getInventoryType(); + params["item_id"] = vm_item_p->getUUID(); + LLToolTipMgr::instance().show(LLToolTip::Params() .message(hover_item_p->getToolTip()) .sticky_rect(hover_item_p->calcScreenRect()) - .delay_time(nTimeout) + .delay_time(LLView::getTooltipTimeout()) .create_callback(boost::bind(&LLInspectTextureUtil::createInventoryToolTip, _1)) - .create_params(LLSD().with("inv_type", vm_item_p->getInventoryType()).with("item_id", vm_item_p->getUUID()))); + .create_params(params)); return TRUE; } } diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 299047d91b..13505a2cf3 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -246,12 +246,17 @@ public: } virtual BOOL handleToolTip(S32 x, S32 y, MASK mask ) { - if (LLAssetType::AT_TEXTURE == mItem->getType()) + if (mItem->getThumbnailUUID().notNull()) { + LLSD params; + params["inv_type"] = mItem->getInventoryType(); + params["thumbnail_id"] = mItem->getThumbnailUUID(); + params["asset_id"] = mItem->getAssetUUID(); + LLToolTipMgr::instance().show(LLToolTip::Params() .message(mToolTip) .create_callback(boost::bind(&LLInspectTextureUtil::createInventoryToolTip, _1)) - .create_params(LLSD().with("inv_type", mItem->getInventoryType()).with("asset_id", mItem->getAssetUUID()))); + .create_params(params)); return TRUE; } -- cgit v1.3 From 999c8cd3b92cdc64549167a261c8c629edc03c55 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 1 Feb 2023 01:33:30 +0200 Subject: SL-19117 Textures should return asset id when thumbnail is not set --- indra/llinventory/llinventory.cpp | 11 +++++++++++ indra/llinventory/llinventory.h | 1 + indra/newview/llfolderviewmodelinventory.h | 1 + indra/newview/llinspecttexture.cpp | 2 +- indra/newview/llinventorybridge.cpp | 15 +++++++++++++++ indra/newview/llinventorybridge.h | 2 ++ indra/newview/llinventorypanel.cpp | 1 + indra/newview/llpanelobjectinventory.cpp | 1 + 8 files changed, 33 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinspecttexture.cpp') diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index b897198d10..e00f652622 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -349,6 +349,7 @@ void LLInventoryItem::copyItem(const LLInventoryItem* other) copyObject(other); mPermissions = other->mPermissions; mAssetUUID = other->mAssetUUID; + mThumbnailUUID = other->mThumbnailUUID; mDescription = other->mDescription; mSaleInfo = other->mSaleInfo; mInventoryType = other->mInventoryType; @@ -413,6 +414,7 @@ U32 LLInventoryItem::getCRC32() const //LL_DEBUGS() << "8 crc: " << std::hex << crc << std::dec << LL_ENDL; crc += (U32)mCreationDate; //LL_DEBUGS() << "9 crc: " << std::hex << crc << std::dec << LL_ENDL; + crc += mThumbnailUUID.getCRC32(); return crc; } @@ -502,6 +504,15 @@ void LLInventoryItem::setSaleInfo(const LLSaleInfo& sale_info) mSaleInfo = sale_info; } +const LLUUID& LLInventoryItem::getThumbnailUUID() const +{ + if (mThumbnailUUID.isNull() && mType == LLAssetType::AT_TEXTURE) + { + return mAssetUUID; + } + return mThumbnailUUID; +} + LLInventoryType::EType LLInventoryItem::getInventoryType() const { return mInventoryType; diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index dfe8b7659b..7af542c49a 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -162,6 +162,7 @@ public: virtual const std::string& getDescription() const; virtual const std::string& getActualDescription() const; // Does not follow links virtual const LLSaleInfo& getSaleInfo() const; + virtual const LLUUID& getThumbnailUUID() const; virtual LLInventoryType::EType getInventoryType() const; virtual U32 getFlags() const; virtual time_t getCreationDate() const; diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h index de28091c32..87e49189d8 100644 --- a/indra/newview/llfolderviewmodelinventory.h +++ b/indra/newview/llfolderviewmodelinventory.h @@ -39,6 +39,7 @@ class LLFolderViewModelItemInventory public: LLFolderViewModelItemInventory(class LLFolderViewModelInventory& root_view_model); virtual const LLUUID& getUUID() const = 0; + virtual const LLUUID& getThumbnailUUID() const = 0; virtual time_t getCreationDate() const = 0; // UTC seconds virtual void setCreationDate(time_t creation_date_utc) = 0; virtual PermissionMask getPermissionMask() const = 0; diff --git a/indra/newview/llinspecttexture.cpp b/indra/newview/llinspecttexture.cpp index af96561c45..8a8d7ed1bb 100644 --- a/indra/newview/llinspecttexture.cpp +++ b/indra/newview/llinspecttexture.cpp @@ -138,7 +138,7 @@ LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p) { const LLSD& sdTooltip = p.create_params; - if (sdTooltip.has("thumbnail_id")) + if (sdTooltip.has("thumbnail_id") && sdTooltip["thumbnail_id"].asUUID().notNull()) { // go straight for tooltip regardless of type return LLUICtrlFactory::create(p); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 7793b71f56..405c1f884a 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2154,6 +2154,21 @@ LLViewerInventoryItem* LLItemBridge::getItem() const return item; } +const LLUUID& LLItemBridge::getThumbnailUUID() const +{ + LLViewerInventoryItem* item = NULL; + LLInventoryModel* model = getInventoryModel(); + if(model) + { + item = (LLViewerInventoryItem*)model->getItem(mUUID); + } + if (item) + { + return item->getThumbnailUUID(); + } + return LLUUID::null; +} + BOOL LLItemBridge::isItemPermissive() const { LLViewerInventoryItem* item = getItem(); diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index bdffecf1c6..d56e0b778d 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -84,6 +84,7 @@ public: // LLInvFVBridge functionality //-------------------------------------------------------------------- virtual const LLUUID& getUUID() const { return mUUID; } + virtual const LLUUID& getThumbnailUUID() const { return LLUUID::null; } virtual void clearDisplayName() { mDisplayName.clear(); } virtual void restoreItem() {} virtual void restoreToWorld() {} @@ -251,6 +252,7 @@ public: virtual LLUIImagePtr getIconOverlay() const; LLViewerInventoryItem* getItem() const; + virtual const LLUUID& getThumbnailUUID() const; protected: BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index d6f4b8f103..e013de2491 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1287,6 +1287,7 @@ BOOL LLInventoryPanel::handleToolTip(S32 x, S32 y, MASK mask) { LLSD params; params["inv_type"] = vm_item_p->getInventoryType(); + params["thumbnail_id"] = vm_item_p->getThumbnailUUID(); params["item_id"] = vm_item_p->getUUID(); LLToolTipMgr::instance().show(LLToolTip::Params() diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index fff25c6c61..70da9e430a 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -116,6 +116,7 @@ public: virtual PermissionMask getPermissionMask() const { return PERM_NONE; } /*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; } virtual const LLUUID& getUUID() const { return mUUID; } + virtual const LLUUID& getThumbnailUUID() const { return LLUUID::null;} virtual time_t getCreationDate() const; virtual void setCreationDate(time_t creation_date_utc); -- cgit v1.3 From 69f6caac73d406b0f0fe9b913e9d2f439677b279 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 17 Feb 2023 23:08:31 +0200 Subject: SL-19117 Fix thumbnail preview not working for outfits --- indra/newview/llinspecttexture.cpp | 57 ++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 15 deletions(-) (limited to 'indra/newview/llinspecttexture.cpp') diff --git a/indra/newview/llinspecttexture.cpp b/indra/newview/llinspecttexture.cpp index 8a8d7ed1bb..de0d65eb7e 100644 --- a/indra/newview/llinspecttexture.cpp +++ b/indra/newview/llinspecttexture.cpp @@ -75,11 +75,11 @@ void LLInspectTexture::onOpen(const LLSD& sdData) // Start fade animation LLInspect::onOpen(sdData); - bool fIsAsset = sdData.has("asset_id"); + bool fIsAsset = sdData.has("thumbnail_id"); bool fIsInventory = sdData.has("item_id"); // Skip if we're being asked to display the same thing - const LLUUID idAsset = (fIsAsset) ? sdData["asset_id"].asUUID() : LLUUID::null; + const LLUUID idAsset = (fIsAsset) ? sdData["thumbnail_id"].asUUID() : LLUUID::null; const LLUUID idItem = (fIsInventory) ? sdData["item_id"].asUUID() : LLUUID::null; if ( (getVisible()) && ( ((fIsAsset) && (idAsset == mAssetId)) || ((fIsInventory) && (idItem == mItemId)) ) ) { @@ -134,13 +134,27 @@ BOOL LLInspectTexture::postBuild() // Helper functions // +class LLIsTextureType : public LLInventoryCollectFunctor +{ +public: + LLIsTextureType() {} + virtual ~LLIsTextureType() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); +}; + +bool LLIsTextureType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + return item && (item->getType() == LLAssetType::AT_TEXTURE); +} + LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p) { const LLSD& sdTooltip = p.create_params; if (sdTooltip.has("thumbnail_id") && sdTooltip["thumbnail_id"].asUUID().notNull()) { - // go straight for tooltip regardless of type + // go straight for thumbnail regardless of type return LLUICtrlFactory::create(p); } @@ -152,18 +166,31 @@ LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p) if (sdTooltip.has("item_id")) { const LLUUID idCategory = sdTooltip["item_id"].asUUID(); - - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - LLIsOfAssetType f(LLAssetType::AT_TEXTURE); - gInventory.getDirectDescendentsOf(idCategory, cats, items, f); - - // Exactly one texture found => show the texture tooltip - if (1 == items.size()) - { - p.create_params.getValue()["asset_id"] = items.front()->getAssetUUID(); - return LLUICtrlFactory::create(p); - } + LLViewerInventoryCategory* cat = gInventory.getCategory(idCategory); + if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT) + { + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + // Not LLIsOfAssetType, because we allow links + LLIsTextureType f; + gInventory.getDirectDescendentsOf(idCategory, cats, items, f); + + // Exactly one texture found => show the texture tooltip + if (1 == items.size()) + { + LLViewerInventoryItem* item = items.front(); + if (item && item->getIsLinkType()) + { + item = item->getLinkedItem(); + } + if (item) + { + // Todo: write this into folder's thumbnail id + p.create_params.getValue()["thumbnail_id"] = item->getAssetUUID(); + return LLUICtrlFactory::create(p); + } + } + } } // No or more than one texture found => show default tooltip -- cgit v1.3 From 2d68a7c33622aa28c49989e959c2a9be1f053d03 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 21 Feb 2023 23:03:00 +0200 Subject: SL-19108 Update Simple snapshot floater --- indra/newview/llfloaterchangeitemthumbnail.cpp | 47 ++++++++++++++++++++++ indra/newview/llfloatersimplesnapshot.cpp | 42 ++++++++----------- indra/newview/llfloatersimplesnapshot.h | 17 ++++---- indra/newview/llinspecttexture.cpp | 3 +- indra/newview/lloutfitgallery.cpp | 40 +++--------------- indra/newview/lloutfitgallery.h | 5 +-- indra/newview/lloutfitslist.cpp | 27 +++---------- indra/newview/lloutfitslist.h | 5 +-- indra/newview/llsnapshotlivepreview.cpp | 26 ++++++++++++ indra/newview/llsnapshotlivepreview.h | 1 + .../default/xui/en/floater_simple_snapshot.xml | 4 +- .../default/xui/en/menu_gallery_outfit_tab.xml | 32 ++------------- .../skins/default/xui/en/menu_outfit_gear.xml | 6 +-- 13 files changed, 123 insertions(+), 132 deletions(-) (limited to 'indra/newview/llinspecttexture.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 378f5bc132..5b47c483fb 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -31,6 +31,7 @@ #include "llbutton.h" #include "llclipboard.h" #include "lliconctrl.h" +#include "llinventoryfunctions.h" #include "llinventoryicon.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" @@ -264,6 +265,20 @@ void LLFloaterChangeItemThumbnail::refreshFromInventory() } } +class LLIsOutfitTextureType : public LLInventoryCollectFunctor +{ +public: + LLIsOutfitTextureType() {} + virtual ~LLIsOutfitTextureType() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); +}; + +bool LLIsOutfitTextureType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + return item && (item->getType() == LLAssetType::AT_TEXTURE); +} + void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) { LLUIImagePtr icon_img; @@ -286,6 +301,35 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) if (cat) { icon_img = LLUI::getUIImage(LLViewerFolderType::lookupIconName(cat->getPreferredType(), true)); + + if (thumbnail_id.isNull() && (cat->getPreferredType() == LLFolderType::FT_OUTFIT)) + { + // Legacy support, check if there is an image inside + + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + // Not LLIsOfAssetType, because we allow links + LLIsOutfitTextureType f; + gInventory.getDirectDescendentsOf(mItemId, cats, items, f); + + if (1 == items.size()) + { + LLViewerInventoryItem* item = items.front(); + if (item && item->getIsLinkType()) + { + item = item->getLinkedItem(); + } + if (item) + { + thumbnail_id = item->getAssetUUID(); + + // per SL-19188, set this image as a thumbnail + cat->setThumbnailUUID(thumbnail_id); + // todo: needs to trigger send/update once server support is done + } + } + } + mRemoveImageBtn->setEnabled(thumbnail_id.notNull()); } } @@ -358,6 +402,7 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) if (obj) { obj->setThumbnailUUID(objects[0]); + // todo: need to trigger send/update once server support is done } } } @@ -384,6 +429,7 @@ void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notificatio if (obj) { obj->setThumbnailUUID(LLUUID::null); + // todo: need to trigger send/update once server support is done } } } @@ -450,6 +496,7 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id) if (obj && floaterp) { obj->setThumbnailUUID(floaterp->getAssetID()); + // todo: need to trigger send/update once server support is done } } diff --git a/indra/newview/llfloatersimplesnapshot.cpp b/indra/newview/llfloatersimplesnapshot.cpp index ca2b9b919a..096db132ac 100644 --- a/indra/newview/llfloatersimplesnapshot.cpp +++ b/indra/newview/llfloatersimplesnapshot.cpp @@ -30,9 +30,9 @@ #include "llfloaterreg.h" #include "llimagefiltersmanager.h" +#include "llinventorymodel.h" #include "llstatusbar.h" // can_afford_transaction() #include "llnotificationsutil.h" -#include "lloutfitgallery.h" #include "llagent.h" #include "llagentbenefits.h" #include "llviewercontrol.h" @@ -44,8 +44,6 @@ LLSimpleSnapshotFloaterView* gSimpleSnapshotFloaterView = NULL; const S32 THUMBNAIL_SNAPSHOT_DIM = 256; -static LLDefaultChildRegistry::Register r("simple_snapshot_floater_view"); - // Thumbnail posting coro static const std::string THUMBNAIL_ITEM_UPLOAD_CAP = "InventoryItemThumbnailUpload"; @@ -229,8 +227,7 @@ void LLFloaterSimpleSnapshot::Impl::setStatus(EStatus status, bool ok, const std ///---------------------------------------------------------------------------- LLFloaterSimpleSnapshot::LLFloaterSimpleSnapshot(const LLSD& key) - : LLFloaterSnapshotBase(key), - mOutfitGallery(NULL) + : LLFloaterSnapshotBase(key) { impl = new Impl(this); } @@ -241,8 +238,6 @@ LLFloaterSimpleSnapshot::~LLFloaterSimpleSnapshot() BOOL LLFloaterSimpleSnapshot::postBuild() { - getChild("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost())); - childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); childSetAction("save_btn", boost::bind(&LLFloaterSimpleSnapshot::onSend, this)); childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleSnapshot::onCancel, this)); @@ -337,18 +332,18 @@ void LLFloaterSimpleSnapshot::onCancel() void LLFloaterSimpleSnapshot::onSend() { - S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); - if (can_afford_transaction(expected_upload_cost)) + LLSnapshotLivePreview* previewp = getPreviewView(); + + std::string temp_file = gDirUtilp->getTempFilename(); + if (previewp->createUploadFile(temp_file, THUMBNAIL_SNAPSHOT_DIM)) { - saveTexture(); - postSave(); + uploadImageUploadFile(temp_file, mInventoryId, mTaskId); } else { - LLSD args; - args["COST"] = llformat("%d", expected_upload_cost); - LLNotificationsUtil::add("ErrorPhotoCannotAfford", args); - inventorySaveFailed(); + LLSD notif_args; + notif_args["REASON"] = LLImage::getLastError().c_str(); + LLNotificationsUtil::add("CannotUploadTexture", notif_args); } } @@ -371,7 +366,12 @@ void LLFloaterSimpleSnapshot::uploadThumbnail(const std::string &file_path, cons LL_WARNS("Thumbnail") << "Failed to upload thumbnail for " << inventory_id << " " << task_id << ", reason: " << notif_args["REASON"].asString() << LL_ENDL; return; } + uploadImageUploadFile(temp_file, inventory_id, task_id); +} +// static +void LLFloaterSimpleSnapshot::uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id) +{ std::string cap_name; LLSD data; @@ -431,22 +431,14 @@ LLFloaterSimpleSnapshot* LLFloaterSimpleSnapshot::getInstance() void LLFloaterSimpleSnapshot::saveTexture() { - LLSnapshotLivePreview* previewp = getPreviewView(); + LLSnapshotLivePreview* previewp = getPreviewView(); if (!previewp) { llassert(previewp != NULL); return; } - if (mOutfitGallery) - { - mOutfitGallery->onBeforeOutfitSnapshotSave(); - } - previewp->saveTexture(TRUE, getOutfitID().asString()); - if (mOutfitGallery) - { - mOutfitGallery->onAfterOutfitSnapshotSave(); - } + previewp->saveTexture(TRUE, getInventoryId().asString()); closeFloater(); } diff --git a/indra/newview/llfloatersimplesnapshot.h b/indra/newview/llfloatersimplesnapshot.h index 55253b38e8..59cb526704 100644 --- a/indra/newview/llfloatersimplesnapshot.h +++ b/indra/newview/llfloatersimplesnapshot.h @@ -31,8 +31,6 @@ #include "llfloatersnapshot.h" #include "llsnapshotlivepreview.h" -class LLOutfitGallery; - ///---------------------------------------------------------------------------- /// Class LLFloaterSimpleSnapshot ///---------------------------------------------------------------------------- @@ -58,11 +56,9 @@ public: const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } - void setOutfitID(LLUUID id) { mOutfitID = id; } - LLUUID getOutfitID() { return mOutfitID; } - void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } - void setInventoryId(const LLUUID &inventory_id) {} - void setTaskId(const LLUUID &task_id) {} + void setInventoryId(const LLUUID &inventory_id) { mInventoryId = inventory_id; } + LLUUID getInventoryId() { return mInventoryId; } + void setTaskId(const LLUUID &task_id) { mTaskId = task_id; } void postSave(); static void uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id); @@ -74,8 +70,11 @@ private: void onSend(); void onCancel(); - LLUUID mOutfitID; - LLOutfitGallery* mOutfitGallery; + // uploads upload-ready file + static void uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id); + + LLUUID mInventoryId; + LLUUID mTaskId; }; ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinspecttexture.cpp b/indra/newview/llinspecttexture.cpp index de0d65eb7e..2e8273d6cf 100644 --- a/indra/newview/llinspecttexture.cpp +++ b/indra/newview/llinspecttexture.cpp @@ -185,7 +185,8 @@ LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p) } if (item) { - // Todo: write this into folder's thumbnail id + // Note: LLFloaterChangeItemThumbnail will attempt to write this + // into folder's thumbnail id when opened p.create_params.getValue()["thumbnail_id"] = item->getAssetUUID(); return LLUICtrlFactory::create(p); } diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 06dbf50bee..d30cc66a38 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -837,52 +837,23 @@ LLContextMenu* LLOutfitGalleryContextMenu::createMenu() registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id)); registrar.add("Outfit.Delete", boost::bind(&LLOutfitGalleryContextMenu::onRemoveOutfit, this, selected_id)); registrar.add("Outfit.Create", boost::bind(&LLOutfitGalleryContextMenu::onCreate, this, _2)); - registrar.add("Outfit.UploadPhoto", boost::bind(&LLOutfitGalleryContextMenu::onUploadPhoto, this, selected_id)); - registrar.add("Outfit.SelectPhoto", boost::bind(&LLOutfitGalleryContextMenu::onSelectPhoto, this, selected_id)); - registrar.add("Outfit.TakeSnapshot", boost::bind(&LLOutfitGalleryContextMenu::onTakeSnapshot, this, selected_id)); - registrar.add("Outfit.RemovePhoto", boost::bind(&LLOutfitGalleryContextMenu::onRemovePhoto, this, selected_id)); + registrar.add("Outfit.Thumbnail", boost::bind(&LLOutfitGalleryContextMenu::onThumbnail, this, selected_id)); enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitGalleryContextMenu::onEnable, this, _2)); enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitGalleryContextMenu::onVisible, this, _2)); return createFromFile("menu_gallery_outfit_tab.xml"); } -void LLOutfitGalleryContextMenu::onUploadPhoto(const LLUUID& outfit_cat_id) +void LLOutfitGalleryContextMenu::onThumbnail(const LLUUID& outfit_cat_id) { LLOutfitGallery* gallery = dynamic_cast(mOutfitList); if (gallery && outfit_cat_id.notNull()) { - gallery->uploadPhoto(outfit_cat_id); + LLSD data(outfit_cat_id); + LLFloaterReg::showInstance("change_item_thumbnail", data); } } -void LLOutfitGalleryContextMenu::onSelectPhoto(const LLUUID& outfit_cat_id) -{ - LLOutfitGallery* gallery = dynamic_cast(mOutfitList); - if (gallery && outfit_cat_id.notNull()) - { - gallery->onSelectPhoto(outfit_cat_id); - } -} - -void LLOutfitGalleryContextMenu::onRemovePhoto(const LLUUID& outfit_cat_id) -{ - LLOutfitGallery* gallery = dynamic_cast(mOutfitList); - if (gallery && outfit_cat_id.notNull()) - { - gallery->checkRemovePhoto(outfit_cat_id); - gallery->refreshOutfit(outfit_cat_id); - } -} - -void LLOutfitGalleryContextMenu::onTakeSnapshot(const LLUUID& outfit_cat_id) -{ - LLOutfitGallery* gallery = dynamic_cast(mOutfitList); - if (gallery && outfit_cat_id.notNull()) - { - gallery->onTakeSnapshot(outfit_cat_id); - } -} void LLOutfitGalleryContextMenu::onRemoveOutfit(const LLUUID& outfit_cat_id) { @@ -1390,8 +1361,7 @@ void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id) LLFloaterSimpleSnapshot* snapshot_floater = LLFloaterSimpleSnapshot::getInstance(); if (snapshot_floater) { - snapshot_floater->setOutfitID(selected_outfit_id); - snapshot_floater->getInstance()->setGallery(this); + snapshot_floater->setInventoryId(selected_outfit_id); } } diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h index ce5c090134..4839477cb2 100644 --- a/indra/newview/lloutfitgallery.h +++ b/indra/newview/lloutfitgallery.h @@ -215,10 +215,7 @@ protected: /* virtual */ LLContextMenu* createMenu(); bool onEnable(LLSD::String param); bool onVisible(LLSD::String param); - void onUploadPhoto(const LLUUID& outfit_cat_id); - void onSelectPhoto(const LLUUID& outfit_cat_id); - void onRemovePhoto(const LLUUID& outfit_cat_id); - void onTakeSnapshot(const LLUUID& outfit_cat_id); + void onThumbnail(const LLUUID& outfit_cat_id); void onCreate(const LLSD& data); void onRemoveOutfit(const LLUUID& outfit_cat_id); void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response, const LLUUID& outfit_cat_id); diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 4171fd8822..2f7d1c433a 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -36,6 +36,7 @@ #include "llagentwearables.h" #include "llappearancemgr.h" #include "llagentbenefits.h" +#include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" @@ -1112,10 +1113,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist) registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this)); - registrar.add("Gear.UploadPhoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this)); - registrar.add("Gear.SelectPhoto", boost::bind(&LLOutfitListGearMenuBase::onSelectPhoto, this)); - registrar.add("Gear.TakeSnapshot", boost::bind(&LLOutfitListGearMenuBase::onTakeSnapshot, this)); - registrar.add("Gear.RemovePhoto", boost::bind(&LLOutfitListGearMenuBase::onRemovePhoto, this)); + registrar.add("Gear.Thumbnail", boost::bind(&LLOutfitListGearMenuBase::onThumbnail, this)); registrar.add("Gear.SortByName", boost::bind(&LLOutfitListGearMenuBase::onChangeSortOrder, this)); enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2)); @@ -1251,24 +1249,11 @@ bool LLOutfitListGearMenuBase::onVisible(LLSD::String param) return true; } -void LLOutfitListGearMenuBase::onUploadFoto() +void LLOutfitListGearMenuBase::onThumbnail() { - -} - -void LLOutfitListGearMenuBase::onSelectPhoto() -{ - -} - -void LLOutfitListGearMenuBase::onTakeSnapshot() -{ - -} - -void LLOutfitListGearMenuBase::onRemovePhoto() -{ - + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + LLSD data(selected_outfit_id); + LLFloaterReg::showInstance("change_item_thumbnail", data); } void LLOutfitListGearMenuBase::onChangeSortOrder() diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 81be8de94f..66b3165169 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -163,10 +163,7 @@ public: protected: virtual void onUpdateItemsVisibility(); - virtual void onUploadFoto(); - virtual void onSelectPhoto(); - virtual void onTakeSnapshot(); - virtual void onRemovePhoto(); + virtual void onThumbnail(); virtual void onChangeSortOrder(); const LLUUID& getSelectedOutfitID(); diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index ed7e18fadc..273e3a403d 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -51,6 +51,7 @@ #include "llviewercontrol.h" #include "llviewermenufile.h" // upload_new_resource() #include "llviewerstats.h" +#include "llviewertexturelist.h" #include "llwindow.h" #include "llworld.h" #include @@ -873,6 +874,31 @@ LLPointer LLSnapshotLivePreview::getEncodedImage() return mPreviewImageEncoded; } +bool LLSnapshotLivePreview::createUploadFile(const std::string &out_filename, const S32 max_image_dimentions) +{ + // make a copy, since convertToUploadFile modifies raw image + LLPointer raw_image = new LLImageRaw( + mPreviewImage->getData(), + mPreviewImage->getWidth(), + mPreviewImage->getHeight(), + mPreviewImage->getComponents()); + + LLPointer compressedImage = LLViewerTextureList::convertToUploadFile(raw_image, max_image_dimentions); + if (compressedImage.isNull()) + { + compressedImage->setLastError("Couldn't convert the image to jpeg2000."); + LL_INFOS() << "Couldn't convert to j2c, file : " << out_filename << LL_ENDL; + return false; + } + if (!compressedImage->save(out_filename)) + { + compressedImage->setLastError("Couldn't create the jpeg2000 image for upload."); + LL_INFOS() << "Couldn't create output file : " << out_filename << LL_ENDL; + return false; + } + return true; +} + // We actually estimate the data size so that we do not require actual compression when showing the preview // Note : whenever formatted image is computed, mDataSize will be updated to reflect the true size void LLSnapshotLivePreview::estimateDataSize() diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index 1f81307976..e78c885789 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -106,6 +106,7 @@ public: LLPointer getFormattedImage(); LLPointer getEncodedImage(); + bool createUploadFile(const std::string &out_file, const S32 max_image_dimentions); /// Sets size of preview thumbnail image and the surrounding rect. void setThumbnailPlaceholderRect(const LLRect& rect) {mThumbnailPlaceholderRect = rect; } diff --git a/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml b/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml index a53d42be2e..97ea59593e 100644 --- a/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml @@ -12,7 +12,7 @@ help_topic="snapshot" save_rect="true" save_visibility="false" - title="THUMBNAIL SNAPSHOT" + title="ITEM SNAPSHOT" width="351">