PropertyAssetCtrl and ThumbnailPropertyCtrl support custom thumbnail images

• PropertyAssetCtrl was previously extended with ThumbnailPropertyCtrl to optionally display a thumbnail and floating zoomed in preview of the selected asset.
• This change allows overriding the image that comes from the thumbnail system with a custom image provided as an attribute. The custom image can be specified as either a file path or a buffer containing a serialized QPixmap.
• This will be used by the material system in the editor to provide a dynamically rendered image of the material with property overrides applied so that the image will update as the user customizes their material.

Signed-off-by: Guthrie Adams <guthadam@amazon.com>
monroegm-disable-blank-issue-2
Guthrie Adams 4 years ago
parent 05767f2d2b
commit f7e08d1c4b

@ -28,6 +28,9 @@ AZ_PUSH_DISABLE_WARNING(4244 4251, "-Wunknown-warning-option")
#include <QTableView> #include <QTableView>
#include <QHeaderView> #include <QHeaderView>
#include <QPainter> #include <QPainter>
#include <QPixmap>
#include <QByteArray>
#include <QDataStream>
AZ_POP_DISABLE_WARNING AZ_POP_DISABLE_WARNING
#include <AzCore/Asset/AssetManager.h> #include <AzCore/Asset/AssetManager.h>
@ -1230,6 +1233,16 @@ namespace AzToolsFramework
return m_showThumbnailDropDownButton; return m_showThumbnailDropDownButton;
} }
void PropertyAssetCtrl::SetCustomThumbnailEnabled(bool enabled)
{
m_thumbnail->SetCustomThumbnailEnabled(enabled);
}
void PropertyAssetCtrl::SetCustomThumbnailPixmap(const QPixmap& pixmap)
{
m_thumbnail->SetCustomThumbnailPixmap(pixmap);
}
void PropertyAssetCtrl::SetThumbnailCallback(EditCallbackType* editNotifyCallback) void PropertyAssetCtrl::SetThumbnailCallback(EditCallbackType* editNotifyCallback)
{ {
m_thumbnailCallback = editNotifyCallback; m_thumbnailCallback = editNotifyCallback;
@ -1356,15 +1369,27 @@ namespace AzToolsFramework
GUI->SetClearNotifyCallback(nullptr); GUI->SetClearNotifyCallback(nullptr);
} }
} }
else if (attrib == AZ_CRC("BrowseIcon", 0x507d7a4f)) else if (attrib == AZ_CRC_CE("BrowseIcon"))
{ {
AZStd::string iconPath; AZStd::string iconPath;
attrValue->Read<AZStd::string>(iconPath); if (attrValue->Read<AZStd::string>(iconPath) && !iconPath.empty())
if (!iconPath.empty())
{ {
GUI->SetBrowseButtonIcon(QIcon(iconPath.c_str())); GUI->SetBrowseButtonIcon(QIcon(iconPath.c_str()));
} }
else
{
// A QPixmap object can't be assigned directly via an attribute.
// This allows dynamic icon data to be supplied as a buffer containing a serialized QPixmap.
AZStd::vector<char> pixmapBuffer;
if (attrValue->Read<AZStd::vector<char>>(pixmapBuffer) && !pixmapBuffer.empty())
{
QByteArray pixmapBytes(pixmapBuffer.data(), aznumeric_cast<int>(pixmapBuffer.size()));
QDataStream stream(&pixmapBytes, QIODevice::ReadOnly);
QPixmap pixmap;
stream >> pixmap;
GUI->SetBrowseButtonIcon(pixmap);
}
}
} }
else if (attrib == AZ_CRC_CE("BrowseButtonEnabled")) else if (attrib == AZ_CRC_CE("BrowseButtonEnabled"))
{ {
@ -1390,6 +1415,30 @@ namespace AzToolsFramework
GUI->SetShowThumbnail(showThumbnail); GUI->SetShowThumbnail(showThumbnail);
} }
} }
else if (attrib == AZ_CRC_CE("ThumbnailIcon"))
{
AZStd::string iconPath;
if (attrValue->Read<AZStd::string>(iconPath) && !iconPath.empty())
{
GUI->SetCustomThumbnailEnabled(true);
GUI->SetCustomThumbnailPixmap(QPixmap::fromImage(QImage(iconPath.c_str())));
}
else
{
// A QPixmap object can't be assigned directly via an attribute.
// This allows dynamic icon data to be supplied as a buffer containing a serialized QPixmap.
AZStd::vector<char> pixmapBuffer;
if (attrValue->Read<AZStd::vector<char>>(pixmapBuffer) && !pixmapBuffer.empty())
{
QByteArray pixmapBytes(pixmapBuffer.data(), aznumeric_cast<int>(pixmapBuffer.size()));
QDataStream stream(&pixmapBytes, QIODevice::ReadOnly);
QPixmap pixmap;
stream >> pixmap;
GUI->SetCustomThumbnailEnabled(true);
GUI->SetCustomThumbnailPixmap(pixmap);
}
}
}
else if (attrib == AZ_CRC_CE("ThumbnailCallback")) else if (attrib == AZ_CRC_CE("ThumbnailCallback"))
{ {
PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast<PropertyAssetCtrl::EditCallbackType*>(attrValue->GetAttribute()); PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast<PropertyAssetCtrl::EditCallbackType*>(attrValue->GetAttribute());

@ -217,12 +217,17 @@ namespace AzToolsFramework
void SetHideProductFilesInAssetPicker(bool hide); void SetHideProductFilesInAssetPicker(bool hide);
bool GetHideProductFilesInAssetPicker() const; bool GetHideProductFilesInAssetPicker() const;
// Enable and configure a thumbnail widget that displays an asset preview and dropdown arrow for a dropdown menu
void SetShowThumbnail(bool enable); void SetShowThumbnail(bool enable);
bool GetShowThumbnail() const; bool GetShowThumbnail() const;
void SetShowThumbnailDropDownButton(bool enable); void SetShowThumbnailDropDownButton(bool enable);
bool GetShowThumbnailDropDownButton() const; bool GetShowThumbnailDropDownButton() const;
void SetThumbnailCallback(EditCallbackType* editNotifyCallback); void SetThumbnailCallback(EditCallbackType* editNotifyCallback);
// If enabled, replaces the thumbnail widget content with a custom pixmap
void SetCustomThumbnailEnabled(bool enabled);
void SetCustomThumbnailPixmap(const QPixmap& pixmap);
void SetSelectedAssetID(const AZ::Data::AssetId& newID); void SetSelectedAssetID(const AZ::Data::AssetId& newID);
void SetCurrentAssetType(const AZ::Data::AssetType& newType); void SetCurrentAssetType(const AZ::Data::AssetType& newType);
void SetSelectedAssetID(const AZ::Data::AssetId& newID, const AZ::Data::AssetType& newType); void SetSelectedAssetID(const AZ::Data::AssetId& newID, const AZ::Data::AssetType& newType);

@ -7,75 +7,117 @@
*/ */
#include <AzToolsFramework/Debug/TraceContext.h> #include <AzToolsFramework/Debug/TraceContext.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // 4251: 'QRawFont::d': class 'QExplicitlySharedDataPointer<QRawFontPrivate>' needs to have dll-interface to be used by clients of class 'QRawFont'
// 4800: 'QTextEngine *const ': forcing value to bool 'true' or 'false' (performance warning) // 4251: 'QRawFont::d': class 'QExplicitlySharedDataPointer<QRawFontPrivate>' needs to have dll-interface to be used by clients of class
#include <QLabel> // 'QRawFont' 4800: 'QTextEngine *const ': forcing value to bool 'true' or 'false' (performance warning)
#include <QHBoxLayout> AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
#include <QApplication>
#include <QEvent> #include <QEvent>
#include <QHBoxLayout>
#include <QLabel>
#include <QPainter> #include <QPainter>
#include <UI/UICore/AspectRatioAwarePixmapWidget.hxx>
#include <Thumbnails/ThumbnailWidget.h> #include <Thumbnails/ThumbnailWidget.h>
#include <QApplication> #include <UI/UICore/AspectRatioAwarePixmapWidget.hxx>
AZ_POP_DISABLE_WARNING AZ_POP_DISABLE_WARNING
#include "ThumbnailPropertyCtrl.h" #include "ThumbnailPropertyCtrl.h"
namespace AzToolsFramework namespace AzToolsFramework
{ {
ThumbnailPropertyCtrl::ThumbnailPropertyCtrl(QWidget* parent) ThumbnailPropertyCtrl::ThumbnailPropertyCtrl(QWidget* parent)
: QWidget(parent) : QWidget(parent)
{ {
QHBoxLayout* pLayout = new QHBoxLayout();
pLayout->setContentsMargins(0, 0, 0, 0);
pLayout->setSpacing(0);
m_thumbnail = new Thumbnailer::ThumbnailWidget(this); m_thumbnail = new Thumbnailer::ThumbnailWidget(this);
m_thumbnail->setFixedSize(QSize(24, 24)); m_thumbnail->setFixedSize(QSize(24, 24));
m_thumbnailEnlarged = new Thumbnailer::ThumbnailWidget(this);
m_thumbnailEnlarged->setFixedSize(QSize(180, 180));
m_thumbnailEnlarged->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
m_customThumbnail = new QLabel(this);
m_customThumbnail->setFixedSize(QSize(24, 24));
m_customThumbnail->setScaledContents(true);
m_customThumbnailEnlarged = new QLabel(this);
m_customThumbnailEnlarged->setFixedSize(QSize(180, 180));
m_customThumbnailEnlarged->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
m_customThumbnailEnlarged->setScaledContents(true);
m_dropDownArrow = new AspectRatioAwarePixmapWidget(this); m_dropDownArrow = new AspectRatioAwarePixmapWidget(this);
m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0.png")); m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0.png"));
m_dropDownArrow->setFixedSize(QSize(8, 24)); m_dropDownArrow->setFixedSize(QSize(8, 24));
ShowDropDownArrow(false);
m_emptyThumbnail = new QLabel(this); m_emptyThumbnail = new QLabel(this);
m_emptyThumbnail->setPixmap(QPixmap(":/stylesheet/img/line.png")); m_emptyThumbnail->setPixmap(QPixmap(":/stylesheet/img/line.png"));
m_emptyThumbnail->setFixedSize(QSize(24, 24)); m_emptyThumbnail->setFixedSize(QSize(24, 24));
pLayout->addWidget(m_emptyThumbnail); QHBoxLayout* pLayout = new QHBoxLayout();
pLayout->setContentsMargins(0, 0, 0, 0);
pLayout->setSpacing(0);
pLayout->addWidget(m_thumbnail); pLayout->addWidget(m_thumbnail);
pLayout->addWidget(m_customThumbnail);
pLayout->addWidget(m_emptyThumbnail);
pLayout->addSpacing(4); pLayout->addSpacing(4);
pLayout->addWidget(m_dropDownArrow); pLayout->addWidget(m_dropDownArrow);
pLayout->addSpacing(4); pLayout->addSpacing(4);
setLayout(pLayout); setLayout(pLayout);
ShowDropDownArrow(false);
UpdateVisibility();
} }
void ThumbnailPropertyCtrl::SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName) void ThumbnailPropertyCtrl::SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName)
{ {
m_key = key; if (m_customThumbnailEnabled)
m_emptyThumbnail->setVisible(false); {
m_thumbnail->SetThumbnailKey(key, contextName); ClearThumbnail();
}
else
{
m_key = key;
m_thumbnail->SetThumbnailKey(m_key, contextName);
m_thumbnailEnlarged->SetThumbnailKey(m_key, contextName);
}
UpdateVisibility();
} }
void ThumbnailPropertyCtrl::ClearThumbnail() void ThumbnailPropertyCtrl::ClearThumbnail()
{ {
m_emptyThumbnail->setVisible(true); m_key.clear();
m_thumbnail->ClearThumbnail(); m_thumbnail->ClearThumbnail();
m_thumbnailEnlarged->ClearThumbnail();
UpdateVisibility();
} }
void ThumbnailPropertyCtrl::ShowDropDownArrow(bool visible) void ThumbnailPropertyCtrl::ShowDropDownArrow(bool visible)
{ {
if (visible) setFixedSize(QSize(visible ? 40 : 24, 24));
{
setFixedSize(QSize(40, 24));
}
else
{
setFixedSize(QSize(24, 24));
}
m_dropDownArrow->setVisible(visible); m_dropDownArrow->setVisible(visible);
} }
void ThumbnailPropertyCtrl::SetCustomThumbnailEnabled(bool enabled)
{
m_customThumbnailEnabled = enabled;
UpdateVisibility();
}
void ThumbnailPropertyCtrl::SetCustomThumbnailPixmap(const QPixmap& pixmap)
{
m_customThumbnail->setPixmap(pixmap);
m_customThumbnailEnlarged->setPixmap(pixmap);
UpdateVisibility();
}
void ThumbnailPropertyCtrl::UpdateVisibility()
{
m_thumbnail->setVisible(m_key && !m_customThumbnailEnabled);
m_thumbnailEnlarged->setVisible(false);
m_customThumbnail->setVisible(m_customThumbnailEnabled);
m_customThumbnailEnlarged->setVisible(false);
m_emptyThumbnail->setVisible(!m_key && !m_customThumbnailEnabled);
}
bool ThumbnailPropertyCtrl::event(QEvent* e) bool ThumbnailPropertyCtrl::event(QEvent* e)
{ {
if (isEnabled()) if (isEnabled())
@ -83,7 +125,7 @@ namespace AzToolsFramework
if (e->type() == QEvent::MouseButtonPress) if (e->type() == QEvent::MouseButtonPress)
{ {
emit clicked(); emit clicked();
return true; //ignore return true; // ignore
} }
} }
@ -94,37 +136,32 @@ namespace AzToolsFramework
{ {
QPainter p(this); QPainter p(this);
QRect targetRect(QPoint(), QSize(40, 24)); QRect targetRect(QPoint(), QSize(40, 24));
p.fillRect(targetRect, QColor(17, 17, 17)); // #111111 p.fillRect(targetRect, QColor("#111111"));
QWidget::paintEvent(e); QWidget::paintEvent(e);
} }
void ThumbnailPropertyCtrl::enterEvent(QEvent* e) void ThumbnailPropertyCtrl::enterEvent(QEvent* e)
{ {
m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0_highlighted.png")); m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0_highlighted.png"));
if (!m_thumbnailEnlarged && m_key) const QPoint offset(-m_thumbnailEnlarged->width() - 5, -m_thumbnailEnlarged->height() / 2 + m_thumbnail->height() / 2);
{
QPoint position = mapToGlobal(pos() - QPoint(185, 0)); m_thumbnailEnlarged->move(mapToGlobal(pos()) + offset);
QSize size(180, 180); m_thumbnailEnlarged->raise();
m_thumbnailEnlarged.reset(new Thumbnailer::ThumbnailWidget()); m_thumbnailEnlarged->setVisible(m_key && !m_customThumbnailEnabled);
m_thumbnailEnlarged->setFixedSize(size);
m_thumbnailEnlarged->move(position); m_customThumbnailEnlarged->move(mapToGlobal(pos()) + offset);
m_thumbnailEnlarged->setWindowFlags(Qt::Window | Qt::FramelessWindowHint); m_customThumbnailEnlarged->raise();
m_thumbnailEnlarged->SetThumbnailKey(m_key); m_customThumbnailEnlarged->setVisible(m_customThumbnailEnabled);
m_thumbnailEnlarged->raise();
m_thumbnailEnlarged->show();
}
QWidget::enterEvent(e); QWidget::enterEvent(e);
} }
void ThumbnailPropertyCtrl::leaveEvent(QEvent* e) void ThumbnailPropertyCtrl::leaveEvent(QEvent* e)
{ {
m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0.png")); m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0.png"));
if (m_thumbnailEnlarged) m_thumbnailEnlarged->setVisible(false);
{ m_customThumbnailEnlarged->setVisible(false);
m_thumbnailEnlarged.reset();
}
QWidget::leaveEvent(e); QWidget::leaveEvent(e);
} }
} } // namespace AzToolsFramework
#include "UI/PropertyEditor/moc_ThumbnailPropertyCtrl.cpp" #include "UI/PropertyEditor/moc_ThumbnailPropertyCtrl.cpp"

