ViewportInteraction.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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. #if !defined(Q_MOC_RUN)
  10. #include "EditorCommon.h"
  11. #include <QObject>
  12. #include <AzCore/Math/Vector2.h>
  13. #include <AzCore/std/optional.h>
  14. #endif
  15. class EditorWindow;
  16. class Draw2dHelper;
  17. class QMouseEvent;
  18. class QKeyEvent;
  19. class QWheelEvent;
  20. class ViewportDragInteraction;
  21. class ViewportInteractionExpanderWatcher;
  22. class ViewportInteraction
  23. : public QObject
  24. {
  25. Q_OBJECT
  26. public: // types
  27. enum class NudgeDirection
  28. {
  29. Up,
  30. Down,
  31. Left,
  32. Right
  33. };
  34. enum class NudgeSpeed
  35. {
  36. Slow,
  37. Fast
  38. };
  39. struct TranslationAndScale
  40. {
  41. TranslationAndScale()
  42. : translation(0.0)
  43. , scale(1.0f) { }
  44. bool operator == (const TranslationAndScale& other) const
  45. {
  46. return translation == other.translation && scale == other.scale;
  47. }
  48. AZ::Vector3 translation;
  49. float scale;
  50. };
  51. public: // member functions
  52. ViewportInteraction(EditorWindow* editorWindow);
  53. virtual ~ViewportInteraction();
  54. bool GetLeftButtonIsActive();
  55. bool GetSpaceBarIsActive();
  56. void ActivateSpaceBar();
  57. void Draw(Draw2dHelper& draw2d,
  58. const QTreeWidgetItemRawPtrQList& selectedItems);
  59. void MousePressEvent(QMouseEvent* ev);
  60. void MouseMoveEvent(QMouseEvent* ev,
  61. const QTreeWidgetItemRawPtrQList& selectedItems);
  62. void MouseReleaseEvent(QMouseEvent* ev,
  63. const QTreeWidgetItemRawPtrQList& selectedItems);
  64. bool MouseWheelEvent(QWheelEvent* ev);
  65. bool KeyPressEvent(QKeyEvent* ev);
  66. bool KeyReleaseEvent(QKeyEvent* ev);
  67. //! Mode of interaction in the viewport
  68. //! This is driven by a toolbar.
  69. enum class InteractionMode
  70. {
  71. SELECTION,
  72. MOVE,
  73. ROTATE,
  74. RESIZE,
  75. ANCHOR
  76. };
  77. //! Type of coordinate system in the viewport
  78. enum class CoordinateSystem
  79. {
  80. LOCAL,
  81. VIEW
  82. };
  83. //! Type of interaction in the viewport
  84. //! This is driven by hovering and the left mouse button.
  85. enum class InteractionType
  86. {
  87. DIRECT, //!< The bounding box.
  88. TRANSFORM_GIZMO, //!< The base axes or circular manipulator.
  89. ANCHORS,
  90. PIVOT, //!< The dot.
  91. GUIDE,
  92. NONE
  93. };
  94. void SetMode(InteractionMode mode);
  95. InteractionMode GetMode() const;
  96. InteractionType GetInteractionType() const;
  97. AZ::Entity* GetActiveElement() const;
  98. const AZ::EntityId& GetActiveElementId() const;
  99. ViewportHelpers::SelectedAnchors GetGrabbedAnchors() const;
  100. void SetCoordinateSystem(CoordinateSystem s);
  101. CoordinateSystem GetCoordinateSystem() const;
  102. void InitializeToolbars();
  103. float GetCanvasToViewportScale() const { return m_canvasViewportMatrixProps.scale; }
  104. AZ::Vector3 GetCanvasToViewportTranslation() const { return m_canvasViewportMatrixProps.translation; }
  105. const TranslationAndScale& GetCanvasViewportMatrixProps();
  106. void SetCanvasViewportMatrixProps(const TranslationAndScale& canvasViewportMatrixProps);
  107. //! Centers the entirety of the canvas so that it's viewable within the viewport.
  108. //
  109. //! The scale of the canvas-to-viewport matrix is decreased (zoomed out) for
  110. //! canvases that are bigger than the viewport, and increased (zoomed in) for
  111. //! canvases that are smaller than the viewport. This scaled view of the canvas
  112. //! is then use to center the canvas within the viewport.
  113. //
  114. //! \param newCanvasSize Because of a one-frame delay in canvas size, if the canvas
  115. //! size was recently changed, and the caller knows the new canvas size, the size
  116. //! can be passed to this function to be immediately applied.
  117. void CenterCanvasInViewport(const AZ::Vector2* newCanvasSize = nullptr);
  118. //! "Zooms out" the view of the canvas in the viewport by an incremental amount
  119. void DecreaseCanvasToViewportScale();
  120. //! "Zooms in" the view of the canvas in the viewport by an incremental amount
  121. void IncreaseCanvasToViewportScale();
  122. //! Assigns a scale of 1.0 to the canvas-to-viewport matrix.
  123. void ResetCanvasToViewportScale();
  124. //! Sets the scale of the canvas-to-viewport matrix.
  125. void SetCanvasZoomPercent(float scale);
  126. //! Return whether the canvas should be scaled to fit when the viewport is resized
  127. bool ShouldScaleToFitOnViewportResize() const { return m_shouldScaleToFitOnViewportResize; }
  128. void UpdateZoomFactorLabel();
  129. //! Reset all transform interaction variables except the interaction mode
  130. void ClearInteraction(bool clearSpaceBarIsActive = true);
  131. //! Move the selected elements a certain number of pixels at a time
  132. void Nudge(NudgeDirection direction, NudgeSpeed speed);
  133. //! Start/stop object pick mode for assigning an entityId property
  134. void StartObjectPickMode();
  135. void StopObjectPickMode();
  136. private: // types
  137. private: // member functions
  138. //! Update the interaction type based on where the cursor is right now
  139. void UpdateInteractionType(const AZ::Vector2& mousePosition,
  140. const QTreeWidgetItemRawPtrQList& selectedItems);
  141. //! Update the cursor based on the current interaction
  142. void UpdateCursor();
  143. //! Update which element is being hovered over
  144. void UpdateHoverElement(const AZ::Vector2 mousePosition);
  145. //! Clear the hover element
  146. void InvalidateHoverElement();
  147. //! Set the string that is to be displayed near the cursor
  148. void SetCursorStr(const AZStd::string& cursorStr);
  149. //! Should be called when our translation and scale properties change for the canvas-to-viewport matrix.
  150. void UpdateCanvasToViewportMatrix();
  151. //! Assigns the given scale to the canvas-to-viewport matrix, clamped between 0.1 and 10.0.
  152. //
  153. //! Note that this method is private since ViewportInteraction matrix exclusively manages
  154. //! the viewport-to-canvas matrix.
  155. void SetCanvasToViewportScale(float newScale, const AZStd::optional<AZ::Vector2>& pivotPoint = AZStd::nullopt);
  156. //! Given a zoom scale quantize it to be a multiple of the zoom step
  157. float QuantizeZoomScale(float newScale);
  158. void GetScaleToFitTransformProps(const AZ::Vector2* newCanvasSize, TranslationAndScale& propsOut);
  159. //! Called when a pan or a zoom is performed.
  160. //! Updates flag that determines whether the canvas will scale to fit when the viewport resizes.
  161. void UpdateShouldScaleToFitOnResize();
  162. //! Process click and drag interaction
  163. void ProcessInteraction(const AZ::Vector2& mousePosition,
  164. Qt::KeyboardModifiers modifiers,
  165. const QTreeWidgetItemRawPtrQList& selectedItems);
  166. //! Draw a transform gizmo on the element
  167. void DrawAxisGizmo(Draw2dHelper& draw2d, const AZ::Entity* element, CoordinateSystem coordinateSystem, const ViewportIcon* lineTextureX, const ViewportIcon* lineTextureY);
  168. void DrawCircleGizmo(Draw2dHelper& draw2d, const AZ::Entity* element);
  169. // The coordinate system toolbar updates based on the interaction mode and coordinate system setting
  170. void UpdateCoordinateSystemToolbarSection();
  171. bool AreaSelectionIsActive();
  172. void BeginReversibleAction(const QTreeWidgetItemRawPtrQList& selectedItems);
  173. void EndReversibleAction();
  174. void PanOnMouseMoveEvent(const AZ::Vector2& mousePosition);
  175. const AZ::Uuid& InitAndGetTransformComponentType();
  176. private: // data
  177. EditorWindow* m_editorWindow;
  178. // The element that is being interacted with
  179. AZ::EntityId m_activeElementId;
  180. // Used for anchor picking
  181. std::unique_ptr< ViewportIcon > m_anchorWhole;
  182. // Used for pivot picking
  183. std::unique_ptr< ViewportIcon > m_pivotIcon;
  184. // Used for transform interaction
  185. InteractionMode m_interactionMode;
  186. InteractionType m_interactionType;
  187. CoordinateSystem m_coordinateSystem;
  188. bool m_spaceBarIsActive; //!< True when the spacebar is held down, false otherwise.
  189. bool m_leftButtonIsActive; //!< True when the left mouse button is down, false otherwise.
  190. bool m_middleButtonIsActive; //!< True when the middle mouse button is down, false otherwise.
  191. bool m_reversibleActionStarted;
  192. AZ::Vector2 m_startMouseDragPos;
  193. AZ::Vector2 m_lastMouseDragPos;
  194. LyShine::EntityArray m_selectedElementsAtSelectionStart;
  195. TranslationAndScale m_canvasViewportMatrixProps; //!< Stores translation and scale properties for canvasToViewport matrix.
  196. //!< Used for zoom and pan functionality.
  197. AZStd::string m_cursorStr;
  198. QCursor m_cursorRotate;
  199. ViewportInteraction::InteractionMode m_interactionModeBeforePickMode;
  200. AZ::EntityId m_hoverElement;
  201. bool m_entityPickedOnMousePress; // used to ignore mouse move/release events if element was picked on the mouse press
  202. bool m_shouldScaleToFitOnViewportResize;
  203. // Used to refresh the properties panel
  204. AZ::Uuid m_transformComponentType;
  205. ViewportHelpers::ElementEdges m_grabbedEdges;
  206. UiTransform2dInterface::Anchors m_startAnchors;
  207. ViewportHelpers::SelectedAnchors m_grabbedAnchors;
  208. ViewportHelpers::GizmoParts m_grabbedGizmoParts;
  209. // Used for drawing the transform gizmo
  210. std::unique_ptr<ViewportIcon> m_lineTriangleX;
  211. std::unique_ptr<ViewportIcon> m_lineTriangleY;
  212. std::unique_ptr<ViewportIcon> m_circle;
  213. std::unique_ptr<ViewportIcon> m_lineSquareX;
  214. std::unique_ptr<ViewportIcon> m_lineSquareY;
  215. std::unique_ptr<ViewportIcon> m_centerSquare;
  216. // Used for rubber band selection
  217. std::unique_ptr< ViewportIcon > m_dottedLine;
  218. ViewportDragInteraction* m_dragInteraction;
  219. ViewportInteractionExpanderWatcher* m_expanderWatcher;
  220. bool m_isAreaSelectionActive = false; //!< True while left mouse is held down for a drag select
  221. // Variables set when InteractionType is GUIDE
  222. bool m_activeGuideIsVertical = false;
  223. int m_activeGuideIndex = 0;
  224. SerializeHelpers::SerializedEntryList m_selectedEntitiesUndoState; //! This can be eliminated once the dragInteractions all use ViewportDragInteraction
  225. };
  226. ADD_ENUM_CLASS_ITERATION_OPERATORS(ViewportInteraction::InteractionMode,
  227. ViewportInteraction::InteractionMode::SELECTION,
  228. ViewportInteraction::InteractionMode::ANCHOR);
  229. ADD_ENUM_CLASS_ITERATION_OPERATORS(ViewportInteraction::CoordinateSystem,
  230. ViewportInteraction::CoordinateSystem::LOCAL,
  231. ViewportInteraction::CoordinateSystem::VIEW);