SlotConnectionPin.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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. #include <QGraphicsItem>
  9. #include <QGraphicsLayoutItem>
  10. #include <QGraphicsLinearLayout>
  11. #include <QGraphicsSceneMouseEvent>
  12. #include <QPainter>
  13. #include <QPointF>
  14. #include <QGraphicsScene>
  15. #include <Components/Slots/SlotConnectionPin.h>
  16. #include <GraphCanvas/Components/SceneBus.h>
  17. #include <GraphCanvas/Components/Slots/SlotBus.h>
  18. #include <GraphCanvas/Editor/GraphCanvasProfiler.h>
  19. #include <GraphCanvas/Styling/definitions.h>
  20. namespace GraphCanvas
  21. {
  22. //////////////////////
  23. // SlotConnectionPin
  24. //////////////////////
  25. SlotConnectionPin::SlotConnectionPin(const AZ::EntityId& slotId)
  26. : m_slotId(slotId)
  27. , m_connectionType(ConnectionType::CT_Invalid)
  28. , m_trackClick(false)
  29. , m_deletionClick(false)
  30. {
  31. setFlags(ItemSendsScenePositionChanges);
  32. setZValue(1);
  33. setOwnedByLayout(true);
  34. }
  35. SlotConnectionPin::~SlotConnectionPin()
  36. {
  37. }
  38. void SlotConnectionPin::Activate()
  39. {
  40. SlotUIRequestBus::Handler::BusConnect(m_slotId);
  41. SlotNotificationBus::Handler::BusConnect(m_slotId);
  42. }
  43. void SlotConnectionPin::Deactivate()
  44. {
  45. SlotNotificationBus::Handler::BusDisconnect();
  46. SlotUIRequestBus::Handler::BusDisconnect();
  47. }
  48. void SlotConnectionPin::OnRegisteredToNode(const AZ::EntityId& nodeId)
  49. {
  50. StateController<RootGraphicsItemDisplayState>* stateController = nullptr;
  51. RootGraphicsItemRequestBus::EventResult(stateController, nodeId, &RootGraphicsItemRequests::GetDisplayStateStateController);
  52. m_nodeDisplayStateStateSetter.AddStateController(stateController);
  53. SlotRequestBus::EventResult(m_connectionType, GetEntityId(), &SlotRequests::GetConnectionType);
  54. }
  55. void SlotConnectionPin::RefreshStyle()
  56. {
  57. OnRefreshStyle();
  58. setCacheMode(QGraphicsItem::CacheMode::ItemCoordinateCache);
  59. }
  60. QPointF SlotConnectionPin::GetPinCenter() const
  61. {
  62. return mapToScene(boundingRect().center());
  63. }
  64. QPointF SlotConnectionPin::GetConnectionPoint() const
  65. {
  66. qreal padding = m_style.GetAttribute(Styling::Attribute::Padding, 2.0);
  67. QPointF localPoint = boundingRect().center();
  68. switch (m_connectionType)
  69. {
  70. case ConnectionType::CT_Input:
  71. localPoint.setX(boundingRect().left() + padding);
  72. break;
  73. case ConnectionType::CT_Output:
  74. localPoint.setX(boundingRect().right() - padding);
  75. break;
  76. default:
  77. break;
  78. }
  79. return mapToScene(localPoint);
  80. }
  81. QPointF SlotConnectionPin::GetJutDirection() const
  82. {
  83. switch (m_connectionType)
  84. {
  85. case ConnectionType::CT_Input:
  86. return QPointF(-1, 0);
  87. case ConnectionType::CT_Output:
  88. return QPointF(1, 0);
  89. default:
  90. return QPointF(0, 0);
  91. }
  92. }
  93. void SlotConnectionPin::OnSlotClicked()
  94. {
  95. }
  96. QRectF SlotConnectionPin::boundingRect() const
  97. {
  98. return{ {0, 0} , geometry().size() };
  99. }
  100. void SlotConnectionPin::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/ /*= nullptr*/)
  101. {
  102. GRAPH_CANVAS_DETAILED_PROFILE_FUNCTION();
  103. qreal decorationPadding = m_style.GetAttribute(Styling::Attribute::Padding, 2.);
  104. qreal borderWidth = m_style.GetBorder().widthF();
  105. painter->setBrush(m_style.GetBrush(Styling::Attribute::BackgroundColor));
  106. // determine rect for drawing shape
  107. qreal margin = decorationPadding + (borderWidth * 0.5);
  108. QRectF drawRect = boundingRect().marginsRemoved({ margin, margin, margin, margin });
  109. bool hasConnections = false;
  110. SlotRequestBus::EventResult(hasConnections, GetEntityId(), &SlotRequests::HasConnections);
  111. DrawConnectionPin(painter, drawRect, hasConnections);
  112. }
  113. void SlotConnectionPin::keyPressEvent(QKeyEvent* keyEvent)
  114. {
  115. SlotLayoutItem::keyPressEvent(keyEvent);
  116. if (m_hovered)
  117. {
  118. if (keyEvent->key() == Qt::Key::Key_Alt)
  119. {
  120. SlotRequestBus::Event(m_slotId, &SlotRequests::SetConnectionDisplayState, RootGraphicsItemDisplayState::Deletion);
  121. }
  122. }
  123. }
  124. void SlotConnectionPin::keyReleaseEvent(QKeyEvent* keyEvent)
  125. {
  126. SlotLayoutItem::keyReleaseEvent(keyEvent);
  127. if (m_hovered)
  128. {
  129. if (keyEvent->key() == Qt::Key::Key_Alt)
  130. {
  131. SlotRequestBus::Event(m_slotId, &SlotRequests::SetConnectionDisplayState, RootGraphicsItemDisplayState::Inspection);
  132. }
  133. }
  134. }
  135. void SlotConnectionPin::hoverEnterEvent(QGraphicsSceneHoverEvent* hoverEvent)
  136. {
  137. OnMouseEnter(hoverEvent->modifiers() & Qt::KeyboardModifier::AltModifier);
  138. }
  139. void SlotConnectionPin::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*hoverEvent*/)
  140. {
  141. OnMouseLeave();
  142. }
  143. void SlotConnectionPin::OnMouseEnter(bool hasAltModifier)
  144. {
  145. m_hovered = true;
  146. if (hasAltModifier)
  147. {
  148. SlotRequestBus::Event(m_slotId, &SlotRequests::SetConnectionDisplayState, RootGraphicsItemDisplayState::Deletion);
  149. }
  150. else
  151. {
  152. SlotRequestBus::Event(m_slotId, &SlotRequests::SetConnectionDisplayState, RootGraphicsItemDisplayState::Inspection);
  153. }
  154. m_nodeDisplayStateStateSetter.SetState(RootGraphicsItemDisplayState::Inspection);
  155. }
  156. void SlotConnectionPin::OnMouseLeave()
  157. {
  158. m_nodeDisplayStateStateSetter.ReleaseState();
  159. m_hovered = false;
  160. AZ::EntityId nodeId;
  161. SlotRequestBus::EventResult(nodeId, m_slotId, &SlotRequests::GetNode);
  162. SlotRequestBus::Event(m_slotId, &SlotRequests::ReleaseConnectionDisplayState);
  163. }
  164. void SlotConnectionPin::mousePressEvent(QGraphicsSceneMouseEvent* event)
  165. {
  166. if (event->button() == Qt::LeftButton && boundingRect().contains(event->pos()))
  167. {
  168. m_trackClick = true;
  169. if (event->modifiers() & Qt::KeyboardModifier::AltModifier)
  170. {
  171. SlotRequestBus::Event(m_slotId, &SlotRequests::ClearConnections);
  172. m_deletionClick = true;
  173. }
  174. return;
  175. }
  176. SlotLayoutItem::mousePressEvent(event);
  177. }
  178. void SlotConnectionPin::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
  179. {
  180. if (m_trackClick)
  181. {
  182. if (!m_deletionClick)
  183. {
  184. OnSlotClicked();
  185. }
  186. }
  187. m_deletionClick = false;
  188. m_trackClick = false;
  189. SlotLayoutItem::mouseReleaseEvent(event);
  190. }
  191. void SlotConnectionPin::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
  192. {
  193. if (m_trackClick)
  194. {
  195. if (!sceneBoundingRect().contains(event->scenePos()))
  196. {
  197. if (!m_deletionClick)
  198. {
  199. m_trackClick = false;
  200. HandleNewConnection();
  201. }
  202. else
  203. {
  204. m_trackClick = false;
  205. m_deletionClick = false;
  206. OnMouseLeave();
  207. }
  208. }
  209. }
  210. SlotLayoutItem::mouseMoveEvent(event);
  211. }
  212. void SlotConnectionPin::setGeometry(const QRectF& rect)
  213. {
  214. prepareGeometryChange();
  215. QGraphicsLayoutItem::setGeometry(rect);
  216. setPos(rect.topLeft());
  217. updateGeometry();
  218. }
  219. QSizeF SlotConnectionPin::sizeHint(Qt::SizeHint which, const QSizeF& /*constraint*/) const
  220. {
  221. const qreal decorationPadding = m_style.GetAttribute(Styling::Attribute::Padding, 2.);
  222. QSizeF rectSize = m_style.GetSize({ 8., 8. }) + QSizeF{ decorationPadding, decorationPadding } * 2.;
  223. switch (which)
  224. {
  225. case Qt::MinimumSize:
  226. return m_style.GetMinimumSize(rectSize);
  227. case Qt::PreferredSize:
  228. return rectSize;
  229. case Qt::MaximumSize:
  230. return m_style.GetMaximumSize();
  231. case Qt::MinimumDescent:
  232. default:
  233. return QSizeF();
  234. }
  235. }
  236. void SlotConnectionPin::HandleNewConnection()
  237. {
  238. m_nodeDisplayStateStateSetter.ReleaseState();
  239. AZ::EntityId nodeId;
  240. SlotRequestBus::EventResult(nodeId, m_slotId, &SlotRequests::GetNode);
  241. AZ::EntityId sceneId;
  242. SceneMemberRequestBus::EventResult(sceneId, nodeId, &SceneMemberRequests::GetScene);
  243. SceneRequestBus::Event(sceneId, &SceneRequestBus::Events::ClearSelection);
  244. SlotRequestBus::Event(m_slotId, &SlotRequests::DisplayConnection);
  245. OnMouseLeave();
  246. }
  247. void SlotConnectionPin::DrawConnectionPin(QPainter* painter, QRectF drawRect, bool isConnected)
  248. {
  249. painter->setPen(m_style.GetBorder());
  250. if (isConnected)
  251. {
  252. painter->fillRect(drawRect, Qt::BrushStyle::SolidPattern);
  253. }
  254. else
  255. {
  256. painter->drawRect(drawRect);
  257. }
  258. }
  259. void SlotConnectionPin::OnRefreshStyle()
  260. {
  261. m_style.SetStyle(m_slotId, Styling::Elements::ConnectionPin);
  262. }
  263. }