summaryrefslogtreecommitdiff
path: root/indra/newview/llthumbnailctrl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llthumbnailctrl.cpp')
-rw-r--r--indra/newview/llthumbnailctrl.cpp238
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);
+}
+
+