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,39 @@
/*
* 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
// Graph Canvas
#include <GraphCanvas/Components/NodePropertyDisplay/BooleanDataInterface.h>
// Graph Model
#include <GraphModel/Model/Slot.h>
namespace GraphModelIntegration
{
//! Satisfies GraphCanvas API requirements for showing bool property widgets in nodes.
class BooleanDataInterface
: public GraphCanvas::BooleanDataInterface
{
public:
AZ_CLASS_ALLOCATOR(BooleanDataInterface, AZ::SystemAllocator, 0);
BooleanDataInterface(GraphModel::SlotPtr slot);
~BooleanDataInterface() = default;
bool GetBool() const override;
void SetBool(bool enabled) override;
private:
AZStd::weak_ptr<GraphModel::Slot> m_slot;
};
}
@@ -0,0 +1,62 @@
/*
* 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 ...
#include <AzCore/std/containers/unordered_map.h>
// GraphCanvas ...
#include <GraphCanvas/Widgets/GraphCanvasEditor/GraphCanvasAssetEditorMainWindow.h>
// GraphModel ...
#include <GraphModel/GraphModelBus.h>
namespace GraphModelIntegration
{
/**
* This class extends the base GraphCanvas windowing framework to integrate
* GraphModel functionality into the generic windowing framework.
*/
class EditorMainWindow
: public GraphCanvas::AssetEditorMainWindow
, protected GraphControllerNotificationBus::MultiHandler
{
public:
explicit EditorMainWindow(GraphCanvas::AssetEditorWindowConfig* config, QWidget* parent = nullptr);
~EditorMainWindow() override;
protected:
/// Subclasses must implement this method so that this class can
/// create graphs on their behalf.
virtual GraphModel::IGraphContextPtr GetGraphContext() const = 0;
/// Helper method for retrieving the graph associated with a graphId.
GraphModel::GraphPtr GetGraphById(GraphCanvas::GraphId graphId) const;
/// Helper method for retrieving the graphId associated with a graph.
GraphCanvas::GraphId GetGraphId(GraphModel::GraphPtr graph) const;
// GraphCanvas::AssetEditorMainWindow overrides ...
void OnEditorOpened(GraphCanvas::EditorDockWidget* dockWidget) override;
void OnEditorClosing(GraphCanvas::EditorDockWidget* dockWidget) override;
void OnWrapperNodeActionWidgetClicked(const AZ::EntityId& wrapperNode, const QRect& actionWidgetBoundingRect, const QPointF& scenePoint, const QPoint& screenPoint) override;
/// Client can override this to handle click events on a wrapper node's action widget
/// using a GraphModel::NodePtr instead of the lower-level GraphCanvas::NodeId
virtual void HandleWrapperNodeActionWidgetClicked(GraphModel::NodePtr wrapperNode, [[maybe_unused]] const QRect& actionWidgetBoundingRect, [[maybe_unused]] const QPointF& scenePoint, [[maybe_unused]] const QPoint& screenPoint) {}
/// Keep track of the graphs we create on behalf of the client when
/// new editor dock widgets are created.
AZStd::unordered_map<GraphCanvas::GraphId, GraphModel::GraphPtr> m_graphs;
};
}
@@ -0,0 +1,45 @@
/*
* 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
// Graph Canvas
#include <GraphCanvas/Components/NodePropertyDisplay/DoubleDataInterface.h>
// Graph Model
#include <GraphModel/Model/Slot.h>
namespace GraphModelIntegration
{
//! Satisfies GraphCanvas API requirements for showing float property widgets in nodes.
class FloatDataInterface
: public GraphCanvas::NumericDataInterface
{
public:
AZ_CLASS_ALLOCATOR(FloatDataInterface, AZ::SystemAllocator, 0);
FloatDataInterface(GraphModel::SlotPtr slot);
~FloatDataInterface() = default;
double GetNumber() const override;
void SetNumber(double value) override;
int GetDecimalPlaces() const override;
int GetDisplayDecimalPlaces() const override;
double GetMin() const override;
double GetMax() const override;
private:
AZStd::weak_ptr<GraphModel::Slot> m_slot;
};
}
@@ -0,0 +1,64 @@
/*
* 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
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/containers/map.h>
// Graph Model
#include <GraphModel/Model/Common.h>
namespace GraphCanvas
{
class EntitySaveDataContainer;
}
namespace GraphModelIntegration
{
//! This class provides a way to bundle metadata from Graph Canvas for storage
//! in a GraphModel::Graph. The Graph class has a single AZStd::any for storing
//! UI-specific metadata, where the node canvas stores one of these GraphCanvasMetadata.
//! This allows the Graph's file on disk to include information about where nodes
//! are located in the scene, bookmarks, comment blocks, node groupings, etc.
class GraphCanvasMetadata
{
public:
AZ_RTTI(GraphCanvasMetadata, "{BD95C3EB-CD09-4F82-9724-032BD1827B95}");
virtual ~GraphCanvasMetadata() = default;
static void Reflect(AZ::ReflectContext* reflectContext);
private:
friend class GraphController;
// I tried using a unique_ptr but SerializeContext didn't like it
typedef AZStd::shared_ptr<GraphCanvas::EntitySaveDataContainer> EntitySaveDataContainerPtr;
// Using a map instead of unordered_map for simpler xml diffs
typedef AZStd::map<GraphModel::NodeId, EntitySaveDataContainerPtr> NodeMetadataMap;
typedef AZStd::map<AZ::EntityId, EntitySaveDataContainerPtr> OtherMetadataMap;
//! Graph Canvas metadata that pertains to the entire scene
EntitySaveDataContainerPtr m_sceneMetadata;
//! Graph Canvas metadata that pertains to each node in our data model. For example,
//! the position of each node.
NodeMetadataMap m_nodeMetadata;
//! Graph Canvas metadata that is not related to our data model. For example,
//! Comment nodes and Group Box nodes.
OtherMetadataMap m_otherMetadata;
};
}
@@ -0,0 +1,327 @@
/*
* 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
#include <AzCore/std/containers/unordered_map.h>
// Qt
#include <QPixmap>
// Graph Canvas
#include <GraphCanvas/Editor/GraphModelBus.h>
#include <GraphCanvas/Components/Slots/SlotBus.h>
#include <GraphCanvas/Components/SceneBus.h>
// Graph Model
#include <GraphModel/GraphModelBus.h>
#include <GraphModel/Model/Common.h>
#include <GraphModel/Model/Slot.h>
class QGraphicsLinearLayout;
namespace GraphModelIntegration
{
class GraphCanvasMetadata;
class ThumbnailItem;
//! This is the main class for binding the node graph data to the UI provided by Graph Canvas
class GraphController
: private GraphCanvas::GraphModelRequestBus::Handler
, private GraphCanvas::SceneNotificationBus::Handler
, public GraphControllerRequestBus::Handler
{
public:
AZ_RTTI(GraphController, "{E8433794-4BAE-4B63-B5A5-6EE69DFF0793}");
GraphController(GraphModel::GraphPtr graph, AZ::EntityId graphCanvasSceneId);
~GraphController() override;
GraphController(const GraphController&) = delete;
GraphModel::GraphPtr GetGraph() { return m_graph; }
const GraphModel::GraphPtr GetGraph() const { return m_graph; }
const AZ::EntityId GetGraphCanvasSceneId() const { return m_graphCanvasSceneId; }
////////////////////////////////////////////////////////////////////////////////////
// GraphModel::GraphControllerRequestBus, connections
//! Adds a node to the Graph and creates the corresponding Graph Canvas UI elements
//! \param node The node to add. This should be a freshly created Node that hasn't been added to the Graph yet.
//! \param sceneDropPosition The position in the Graph Cavnas scene where the Node was dropped
GraphCanvas::NodeId AddNode(GraphModel::NodePtr node, AZ::Vector2& sceneDropPosition) override;
bool RemoveNode(GraphModel::NodePtr node) override;
AZ::Vector2 GetPosition(GraphModel::NodePtr node) const override;
void WrapNode(GraphModel::NodePtr wrapperNode, GraphModel::NodePtr node) override;
void WrapNodeOrdered(GraphModel::NodePtr wrapperNode, GraphModel::NodePtr node, AZ::u32 layoutOrder) override;
void UnwrapNode(GraphModel::NodePtr wrapperNode, GraphModel::NodePtr node) override;
void SetWrapperNodeActionString(GraphModel::NodePtr node, const char* actionString) override;
GraphModel::ConnectionPtr AddConnection(GraphModel::SlotPtr sourceSlot, GraphModel::SlotPtr targetSlot) override;
GraphModel::ConnectionPtr AddConnectionBySlotId(GraphModel::NodePtr sourceNode, GraphModel::SlotId sourceSlotId, GraphModel::NodePtr targetNode, GraphModel::SlotId targetSlotId) override;
bool RemoveConnection(GraphModel::ConnectionPtr connection) override;
GraphModel::SlotId ExtendSlot(GraphModel::NodePtr node, GraphModel::SlotName slotName) override;
GraphModel::NodePtr GetNodeById(const GraphCanvas::NodeId& nodeId) override;
GraphModel::NodePtrList GetNodesFromGraphNodeIds(const AZStd::vector<GraphCanvas::NodeId>& nodeIds) override;
GraphCanvas::NodeId GetNodeIdByNode(GraphModel::NodePtr node) const override;
GraphCanvas::SlotId GetSlotIdBySlot(GraphModel::SlotPtr slot) const override;
GraphModel::NodePtrList GetNodes() override;
GraphModel::NodePtrList GetSelectedNodes() override;
void SetSelected(GraphModel::NodePtrList nodes, bool selected) override;
void ClearSelection() override;
void EnableNode(GraphModel::NodePtr node);
void DisableNode(GraphModel::NodePtr node);
void CenterOnNodes(GraphModel::NodePtrList nodes) override;
AZ::Vector2 GetMajorPitch() const override;
void SetThumbnailImageOnNode(GraphModel::NodePtr node, const QPixmap& image) override;
void SetThumbnailOnNode(GraphModel::NodePtr node, ThumbnailItem* item) override;
void RemoveThumbnailFromNode(GraphModel::NodePtr node) override;
////////////////////////////////////////////////////////////////////////////////////
private:
//! Helper method for retrieving the UI layout for a given node
QGraphicsLinearLayout* GetLayoutFromNode(GraphModel::NodePtr node);
//! Saves metadata for a Graph Canvas element into the Graph data model so it's ready
//! to be serialized out with the data model. graphCanvasElement could be any number
//! of entities including a node, comment, group, or the scene itself.
void SaveMetadata(const AZ::EntityId& graphCanvasElement);
//! Utility function for getting the GraphCanvasMetadata from the Graph data model
GraphCanvasMetadata* GetGraphMetadata();
////////////////////////////////////////////////////////////////////////////////////
// Functions for building Graph Canvas UI from our data model
//! Creates the all Graph Canvas elements necessary for representing the Graph. This will be called once
//! to instrument a Graph that was recently loaded.
void CreateFullGraphUi();
//! Creates the GraphCanvas slot UI representing a given Slot
AZ::Entity* CreateSlotUi(GraphModel::SlotPtr slot, AZ::EntityId nodeUiId);
//! Creates the GraphCanvas node UI represeting a given Node
//! \param scenePosition Pass in a lambda function that provides the node's position given it's GraphCanvas node EntityId.
AZ::EntityId CreateNodeUi(GraphModel::NodeId nodeId, GraphModel::NodePtr node, AZStd::function<AZ::Vector2(AZ::EntityId/*nodeUiId*/)> getScenePosition);
//! Utility function for adding a Graph Canvas node to a Graph Canvas scene
void AddNodeUiToScene(AZ::EntityId graphCanvasNodeId, const AZ::Vector2& scenePosition);
//! Creates the GraphCanvas UI represeting a given Connection
void CreateConnectionUi(GraphModel::ConnectionPtr connection);
//! Create a new GraphModel::Connection using the given source and target slots. This will also remove any existing connections on the target slot.
GraphModel::ConnectionPtr CreateConnection(GraphModel::SlotPtr sourceSlot, GraphModel::SlotPtr targetSlot);
//! Check if creating a connection between the specified target and source node would
//! cause a connection loopback.
bool CheckForLoopback(GraphModel::NodePtr sourceNode, GraphModel::NodePtr targetNode) const;
void WrapNodeUi(GraphModel::NodePtr wrapperNode, GraphModel::NodePtr node, AZ::u32 layoutOrder = GraphModel::DefaultWrappedNodeLayoutOrder);
void WrapNodeInternal(GraphModel::NodePtr wrapperNode, GraphModel::NodePtr node, AZ::u32 layoutOrder = GraphModel::DefaultWrappedNodeLayoutOrder);
////////////////////////////////////////////////////////////////////////////////////
// GraphCanvas::SceneNotificationBus, connections
void OnNodeAdded(const AZ::EntityId& nodeUiId) override;
void OnNodeRemoved(const AZ::EntityId& nodeUiId) override;
void PreOnNodeRemoved(const AZ::EntityId& nodeUiId) override;
void OnConnectionRemoved(const AZ::EntityId& connectionUiId) override;
void OnEntitiesSerialized(GraphCanvas::GraphSerialization& serializationTarget) override;
void OnEntitiesDeserialized(const GraphCanvas::GraphSerialization& serializationSource) override;
void OnEntitiesDeserializationComplete(const GraphCanvas::GraphSerialization& serializationSource) override;
////////////////////////////////////////////////////////////////////////////////////
// GraphCanvas::GraphModelRequestBus, connections
void DisconnectConnection([[maybe_unused]] const AZ::EntityId& connectionUiId) override {}
bool CreateConnection(const AZ::EntityId& connectionUiId, const GraphCanvas::Endpoint& sourcePoint, const GraphCanvas::Endpoint& targetPoint) override;
bool IsValidConnection(const GraphCanvas::Endpoint& sourcePoint, const GraphCanvas::Endpoint& targetPoint) const override;
bool IsValidVariableAssignment(const AZ::EntityId& variableId, const GraphCanvas::Endpoint& targetPoint) const override;
////////////////////////////////////////////////////////////////////////////////////
// GraphCanvas::GraphModelRequestBus, undo
// CJS TODO: I put this stuff in to handle making the file as dirty, but it looks like I might be able to get OnSaveDataDirtied to do that instead.
void RequestUndoPoint() override;
void RequestPushPreventUndoStateUpdate() override;
void RequestPopPreventUndoStateUpdate() override;
void TriggerUndo() override {}
void TriggerRedo() override {}
////////////////////////////////////////////////////////////////////////////////////
// GraphCanvas::GraphModelRequestBus, other
bool EnableNodes(const AZStd::unordered_set<GraphCanvas::NodeId>& nodeIds) override;
bool DisableNodes(const AZStd::unordered_set<GraphCanvas::NodeId>& nodeIds) override;
AZStd::string GetDataTypeString(const AZ::Uuid& typeId);
//! This is where we find all of the graph metadata (like node positions, comments, etc) and store it in the node graph for serialization
// CJS TODO: Use this instead of the above undo functions
void OnSaveDataDirtied(const AZ::EntityId& savedElement) override;
void OnRemoveUnusedNodes() override {}
void OnRemoveUnusedElements() override {}
void ResetSlotToDefaultValue(const GraphCanvas::Endpoint& endpoint) override;
/// Extendable slot handlers
void RemoveSlot(const GraphCanvas::Endpoint& endpoint) override;
bool IsSlotRemovable(const GraphCanvas::Endpoint& endpoint) const override;
GraphCanvas::SlotId RequestExtension(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId) override;
bool ShouldWrapperAcceptDrop(const GraphCanvas::NodeId& wrapperNode, const QMimeData* mimeData) const override;
void AddWrapperDropTarget(const GraphCanvas::NodeId& wrapperNode) override;
void RemoveWrapperDropTarget(const GraphCanvas::NodeId& wrapperNode) override;
////////////////////////////////////////////////////////////////////////////////////
// GraphCanvas::GraphModelRequestBus, node properties
//! Creates a GraphCanvas::NodePropertyDisplay and a data interface for editing input values
GraphCanvas::NodePropertyDisplay* CreateDataSlotPropertyDisplay(const AZ::Uuid& dataTypeUuid, const GraphCanvas::NodeId& nodeUiId, const GraphCanvas::SlotId& slotUiId) const override;
GraphCanvas::NodePropertyDisplay* CreatePropertySlotPropertyDisplay(const AZ::Crc32& propertyId, const GraphCanvas::NodeId& nodeUiId, const GraphCanvas::SlotId& slotUiId) const override;
//! Common implementation for CreateDataSlotPropertyDisplay and CreatePropertySlotPropertyDisplay
GraphCanvas::NodePropertyDisplay* CreateSlotPropertyDisplay(GraphModel::SlotPtr inputSlot) const;
////////////////////////////////////////////////////////////////////////////////////
//! This class maps the association between our data model's GraphElements and Graph Camvas's UI elements
class GraphElementMap
{
public:
//! Adds a 1:1 mapping between a Graph Canvas UI element and a GraphElement
void Add(AZ::EntityId graphCanvasId, GraphModel::GraphElementPtr graphElement);
//! Removes the Graph Canvas EntityId and its associated GraphElement from the map
void Remove(AZ::EntityId graphCanvasId);
//! Removes the GraphElement and its associated Graph Canvas EntityId from the map
void Remove(GraphModel::ConstGraphElementPtr graphElement);
//! Find the GraphElement that corresponds to the given Graph Canvas EntityId.
//! Returns nullptr if the mapping doesn't exist.
GraphModel::GraphElementPtr Find(AZ::EntityId graphCanvasId);
GraphModel::ConstGraphElementPtr Find(AZ::EntityId graphCanvasId) const;
//! Find the Graph Canvas EntityId that corresponds to the given GraphElement.
//! Returns an invalid EntityId if the mapping doesn't exist.
AZ::EntityId Find(GraphModel::ConstGraphElementPtr graphElement) const;
private:
// shared_ptr can't be a key in a map so we use a raw pointer. This is fine because the two maps
// are kept in sync, and the other map has a shared_ptr.
typedef AZStd::unordered_map<const GraphModel::GraphElement*, AZ::EntityId /*graphCanvasId*/> GraphElementToUiMap;
GraphElementToUiMap m_graphElementToUi;
typedef AZStd::unordered_map<AZ::EntityId /*graphCanvasId*/, GraphModel::GraphElementPtr> UiToGraphElementMap;
UiToGraphElementMap m_uiToGraphElement;
};
//! This class provides a collection of GraphElementMaps for the various types of elements. We could
//! put all the elements in one GraphElementMap, but splitting them out makes debugging a lot easier.
class GraphElementMapCollection
{
public:
GraphElementMapCollection() = default;
//! Adds a 1:1 mapping between a Graph Canvas UI element and a GraphElement.
//! Automatically determines which GraphElementMap is appropriate.
void Add(AZ::EntityId graphCanvasId, GraphModel::GraphElementPtr graphElement);
void Remove(AZ::EntityId graphCanvasId);
void Remove(GraphModel::ConstGraphElementPtr graphElement);
//! Find the GraphElement that corresponds to the given Graph Canvas EntityId.
//! Returns nullptr if the mapping doesn't exist, or the ElementType is wrong.
template<typename ElementType>
AZStd::shared_ptr<ElementType> Find(AZ::EntityId graphCanvasId);
template<typename ElementType>
AZStd::shared_ptr<const ElementType> Find(AZ::EntityId graphCanvasId) const;
//! Find the Graph Canvas EntityId that corresponds to the given GraphElement.
//! Returns an invalid EntityId if the mapping doesn't exist.
AZ::EntityId Find(GraphModel::ConstGraphElementPtr graphElement) const;
private:
GraphElementMap m_nodeMap;
GraphElementMap m_slotMap;
GraphElementMap m_connectionMap;
//! Returns which is the right GraphElementMap for graphElement based on its type
GraphElementMap* GetMapFor(GraphModel::ConstGraphElementPtr graphElement);
const GraphElementMap* GetMapFor(GraphModel::ConstGraphElementPtr graphElement) const;
// This list allows for easy iteration over all the GraphElementMaps.
AZStd::vector<GraphElementMap*> m_allMaps = { &m_nodeMap, &m_slotMap, &m_connectionMap };
} m_elementMap;
AZ::SerializeContext* m_serializeContext = nullptr;
GraphModel::GraphPtr m_graph;
AZ::EntityId m_graphCanvasSceneId;
AZStd::unordered_map<GraphModel::NodeId, GraphModelIntegration::ThumbnailItem*> m_nodeThumbnails;
AZStd::unordered_map<GraphCanvas::NodeId, AZStd::unordered_map<GraphCanvas::ExtenderId, GraphModel::SlotName>> m_nodeExtenderIds;
bool m_isCreatingConnectionUi = false;
};
template<typename ElementType>
AZStd::shared_ptr<ElementType> GraphController::GraphElementMapCollection::Find(AZ::EntityId graphCanvasId)
{
GraphModel::GraphElementPtr graphElement;
for (GraphElementMap* map : m_allMaps)
{
graphElement = map->Find(graphCanvasId);
if (graphElement)
{
break;
}
}
return azrtti_cast<ElementType*>(graphElement);
}
template<typename ElementType>
AZStd::shared_ptr<const ElementType> GraphController::GraphElementMapCollection::Find(AZ::EntityId graphCanvasId) const
{
GraphModel::ConstGraphElementPtr graphElement;
for (GraphElementMap* map : m_allMaps)
{
graphElement = map->Find(graphCanvasId);
if (graphElement)
{
break;
}
}
return azrtti_cast<const ElementType*>(graphElement);
}
}
@@ -0,0 +1,54 @@
/*
* 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
#include <AzCore/base.h>
// Graph Model
#include <GraphModel/GraphModelBus.h>
#include <GraphModel/Integration/GraphController.h>
namespace GraphModelIntegration
{
//! This is the main class for managing the Graph Controllers for Graph Canvas scenes
class GraphControllerManager
: private GraphManagerRequestBus::Handler
{
public:
AZ_RTTI(GraphControllerManager, "{DA358B3E-46EF-411B-B84B-0397F5CD3539}");
GraphControllerManager() = default;
////////////////////////////////////////////////////////////////////////////////////
// GraphModelIntegration::GraphManagerRequestBus overrides
AZ::Entity* CreateScene(GraphModel::GraphPtr graph, const GraphCanvas::EditorId editorId) override;
void RemoveScene(const GraphCanvas::GraphId& sceneId) override;
void CreateGraphController(const GraphCanvas::GraphId& sceneId, GraphModel::GraphPtr graph) override;
void DeleteGraphController(const GraphCanvas::GraphId& sceneId) override;
GraphModel::GraphPtr GetGraph(const GraphCanvas::GraphId& sceneId) override;
const GraphModelSerialization& GetSerializedMappings() override;
void SetSerializedMappings(const GraphModelSerialization& serialization) override;
////////////////////////////////////////////////////////////////////////////////////
void Activate();
void Deactivate();
private:
AZ_DISABLE_COPY_MOVE(GraphControllerManager);
AZStd::unordered_map<GraphCanvas::GraphId, AZStd::shared_ptr<GraphController>> m_graphControllers;
GraphModelSerialization m_serialization;
};
}
@@ -0,0 +1,89 @@
/*
* 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 <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/RTTI/TypeInfo.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/string/string.h>
namespace GraphModelIntegration
{
namespace Attributes
{
const static AZ::Crc32 TitlePaletteOverride = AZ_CRC("TitlePaletteOverride", 0x2faad537);
}
class Helpers
{
public:
//! Helper method to retrieve the TitlePaletteOverride attribute (if exists) set on
//! a given AZ type class, that will also check any base class that it is derived from
static AZStd::string GetTitlePaletteOverride(const AZ::TypeId& typeId)
{
AZ::SerializeContext* serializeContext = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
AZ_Assert(serializeContext, "Failed to acquire application serialize context.");
AZStd::string paletteOverride;
const AZ::SerializeContext::ClassData* derivedClassData = serializeContext->FindClassData(typeId);
if (!derivedClassData)
{
return paletteOverride;
}
// Use the EnumHierarchy API to retrive a list of TypeIds that this class derives from,
// starting with the actual type and going backwards
AZStd::vector<AZ::TypeId> typeIds;
if (derivedClassData->m_azRtti)
{
derivedClassData->m_azRtti->EnumHierarchy(&RttiEnumHeirarchyHelper, &typeIds);
}
// Look through all the derived TypeIds to see if the TitlePaletteOverride attribute
// was set in the EditContext at any level
for (auto currentTypeId : typeIds)
{
auto classData = serializeContext->FindClassData(currentTypeId);
if (classData)
{
if (classData->m_editData)
{
const AZ::Edit::ElementData* elementData = classData->m_editData->FindElementData(AZ::Edit::ClassElements::EditorData);
if (elementData)
{
if (auto titlePaletteAttribute = elementData->FindAttribute(Attributes::TitlePaletteOverride))
{
AZ::AttributeReader nameReader(nullptr, titlePaletteAttribute);
nameReader.Read<AZStd::string>(paletteOverride);
}
}
}
}
}
return paletteOverride;
}
private:
//! Callback method needed for IRttiHelper::EnumHierarchy that gets invoked at every level
//! allowing us to build a list of each TypeId it encounters
static void RttiEnumHeirarchyHelper(const AZ::TypeId& typeId, void* userData)
{
AZStd::vector<AZ::TypeId>* typeIds = reinterpret_cast<AZStd::vector<AZ::TypeId>*>(userData);
typeIds->push_back(typeId);
}
};
}
@@ -0,0 +1,44 @@
/*
* 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
// Graph Canvas
#include <GraphCanvas/Components/NodePropertyDisplay/NumericDataInterface.h>
// Graph Model
#include <GraphModel/Model/Slot.h>
namespace GraphModelIntegration
{
//! Satisfies GraphCanvas API requirements for showing int property widgets in nodes.
class IntegerDataInterface
: public GraphCanvas::NumericDataInterface
{
public:
AZ_CLASS_ALLOCATOR(IntegerDataInterface, AZ::SystemAllocator, 0);
IntegerDataInterface(GraphModel::SlotPtr slot);
~IntegerDataInterface() = default;
double GetNumber() const override;
void SetNumber(double value) override;
int GetDecimalPlaces() const override;
int GetDisplayDecimalPlaces() const override;
double GetMin() const override;
double GetMax() const override;
private:
AZStd::weak_ptr<GraphModel::Slot> m_slot;
};
}
@@ -0,0 +1,39 @@
/*
* 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
#include <AzCore/EBus/EBus.h>
// Graph Canvas
#include <GraphCanvas/Editor/EditorTypes.h>
namespace GraphModelIntegration
{
class GraphController;
//! Bus functions that allow the GraphModel Integration system to callback to the client system.
class IntegrationBusInterface : public AZ::EBusTraits
{
public:
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//! Return the Graph Canvas EntityId for whichever Graph Canvas scene is active in the Editor
virtual GraphCanvas::GraphId GetActiveGraphCanvasSceneId() const = 0;
//! Notifies the client node graph system that the graph data has changed
virtual void SignalSceneDirty(GraphCanvas::GraphId graphCanvasSceneId) = 0;
};
using IntegrationBus = AZ::EBus<IntegrationBusInterface>;
}
@@ -0,0 +1,179 @@
/*
* 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
#include <AzCore/Serialization/SerializeContext.h>
// Graph Canvas
#include <GraphCanvas/Components/GridBus.h>
#include <GraphCanvas/GraphCanvasBus.h>
#include <GraphCanvas/Widgets/NodePalette/TreeItems/DraggableNodePaletteTreeItem.h>
#include <GraphCanvas/Widgets/GraphCanvasMimeEvent.h>
namespace GraphModelIntegration
{
//! Provides a common interface for instantiating Graph Canvas support nodes like comments through the Node Palette
class CreateGraphCanvasNodeMimeEvent
: public GraphCanvas::GraphCanvasMimeEvent
{
public:
AZ_RTTI(CreateGraphCanvasNodeMimeEvent, "{7171A847-7405-459F-A031-CC9AE50745B6}", GraphCanvas::GraphCanvasMimeEvent);
AZ_CLASS_ALLOCATOR(CreateGraphCanvasNodeMimeEvent, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serializeContext)
{
serializeContext->Class<CreateGraphCanvasNodeMimeEvent, GraphCanvas::GraphCanvasMimeEvent>()
->Version(0)
;
}
}
CreateGraphCanvasNodeMimeEvent() = default;
~CreateGraphCanvasNodeMimeEvent() = default;
bool ExecuteEvent([[maybe_unused]] const AZ::Vector2& mouseDropPosition, AZ::Vector2& dropPosition, const AZ::EntityId& graphCanvasSceneId) override final
{
AZ::Entity* graphCanvasNode = CreateNode();
if (graphCanvasNode)
{
AZ::EntityId graphCanvasNodeId = graphCanvasNode->GetId();
GraphCanvas::SceneRequestBus::Event(graphCanvasSceneId, &GraphCanvas::SceneRequests::AddNode, graphCanvasNodeId, dropPosition);
GraphCanvas::SceneMemberUIRequestBus::Event(graphCanvasNodeId, &GraphCanvas::SceneMemberUIRequests::SetSelected, true);
AZ::EntityId gridId;
GraphCanvas::SceneRequestBus::EventResult(gridId, graphCanvasSceneId, &GraphCanvas::SceneRequests::GetGrid);
AZ::Vector2 offset;
GraphCanvas::GridRequestBus::EventResult(offset, gridId, &GraphCanvas::GridRequests::GetMinorPitch);
dropPosition += offset;
return true;
}
return false;
}
protected:
virtual AZ::Entity* CreateNode() const = 0;
};
////////////////////////////////////////////////////////////////////////////////////
// Comment Node
class CreateCommentNodeMimeEvent
: public CreateGraphCanvasNodeMimeEvent
{
public:
AZ_RTTI(CreateCommentNodeMimeEvent, "{1060EE7B-DBC2-4B7F-BC4C-4AB4651A3812}", CreateGraphCanvasNodeMimeEvent);
AZ_CLASS_ALLOCATOR(CreateCommentNodeMimeEvent, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serializeContext)
{
serializeContext->Class<CreateCommentNodeMimeEvent, GraphCanvas::GraphCanvasMimeEvent>()
->Version(0)
;
}
}
CreateCommentNodeMimeEvent() = default;
~CreateCommentNodeMimeEvent() = default;
virtual AZ::Entity* CreateNode() const override
{
AZ::Entity* graphCanvasNode = nullptr;
GraphCanvas::GraphCanvasRequestBus::BroadcastResult(graphCanvasNode, &GraphCanvas::GraphCanvasRequests::CreateCommentNodeAndActivate);
return graphCanvasNode;
}
};
class CommentNodePaletteTreeItem
: public GraphCanvas::DraggableNodePaletteTreeItem
{
public:
AZ_CLASS_ALLOCATOR(CommentNodePaletteTreeItem, AZ::SystemAllocator, 0);
CommentNodePaletteTreeItem(AZStd::string_view nodeName, GraphCanvas::EditorId editorId)
: DraggableNodePaletteTreeItem(nodeName, editorId)
{
SetToolTip("Comment box for notes. Does not affect script execution or data.");
}
~CommentNodePaletteTreeItem() = default;
GraphCanvas::GraphCanvasMimeEvent* CreateMimeEvent() const override
{
return aznew CreateCommentNodeMimeEvent();
}
};
////////////////////////////////////////////////////////////////////////////////////
// Node Group Node
class CreateNodeGroupNodeMimeEvent
: public CreateGraphCanvasNodeMimeEvent
{
public:
AZ_RTTI(CreateNodeGroupNodeMimeEvent, "{1451A2F2-640B-4CB3-BF48-DD77E97EC900}", CreateGraphCanvasNodeMimeEvent);
AZ_CLASS_ALLOCATOR(CreateNodeGroupNodeMimeEvent, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serializeContext)
{
serializeContext->Class<CreateNodeGroupNodeMimeEvent, GraphCanvas::GraphCanvasMimeEvent>()
->Version(0)
;
}
}
CreateNodeGroupNodeMimeEvent() = default;
~CreateNodeGroupNodeMimeEvent() = default;
virtual AZ::Entity* CreateNode() const override
{
AZ::Entity* graphCanvasNode = nullptr;
GraphCanvas::GraphCanvasRequestBus::BroadcastResult(graphCanvasNode, &GraphCanvas::GraphCanvasRequests::CreateNodeGroupAndActivate);
return graphCanvasNode;
}
};
class NodeGroupNodePaletteTreeItem
: public GraphCanvas::DraggableNodePaletteTreeItem
{
public:
AZ_CLASS_ALLOCATOR(NodeGroupNodePaletteTreeItem, AZ::SystemAllocator, 0);
NodeGroupNodePaletteTreeItem(AZStd::string_view nodeName, GraphCanvas::EditorId editorId)
: DraggableNodePaletteTreeItem(nodeName, editorId)
{}
~NodeGroupNodePaletteTreeItem() = default;
GraphCanvas::GraphCanvasMimeEvent* CreateMimeEvent() const override
{
return aznew CreateNodeGroupNodeMimeEvent();
}
};
/// Add common utilities to a specific Node Palette tree.
void AddCommonNodePaletteUtilities(GraphCanvas::GraphCanvasTreeItem* rootItem, const GraphCanvas::EditorId& editorId);
}
@@ -0,0 +1,110 @@
/*
* 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
#include <AzCore/std/smart_ptr/make_shared.h>
// Graph Canvas
#include <GraphCanvas/Widgets/NodePalette/TreeItems/DraggableNodePaletteTreeItem.h>
#include <GraphCanvas/Widgets/GraphCanvasMimeEvent.h>
// Graph Model
#include <GraphModel/GraphModelBus.h>
#include <GraphModel/Model/Common.h>
namespace GraphModelIntegration
{
template<typename NodeType>
class CreateInputOutputNodeMimeEvent;
//! Provides a common interface for instantiating InputGraphNode and OutputGraphNode through the Node Palette
template<typename NodeType>
class InputOutputNodePaletteItem
: public GraphCanvas::DraggableNodePaletteTreeItem
{
public:
AZ_CLASS_ALLOCATOR(InputOutputNodePaletteItem, AZ::SystemAllocator, 0);
//! Constructor
//! \param nodeName Name of the node that will show up in the Palette
//! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0xa6d1a85a))
//! \param dataType The type of data that the InputGraphNode or OutputGraphNode will represent
InputOutputNodePaletteItem(AZStd::string_view nodeName, GraphCanvas::EditorId editorId, GraphModel::DataTypePtr dataType)
: DraggableNodePaletteTreeItem(nodeName, editorId)
, m_dataType(dataType)
{}
~InputOutputNodePaletteItem() = default;
GraphCanvas::GraphCanvasMimeEvent* CreateMimeEvent() const override
{
return aznew CreateInputOutputNodeMimeEvent<NodeType>(m_dataType);
}
protected:
GraphModel::DataTypePtr m_dataType;
};
template<typename NodeType>
class CreateInputOutputNodeMimeEvent
: public GraphCanvas::GraphCanvasMimeEvent
{
public:
AZ_RTTI(((CreateInputOutputNodeMimeEvent<NodeType>), "{16BED069-A386-4E5C-8A5A-0827121991E7}", NodeType), GraphCanvas::GraphCanvasMimeEvent);
AZ_CLASS_ALLOCATOR(CreateInputOutputNodeMimeEvent, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serializeContext)
{
serializeContext->Class<CreateInputOutputNodeMimeEvent, GraphCanvas::GraphCanvasMimeEvent>()
->Version(0)
->Field("m_dataType", &CreateInputOutputNodeMimeEvent::m_dataType)
;
}
}
CreateInputOutputNodeMimeEvent() = default; // Required by SerializeContext
explicit CreateInputOutputNodeMimeEvent(GraphModel::DataTypePtr dataType)
{
// Copy because m_dataType has to be non-const for use with SerializeContext, and dataType is const
m_dataType = AZStd::make_shared<GraphModel::DataType>(*dataType);
}
bool ExecuteEvent([[maybe_unused]] const AZ::Vector2& mouseDropPosition, AZ::Vector2& dropPosition, const AZ::EntityId& graphCanvasSceneId) override
{
GraphModel::GraphPtr graph = nullptr;
GraphManagerRequestBus::BroadcastResult(graph, &GraphManagerRequests::GetGraph, graphCanvasSceneId);
if (!graph)
{
return false;
}
AZStd::shared_ptr<GraphModel::Node> node = AZStd::make_shared<NodeType>(graph, m_dataType);
if (!node)
{
return false;
}
GraphControllerRequestBus::Event(graphCanvasSceneId, &GraphControllerRequests::AddNode, node, dropPosition);
return true;
}
protected:
AZStd::shared_ptr<GraphModel::DataType> m_dataType;
};
}
@@ -0,0 +1,121 @@
/*
* 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
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzFramework/StringFunc/StringFunc.h>
// Graph Canvas
#include <GraphCanvas/Widgets/NodePalette/TreeItems/DraggableNodePaletteTreeItem.h>
#include <GraphCanvas/Widgets/GraphCanvasMimeEvent.h>
// Graph Model
#include <GraphModel/GraphModelBus.h>
#include <GraphModel/Model/Common.h>
#include <GraphModel/Model/Module/ModuleNode.h>
namespace GraphModelIntegration
{
AZStd::string GetNodeName(AZStd::string_view sourceFileName)
{
AZStd::string name = "Unnamed";
if (!AzFramework::StringFunc::Path::GetFileName(sourceFileName.data(), name))
{
AZ_Assert(false, "Could not get node name from module file path [%s]", sourceFileName.data());
}
return name;
}
class CreateModuleNodeMimeEvent
: public GraphCanvas::GraphCanvasMimeEvent
{
public:
AZ_RTTI(CreateModuleNodeMimeEvent, "{914F9D88-7B60-408D-A16F-BCCE4CA41EFB}", GraphCanvas::GraphCanvasMimeEvent);
AZ_CLASS_ALLOCATOR(CreateModuleNodeMimeEvent, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serializeContext)
{
serializeContext->Class<CreateModuleNodeMimeEvent, GraphCanvas::GraphCanvasMimeEvent>()
->Version(0)
->Field("m_sourceFileName", &CreateModuleNodeMimeEvent::m_sourceFileName)
->Field("m_sourceFileId", &CreateModuleNodeMimeEvent::m_sourceFileId)
;
}
}
CreateModuleNodeMimeEvent() = default; // required by SerializeContext
CreateModuleNodeMimeEvent(AZStd::string_view sourceFileName, AZ::Uuid sourceFileId)
: m_sourceFileName(sourceFileName)
, m_sourceFileId(sourceFileId)
{
}
bool ExecuteEvent([[maybe_unused]] const AZ::Vector2& mouseDropPosition, AZ::Vector2& dropPosition, const AZ::EntityId& graphCanvasSceneId) override
{
GraphModel::GraphPtr graph = nullptr;
GraphManagerRequestBus::BroadcastResult(graph, &GraphManagerRequests::GetGraph, graphCanvasSceneId);
if (!graph)
{
return false;
}
AZStd::shared_ptr<GraphModel::Node> node = AZStd::make_shared<GraphModel::ModuleNode>(graph, m_sourceFileId, m_sourceFileName);
if (!node)
{
return false;
}
GraphControllerRequestBus::Event(graphCanvasSceneId, &GraphControllerRequests::AddNode, node, dropPosition);
return true;
}
protected:
AZStd::string m_sourceFileName;
AZ::Uuid m_sourceFileId;
};
//! Provides the interface for instantiating ModuleNodes through the Node Palette. The ModuleNode is based on a
//! module node graph file that defines the inputs, outputs, and behavior of the node.
class ModuleNodePaletteItem
: public GraphCanvas::DraggableNodePaletteTreeItem
{
public:
AZ_CLASS_ALLOCATOR(ModuleNodePaletteItem, AZ::SystemAllocator, 0);
//! Constructor
//! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0xa6d1a85a))
//! \param sourceFileId The unique id for the module node graph source file.
//! \param sourceFilePath The path to the module node graph source file. This will be used for node naming and debug output.
ModuleNodePaletteItem(GraphCanvas::EditorId editorId, AZ::Uuid sourceFileId, AZStd::string_view sourceFilePath)
: DraggableNodePaletteTreeItem(GetNodeName(sourceFilePath).data(), editorId)
, m_sourceFileName(sourceFilePath)
, m_sourceFileId(sourceFileId)
{}
~ModuleNodePaletteItem() = default;
GraphCanvas::GraphCanvasMimeEvent* CreateMimeEvent() const override
{
return aznew CreateModuleNodeMimeEvent(m_sourceFileName, m_sourceFileId);
}
protected:
AZStd::string m_sourceFileName;
AZ::Uuid m_sourceFileId;
};
}
@@ -0,0 +1,108 @@
/*
* 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
#include <AzCore/std/smart_ptr/make_shared.h>
// Graph Canvas
#include <GraphCanvas/Widgets/NodePalette/TreeItems/DraggableNodePaletteTreeItem.h>
#include <GraphCanvas/Widgets/GraphCanvasMimeEvent.h>
// Graph Model
#include <GraphModel/GraphModelBus.h>
#include <GraphModel/Integration/Helpers.h>
namespace GraphModelIntegration
{
template<typename NodeType>
class CreateStandardNodeMimeEvent;
//! Provides a common interface for instantiating GraphModel::Node subclasses through the Node Palette
template<typename NodeType>
class StandardNodePaletteItem
: public GraphCanvas::DraggableNodePaletteTreeItem
{
public:
AZ_CLASS_ALLOCATOR(StandardNodePaletteItem, AZ::SystemAllocator, 0);
//! Constructor
//! \param nodeName Name of the node that will show up in the Palette
//! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0xa6d1a85a))
StandardNodePaletteItem(AZStd::string_view nodeName, GraphCanvas::EditorId editorId)
: DraggableNodePaletteTreeItem(nodeName, editorId)
{
// Setting the palette override (if specified) is mainly used to set the icon color for this
// node palette item, but it can also be used to override other styling aspects as well
AZStd::string paletteOverride = Helpers::GetTitlePaletteOverride(azrtti_typeid<NodeType>());
if (!paletteOverride.empty())
{
SetTitlePalette(paletteOverride);
}
}
~StandardNodePaletteItem() = default;
GraphCanvas::GraphCanvasMimeEvent* CreateMimeEvent() const override
{
return aznew CreateStandardNodeMimeEvent<NodeType>();
}
};
template<typename NodeType>
class CreateStandardNodeMimeEvent
: public GraphCanvas::GraphCanvasMimeEvent
{
public:
AZ_RTTI( ( (CreateStandardNodeMimeEvent<NodeType>), "{DF6213A0-5C60-4C22-88F1-4CEA6D8A17EF}", NodeType), GraphCanvas::GraphCanvasMimeEvent);
AZ_CLASS_ALLOCATOR(CreateStandardNodeMimeEvent, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serializeContext)
{
serializeContext->Class<CreateStandardNodeMimeEvent, GraphCanvas::GraphCanvasMimeEvent>()
->Version(0)
;
}
}
bool ExecuteEvent([[maybe_unused]] const AZ::Vector2& mouseDropPosition, AZ::Vector2& dropPosition, const AZ::EntityId& graphCanvasSceneId) override
{
GraphModel::GraphPtr graph = nullptr;
GraphManagerRequestBus::BroadcastResult(graph, &GraphManagerRequests::GetGraph, graphCanvasSceneId);
if (!graph)
{
return false;
}
AZStd::shared_ptr<GraphModel::Node> node = AZStd::make_shared<NodeType>(graph);
if (!node)
{
return false;
}
GraphControllerRequestBus::EventResult(m_createdNodeId, graphCanvasSceneId, &GraphControllerRequests::AddNode, node, dropPosition);
return true;
}
};
template<typename NodeType>
void ReflectAndCreateNodeMimeEvent(AZ::ReflectContext* context)
{
NodeType::Reflect(context);
GraphModelIntegration::CreateStandardNodeMimeEvent<NodeType>::Reflect(context);
}
}
@@ -0,0 +1,39 @@
/*
* 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
// Graph Canvas
#include <GraphCanvas/Components/NodePropertyDisplay/ReadOnlyDataInterface.h>
// Graph Model
#include <GraphModel/Model/Slot.h>
namespace GraphModelIntegration
{
//! Satisfies GraphCanvas API requirements for showing read only property widgets in nodes.
class ReadOnlyDataInterface
: public GraphCanvas::ReadOnlyDataInterface
{
public:
AZ_CLASS_ALLOCATOR(ReadOnlyDataInterface, AZ::SystemAllocator, 0);
ReadOnlyDataInterface(GraphModel::SlotPtr slot);
~ReadOnlyDataInterface() = default;
// GraphCanvas::ReadOnlyDataInterface overrides ...
AZStd::string GetString() const override;
private:
AZStd::weak_ptr<GraphModel::Slot> m_slot;
};
}
@@ -0,0 +1,39 @@
/*
* 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
// Graph Canvas
#include <GraphCanvas/Components/NodePropertyDisplay/StringDataInterface.h>
// Graph Model
#include <GraphModel/Model/Slot.h>
namespace GraphModelIntegration
{
//! Satisfies GraphCanvas API requirements for showing string property widgets in nodes.
class StringDataInterface
: public GraphCanvas::StringDataInterface
{
public:
AZ_CLASS_ALLOCATOR(StringDataInterface, AZ::SystemAllocator, 0);
StringDataInterface(GraphModel::SlotPtr slot);
~StringDataInterface() = default;
AZStd::string GetString() const;
void SetString(const AZStd::string& value);
private:
AZStd::weak_ptr<GraphModel::Slot> m_slot;
};
}
@@ -0,0 +1,46 @@
/*
* 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
// Qt
#include <QPixmap>
// GraphModel
#include <GraphModel/Integration/ThumbnailItem.h>
namespace GraphModelIntegration
{
/**
* Default image implementation of our ThumbnailItem class to draw a
* simple QPixmap as the thumbnail.
*/
class ThumbnailImageItem
: public ThumbnailItem
{
public:
AZ_RTTI(ThumbnailImageItem, "{DB2F488F-95CF-49BC-8DD4-806969A71A16}", ThumbnailItem);
ThumbnailImageItem(const QPixmap& image, QGraphicsItem* parent = nullptr);
void UpdateImage(const QPixmap& image);
//! Override from QGraphicsLayoutItem
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override;
//! Override from QGraphicsItem
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
protected:
QPixmap m_pixmap;
};
}
@@ -0,0 +1,43 @@
/*
* 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
#include <AzCore/RTTI/RTTI.h>
// Qt
#include <QGraphicsItem>
#include <QGraphicsLayoutItem>
namespace GraphModelIntegration
{
/**
* Base layout item class for embedding thumbnails inside a Node. The paint()
* method can be overriden to implement any custom rendering desired.
*/
class ThumbnailItem
: public QGraphicsLayoutItem
, public QGraphicsItem
{
public:
AZ_RTTI(ThumbnailItem, "{4248ADDE-4DFF-4A02-A8FD-B992E3CFF94B}");
ThumbnailItem(QGraphicsItem* parent = nullptr);
//! Override from QGraphicsLayoutItem
void setGeometry(const QRectF &geom) override;
//! Override from QGraphicsItem
QRectF boundingRect() const override;
};
}
@@ -0,0 +1,102 @@
/*
* 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
// Graph Canvas
#include <GraphCanvas/Components/NodePropertyDisplay/VectorDataInterface.h>
// Graph Model
#include <GraphModel/Integration/IntegrationBus.h>
#include <GraphModel/Model/Slot.h>
namespace GraphModelIntegration
{
template<class Type, int ElementCount>
class VectorDataInterface
: public GraphCanvas::VectorDataInterface
{
public:
AZ_CLASS_ALLOCATOR(VectorDataInterface, AZ::SystemAllocator, 0);
VectorDataInterface(GraphModel::SlotPtr slot)
: m_slot(slot)
{
}
~VectorDataInterface() = default;
const char* GetLabel(int index) const override
{
if (index == 0)
{
return "X";
}
else if (index == 1)
{
return "Y";
}
else if (index == 2)
{
return "Z";
}
else if (index == 3)
{
return "W";
}
return "???";
}
AZStd::string GetStyle() const override
{
return "vectorized";
}
AZStd::string GetElementStyle(int index) const override
{
return AZStd::string::format("vector_%i", index);
}
int GetElementCount() const override
{
return ElementCount;
}
double GetValue(int index) const override
{
if (GraphModel::SlotPtr slot = m_slot.lock())
{
return slot->GetValue<Type>().GetElement(index);
}
else
{
return 0.0;
}
}
void SetValue(int index, double value) override
{
if (GraphModel::SlotPtr slot = m_slot.lock())
{
Type vector = slot->GetValue<Type>();
if (value != vector.GetElement(index))
{
vector.SetElement(index, aznumeric_cast<float>(value));
slot->SetValue(vector);
GraphCanvas::GraphId graphCanvasSceneId;
IntegrationBus::BroadcastResult(graphCanvasSceneId, &IntegrationBusInterface::GetActiveGraphCanvasSceneId);
IntegrationBus::Broadcast(&IntegrationBusInterface::SignalSceneDirty, graphCanvasSceneId);
}
}
}
private:
AZStd::weak_ptr<GraphModel::Slot> m_slot;
};
}