@ -1,5 +1,3 @@
#pragma once
/* /*
* Copyright (c) Contributors to the Open 3D Engine Project. * Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
@ -8,6 +6,8 @@
* *
*/ */
#pragma once
#if !defined(Q_MOC_RUN) #if !defined(Q_MOC_RUN)
#include <AzCore/PlatformDef.h> #include <AzCore/PlatformDef.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h> #include <AzToolsFramework/Thumbnails/Thumbnail.h>
@ -35,25 +35,38 @@ namespace AzToolsFramework
//! Call this to set what thumbnail widget will display //! Call this to set what thumbnail widget will display
void SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName = "Default"); void SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName = "Default");
//! Remove current thumbnail //! Remove current thumbnail
void ClearThumbnail(); void ClearThumbnail();
//! Display a clickble dropdown arrow next to the thumbnail
void ShowDropDownArrow(bool visible); void ShowDropDownArrow(bool visible);
bool event(QEvent* e) override; //! Override the thumbnail widget with a custom image
void SetCustomThumbnailEnabled(bool enabled);
//! Assign a custom image to dispsy in place of thumbnail
void SetCustomThumbnailPixmap(const QPixmap& pixmap);
Q_SIGNALS: Q_SIGNALS:
void clicked(); void clicked();
protected: private:
void UpdateVisibility();
bool event(QEvent* e) override;
void paintEvent(QPaintEvent* e) override; void paintEvent(QPaintEvent* e) override;
void enterEvent(QEvent* e) override; void enterEvent(QEvent* e) override;
void leaveEvent(QEvent* e) override; void leaveEvent(QEvent* e) override;
private:
Thumbnailer::SharedThumbnailKey m_key; Thumbnailer::SharedThumbnailKey m_key;
Thumbnailer::ThumbnailWidget* m_thumbnail = nullptr; Thumbnailer::ThumbnailWidget* m_thumbnail = nullptr;
QScopedPointer<Thumbnailer::ThumbnailWidget> m_thumbnailEnlarged; Thumbnailer::ThumbnailWidget* m_thumbnailEnlarged = nullptr;
QLabel* m_customThumbnail = nullptr;
QLabel* m_customThumbnailEnlarged = nullptr;
bool m_customThumbnailEnabled = false;
QLabel* m_emptyThumbnail = nullptr; QLabel* m_emptyThumbnail = nullptr;
AspectRatioAwarePixmapWidget* m_dropDownArrow = nullptr; AspectRatioAwarePixmapWidget* m_dropDownArrow = nullptr;
}; };

Loading…
Cancel
Save