ConnectionComponent.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <AzCore/PlatformDef.h>
  10. AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
  11. #include <qgraphicswidget.h>
  12. #include <qgraphicssceneevent.h>
  13. #include <QTimer>
  14. AZ_POP_DISABLE_WARNING
  15. #include <AzCore/Component/Component.h>
  16. #include <AzCore/Component/EntityBus.h>
  17. #include <AzCore/std/string/string.h>
  18. #include <AzToolsFramework/API/ToolsApplicationAPI.h>
  19. #include <AzToolsFramework/UI/Notifications/ToastBus.h>
  20. #include <GraphCanvas/Components/Connections/ConnectionBus.h>
  21. #include <GraphCanvas/Components/GeometryBus.h>
  22. #include <GraphCanvas/Components/Nodes/NodeBus.h>
  23. #include <GraphCanvas/Components/SceneBus.h>
  24. #include <GraphCanvas/GraphicsItems/GraphCanvasSceneEventFilter.h>
  25. #include <GraphCanvas/Utils/StateControllers/StateController.h>
  26. namespace GraphCanvas
  27. {
  28. class ConnectionEventFilter;
  29. class ConnectionComponent
  30. : public AZ::Component
  31. , public ConnectionRequestBus::Handler
  32. , public SceneMemberRequestBus::Handler
  33. , public AZ::TickBus::Handler
  34. , public ViewNotificationBus::Handler
  35. , public NodeNotificationBus::Handler
  36. , public SceneNotificationBus::Handler
  37. {
  38. private:
  39. friend class ConnectionEventFilter;
  40. protected:
  41. class ConnectionEndpointAnimator
  42. {
  43. public:
  44. ConnectionEndpointAnimator();
  45. bool IsAnimating() const;
  46. void AnimateToEndpoint(const QPointF& startPoint, const Endpoint& endPoint, float timeFrame);
  47. QPointF GetAnimatedPosition() const;
  48. bool Tick(float deltaTime);
  49. private:
  50. bool m_isAnimating;
  51. float m_maxTime;
  52. float m_timer;
  53. QPointF m_currentPosition;
  54. QPointF m_startPosition;
  55. Endpoint m_targetEndpoint;
  56. };
  57. enum class DragContext
  58. {
  59. Unknown,
  60. TryConnection,
  61. MoveSource,
  62. MoveTarget,
  63. Connected
  64. };
  65. enum class ConnectionMoveResult
  66. {
  67. DeleteConnection,
  68. ConnectionMove,
  69. NodeCreation
  70. };
  71. struct ConnectionCandidate
  72. {
  73. Endpoint m_connectableTarget;
  74. Endpoint m_testedTarget;
  75. };
  76. public:
  77. AZ_COMPONENT(ConnectionComponent, "{14BB1535-3B30-4B1C-8324-D864963FBC76}", AZ::Component);
  78. static void Reflect(AZ::ReflectContext* context);
  79. static AZ::Entity* CreateBaseConnectionEntity(const Endpoint& sourceEndpoint, const Endpoint& targetEndpoint, bool createModelConnection, const AZStd::string& selectorClass);
  80. static AZ::Entity* CreateGeneralConnection(const Endpoint& sourceEndpoint, const Endpoint& targetEndpoint, bool createModelConnection, const AZStd::string& substyle = "");
  81. ConnectionComponent();
  82. ConnectionComponent(const Endpoint& sourceEndpoint,const Endpoint& targetEndpoint, bool createModelConnection = true);
  83. ~ConnectionComponent() override = default;
  84. // AZ::Component
  85. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  86. {
  87. provided.push_back(AZ_CRC_CE("GraphCanvas_ConnectionService"));
  88. provided.push_back(AZ_CRC_CE("GraphCanvas_SceneMemberService"));
  89. }
  90. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  91. {
  92. incompatible.push_back(AZ_CRC_CE("GraphCanvas_ConnectionService"));
  93. }
  94. static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
  95. {
  96. (void)dependent;
  97. }
  98. static void GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
  99. {
  100. }
  101. void Activate() override;
  102. void Deactivate() override;
  103. ////
  104. // NodeNotificationBus
  105. void OnSlotRemovedFromNode(const AZ::EntityId& slotId) override;
  106. ////
  107. // ConnectionRequestBus
  108. AZ::EntityId GetSourceSlotId() const override;
  109. AZ::EntityId GetSourceNodeId() const override;
  110. Endpoint GetSourceEndpoint() const override;
  111. QPointF GetSourcePosition() const override;
  112. void StartSourceMove() override;
  113. void SnapSourceDisplayTo(const Endpoint& sourceEndpoint) override;
  114. void AnimateSourceDisplayTo(const Endpoint& sourceEndpoint, float connectionTime) override;
  115. AZ::EntityId GetTargetSlotId() const override;
  116. AZ::EntityId GetTargetNodeId() const override;
  117. Endpoint GetTargetEndpoint() const override;
  118. QPointF GetTargetPosition() const override;
  119. void StartTargetMove() override;
  120. void SnapTargetDisplayTo(const Endpoint& targetEndpoint) override;
  121. void AnimateTargetDisplayTo(const Endpoint& targetEndpoint, float connectionTime) override;
  122. bool ContainsEndpoint(const Endpoint& endpoint) const override;
  123. void ChainProposalCreation(const QPointF& scenePos, const QPoint& screenPos, AZ::EntityId groupTarget) override;
  124. ////
  125. // SceneMemberRequestBus
  126. void SetScene(const AZ::EntityId& sceneId) override;
  127. void ClearScene(const AZ::EntityId& oldSceneId) override;
  128. void SignalMemberSetupComplete() override;
  129. AZ::EntityId GetScene() const override;
  130. ////
  131. // ConnectionRequestBus
  132. AZStd::string GetTooltip() const override;
  133. void SetTooltip(const AZStd::string& tooltip) override;
  134. AZStd::any* GetUserData() override;
  135. ////
  136. // TickBus
  137. void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
  138. ////
  139. // ViewNotificationBus
  140. void OnEscape() override;
  141. void OnFocusLost() override;
  142. ////
  143. // SceneNotificationBus
  144. void OnNodeIsBeingEdited(bool isBeingEditeed) override;
  145. ////
  146. protected:
  147. ConnectionComponent(const ConnectionComponent&) = delete;
  148. const ConnectionComponent& operator=(const ConnectionComponent&) = delete;
  149. void SetGroupTarget(AZ::EntityId groupTarget);
  150. void FinalizeMove();
  151. virtual void OnConnectionMoveStart();
  152. virtual bool OnConnectionMoveCancelled();
  153. virtual ConnectionMoveResult OnConnectionMoveComplete(const QPointF& scenePos, const QPoint& screenPos, AZ::EntityId groupTarget);
  154. virtual bool AllowNodeCreation() const;
  155. void CleanupToast();
  156. void StartMove();
  157. void StopMove();
  158. bool UpdateProposal(Endpoint& activePoint, const Endpoint& proposedEndpoint, AZStd::function< void(const AZ::EntityId&, const AZ::EntityId&)> endpointChangedFunctor);
  159. ConnectionCandidate FindConnectionCandidateAt(const QPointF& scenePos) const;
  160. void UpdateMovePosition(const QPointF& scenePos);
  161. void FinalizeMove(const QPointF& scenePos, const QPoint& screenPos, bool chainAddition);
  162. void DisplayConnectionToolTip(const QPointF& scenePos, const Endpoint& connectionTarget);
  163. ConnectionValidationTooltip m_validationResult;
  164. Endpoint m_endpointTooltip;
  165. AzToolsFramework::ToastId m_toastId;
  166. //! The Id of the graph this connection belongs to.
  167. GraphId m_graphId;
  168. //! The source endpoint that this connection is from.
  169. Endpoint m_sourceEndpoint;
  170. ConnectionEndpointAnimator m_sourceAnimator;
  171. //! The target endpoint that this connection is to.
  172. Endpoint m_targetEndpoint;
  173. ConnectionEndpointAnimator m_targetAnimator;
  174. //! Information needed to handle the dragging aspect of the connections
  175. QPointF m_mousePoint;
  176. DragContext m_dragContext;
  177. Endpoint m_previousEndPoint;
  178. AZStd::string m_tooltip;
  179. ConnectionEventFilter* m_eventFilter = nullptr;
  180. //! Store custom data for this connection
  181. AZStd::any m_userData;
  182. StateSetter<RootGraphicsItemDisplayState> m_nodeDisplayStateStateSetter;
  183. StateSetter<RootGraphicsItemDisplayState> m_connectionStateStateSetter;
  184. // Group Interactions
  185. AZ::EntityId m_groupTarget;
  186. StateSetter< RootGraphicsItemDisplayState > m_forcedGroupDisplayStateStateSetter;
  187. StateSetter< AZStd::string > m_forcedLayerStateSetter;
  188. };
  189. class ConnectionEventFilter
  190. : public SceneEventFilter
  191. {
  192. public:
  193. AZ_CLASS_ALLOCATOR(ConnectionEventFilter, AZ::SystemAllocator);
  194. ConnectionEventFilter(ConnectionComponent& connection)
  195. : SceneEventFilter(nullptr)
  196. , m_connection(connection)
  197. {
  198. }
  199. bool sceneEventFilter(QGraphicsItem*, QEvent* event) override
  200. {
  201. switch (event->type())
  202. {
  203. case QEvent::GraphicsSceneMouseMove:
  204. {
  205. QGraphicsSceneMouseEvent* mouseEvent = static_cast<QGraphicsSceneMouseEvent*>(event);
  206. m_connection.UpdateMovePosition(mouseEvent->scenePos());
  207. return true;
  208. }
  209. case QEvent::GraphicsSceneMouseRelease:
  210. {
  211. QGraphicsSceneMouseEvent* mouseEvent = static_cast<QGraphicsSceneMouseEvent*>(event);
  212. bool chainAddition = (mouseEvent->modifiers() & Qt::KeyboardModifier::ShiftModifier) != 0;
  213. m_connection.FinalizeMove(mouseEvent->scenePos(), mouseEvent->screenPos(), chainAddition);
  214. return true;
  215. }
  216. default:
  217. break;
  218. }
  219. return false;
  220. }
  221. private:
  222. ConnectionComponent& m_connection;
  223. };
  224. }