Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "precompiled.h"
#include <Source/Components/Nodes/Comment/CommentLayerControllerComponent.h>
@@ -0,0 +1,42 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Source/Components/LayerControllerComponent.h>
namespace GraphCanvas
{
class CommentLayerControllerComponent
: public LayerControllerComponent
{
public:
static void Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<CommentLayerControllerComponent, LayerControllerComponent>()
->Version(0)
;
}
}
AZ_COMPONENT(CommentLayerControllerComponent, "{E6E6A329-40DA-4F95-B42E-6843DF2B6E2E}", LayerControllerComponent);
CommentLayerControllerComponent()
: LayerControllerComponent("CommentLayer")
{
}
};
}
@@ -0,0 +1,87 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "precompiled.h"
#include <Components/Nodes/Comment/CommentNodeFrameComponent.h>
#include <GraphCanvas/Components/Nodes/Comment/CommentBus.h>
namespace GraphCanvas
{
//////////////////////////////
// CommentNodeFrameComponent
//////////////////////////////
void CommentNodeFrameComponent::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<CommentNodeFrameComponent, AZ::Component>()
->Version(1)
;
}
}
CommentNodeFrameComponent::CommentNodeFrameComponent()
: m_frameWidget(nullptr)
{
}
void CommentNodeFrameComponent::Init()
{
m_frameWidget = AZStd::make_unique<CommentNodeFrameGraphicsWidget>(GetEntityId());
}
void CommentNodeFrameComponent::Activate()
{
NodeNotificationBus::Handler::BusConnect(GetEntityId());
m_frameWidget->Activate();
}
void CommentNodeFrameComponent::Deactivate()
{
m_frameWidget->Deactivate();
NodeNotificationBus::Handler::BusDisconnect();
}
void CommentNodeFrameComponent::OnNodeActivated()
{
QGraphicsLayout* layout = nullptr;
NodeLayoutRequestBus::EventResult(layout, GetEntityId(), &NodeLayoutRequests::GetLayout);
m_frameWidget->setLayout(layout);
}
///////////////////////////////////
// CommentNodeFrameGraphicsWidget
///////////////////////////////////
CommentNodeFrameGraphicsWidget::CommentNodeFrameGraphicsWidget(const AZ::EntityId& entityKey)
: GeneralNodeFrameGraphicsWidget(entityKey)
{
CommentNotificationBus::Handler::BusConnect(entityKey);
}
void CommentNodeFrameGraphicsWidget::OnBackgroundColorChanged(const AZ::Color& color)
{
QColor convertedColor = ConversionUtils::AZToQColor(color);
m_style.AddAttributeOverride(Styling::Attribute::BackgroundColor, convertedColor);
update();
}
void CommentNodeFrameGraphicsWidget::mouseDoubleClickEvent([[maybe_unused]] QGraphicsSceneMouseEvent* mouseEvent)
{
CommentUIRequestBus::Event(GetEntityId(), &CommentUIRequests::SetEditable, true);
}
}
@@ -0,0 +1,105 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <QGraphicsWidget>
#include <Components/Nodes/General/GeneralNodeFrameComponent.h>
#include <Components/Nodes/NodeFrameGraphicsWidget.h>
#include <GraphCanvas/Components/Nodes/Comment/CommentBus.h>
#include <GraphCanvas/Components/Nodes/NodeBus.h>
#include <GraphCanvas/Components/Nodes/NodeLayoutBus.h>
#include <GraphCanvas/Components/Nodes/NodeUIBus.h>
#include <GraphCanvas/Components/VisualBus.h>
#include <GraphCanvas/Styling/StyleHelper.h>
namespace GraphCanvas
{
class CommentNodeFrameGraphicsWidget;
class CommentNodeFrameComponent
: public AZ::Component
, public NodeNotificationBus::Handler
{
public:
AZ_COMPONENT(CommentNodeFrameComponent, "{207F2AC3-40C6-49EC-9B73-E691A9ED73E7}", AZ::Component);
static void Reflect(AZ::ReflectContext*);
CommentNodeFrameComponent();
~CommentNodeFrameComponent() override = default;
// AZ::Component
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("GraphCanvas_NodeVisualService", 0x39c4e7f3));
provided.push_back(AZ_CRC("GraphCanvas_RootVisualService", 0x9ec46d3b));
provided.push_back(AZ_CRC("GraphCanvas_VisualService", 0xfbb2c871));
}
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("GraphCanvas_NodeVisualService", 0x39c4e7f3));
incompatible.push_back(AZ_CRC("GraphCanvas_RootVisualService", 0x9ec46d3b));
incompatible.push_back(AZ_CRC("GraphCanvas_VisualService", 0xfbb2c871));
}
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
(void)dependent;
}
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC("GraphCanvas_NodeService", 0xcc0f32cc));
required.push_back(AZ_CRC("GraphCanvas_StyledGraphicItemService", 0xeae4cdf4));
}
void Init() override;
void Activate() override;
void Deactivate() override;
////
// NodeNotifications
void OnNodeActivated();
////
private:
CommentNodeFrameComponent(const CommentNodeFrameComponent&) = delete;
const CommentNodeFrameComponent& operator=(const CommentNodeFrameComponent&) = delete;
AZStd::unique_ptr<CommentNodeFrameGraphicsWidget> m_frameWidget;
};
//! The QGraphicsItem for the generic frame.
class CommentNodeFrameGraphicsWidget
: public GeneralNodeFrameGraphicsWidget
, public CommentNotificationBus::Handler
{
public:
AZ_TYPE_INFO_LEGACY(CommentNodeFrameGraphicsWidget, "{99343103-C8EF-44D0-BD6C-EF44ACDBD69B}", GeneralNodeFrameGraphicsWidget);
AZ_CLASS_ALLOCATOR(CommentNodeFrameGraphicsWidget, AZ::SystemAllocator, 0);
// Do not allow Serialization of Graphics Ui classes
static void Reflect(AZ::ReflectContext*) = delete;
CommentNodeFrameGraphicsWidget(const AZ::EntityId& nodeVisual);
~CommentNodeFrameGraphicsWidget() override = default;
// CommentNotificationBus
void OnBackgroundColorChanged(const AZ::Color& color) override;
////
// QGraphicsWidget
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
////
};
}
@@ -0,0 +1,156 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "precompiled.h"
#include <functional>
#include <QGraphicsLayoutItem>
#include <QGraphicsGridLayout>
#include <AzCore/RTTI/TypeInfo.h>
#include <Components/Nodes/Comment/CommentNodeLayoutComponent.h>
#include <Components/Nodes/Comment/CommentLayerControllerComponent.h>
#include <Components/Nodes/Comment/CommentNodeFrameComponent.h>
#include <Components/Nodes/Comment/CommentNodeTextComponent.h>
#include <Components/Nodes/General/GeneralNodeFrameComponent.h>
#include <Components/Nodes/NodeComponent.h>
#include <Components/StylingComponent.h>
#include <GraphCanvas/Components/Nodes/Comment/CommentBus.h>
#include <GraphCanvas/Components/Slots/SlotBus.h>
#include <GraphCanvas/tools.h>
#include <GraphCanvas/Styling/StyleHelper.h>
namespace GraphCanvas
{
///////////////////////////////
// CommentNodeLayoutComponent
///////////////////////////////
void CommentNodeLayoutComponent::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<CommentNodeLayoutComponent, NodeLayoutComponent>()
->Version(1)
;
}
}
AZ::Entity* CommentNodeLayoutComponent::CreateCommentNodeEntity()
{
// Create this Node's entity.
NodeConfiguration config;
config.SetShowInOutliner(false);
AZ::Entity* entity = NodeComponent::CreateCoreNodeEntity(config);
entity->SetName("Comment");
entity->CreateComponent<StylingComponent>(Styling::Elements::Comment, AZ::EntityId());
entity->CreateComponent<CommentNodeFrameComponent>();
entity->CreateComponent<CommentNodeLayoutComponent>();
entity->CreateComponent<CommentNodeTextComponent>();
entity->CreateComponent<CommentLayerControllerComponent>();
return entity;
}
CommentNodeLayoutComponent::CommentNodeLayoutComponent()
{
}
CommentNodeLayoutComponent::~CommentNodeLayoutComponent()
{
}
void CommentNodeLayoutComponent::Init()
{
NodeLayoutComponent::Init();
AZ::EntityBus::Handler::BusConnect(GetEntityId());
m_layout = new QGraphicsLinearLayout(Qt::Vertical);
m_comment = new QGraphicsLinearLayout(Qt::Horizontal);
}
void CommentNodeLayoutComponent::Activate()
{
NodeLayoutComponent::Activate();
NodeNotificationBus::Handler::BusConnect(GetEntityId());
StyleNotificationBus::Handler::BusConnect(GetEntityId());
}
void CommentNodeLayoutComponent::Deactivate()
{
NodeLayoutComponent::Deactivate();
StyleNotificationBus::Handler::BusDisconnect();
NodeNotificationBus::Handler::BusDisconnect();
}
void CommentNodeLayoutComponent::OnEntityExists([[maybe_unused]] const AZ::EntityId& entityId)
{
AZ::Entity* entity = GetEntity();
CommentNodeFrameComponent* commentFrameComponent = entity->FindComponent<CommentNodeFrameComponent>();
if (!commentFrameComponent)
{
GeneralNodeFrameComponent* generalNodeFrameComponent = entity->FindComponent<GeneralNodeFrameComponent>();
entity->RemoveComponent(generalNodeFrameComponent);
delete generalNodeFrameComponent;
entity->CreateComponent<CommentNodeFrameComponent>();
}
AZ::EntityBus::Handler::BusDisconnect(GetEntityId());
}
void CommentNodeLayoutComponent::OnStyleChanged()
{
m_style.SetStyle(GetEntityId());
UpdateLayoutParameters();
}
void CommentNodeLayoutComponent::OnNodeActivated()
{
QGraphicsLayoutItem* commentGraphicsItem = nullptr;
CommentLayoutRequestBus::EventResult(commentGraphicsItem, GetEntityId(), &CommentLayoutRequestBus::Events::GetGraphicsLayoutItem);
if (commentGraphicsItem)
{
m_comment->addItem(commentGraphicsItem);
}
GetLayoutAs<QGraphicsLinearLayout>()->addItem(m_comment);
UpdateLayoutParameters();
}
void CommentNodeLayoutComponent::UpdateLayoutParameters()
{
qreal border = m_style.GetAttribute(Styling::Attribute::BorderWidth, 0.);
qreal spacing = m_style.GetAttribute(Styling::Attribute::Spacing, 4.);
qreal margin = m_style.GetAttribute(Styling::Attribute::Margin, 4.);
m_layout->setContentsMargins(border, border, border, border);
for (QGraphicsLinearLayout* internalLayout : { m_comment })
{
internalLayout->setContentsMargins(margin, margin, margin, margin);
internalLayout->setSpacing(spacing);
}
m_layout->invalidate();
}
}
@@ -0,0 +1,82 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <QGraphicsLinearLayout>
#include <AzCore/Component/Component.h>
#include <Components/Nodes/NodeLayoutComponent.h>
#include <GraphCanvas/Components/Nodes/NodeLayoutBus.h>
#include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
#include <GraphCanvas/Components/StyleBus.h>
#include <GraphCanvas/Styling/StyleHelper.h>
class QGraphicsGridLayout;
namespace GraphCanvas
{
//! Lays out the parts of the comment node
class CommentNodeLayoutComponent
: public NodeLayoutComponent
, public NodeNotificationBus::Handler
, public StyleNotificationBus::Handler
, public AZ::EntityBus::Handler
{
public:
AZ_COMPONENT(CommentNodeLayoutComponent, "{6926658C-372A-43D5-8758-FB67DDE3D857}", NodeLayoutComponent);
static void Reflect(AZ::ReflectContext*);
static AZ::Entity* CreateCommentNodeEntity();
CommentNodeLayoutComponent();
~CommentNodeLayoutComponent();
// AZ::Component
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
dependent.push_back(AZ_CRC("GraphCanvas_NodeLayoutSupportService", 0xa8b639be));
dependent.push_back(AZ_CRC("GraphCanvas_CommentTextService", 0xb650db99));
}
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC("GraphCanvas_NodeService", 0xcc0f32cc));
required.push_back(AZ_CRC("GraphCanvas_StyledGraphicItemService", 0xeae4cdf4));
}
void Init();
void Activate();
void Deactivate();
////
// EntityBus
void OnEntityExists(const AZ::EntityId& entityId) override;
////
// StyleNotificationBus
void OnStyleChanged() override;
////
// NodeNotification
void OnNodeActivated();
////
protected:
void UpdateLayoutParameters();
Styling::StyleHelper m_style;
QGraphicsLinearLayout* m_comment;
};
}
@@ -0,0 +1,349 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "precompiled.h"
#include <functional>
AZ_PUSH_DISABLE_WARNING(4251 4800 4244, "-Wunknown-warning-option")
#include <QGraphicsItem>
#include <QGraphicsGridLayout>
#include <QGraphicsLayoutItem>
#include <QGraphicsScene>
#include <QGraphicsWidget>
#include <QPainter>
AZ_POP_DISABLE_WARNING
#include <AzCore/RTTI/TypeInfo.h>
#include <Components/Nodes/Comment/CommentNodeTextComponent.h>
#include <Components/Nodes/Comment/CommentTextGraphicsWidget.h>
#include <Components/Nodes/General/GeneralNodeFrameComponent.h>
#include <GraphCanvas/Components/GridBus.h>
#include <GraphCanvas/Components/Nodes/NodeBus.h>
#include <GraphCanvas/Components/Slots/SlotBus.h>
#include <GraphCanvas/Editor/GraphModelBus.h>
#include <GraphCanvas/GraphCanvasBus.h>
#include <GraphCanvas/tools.h>
#include <GraphCanvas/Styling/StyleHelper.h>
#include <GraphCanvas/Utils/ConversionUtils.h>
namespace GraphCanvas
{
/////////////////////////////
// CommentNodeTextComponent
/////////////////////////////
bool CommentNodeTextComponentVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
{
if (classElement.GetVersion() <= 2)
{
AZ::Crc32 commentId = AZ_CRC("Comment", 0x9474526c);
AZ::Crc32 fontId = AZ_CRC("FontSettings", 0x9d90b4cf);
CommentNodeTextSaveData saveData;
AZ::SerializeContext::DataElementNode* dataNode = classElement.FindSubElement(commentId);
if (dataNode)
{
dataNode->GetData(saveData.m_comment);
}
dataNode = nullptr;
dataNode = classElement.FindSubElement(fontId);
if (dataNode)
{
dataNode->GetData(saveData.m_fontConfiguration);
}
classElement.RemoveElementByName(commentId);
classElement.RemoveElementByName(fontId);
classElement.AddElementWithData(context, "SaveData", saveData);
}
return true;
}
void CommentNodeTextComponent::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<CommentNodeTextSaveData, ComponentSaveData>()
->Version(2)
->Field("Comment", &CommentNodeTextSaveData::m_comment)
->Field("BackgroundColor", &CommentNodeTextSaveData::m_backgroundColor)
->Field("FontSettings", &CommentNodeTextSaveData::m_fontConfiguration)
;
serializeContext->Class<CommentNodeTextComponent, GraphCanvasPropertyComponent>()
->Version(3, &CommentNodeTextComponentVersionConverter)
->Field("SaveData", &CommentNodeTextComponent::m_saveData)
;
serializeContext->Class<FontConfiguration>()
->Field("FontColor", &FontConfiguration::m_fontColor)
->Field("FontFamily", &FontConfiguration::m_fontFamily)
->Field("PixelSize", &FontConfiguration::m_pixelSize)
->Field("Weight", &FontConfiguration::m_weight)
->Field("Style", &FontConfiguration::m_style)
->Field("VAlign", &FontConfiguration::m_verticalAlignment)
->Field("HAlign", &FontConfiguration::m_horizontalAlignment)
;
AZ::EditContext* editContext = serializeContext->GetEditContext();
if (editContext)
{
editContext->Class < CommentNodeTextSaveData >("SaveData", "The save information regarding a comment node")
->ClassElement(AZ::Edit::ClassElements::EditorData, "Properties")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &CommentNodeTextSaveData::m_comment, "Title", "The comment to display on this node")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &CommentNodeTextSaveData::OnCommentChanged)
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &CommentNodeTextSaveData::GetCommentLabel)
->DataElement(AZ::Edit::UIHandlers::Default, &CommentNodeTextSaveData::m_fontConfiguration, "Font Settings", "The font settings used to render the font in the comment.")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &CommentNodeTextSaveData::UpdateStyleOverrides)
->DataElement(AZ::Edit::UIHandlers::Default, &CommentNodeTextSaveData::m_backgroundColor, "Background Color", "The background color to display the node comment on")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &CommentNodeTextSaveData::OnBackgroundColorChanged)
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &CommentNodeTextSaveData::GetBackgroundLabel)
;
editContext->Class<CommentNodeTextComponent>("Comment", "The node's customizable properties")
->ClassElement(AZ::Edit::ClassElements::EditorData, "Properties")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &CommentNodeTextComponent::m_saveData, "SaveData", "The modifiable information about this comment.")
;
editContext->Class<FontConfiguration>("Font Settings", "Various settings used to control a font.")
->DataElement(AZ::Edit::UIHandlers::Default, &FontConfiguration::m_fontColor, "Font Color", "The color that the font of this comment should render with")
->DataElement(AZ::Edit::UIHandlers::Default, &FontConfiguration::m_fontFamily, "Font Family", "The font family to use when rendering this comment.")
->DataElement(AZ::Edit::UIHandlers::Default, &FontConfiguration::m_pixelSize, "Pixel Size", "The size of the font(in pixels)")
->Attribute(AZ::Edit::Attributes::Min, 1)
->Attribute(AZ::Edit::Attributes::Max, 200)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &FontConfiguration::m_weight, "Weight", "The weight of the font")
->EnumAttribute(QFont::Thin, "Thin")
->EnumAttribute(QFont::ExtraLight, "Extra Light")
->EnumAttribute(QFont::Light, "Light")
->EnumAttribute(QFont::Normal, "Normal")
->EnumAttribute(QFont::Medium, "Medium")
->EnumAttribute(QFont::DemiBold, "Demi-Bold")
->EnumAttribute(QFont::Bold, "Bold")
->EnumAttribute(QFont::ExtraBold, "Extra Bold")
->DataElement(AZ::Edit::UIHandlers::ComboBox, &FontConfiguration::m_style, "Style", "The style of the font")
->EnumAttribute(QFont::Style::StyleNormal, "Normal")
->EnumAttribute(QFont::Style::StyleItalic, "Italic")
->EnumAttribute(QFont::Style::StyleOblique, "Oblique")
->DataElement(AZ::Edit::UIHandlers::ComboBox, &FontConfiguration::m_verticalAlignment, "Vertical Alignment", "The Vertical Alignment of the font")
->EnumAttribute(Qt::AlignmentFlag::AlignTop, "Top")
->EnumAttribute(Qt::AlignmentFlag::AlignVCenter, "Middle")
->EnumAttribute(Qt::AlignmentFlag::AlignBottom, "Bottom")
->DataElement(AZ::Edit::UIHandlers::ComboBox, &FontConfiguration::m_horizontalAlignment, "Horizontal Alignment", "The Horizontal Alignment of the font")
->EnumAttribute(Qt::AlignmentFlag::AlignLeft, "Left")
->EnumAttribute(Qt::AlignmentFlag::AlignHCenter, "Center")
->EnumAttribute(Qt::AlignmentFlag::AlignRight, "Right")
;
}
}
}
CommentNodeTextComponent::CommentNodeTextComponent()
: m_saveData(this)
, m_commentTextWidget(nullptr)
, m_commentMode(CommentMode::Comment)
{
}
CommentNodeTextComponent::CommentNodeTextComponent(AZStd::string_view initialText)
: CommentNodeTextComponent()
{
m_saveData.m_comment = initialText;
}
void CommentNodeTextComponent::Init()
{
GraphCanvasPropertyComponent::Init();
m_saveData.m_fontConfiguration.InitializePixelSize();
EntitySaveDataRequestBus::Handler::BusConnect(GetEntityId());
}
void CommentNodeTextComponent::Activate()
{
if (m_commentTextWidget == nullptr)
{
m_commentTextWidget = aznew CommentTextGraphicsWidget(GetEntityId());
m_commentTextWidget->SetStyle(Styling::Elements::CommentText);
}
GraphCanvasPropertyComponent::Activate();
CommentRequestBus::Handler::BusConnect(GetEntityId());
CommentLayoutRequestBus::Handler::BusConnect(GetEntityId());
NodeNotificationBus::Handler::BusConnect(GetEntityId());
m_commentTextWidget->Activate();
}
void CommentNodeTextComponent::Deactivate()
{
GraphCanvasPropertyComponent::Deactivate();
NodeNotificationBus::Handler::BusDisconnect();
CommentLayoutRequestBus::Handler::BusDisconnect();
CommentRequestBus::Handler::BusDisconnect();
m_commentTextWidget->Deactivate();
}
void CommentNodeTextComponent::OnAddedToScene(const AZ::EntityId& sceneId)
{
NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::SetSnapToGrid, true);
if (m_commentTextWidget->GetCommentMode() == CommentMode::Comment)
{
NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::SetResizeToGrid, false);
}
else if (m_commentTextWidget->GetCommentMode() == CommentMode::BlockComment)
{
NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::SetResizeToGrid, true);
}
AZ::EntityId grid;
SceneRequestBus::EventResult(grid, sceneId, &SceneRequests::GetGrid);
NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::SetGrid, grid);
m_commentTextWidget->OnAddedToScene();
UpdateStyleOverrides();
OnCommentChanged();
OnBackgroundColorChanged();
m_saveData.RegisterIds(GetEntityId(), sceneId);
}
void CommentNodeTextComponent::SetComment(const AZStd::string& comment)
{
if (m_saveData.m_comment.compare(comment) != 0)
{
m_saveData.m_comment = comment;
m_commentTextWidget->SetComment(comment);
AZ::EntityId sceneId;
SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
GraphModelRequestBus::Event(sceneId, &GraphModelRequests::RequestUndoPoint);
}
}
void CommentNodeTextComponent::SetCommentMode(CommentMode commentMode)
{
NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::SetSnapToGrid, true);
m_commentTextWidget->SetCommentMode(commentMode);
m_commentMode = commentMode;
if (m_commentTextWidget->GetCommentMode() == CommentMode::Comment)
{
NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::SetResizeToGrid, false);
}
else if (m_commentTextWidget->GetCommentMode() == CommentMode::BlockComment)
{
NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::SetResizeToGrid, true);
}
}
void CommentNodeTextComponent::SetBackgroundColor(const AZ::Color& backgroundColor)
{
m_saveData.m_backgroundColor = backgroundColor;
m_saveData.SignalDirty();
OnBackgroundColorChanged();
}
AZ::Color CommentNodeTextComponent::GetBackgroundColor() const
{
return m_saveData.m_backgroundColor;
}
CommentMode CommentNodeTextComponent::GetCommentMode() const
{
return m_commentMode;
}
const AZStd::string& CommentNodeTextComponent::GetComment() const
{
return m_saveData.m_comment;
}
QGraphicsLayoutItem* CommentNodeTextComponent::GetGraphicsLayoutItem()
{
return m_commentTextWidget;
}
void CommentNodeTextComponent::WriteSaveData(EntitySaveDataContainer& saveDataContainer) const
{
CommentNodeTextSaveData* saveData = saveDataContainer.FindCreateSaveData<CommentNodeTextSaveData>();
if (saveData)
{
(*saveData) = m_saveData;
}
}
void CommentNodeTextComponent::ReadSaveData(const EntitySaveDataContainer& saveDataContainer)
{
CommentNodeTextSaveData* saveData = saveDataContainer.FindSaveDataAs<CommentNodeTextSaveData>();
if (saveData)
{
m_saveData = (*saveData);
}
}
void CommentNodeTextComponent::OnCommentChanged()
{
if (m_commentTextWidget)
{
m_commentTextWidget->SetComment(m_saveData.m_comment);
CommentNotificationBus::Event(GetEntityId(), &CommentNotifications::OnCommentChanged, m_saveData.m_comment);
}
}
void CommentNodeTextComponent::OnBackgroundColorChanged()
{
CommentNotificationBus::Event(GetEntityId(), &CommentNotifications::OnBackgroundColorChanged, m_saveData.m_backgroundColor);
}
void CommentNodeTextComponent::UpdateStyleOverrides()
{
CommentNotificationBus::Event(GetEntityId(), &CommentNotifications::OnCommentFontReloadBegin);
QColor fontColor = ConversionUtils::AZToQColor(m_saveData.m_fontConfiguration.m_fontColor);
Styling::StyleHelper& styleHelper = m_commentTextWidget->GetStyleHelper();
styleHelper.AddAttributeOverride(Styling::Attribute::Color, fontColor);
styleHelper.AddAttributeOverride(Styling::Attribute::FontFamily, QString(m_saveData.m_fontConfiguration.m_fontFamily.c_str()));
styleHelper.AddAttributeOverride(Styling::Attribute::FontSize, m_saveData.m_fontConfiguration.m_pixelSize);
styleHelper.AddAttributeOverride(Styling::Attribute::FontWeight, m_saveData.m_fontConfiguration.m_weight);
styleHelper.AddAttributeOverride(Styling::Attribute::FontStyle, m_saveData.m_fontConfiguration.m_style);
styleHelper.AddAttributeOverride(Styling::Attribute::TextAlignment, m_saveData.m_fontConfiguration.m_horizontalAlignment);
styleHelper.AddAttributeOverride(Styling::Attribute::TextVerticalAlignment, m_saveData.m_fontConfiguration.m_verticalAlignment);
m_commentTextWidget->OnStyleChanged();
CommentNotificationBus::Event(GetEntityId(), &CommentNotifications::OnCommentFontReloadEnd);
}
}
@@ -0,0 +1,138 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
AZ_PUSH_DISABLE_WARNING(4251 4800 4244, "-Wunknown-warning-option")
#include <QGraphicsGridLayout>
#include <QGraphicsLinearLayout>
#include <QGraphicsProxyWidget>
#include <QGraphicsWidget>
#include <QPlainTextEdit>
#include <QTimer>
AZ_POP_DISABLE_WARNING
#include <AzCore/Component/Component.h>
#include <AzCore/Math/Color.h>
#include <AzCore/RTTI/TypeInfo.h>
#include <Components/Nodes/General/GeneralNodeLayoutComponent.h>
#include <GraphCanvas/Components/EntitySaveDataBus.h>
#include <GraphCanvas/Components/GraphCanvasPropertyBus.h>
#include <GraphCanvas/Components/Nodes/Comment/CommentBus.h>
#include <GraphCanvas/Components/Nodes/NodeLayoutBus.h>
#include <GraphCanvas/Components/SceneBus.h>
#include <GraphCanvas/Components/Slots/Data/DataSlotBus.h>
#include <GraphCanvas/Types/EntitySaveData.h>
#include <Widgets/GraphCanvasLabel.h>
#include <Widgets/NodePropertyDisplayWidget.h>
class QGraphicsGridLayout;
namespace GraphCanvas
{
class CommentTextGraphicsWidget;
class CommentNodeTextComponent
: public GraphCanvasPropertyComponent
, public NodeNotificationBus::Handler
, public CommentRequestBus::Handler
, public CommentLayoutRequestBus::Handler
, public EntitySaveDataRequestBus::Handler
, public CommentNodeTextSaveDataInterface
{
public:
AZ_COMPONENT(CommentNodeTextComponent, "{15C568B0-425C-4655-814D-0A299341F757}", GraphCanvasPropertyComponent);
static void Reflect(AZ::ReflectContext*);
CommentNodeTextComponent();
CommentNodeTextComponent(AZStd::string_view initialText);
~CommentNodeTextComponent() = default;
// AZ::Component
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("GraphCanvas_CommentTextService", 0xb650db99));
}
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incombatible)
{
incombatible.push_back(AZ_CRC("GraphCanvas_CommentTextService", 0xb650db99));
}
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
(void)dependent;
}
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC("GraphCanvas_StyledGraphicItemService", 0xeae4cdf4));
required.push_back(AZ_CRC("GraphCanvas_SceneMemberService", 0xe9759a2d));
}
void Init() override;
void Activate() override;
void Deactivate() override;
////
// NodeNotification
void OnAddedToScene(const AZ::EntityId&);
////
// CommentRequestBus
void SetComment(const AZStd::string& comment) override;
const AZStd::string& GetComment() const override;
void SetCommentMode(CommentMode commentMode) override;
void SetBackgroundColor(const AZ::Color& color) override;
AZ::Color GetBackgroundColor() const override;
////
// CommentNodeTextSaveDataInterface
CommentMode GetCommentMode() const override;
////
// CommentLayoutRequestBus
QGraphicsLayoutItem* GetGraphicsLayoutItem() override;
////
// EntitySaveDataRequestBus
void WriteSaveData(EntitySaveDataContainer& saveDataContainer) const override;
void ReadSaveData(const EntitySaveDataContainer& saveDataContainer) override;
////
protected:
// CommentNodeTextSaveDataInterface
void OnCommentChanged() override;
void OnBackgroundColorChanged() override;
void UpdateStyleOverrides() override;
////
private:
CommentNodeTextComponent(const CommentNodeTextComponent&) = delete;
CommentMode m_commentMode;
CommentNodeTextSaveData m_saveData;
CommentTextGraphicsWidget* m_commentTextWidget;
};
}
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(Qt::AlignmentFlag, "{8CCC83B0-F267-49FE-A9B7-8065F5869E91}")
AZ_TYPE_INFO_SPECIALIZE(QFont::Style, "{49E7569D-19FE-4BC2-8242-D5DCF5454137}");
AZ_TYPE_INFO_SPECIALIZE(QFont::Capitalization, "{37EDD868-C58E-4C21-840A-3CE4714CEEA3}");
}
@@ -0,0 +1,486 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "precompiled.h"
#include <functional>
AZ_PUSH_DISABLE_WARNING(4251 4800 4244, "-Wunknown-warning-option")
#include <QEvent>
#include <QGraphicsItem>
#include <QGraphicsGridLayout>
#include <QGraphicsLayoutItem>
#include <QGraphicsScene>
#include <qgraphicssceneevent.h>
#include <QGraphicsWidget>
#include <QPainter>
AZ_POP_DISABLE_WARNING
#include <Components/Nodes/Comment/CommentTextGraphicsWidget.h>
#include <GraphCanvas/Components/GeometryBus.h>
#include <GraphCanvas/Components/Nodes/NodeBus.h>
#include <GraphCanvas/Components/Nodes/NodeUIBus.h>
#include <GraphCanvas/Components/Slots/SlotBus.h>
#include <GraphCanvas/Components/VisualBus.h>
#include <GraphCanvas/tools.h>
namespace GraphCanvas
{
//////////////////////////////////
// CommentNodeTextGraphicsWidget
//////////////////////////////////
CommentTextGraphicsWidget::CommentTextGraphicsWidget(const AZ::EntityId& targetId)
: m_commentMode(CommentMode::Unknown)
, m_editable(false)
, m_layoutLock(false)
, m_displayLabel(nullptr)
, m_textEdit(nullptr)
, m_proxyWidget(nullptr)
, m_pressed(false)
, m_entityId(targetId)
{
setFlag(ItemIsMovable, false);
m_displayLabel = aznew GraphCanvasLabel();
m_displayLabel->SetAllowNewlines(true);
m_layout = new QGraphicsLinearLayout(Qt::Vertical);
m_layout->setSpacing(0);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setInstantInvalidatePropagation(true);
m_layout->addItem(m_displayLabel);
setLayout(m_layout);
setData(GraphicsItemName, QStringLiteral("Comment/%1").arg(static_cast<AZ::u64>(GetEntityId()), 16, 16, QChar('0')));
SetCommentMode(CommentMode::Comment);
}
void CommentTextGraphicsWidget::Activate()
{
CommentUIRequestBus::Handler::BusConnect(GetEntityId());
CommentLayoutRequestBus::Handler::BusConnect(GetEntityId());
StyleNotificationBus::Handler::BusConnect(GetEntityId());
UpdateLayout();
}
void CommentTextGraphicsWidget::Deactivate()
{
StyleNotificationBus::Handler::BusDisconnect();
CommentLayoutRequestBus::Handler::BusDisconnect();
CommentUIRequestBus::Handler::BusDisconnect();
}
void CommentTextGraphicsWidget::OnAddedToScene()
{
UpdateSizing();
}
void CommentTextGraphicsWidget::SetStyle(const AZStd::string& style)
{
if (m_style != style)
{
m_style = style;
OnStyleChanged();
}
}
void CommentTextGraphicsWidget::UpdateLayout()
{
if (m_layoutLock)
{
return;
}
QGraphicsScene* graphicsScene = nullptr;
AZ::EntityId sceneId;
SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
SceneRequestBus::EventResult(graphicsScene, sceneId, &SceneRequests::AsQGraphicsScene);
prepareGeometryChange();
for (int i = m_layout->count() - 1; i >= 0; --i)
{
QGraphicsLayoutItem* layoutItem = m_layout->itemAt(i);
m_layout->removeAt(i);
layoutItem->setParentLayoutItem(nullptr);
if (graphicsScene)
{
graphicsScene->removeItem(layoutItem->graphicsItem());
}
}
if (m_editable)
{
// Adjust the size of the editable widget to match the label
m_layout->addItem(m_proxyWidget);
UpdateSizing();
}
else
{
m_layout->addItem(m_displayLabel);
}
RefreshDisplay();
}
void CommentTextGraphicsWidget::UpdateStyles()
{
Styling::StyleHelper overallStyle(GetEntityId());
qreal margin = overallStyle.GetAttribute(Styling::Attribute::Margin, 0.0);
m_layout->setContentsMargins(margin, margin, margin, margin);
m_displayLabel->SetStyle(GetEntityId(), m_style.c_str());
const Styling::StyleHelper& styleHelper = m_displayLabel->GetStyleHelper();
QPen border = styleHelper.GetBorder();
// We construct a stylesheet for the Qt widget based on our calculated style
QStringList fields;
fields.push_back("background-color: rgba(0,0,0,0)");
fields.push_back(QString("border-width: %1").arg(border.width()));
switch (border.style())
{
case Qt::PenStyle::SolidLine:
fields.push_back("border-style: solid");
break;
case Qt::PenStyle::DashLine:
fields.push_back("border-style: dashed");
break;
case Qt::PenStyle::DotLine:
fields.push_back("border-style: dotted");
break;
default:
fields.push_back("border-style: none");
}
fields.push_back(QString("border-color: rgba(%1,%2,%3,%4)").arg(border.color().red()).arg(border.color().green()).arg(border.color().blue()).arg(border.color().alpha()));
fields.push_back(QString("border-radius: %1").arg(styleHelper.GetAttribute(Styling::Attribute::BorderRadius, 0)));
fields.push_back("margin: 0");
fields.push_back("padding: 0");
fields.push_back(styleHelper.GetFontStyleSheet());
if (m_textEdit)
{
m_textEdit->setStyleSheet(fields.join("; ").toUtf8().data());
if (styleHelper.HasTextAlignment())
{
m_textEdit->setAlignment(styleHelper.GetTextAlignment(m_textEdit->alignment()));
}
}
UpdateSizing();
}
void CommentTextGraphicsWidget::RefreshDisplay()
{
updateGeometry();
m_layout->invalidate();
update();
}
void CommentTextGraphicsWidget::SetComment(const AZStd::string& comment)
{
m_commentText = comment;
if (!comment.empty())
{
m_displayLabel->SetLabel(comment);
if (m_textEdit)
{
m_textEdit->setPlainText(comment.c_str());
}
}
else
{
// Hack to force the minimum height based on the style's font/size
m_displayLabel->SetLabel(" ");
if (m_textEdit)
{
m_textEdit->setPlainText(" ");
}
}
UpdateSizing();
}
AZStd::string CommentTextGraphicsWidget::GetComment() const
{
return m_commentText;
}
Styling::StyleHelper& CommentTextGraphicsWidget::GetStyleHelper()
{
return m_displayLabel->GetStyleHelper();
}
const Styling::StyleHelper& CommentTextGraphicsWidget::GetStyleHelper() const
{
return m_displayLabel->GetStyleHelper();
}
void CommentTextGraphicsWidget::SetCommentMode(CommentMode commentMode)
{
if (m_commentMode != commentMode)
{
m_commentMode = commentMode;
UpdateSizePolicies();
}
}
CommentMode CommentTextGraphicsWidget::GetCommentMode() const
{
return m_commentMode;
}
void CommentTextGraphicsWidget::SetEditable(bool editable)
{
if (m_editable != editable)
{
m_editable = editable;
if (!m_editable)
{
SubmitValue();
}
(m_editable ? SetupProxyWidget() : CleanupProxyWidget());
UpdateLayout();
if (m_editable)
{
AZ::EntityId sceneId;
SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
SceneNotificationBus::Event(sceneId, &SceneNotifications::OnNodeIsBeingEdited, true);
CommentNotificationBus::Event(GetEntityId(), &CommentNotifications::OnEditBegin);
UpdateSizing();
StyledEntityRequestBus::Event(GetEntityId(), &StyledEntityRequests::AddSelectorState, Styling::States::Editing);
m_textEdit->selectAll();
SceneMemberUIRequestBus::Event(GetEntityId(), &SceneMemberUIRequests::SetSelected, true);
}
else
{
AZ::EntityId sceneId;
SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
SceneNotificationBus::Event(sceneId, &SceneNotifications::OnNodeIsBeingEdited, false);
CommentNotificationBus::Event(GetEntityId(), &CommentNotifications::OnEditEnd);
StyledEntityRequestBus::Event(GetEntityId(), &StyledEntityRequests::RemoveSelectorState, Styling::States::Editing);
m_layoutLock = false;
}
OnStyleChanged();
}
}
QGraphicsLayoutItem* CommentTextGraphicsWidget::GetGraphicsLayoutItem()
{
return this;
}
void CommentTextGraphicsWidget::OnStyleChanged()
{
UpdateStyles();
RefreshDisplay();
}
void CommentTextGraphicsWidget::UpdateSizing()
{
AZStd::string value = (m_textEdit ? AZStd::string(m_textEdit->toPlainText().toUtf8().data()) : m_commentText);
m_displayLabel->SetLabel(value);
prepareGeometryChange();
if (m_textEdit)
{
QSizeF oldSize = m_textEdit->minimumSize();
// As we update the label with the new contents, adjust the editable widget size to match
if (m_commentMode == CommentMode::Comment)
{
m_textEdit->setMinimumSize(m_displayLabel->preferredSize().toSize());
m_textEdit->setMaximumSize(m_displayLabel->preferredSize().toSize());
}
else if (m_commentMode == CommentMode::BlockComment)
{
QSizeF preferredSize = m_displayLabel->preferredSize();
QRectF displaySize = m_displayLabel->GetDisplayedSize();
displaySize.setHeight(preferredSize.height());
if (displaySize.width() == 0)
{
m_textEdit->setMinimumHeight(aznumeric_cast<int>(preferredSize.height()));
m_textEdit->setMaximumHeight(aznumeric_cast<int>(preferredSize.height()));
}
else
{
m_textEdit->setMinimumSize(displaySize.size().toSize());
m_textEdit->setMaximumSize(displaySize.size().toSize());
}
}
QSizeF newSize = m_textEdit->minimumSize();
if (oldSize != newSize)
{
CommentNotificationBus::Event(GetEntityId(), &CommentNotifications::OnCommentSizeChanged, oldSize, newSize);
}
}
updateGeometry();
}
void CommentTextGraphicsWidget::SubmitValue()
{
if (m_textEdit)
{
m_commentText = m_textEdit->toPlainText().toUtf8().data();
}
CommentRequestBus::Event(GetEntityId(), &CommentRequests::SetComment, m_commentText);
CommentNotificationBus::Event(GetEntityId(), &CommentNotifications::OnCommentChanged, m_commentText);
UpdateSizing();
}
bool CommentTextGraphicsWidget::sceneEventFilter(QGraphicsItem*, QEvent* event)
{
bool consumeEvent = event->isAccepted();
switch (event->type())
{
case QEvent::GraphicsSceneMouseDoubleClick:
consumeEvent = true;
// Need to queue this since if we change out display in the middle of processing input
// Things get sad.
QTimer::singleShot(0, [this]() { this->SetEditable(true); });
break;
}
return consumeEvent;
}
void CommentTextGraphicsWidget::UpdateSizePolicies()
{
prepareGeometryChange();
switch (m_commentMode)
{
case CommentMode::BlockComment:
if (m_textEdit)
{
m_textEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_textEdit->setWordWrapMode(QTextOption::WrapMode::NoWrap);
m_proxyWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
}
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_layout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_displayLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_displayLabel->SetElide(true);
m_displayLabel->SetWrap(false);
m_displayLabel->SetWrapMode(GraphCanvasLabel::WrapMode::BoundingWidth);
break;
case CommentMode::Comment:
if (m_textEdit)
{
m_textEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_textEdit->setWordWrapMode(QTextOption::WrapMode::WordWrap);
m_proxyWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
}
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_layout->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_displayLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_displayLabel->SetElide(false);
m_displayLabel->SetWrap(true);
m_displayLabel->SetWrapMode(GraphCanvasLabel::WrapMode::MaximumWidth);
break;
default:
AZ_Warning("Graph Canvas", false, "Unhandled Comment Mode: %i", m_commentMode);
}
updateGeometry();
}
void CommentTextGraphicsWidget::SetupProxyWidget()
{
if (!m_textEdit)
{
m_proxyWidget = new QGraphicsProxyWidget();
m_proxyWidget->setFocusPolicy(Qt::FocusPolicy::StrongFocus);
m_textEdit = aznew Internal::FocusableTextEdit();
m_textEdit->setProperty("HasNoWindowDecorations", true);
m_textEdit->setFocusPolicy(Qt::FocusPolicy::StrongFocus);
m_textEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
m_textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
m_textEdit->setSizeAdjustPolicy(QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents);
m_textEdit->setEnabled(true);
m_proxyWidget->setWidget(m_textEdit);
UpdateSizePolicies();
m_textEdit->setPlainText(m_commentText.c_str());
QTimer::singleShot(0, [&]()
{
m_textEdit->setFocus(Qt::FocusReason::MouseFocusReason);
m_proxyWidget->setFocus(Qt::FocusReason::MouseFocusReason);
});
QObject::connect(m_textEdit, &Internal::FocusableTextEdit::textChanged, [this]() { this->UpdateSizing(); });
QObject::connect(m_textEdit, &Internal::FocusableTextEdit::OnFocusIn, [this]() { this->m_layoutLock = true; });
QObject::connect(m_textEdit, &Internal::FocusableTextEdit::OnFocusOut, [this]() { this->SubmitValue(); this->m_layoutLock = false; this->SetEditable(false); });
QObject::connect(m_textEdit, &Internal::FocusableTextEdit::EnterPressed, [this]()
{
QTimer::singleShot(0, [this]()
{
this->SubmitValue();
this->m_layoutLock = false;
this->SetEditable(false);
});
});
}
}
void CommentTextGraphicsWidget::CleanupProxyWidget()
{
if (m_textEdit)
{
delete m_textEdit; // NB: this implicitly deletes m_proxy widget
m_textEdit = nullptr;
m_proxyWidget = nullptr;
}
}
#include <Source/Components/Nodes/Comment/moc_CommentTextGraphicsWidget.cpp>
}
@@ -0,0 +1,197 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
AZ_PUSH_DISABLE_WARNING(4251 4800 4244, "-Wunknown-warning-option")
#include <QGraphicsGridLayout>
#include <QGraphicsLinearLayout>
#include <QGraphicsProxyWidget>
#include <QGraphicsWidget>
#include <QPlainTextEdit>
#include <QTimer>
AZ_POP_DISABLE_WARNING
#include <AzCore/Component/EntityId.h>
#include <GraphCanvas/Components/Nodes/Comment/CommentBus.h>
#include <GraphCanvas/Components/SceneBus.h>
#include <GraphCanvas/Components/StyleBus.h>
#include <GraphCanvas/Styling/StyleHelper.h>
#include <Widgets/GraphCanvasLabel.h>
#endif
namespace GraphCanvas
{
namespace Internal
{
// Need to know when the text edit gets focus in order to
// manage the layout display when the mouse hovers off, but the
// widget still has focus. Qt does not expose focus events in any
// signal way, so this exposes that functionality for me.
class FocusableTextEdit
: public QTextEdit
{
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(FocusableTextEdit, AZ::SystemAllocator, 0);
FocusableTextEdit()
: m_eatEnterKey(false)
{
setContextMenuPolicy(Qt::ContextMenuPolicy::PreventContextMenu);
}
~FocusableTextEdit() = default;
signals:
void OnFocusIn();
void OnFocusOut();
void EnterPressed();
private:
void focusInEvent(QFocusEvent* focusEvent) override
{
QTextEdit::focusInEvent(focusEvent);
emit OnFocusIn();
}
void focusOutEvent(QFocusEvent* focusEvent) override
{
QTextEdit::focusOutEvent(focusEvent);
emit OnFocusOut();
}
void keyPressEvent(QKeyEvent* keyEvent) override
{
if (keyEvent->key() == Qt::Key_Enter
|| keyEvent->key() == Qt::Key_Return)
{
if (keyEvent->modifiers() == Qt::KeyboardModifier::NoModifier)
{
m_eatEnterKey = true;
return;
}
}
QTextEdit::keyPressEvent(keyEvent);
}
void keyReleaseEvent(QKeyEvent* keyEvent) override
{
if (keyEvent->key() == Qt::Key_Enter
|| keyEvent->key() == Qt::Key_Return)
{
if (m_eatEnterKey)
{
emit EnterPressed();
m_eatEnterKey = false;
}
}
QTextEdit::keyReleaseEvent(keyEvent);
}
bool m_eatEnterKey;
};
}
//! The QGraphicsWidget for displaying the comment text
// This class is not meant to be serializable
class CommentTextGraphicsWidget
: public QGraphicsWidget
, public CommentLayoutRequestBus::Handler
, public CommentUIRequestBus::Handler
, public StyleNotificationBus::Handler
{
public:
AZ_TYPE_INFO(CommentTextGraphicsWidget, "{1779F401-6A9F-42A8-B4B7-F7732DBEC462}");
AZ_CLASS_ALLOCATOR(CommentTextGraphicsWidget, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* context) = delete;
CommentTextGraphicsWidget(const AZ::EntityId& targetId);
~CommentTextGraphicsWidget() override = default;
void Activate();
void Deactivate();
void OnAddedToScene();
void SetStyle(const AZStd::string& style);
void UpdateLayout();
void UpdateStyles();
void RefreshDisplay();
void SetComment(const AZStd::string& comment);
AZStd::string GetComment() const;
// NOTE: Currently the style helper does not signal out when it's value has changed.
// As such, any modifications to the style helper will need to call OnStyleChanged in order
// to propogate those changes.
Styling::StyleHelper& GetStyleHelper();
const Styling::StyleHelper& GetStyleHelper() const;
void SetCommentMode(CommentMode commentMode);
CommentMode GetCommentMode() const;
// CommentUIRequestBus
void SetEditable(bool editable) override;
////
// CommentLayoutRequestBus
QGraphicsLayoutItem* GetGraphicsLayoutItem() override;
////
// StyleNotificationBus
void OnStyleChanged() override;
////
protected:
void UpdateSizing();
void SubmitValue();
void UpdateSizePolicies();
bool sceneEventFilter(QGraphicsItem*, QEvent* event);
const AZ::EntityId& GetEntityId() const { return m_entityId; }
void SetupProxyWidget();
void CleanupProxyWidget();
private:
CommentTextGraphicsWidget(const CommentTextGraphicsWidget&) = delete;
CommentMode m_commentMode;
AZStd::string m_commentText;
bool m_editable;
bool m_layoutLock;
QGraphicsLinearLayout* m_layout;
GraphCanvasLabel* m_displayLabel;
Internal::FocusableTextEdit* m_textEdit;
QGraphicsProxyWidget* m_proxyWidget;
Styling::StyleHelper m_styleHelper;
AZStd::string m_style;
QPointF m_initialClick;
bool m_pressed;
AZ::EntityId m_entityId;
};
}