UiDraggableComponent.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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 <LyShine/Bus/UiDraggableBus.h>
  10. #include <LyShine/UiComponentTypes.h>
  11. #include "UiInteractableComponent.h"
  12. ////////////////////////////////////////////////////////////////////////////////////////////////////
  13. class UiDraggableComponent
  14. : public UiInteractableComponent
  15. , public UiDraggableBus::Handler
  16. {
  17. public: // types
  18. //! These are the visual states
  19. enum
  20. {
  21. StateDragNormal = UiInteractableStatesInterface::NumStates,
  22. StateDragValid,
  23. StateDragInvalid
  24. };
  25. public: // member functions
  26. AZ_COMPONENT(UiDraggableComponent, LyShine::UiDraggableComponentUuid, UiInteractableComponent);
  27. UiDraggableComponent();
  28. ~UiDraggableComponent() override;
  29. // UiInteractableInterface
  30. bool HandlePressed(AZ::Vector2 point, bool& shouldStayActive) override;
  31. bool HandleReleased(AZ::Vector2 point) override;
  32. bool HandleEnterPressed(bool& shouldStayActive) override;
  33. bool HandleKeyInputBegan(const AzFramework::InputChannel::Snapshot& inputSnapshot, AzFramework::ModifierKeyMask activeModifierKeys) override;
  34. void InputPositionUpdate(AZ::Vector2 point) override;
  35. bool DoesSupportDragHandOff(AZ::Vector2 startPoint) override;
  36. bool OfferDragHandOff(AZ::EntityId currentActiveInteractable, AZ::Vector2 startPoint, AZ::Vector2 currentPoint, float dragThreshold) override;
  37. void LostActiveStatus() override;
  38. // ~UiInteractableInterface
  39. // UiDraggableInterface
  40. DragState GetDragState() override;
  41. void SetDragState(DragState dragState) override;
  42. void RedoDrag(AZ::Vector2 point) override;
  43. void SetAsProxy(AZ::EntityId originalDraggableId, AZ::Vector2 point) override;
  44. void ProxyDragEnd(AZ::Vector2 point) override;
  45. bool IsProxy() override;
  46. AZ::EntityId GetOriginalFromProxy() override;
  47. bool GetCanDropOnAnyCanvas() override;
  48. void SetCanDropOnAnyCanvas(bool anyCanvas) override;
  49. // ~UiDraggableInterface
  50. protected: // member functions
  51. // AZ::Component
  52. void Activate() override;
  53. void Deactivate() override;
  54. // ~AZ::Component
  55. // UiInteractableInterface
  56. UiInteractableStatesInterface::State ComputeInteractableState() override;
  57. // ~UiInteractableInterface
  58. void OnDragNormalStateActionsChanged();
  59. void OnDragValidStateActionsChanged();
  60. void OnDragInvalidStateActionsChanged();
  61. protected: // static member functions
  62. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  63. {
  64. provided.push_back(AZ_CRC("UiInteractableService", 0x1d474c98));
  65. provided.push_back(AZ_CRC("UiNavigationService"));
  66. provided.push_back(AZ_CRC("UiStateActionsService"));
  67. }
  68. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  69. {
  70. incompatible.push_back(AZ_CRC("UiInteractableService", 0x1d474c98));
  71. incompatible.push_back(AZ_CRC("UiNavigationService"));
  72. incompatible.push_back(AZ_CRC("UiStateActionsService"));
  73. }
  74. static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  75. {
  76. required.push_back(AZ_CRC("UiElementService", 0x3dca7ad4));
  77. required.push_back(AZ_CRC("UiTransformService", 0x3a838e34));
  78. }
  79. static void Reflect(AZ::ReflectContext* context);
  80. private: // member functions
  81. AZ_DISABLE_COPY_MOVE(UiDraggableComponent);
  82. //! Look for an interactable drop target at the given point
  83. AZ::EntityId GetDropTargetUnderDraggable(AZ::Vector2 point, bool ignoreInteractables);
  84. //! Used to detect when we have started a drag
  85. bool CheckForDragOrHandOffToParent(AZ::EntityId currentActiveInteractable, AZ::Vector2 startPoint, AZ::Vector2 currentPoint, float childDragThreshold, bool& handOffDone);
  86. //! Common code for each frame of drag operation
  87. void DoDrag(AZ::Vector2 viewportPoint, bool ignoreInteractables);
  88. //! Common code for the end of a drag
  89. void EndDragOperation(AZ::Vector2 viewportPoint, bool ignoreInteractables);
  90. //! Find the drop target elements that we can navigate to
  91. void FindNavigableDropTargetElements(AZ::EntityId ignoreElement, LyShine::EntityArray& result);
  92. //! Find the closest drop target to the draggable (used for keyboard navigation)
  93. AZ::EntityId FindClosestNavigableDropTarget();
  94. private: // static member functions
  95. //! Perform a recursive search for a valid drop target in all canvases
  96. static AZ::EntityId FindDropTargetOrInteractableOnAllCanvases(
  97. AZ::Vector2 point, AZ::EntityId ignoreElement, bool ignoreInteractables);
  98. //! Perform a recursive search for a valid drop target in the given canvas
  99. static AZ::EntityId FindDropTargetOrInteractableOnCanvas(AZ::EntityId canvasEntityId,
  100. AZ::Vector2 point, AZ::EntityId ignoreElement, bool ignoreInteractables);
  101. //! Perform a recursive search for a valid drop target
  102. static AZ::EntityId FindDropTargetOrInteractableUnderCursor(AZ::EntityId element,
  103. AZ::Vector2 point, AZ::EntityId ignoreElement, bool ignoreInteractables);
  104. private: // persistent data
  105. //! Dragging state action properties - allow visual states to be defined
  106. StateActions m_dragNormalStateActions;
  107. StateActions m_dragValidStateActions;
  108. StateActions m_dragInvalidStateActions;
  109. private: // data
  110. //! True when a drag has started
  111. bool m_isDragging = false;
  112. //! True when interactable can be manipulated by key input
  113. bool m_isActive = false;
  114. //! This tracks the drop target that the draggable is hovering over (if any)
  115. AZ::EntityId m_hoverDropTarget;
  116. //! The drag state indicates the state that we want to communicate to the user about the drag
  117. DragState m_dragState = DragState::Normal;
  118. //! For a proxy draggable this stores the ID of the draggable that it is a proxy for
  119. AZ::EntityId m_isProxyFor;
  120. //! If true this draggable will search for drop targets on any canvas
  121. bool m_canDropOnAnyCanvas = false;
  122. };