232 lines
7.0 KiB
C++
232 lines
7.0 KiB
C++
/**
|
|
* @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();
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
|