diff options
Diffstat (limited to 'indra/newview/llthumbnailctrl.cpp')
-rw-r--r-- | indra/newview/llthumbnailctrl.cpp | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/indra/newview/llthumbnailctrl.cpp b/indra/newview/llthumbnailctrl.cpp new file mode 100644 index 0000000000..340dba3717 --- /dev/null +++ b/indra/newview/llthumbnailctrl.cpp @@ -0,0 +1,238 @@ +/** + * @file llthumbnailctrl.cpp + * @brief LLThumbnailCtrl base class + * + * $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$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llthumbnailctrl.h" + +#include "linden_common.h" +#include "llagent.h" +#include "lluictrlfactory.h" +#include "lluuid.h" +#include "lltrans.h" +#include "llviewborder.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" +#include "llwindow.h" + +static LLDefaultChildRegistry::Register<LLThumbnailCtrl> r("thumbnail"); + +LLThumbnailCtrl::Params::Params() +: border("border") +, border_color("border_color") +, fallback_image("fallback_image") +, image_name("image_name") +, border_visible("show_visible", false) +, interactable("interactable", false) +, show_loading("show_loading", true) +{} + +LLThumbnailCtrl::LLThumbnailCtrl(const LLThumbnailCtrl::Params& p) +: LLUICtrl(p) +, mBorderColor(p.border_color()) +, mBorderVisible(p.border_visible()) +, mFallbackImagep(p.fallback_image) +, mInteractable(p.interactable()) +, mShowLoadingPlaceholder(p.show_loading()) +, mPriority(LLGLTexture::BOOST_PREVIEW) +{ + mLoadingPlaceholderString = LLTrans::getString("texture_loading"); + + LLRect border_rect = getLocalRect(); + LLViewBorder::Params vbparams(p.border); + vbparams.name("border"); + vbparams.rect(border_rect); + mBorder = LLUICtrlFactory::create<LLViewBorder> (vbparams); + addChild(mBorder); + + if (p.image_name.isProvided()) + { + setValue(p.image_name()); + } +} + +LLThumbnailCtrl::~LLThumbnailCtrl() +{ + mTexturep = nullptr; + mImagep = nullptr; + mFallbackImagep = nullptr; +} + + +void LLThumbnailCtrl::draw() +{ + LLRect draw_rect = getLocalRect(); + + if (mBorderVisible) + { + mBorder->setKeyboardFocusHighlight(hasFocus()); + + gl_rect_2d( draw_rect, mBorderColor.get(), FALSE ); + draw_rect.stretch( -1 ); + } + + // If we're in a focused floater, don't apply the floater's alpha to the texture. + const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + if( mTexturep ) + { + if( mTexturep->getComponents() == 4 ) + { + gl_rect_2d_checkerboard( draw_rect, alpha ); + } + + gl_draw_scaled_image( draw_rect.mLeft, draw_rect.mBottom, draw_rect.getWidth(), draw_rect.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha); + + mTexturep->setKnownDrawSize(draw_rect.getWidth(), draw_rect.getHeight()); + } + else if( mImagep.notNull() ) + { + mImagep->draw(draw_rect, UI_VERTEX_COLOR % alpha ); + } + else if (mFallbackImagep.notNull()) + { + if (draw_rect.getWidth() > mFallbackImagep->getWidth() + && draw_rect.getHeight() > mFallbackImagep->getHeight()) + { + S32 img_width = mFallbackImagep->getWidth(); + S32 img_height = mFallbackImagep->getHeight(); + S32 rect_width = draw_rect.getWidth(); + S32 rect_height = draw_rect.getHeight(); + + LLRect fallback_rect; + fallback_rect.mLeft = draw_rect.mLeft + (rect_width - img_width) / 2; + fallback_rect.mRight = fallback_rect.mLeft + img_width; + fallback_rect.mBottom = draw_rect.mBottom + (rect_height - img_height) / 2; + fallback_rect.mTop = fallback_rect.mBottom + img_height; + + mFallbackImagep->draw(fallback_rect, UI_VERTEX_COLOR % alpha); + } + else + { + mFallbackImagep->draw(draw_rect, UI_VERTEX_COLOR % alpha); + } + } + else + { + gl_rect_2d( draw_rect, LLColor4::grey % alpha, TRUE ); + + // Draw X + gl_draw_x( draw_rect, LLColor4::black ); + } + + // Show "Loading..." string on the top left corner while this texture is loading. + // Using the discard level, do not show the string if the texture is almost but not + // fully loaded. + if (mTexturep.notNull() + && mShowLoadingPlaceholder + && !mTexturep->isFullyLoaded()) + { + U32 v_offset = 25; + LLFontGL* font = LLFontGL::getFontSansSerif(); + + // Don't show as loaded if the texture is almost fully loaded (i.e. discard1) unless god + if ((mTexturep->getDiscardLevel() > 1) || gAgent.isGodlike()) + { + font->renderUTF8( + mLoadingPlaceholderString, + 0, + llfloor(draw_rect.mLeft+3), + llfloor(draw_rect.mTop-v_offset), + LLColor4::white, + LLFontGL::LEFT, + LLFontGL::BASELINE, + LLFontGL::DROP_SHADOW); + } + } + + LLUICtrl::draw(); +} + +void LLThumbnailCtrl::clearTexture() +{ + mImageAssetID = LLUUID::null; + mTexturep = nullptr; + mImagep = nullptr; +} + +// virtual +// value might be a string or a UUID +void LLThumbnailCtrl::setValue(const LLSD& value) +{ + LLSD tvalue(value); + if (value.isString() && LLUUID::validate(value.asString())) + { + //RN: support UUIDs masquerading as strings + tvalue = LLSD(LLUUID(value.asString())); + } + + LLUICtrl::setValue(tvalue); + + mImageAssetID = LLUUID::null; + mTexturep = nullptr; + mImagep = nullptr; + + if (tvalue.isUUID()) + { + mImageAssetID = tvalue.asUUID(); + if (mImageAssetID.notNull()) + { + // Should it support baked textures? + mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + + mTexturep->setBoostLevel(mPriority); + mTexturep->forceToSaveRawImage(0); + + S32 desired_draw_width = mTexturep->getWidth(); + S32 desired_draw_height = mTexturep->getHeight(); + + mTexturep->setKnownDrawSize(desired_draw_width, desired_draw_height); + } + } + else if (tvalue.isString()) + { + mImagep = LLUI::getUIImage(tvalue.asString(), LLGLTexture::BOOST_UI); + if (mImagep) + { + LLViewerFetchedTexture* texture = dynamic_cast<LLViewerFetchedTexture*>(mImagep->getImage().get()); + if(texture) + { + mImageAssetID = texture->getID(); + } + } + } +} + +BOOL LLThumbnailCtrl::handleHover(S32 x, S32 y, MASK mask) +{ + if (mInteractable && getEnabled()) + { + getWindow()->setCursor(UI_CURSOR_HAND); + return TRUE; + } + return LLUICtrl::handleHover(x, y, mask); +} + + |