You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
530 lines
17 KiB
C++
530 lines
17 KiB
C++
/*
|
|
* 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.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#include <QGraphicsItem>
|
|
#include <QFont>
|
|
#include <QPainter>
|
|
|
|
#include <AzCore/Serialization/EditContext.h>
|
|
|
|
#include <Components/Nodes/General/GeneralNodeTitleComponent.h>
|
|
|
|
#include <Components/Nodes/General/GeneralNodeFrameComponent.h>
|
|
#include <GraphCanvas/Components/StyleBus.h>
|
|
#include <GraphCanvas/Components/Nodes/NodeBus.h>
|
|
#include <GraphCanvas/Editor/GraphCanvasProfiler.h>
|
|
#include <GraphCanvas/tools.h>
|
|
#include <GraphCanvas/Styling/StyleHelper.h>
|
|
#include <GraphCanvas/Utils/QtDrawingUtils.h>
|
|
#include <GraphCanvas/Components/VisualBus.h>
|
|
|
|
|
|
namespace GraphCanvas
|
|
{
|
|
//////////////////////////////
|
|
// GeneralNodeTitleComponent
|
|
//////////////////////////////
|
|
|
|
void GeneralNodeTitleComponent::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serializeContext)
|
|
{
|
|
serializeContext->Class<GeneralNodeTitleComponentSaveData, ComponentSaveData>()
|
|
->Version(1)
|
|
->Field("PaletteOverride", &GeneralNodeTitleComponentSaveData::m_paletteOverride)
|
|
;
|
|
|
|
serializeContext->Class<GeneralNodeTitleComponent, AZ::Component >()
|
|
->Version(4)
|
|
->Field("Title", &GeneralNodeTitleComponent::m_title)
|
|
->Field("SubTitle", &GeneralNodeTitleComponent::m_subTitle)
|
|
->Field("SaveData", &GeneralNodeTitleComponent::m_saveData)
|
|
->Field("DefaultPalette", &GeneralNodeTitleComponent::m_basePalette)
|
|
;
|
|
}
|
|
}
|
|
|
|
GeneralNodeTitleComponent::GeneralNodeTitleComponent()
|
|
{
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::Init()
|
|
{
|
|
m_generalNodeTitleWidget = aznew GeneralNodeTitleGraphicsWidget(GetEntityId());
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::Activate()
|
|
{
|
|
AZ::EntityId entityId = GetEntityId();
|
|
m_saveData.Activate(entityId);
|
|
SceneMemberNotificationBus::Handler::BusConnect(entityId);
|
|
NodeTitleRequestBus::Handler::BusConnect(entityId);
|
|
VisualNotificationBus::Handler::BusConnect(entityId);
|
|
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->SetTitle(m_title);
|
|
m_generalNodeTitleWidget->SetSubTitle(m_subTitle);
|
|
|
|
m_generalNodeTitleWidget->UpdateLayout();
|
|
|
|
m_generalNodeTitleWidget->Activate();
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::Deactivate()
|
|
{
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->Deactivate();
|
|
}
|
|
|
|
SceneMemberNotificationBus::Handler::BusDisconnect();
|
|
NodeTitleRequestBus::Handler::BusDisconnect();
|
|
VisualNotificationBus::Handler::BusDisconnect();
|
|
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::SetTitle(const AZStd::string& title)
|
|
{
|
|
m_title.SetFallback(title);
|
|
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->SetTitle(title);
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::SetTranslationKeyedTitle(const TranslationKeyedString& title)
|
|
{
|
|
m_title = title;
|
|
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->SetTitle(title);
|
|
}
|
|
}
|
|
|
|
AZStd::string GeneralNodeTitleComponent::GetTitle() const
|
|
{
|
|
return m_title.GetDisplayString();
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::SetSubTitle(const AZStd::string& subtitle)
|
|
{
|
|
m_subTitle.SetFallback(subtitle);
|
|
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->SetSubTitle(subtitle);
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::SetTranslationKeyedSubTitle(const TranslationKeyedString& subtitle)
|
|
{
|
|
m_subTitle = subtitle;
|
|
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->SetSubTitle(subtitle);
|
|
}
|
|
}
|
|
|
|
AZStd::string GeneralNodeTitleComponent::GetSubTitle() const
|
|
{
|
|
return m_subTitle.GetDisplayString();
|
|
}
|
|
|
|
QGraphicsWidget* GeneralNodeTitleComponent::GetGraphicsWidget()
|
|
{
|
|
return m_generalNodeTitleWidget;
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::SetDefaultPalette(const AZStd::string& basePalette)
|
|
{
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_basePalette = basePalette;
|
|
m_generalNodeTitleWidget->SetPaletteOverride(basePalette);
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::SetPaletteOverride(const AZStd::string& paletteOverride)
|
|
{
|
|
m_saveData.m_paletteOverride = paletteOverride;
|
|
m_saveData.SignalDirty();
|
|
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->SetPaletteOverride(paletteOverride);
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::SetDataPaletteOverride(const AZ::Uuid& uuid)
|
|
{
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->SetPaletteOverride(uuid);
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::SetColorPaletteOverride(const QColor& color)
|
|
{
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->SetPaletteOverride(color);
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::ConfigureIconConfiguration(PaletteIconConfiguration& paletteConfiguration)
|
|
{
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->ConfigureIconConfiguration(paletteConfiguration);
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::ClearPaletteOverride()
|
|
{
|
|
m_saveData.m_paletteOverride = "";
|
|
m_saveData.SignalDirty();
|
|
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->ClearPaletteOverride();
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleComponent::OnSceneSet(const AZ::EntityId& /*graphId*/)
|
|
{
|
|
if (!m_saveData.m_paletteOverride.empty())
|
|
{
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->SetPaletteOverride(m_saveData.m_paletteOverride);
|
|
}
|
|
}
|
|
else if (!m_basePalette.empty())
|
|
{
|
|
if (m_generalNodeTitleWidget)
|
|
{
|
|
m_generalNodeTitleWidget->SetPaletteOverride(m_basePalette);
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////
|
|
// GeneralNodeTitleGraphicsWidget
|
|
///////////////////////////////////
|
|
GeneralNodeTitleGraphicsWidget::GeneralNodeTitleGraphicsWidget(const AZ::EntityId& entityId)
|
|
: m_entityId(entityId)
|
|
, m_paletteOverride(nullptr)
|
|
, m_colorOverride(nullptr)
|
|
{
|
|
setCacheMode(QGraphicsItem::CacheMode::DeviceCoordinateCache);
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
|
setGraphicsItem(this);
|
|
setAcceptHoverEvents(false);
|
|
setFlag(ItemIsMovable, false);
|
|
|
|
m_titleWidget = aznew GraphCanvasLabel(this);
|
|
m_subTitleWidget = aznew GraphCanvasLabel(this);
|
|
m_linearLayout = new QGraphicsLinearLayout(Qt::Vertical);
|
|
m_linearLayout->setSpacing(0);
|
|
setLayout(m_linearLayout);
|
|
setData(GraphicsItemName, QStringLiteral("Title/%1").arg(static_cast<AZ::u64>(entityId), 16, 16, QChar('0')));
|
|
}
|
|
|
|
GeneralNodeTitleGraphicsWidget::~GeneralNodeTitleGraphicsWidget()
|
|
{
|
|
delete m_colorOverride;
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::Activate()
|
|
{
|
|
AZ::EntityId entityId = GetEntityId();
|
|
SceneMemberNotificationBus::Handler::BusConnect(entityId);
|
|
NodeNotificationBus::Handler::BusConnect(entityId);
|
|
RootGraphicsItemNotificationBus::Handler::BusConnect(entityId);
|
|
|
|
AZ::EntityId scene;
|
|
SceneMemberRequestBus::EventResult(scene, entityId, &SceneMemberRequests::GetScene);
|
|
if (scene.IsValid())
|
|
{
|
|
SceneNotificationBus::Handler::BusConnect(scene);
|
|
UpdateStyles();
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::Deactivate()
|
|
{
|
|
SceneMemberNotificationBus::Handler::BusDisconnect();
|
|
RootGraphicsItemNotificationBus::Handler::BusDisconnect();
|
|
NodeNotificationBus::Handler::BusDisconnect();
|
|
SceneNotificationBus::Handler::BusDisconnect();
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::SetTitle(const TranslationKeyedString& title)
|
|
{
|
|
if (m_titleWidget)
|
|
{
|
|
m_titleWidget->SetLabel(title);
|
|
UpdateLayout();
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::SetSubTitle(const TranslationKeyedString& subtitle)
|
|
{
|
|
if (m_subTitleWidget)
|
|
{
|
|
m_subTitleWidget->SetLabel(subtitle);
|
|
UpdateLayout();
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::SetPaletteOverride(AZStd::string_view paletteOverride)
|
|
{
|
|
AZ_Error("GraphCanvas", m_colorOverride == nullptr, "Unsupported use of Color and Palete Overrides");
|
|
if (m_colorOverride)
|
|
{
|
|
delete m_colorOverride;
|
|
m_colorOverride = nullptr;
|
|
}
|
|
|
|
AZ::EntityId sceneId;
|
|
SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
|
|
|
|
m_paletteOverride = nullptr;
|
|
StyleManagerRequestBus::BroadcastResult(m_paletteOverride, &StyleManagerRequests::FindColorPalette, paletteOverride);
|
|
update();
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::ConfigureIconConfiguration(PaletteIconConfiguration& paletteConfiguration)
|
|
{
|
|
bool isEnabled = false;
|
|
RootGraphicsItemRequestBus::EventResult(isEnabled, GetEntityId(), &RootGraphicsItemRequests::IsEnabled);
|
|
|
|
if (!isEnabled)
|
|
{
|
|
if (!m_disabledPalette)
|
|
{
|
|
StyleManagerRequestBus::BroadcastResult(m_disabledPalette, &StyleManagerRequests::FindColorPalette, "DisabledColorPalette");
|
|
}
|
|
|
|
if (m_disabledPalette)
|
|
{
|
|
m_disabledPalette->PopulatePaletteConfiguration(paletteConfiguration);
|
|
}
|
|
}
|
|
else if (m_colorOverride)
|
|
{
|
|
m_colorOverride->PopulatePaletteConfiguration(paletteConfiguration);
|
|
}
|
|
else if (m_paletteOverride)
|
|
{
|
|
m_paletteOverride->PopulatePaletteConfiguration(paletteConfiguration);
|
|
}
|
|
else
|
|
{
|
|
m_styleHelper.PopulatePaletteConfiguration(paletteConfiguration);
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::SetPaletteOverride(const AZ::Uuid& uuid)
|
|
{
|
|
AZ_Error("GraphCanvas", m_colorOverride == nullptr, "Unsupported use of Color and DataType Overrides");
|
|
if (m_colorOverride)
|
|
{
|
|
delete m_colorOverride;
|
|
m_colorOverride = nullptr;
|
|
}
|
|
|
|
AZ::EntityId sceneId;
|
|
SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
|
|
|
|
m_paletteOverride = nullptr;
|
|
StyleManagerRequestBus::BroadcastResult(m_paletteOverride, &StyleManagerRequests::FindDataColorPalette, uuid);
|
|
update();
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::SetPaletteOverride(const QColor& color)
|
|
{
|
|
if (m_colorOverride == nullptr)
|
|
{
|
|
if (m_paletteOverride != nullptr)
|
|
{
|
|
m_paletteOverride = nullptr;
|
|
}
|
|
|
|
AZ::EntityId sceneId;
|
|
SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
|
|
|
|
m_colorOverride = new Styling::StyleHelper();
|
|
m_colorOverride->SetScene(sceneId);
|
|
m_colorOverride->SetStyle("ColorOverrideNodeTitlePalette");
|
|
}
|
|
|
|
if (m_colorOverride)
|
|
{
|
|
m_colorOverride->AddAttributeOverride(Styling::Attribute::BackgroundColor, color);
|
|
m_colorOverride->AddAttributeOverride(Styling::Attribute::LineColor, color);
|
|
update();
|
|
}
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::ClearPaletteOverride()
|
|
{
|
|
m_paletteOverride = nullptr;
|
|
update();
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::UpdateLayout()
|
|
{
|
|
while (m_linearLayout->count() != 0)
|
|
{
|
|
m_linearLayout->removeAt(0);
|
|
}
|
|
|
|
if (!m_titleWidget->GetLabel().empty())
|
|
{
|
|
m_linearLayout->addItem(m_titleWidget);
|
|
}
|
|
|
|
if (!m_subTitleWidget->GetLabel().empty())
|
|
{
|
|
m_linearLayout->addItem(m_subTitleWidget);
|
|
}
|
|
|
|
RefreshDisplay();
|
|
NodeTitleNotificationsBus::Event(GetEntityId(), &NodeTitleNotifications::OnTitleChanged);
|
|
NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::AdjustSize);
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::UpdateStyles()
|
|
{
|
|
m_styleHelper.SetStyle(GetEntityId(), Styling::Elements::Title);
|
|
m_titleWidget->SetStyle(GetEntityId(), Styling::Elements::MainTitle);
|
|
m_subTitleWidget->SetStyle(GetEntityId(), Styling::Elements::SubTitle);
|
|
|
|
// Just clear our the disabled palette and we'll get it when we need it.
|
|
m_disabledPalette = nullptr;
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::RefreshDisplay()
|
|
{
|
|
updateGeometry();
|
|
update();
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::OnStylesChanged()
|
|
{
|
|
UpdateStyles();
|
|
RefreshDisplay();
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::OnAddedToScene(const AZ::EntityId& scene)
|
|
{
|
|
SceneNotificationBus::Handler::BusConnect(scene);
|
|
UpdateStyles();
|
|
RefreshDisplay();
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::OnRemovedFromScene(const AZ::EntityId& /*scene*/)
|
|
{
|
|
SceneNotificationBus::Handler::BusDisconnect();
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::OnTooltipChanged(const AZStd::string& tooltip)
|
|
{
|
|
setToolTip(Tools::qStringFromUtf8(tooltip));
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::OnEnabledChanged(RootGraphicsItemEnabledState /*enabledState*/)
|
|
{
|
|
UpdateStyles();
|
|
RefreshDisplay();
|
|
}
|
|
|
|
void GeneralNodeTitleGraphicsWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
|
|
{
|
|
GRAPH_CANVAS_DETAILED_PROFILE_FUNCTION();
|
|
|
|
Styling::PaletteStyle style = m_styleHelper.GetAttribute(Styling::Attribute::PaletteStyle, Styling::PaletteStyle::Solid);
|
|
|
|
if (m_paletteOverride)
|
|
{
|
|
style = m_paletteOverride->GetAttribute(Styling::Attribute::PaletteStyle, Styling::PaletteStyle::Solid);
|
|
}
|
|
|
|
// Background
|
|
QRectF bounds = boundingRect();
|
|
|
|
qreal cornerRadius = 0.0;
|
|
|
|
NodeUIRequestBus::EventResult(cornerRadius, GetEntityId(), &NodeUIRequests::GetCornerRadius);
|
|
|
|
// Ensure the bounds are large enough to draw the full radius
|
|
// Even in our smaller section
|
|
if (bounds.height() < 2.0 * cornerRadius)
|
|
{
|
|
bounds.setHeight(2.0 * cornerRadius);
|
|
}
|
|
|
|
QPainterPath path;
|
|
path.setFillRule(Qt::WindingFill);
|
|
|
|
// -1.0 because the rounding is a little bit short(for some reason), so I subtract one and let it overshoot a smidge.
|
|
path.addRoundedRect(bounds, cornerRadius - 1.0, cornerRadius - 1.0);
|
|
|
|
// We only want corners on the top half. So we need to draw a rectangle over the bottom bits to square it out.
|
|
QPointF bottomTopLeft(bounds.bottomLeft());
|
|
bottomTopLeft.setY(bottomTopLeft.y() - cornerRadius - 1.0);
|
|
path.addRect(QRectF(bottomTopLeft, bounds.bottomRight()));
|
|
|
|
painter->save();
|
|
painter->setClipPath(path);
|
|
|
|
bool isEnabled = false;
|
|
RootGraphicsItemRequestBus::EventResult(isEnabled, GetEntityId(), &RootGraphicsItemRequests::IsEnabled);
|
|
|
|
if (!isEnabled)
|
|
{
|
|
if (!m_disabledPalette)
|
|
{
|
|
StyleManagerRequestBus::BroadcastResult(m_disabledPalette, &StyleManagerRequests::FindColorPalette, "DisabledColorPalette");
|
|
}
|
|
|
|
if (m_disabledPalette)
|
|
{
|
|
QtDrawingUtils::FillArea((*painter), path.boundingRect(), (*m_disabledPalette));
|
|
}
|
|
}
|
|
else if (m_colorOverride)
|
|
{
|
|
QtDrawingUtils::FillArea((*painter), path.boundingRect(), (*m_colorOverride));
|
|
}
|
|
else if (m_paletteOverride)
|
|
{
|
|
QtDrawingUtils::FillArea((*painter), path.boundingRect(), (*m_paletteOverride));
|
|
}
|
|
else
|
|
{
|
|
QtDrawingUtils::FillArea((*painter), path.boundingRect(), m_styleHelper);
|
|
}
|
|
|
|
QLinearGradient gradient(bounds.bottomLeft(), bounds.topLeft());
|
|
gradient.setColorAt(0, QColor(0, 0, 0, 102));
|
|
gradient.setColorAt(1, QColor(0, 0, 0, 77));
|
|
painter->fillPath(path, gradient);
|
|
|
|
painter->restore();
|
|
|
|
QGraphicsWidget::paint(painter, option, widget);
|
|
}
|
|
}
|