UiCanvasComponent.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  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/Component/Component.h>
  10. #include <AzCore/Component/EntityBus.h>
  11. #include <AzCore/RTTI/TypeInfo.h>
  12. #include <LyShine/Bus/UiCanvasBus.h>
  13. #include <LyShine/Bus/UiInteractableBus.h>
  14. #include <LyShine/Bus/UiAnimationBus.h>
  15. #include <LyShine/Bus/UiEditorCanvasBus.h>
  16. #include <LyShine/UiEntityContext.h>
  17. #include <LyShine/UiComponentTypes.h>
  18. #include "UiElementComponent.h"
  19. #include "UiSerialize.h"
  20. #include "Animation/UiAnimationSystem.h"
  21. #include "UiLayoutManager.h"
  22. #include "UiNavigationHelpers.h"
  23. #include "RenderGraph.h"
  24. #ifndef _RELEASE
  25. #include "LyShineDebug.h"
  26. #endif
  27. #include "TextureAtlas/TextureAtlas.h"
  28. #include "TextureAtlas/TextureAtlasBus.h"
  29. #include "TextureAtlas/TextureAtlasNotificationBus.h"
  30. #include "RenderToTextureBus.h"
  31. namespace AZ
  32. {
  33. class SerializeContext;
  34. }
  35. struct SDepthTexture;
  36. class CDraw2d;
  37. ////////////////////////////////////////////////////////////////////////////////////////////////////
  38. class UiCanvasComponent
  39. : public AZ::Component
  40. , public UiCanvasBus::Handler
  41. , public AZ::EntityBus::Handler
  42. , public UiAnimationBus::Handler
  43. , public UiInteractableActiveNotificationBus::Handler
  44. , public IUiAnimationListener
  45. , public UiEditorCanvasBus::Handler
  46. , public UiCanvasComponentImplementationBus::Handler
  47. , public LyShine::RenderToTextureRequestBus::Handler
  48. {
  49. public: // constants
  50. static const AZ::Vector2 s_defaultCanvasSize;
  51. static const AZ::Color s_defaultGuideColor;
  52. public: // member functions
  53. AZ_COMPONENT(UiCanvasComponent, LyShine::UiCanvasComponentUuid, AZ::Component);
  54. //! Constructor, constructed by the LyShine class
  55. UiCanvasComponent();
  56. ~UiCanvasComponent() override;
  57. // UiCanvasInterface
  58. const AZStd::string& GetPathname() override;
  59. LyShine::CanvasId GetCanvasId() override;
  60. AZ::u64 GetUniqueCanvasId() override;
  61. int GetDrawOrder() override;
  62. void SetDrawOrder(int drawOrder) override;
  63. bool GetKeepLoadedOnLevelUnload() override;
  64. void SetKeepLoadedOnLevelUnload(bool keepLoaded) override;
  65. void RecomputeChangedLayouts() override;
  66. int GetNumChildElements() override;
  67. AZ::Entity* GetChildElement(int index) override;
  68. AZ::EntityId GetChildElementEntityId(int index) override;
  69. LyShine::EntityArray GetChildElements() override;
  70. AZStd::vector<AZ::EntityId> GetChildElementEntityIds() override;
  71. AZ::Entity* CreateChildElement(const LyShine::NameType& name) override;
  72. AZ::Entity* FindElementById(LyShine::ElementId id) override;
  73. AZ::Entity* FindElementByName(const LyShine::NameType& name) override;
  74. void FindElementsByName(const LyShine::NameType& name, LyShine::EntityArray& result) override;
  75. AZ::EntityId FindElementEntityIdByName(const LyShine::NameType& name) override;
  76. AZ::Entity* FindElementByHierarchicalName(const LyShine::NameType& name) override;
  77. void FindElements(AZStd::function<bool(const AZ::Entity*)> predicate, LyShine::EntityArray& result) override;
  78. AZ::Entity* PickElement(AZ::Vector2 point) override;
  79. LyShine::EntityArray PickElements(const AZ::Vector2& bound0, const AZ::Vector2& bound1) override;
  80. AZ::EntityId FindInteractableToHandleEvent(AZ::Vector2 point) override;
  81. bool SaveToXml(const AZStd::string& assetIdPathname, const AZStd::string& sourceAssetPathname) override;
  82. void FixupCreatedEntities(LyShine::EntityArray topLevelEntities, bool makeUniqueNamesAndIds, AZ::Entity* optionalInsertionPoint) override;
  83. void AddElement(AZ::Entity* element, AZ::Entity* parent, AZ::Entity* insertBefore) override;
  84. void ReinitializeElements() override;
  85. AZStd::string SaveToXmlString() override;
  86. AZStd::string GetUniqueChildName(AZ::EntityId parentEntityId, AZStd::string baseName, const LyShine::EntityArray* includeChildren) override;
  87. AZ::Entity* CloneElement(AZ::Entity* sourceEntity, AZ::Entity* parentEntity) override;
  88. AZ::EntityId CloneElementEntityId(AZ::EntityId sourceEntity, AZ::EntityId parentEntity, AZ::EntityId insertBefore) override;
  89. AZ::Entity* CloneCanvas(const AZ::Vector2& canvasSize) override;
  90. void SetCanvasToViewportMatrix(const AZ::Matrix4x4& matrix) override;
  91. const AZ::Matrix4x4& GetCanvasToViewportMatrix() override;
  92. void GetViewportToCanvasMatrix(AZ::Matrix4x4& matrix) override;
  93. AZ::Vector2 GetCanvasSize() override;
  94. AZ::Vector2 GetAuthoredCanvasSize() override;
  95. void SetCanvasSize(const AZ::Vector2& canvasSize) override;
  96. void SetTargetCanvasSize(bool isInGame, const AZ::Vector2& targetCanvasSize) override;
  97. AZ::Vector2 GetDeviceScale() override;
  98. bool GetIsPixelAligned() override;
  99. void SetIsPixelAligned(bool isPixelAligned) override;
  100. bool GetIsTextPixelAligned() override;
  101. void SetIsTextPixelAligned(bool isTextPixelAligned) override;
  102. IUiAnimationSystem* GetAnimationSystem() override;
  103. bool GetEnabled() override;
  104. void SetEnabled(bool enabled) override;
  105. bool GetIsRenderToTexture() override;
  106. void SetIsRenderToTexture(bool isRenderToTexture) override;
  107. const AZ::Data::Asset<AZ::RPI::AttachmentImageAsset>& GetAttachmentImageAsset() override;
  108. void SetAttachmentImageAsset(const AZ::Data::Asset<AZ::RPI::AttachmentImageAsset>& attachmentImageAsset) override;
  109. bool GetIsPositionalInputSupported() override;
  110. void SetIsPositionalInputSupported(bool isSupported) override;
  111. bool GetIsConsumingAllInputEvents() override;
  112. void SetIsConsumingAllInputEvents(bool isConsuming) override;
  113. bool GetIsMultiTouchSupported() override;
  114. void SetIsMultiTouchSupported(bool isSupported) override;
  115. bool GetIsNavigationSupported() override;
  116. void SetIsNavigationSupported(bool isSupported) override;
  117. float GetNavigationThreshold() override;
  118. void SetNavigationThreshold(float navigationThreshold) override;
  119. AZ::u64 GetNavigationRepeatDelay() override;
  120. void SetNavigationRepeatDelay(AZ::u64 navigationRepeatDelay) override;
  121. AZ::u64 GetNavigationRepeatPeriod() override;
  122. void SetNavigationRepeatPeriod(AZ::u64 navigationRepeatPeriod) override;
  123. AzFramework::LocalUserId GetLocalUserIdInputFilter() override;
  124. void SetLocalUserIdInputFilter(AzFramework::LocalUserId localUserId) override;
  125. bool HandleInputEvent(const AzFramework::InputChannel::Snapshot& inputSnapshot,
  126. const AZ::Vector2* viewportPos = nullptr,
  127. AzFramework::ModifierKeyMask activeModifierKeys = AzFramework::ModifierKeyMask::None) override;
  128. bool HandleTextEvent(const AZStd::string& textUTF8) override;
  129. bool HandleInputPositionalEvent(const AzFramework::InputChannel::Snapshot& inputSnapshot, AZ::Vector2 viewportPos) override;
  130. AZ::Vector2 GetMousePosition() override;
  131. AZ::EntityId GetTooltipDisplayElement() override;
  132. void SetTooltipDisplayElement(AZ::EntityId entityId) override;
  133. void ForceFocusInteractable(AZ::EntityId interactableId) override;
  134. void ForceActiveInteractable(AZ::EntityId interactableId, bool shouldStayActive, AZ::Vector2 point) override;
  135. AZ::EntityId GetHoverInteractable() override;
  136. void ForceHoverInteractable(AZ::EntityId interactableId) override;
  137. void ClearAllInteractables() override;
  138. void ForceEnterInputEventOnInteractable(AZ::EntityId interactableId) override;
  139. // ~UiCanvasInterface
  140. // EntityEvents
  141. void OnEntityDeactivated(const AZ::EntityId& entityId) override;
  142. // ~EntityEvents
  143. // UiAnimationInterface
  144. void StartSequence(const AZStd::string& sequenceName) override;
  145. void PlaySequenceRange(const AZStd::string& sequenceName, float startTime, float endTime) override;
  146. void StopSequence(const AZStd::string& sequenceName) override;
  147. void AbortSequence(const AZStd::string& sequenceName) override;
  148. void PauseSequence(const AZStd::string& sequenceName) override;
  149. void ResumeSequence(const AZStd::string& sequenceName) override;
  150. void ResetSequence(const AZStd::string& sequenceName) override;
  151. float GetSequencePlayingSpeed(const AZStd::string& sequenceName) override;
  152. void SetSequencePlayingSpeed(const AZStd::string& sequenceName, float speed) override;
  153. float GetSequencePlayingTime(const AZStd::string& sequenceName) override;
  154. bool IsSequencePlaying(const AZStd::string& sequenceName) override;
  155. float GetSequenceLength(const AZStd::string& sequenceName) override;
  156. void SetSequenceStopBehavior(IUiAnimationSystem::ESequenceStopBehavior stopBehavior) override;
  157. // ~UiAnimationInterface
  158. // UiInteractableActiveNotifications
  159. void ActiveCancelled() override;
  160. void ActiveChanged(AZ::EntityId m_newActiveInteractable, bool shouldStayActive) override;
  161. // ~UiInteractableActiveNotifications
  162. // IUiAnimationListener
  163. void OnUiAnimationEvent(EUiAnimationEvent uiAnimationEvent, IUiAnimSequence* pAnimSequence) override;
  164. void OnUiTrackEvent(AZStd::string eventName, AZStd::string valueName, IUiAnimSequence* pAnimSequence) override;
  165. // ~IUiAnimationListener
  166. // UiEditorCanvasInterface
  167. bool GetIsSnapEnabled() override;
  168. void SetIsSnapEnabled(bool enabled) override;
  169. float GetSnapDistance() override;
  170. void SetSnapDistance(float distance) override;
  171. float GetSnapRotationDegrees() override;
  172. void SetSnapRotationDegrees(float degrees) override;
  173. AZStd::vector<float> GetHorizontalGuidePositions() override;
  174. void AddHorizontalGuide(float position) override;
  175. void RemoveHorizontalGuide(int index) override;
  176. void SetHorizontalGuidePosition(int index, float position) override;
  177. AZStd::vector<float> GetVerticalGuidePositions() override;
  178. void AddVerticalGuide(float position) override;
  179. void RemoveVerticalGuide(int index) override;
  180. void SetVerticalGuidePosition(int index, float position) override;
  181. void RemoveAllGuides() override;
  182. AZ::Color GetGuideColor() override;
  183. void SetGuideColor(const AZ::Color& color) override;
  184. bool GetGuidesAreLocked() override;
  185. void SetGuidesAreLocked(bool areLocked) override;
  186. bool CheckForOrphanedElements() override;
  187. void RecoverOrphanedElements() override;
  188. void RemoveOrphanedElements() override;
  189. void UpdateCanvasInEditorViewport(float deltaTime, bool isInGame) override;
  190. void RenderCanvasInEditorViewport(bool isInGame, AZ::Vector2 viewportSize) override;
  191. // ~UiEditorCanvasInterface
  192. // UiCanvasComponentImplementationInterface
  193. void MarkRenderGraphDirty() override;
  194. // ~UiCanvasComponentImplementationInterface
  195. // LyShine::RenderToTextureRequestBus overrides ...
  196. AZ::RHI::AttachmentId UseRenderTarget(const AZ::Name& renderTargetName, AZ::RHI::Size size) override;
  197. AZ::RHI::AttachmentId UseRenderTargetAsset(const AZ::Data::Asset<AZ::RPI::AttachmentImageAsset>& attachmentImageAsset) override;
  198. void ReleaseRenderTarget(const AZ::RHI::AttachmentId& attachmentId) override;
  199. AZ::Data::Instance<AZ::RPI::AttachmentImage> GetRenderTarget(const AZ::RHI::AttachmentId& attachmentId) override;
  200. void UpdateCanvas(float deltaTime, bool isInGame);
  201. void RenderCanvas(bool isInGame, AZ::Vector2 viewportSize, UiRenderer* uiRenderer = nullptr);
  202. AZ::Entity* GetRootElement() const;
  203. LyShine::ElementId GenerateId();
  204. //! Clone this canvas's entity and return the Canvas component
  205. //! (used when it is loaded from in game or for preview mode etc)
  206. UiCanvasComponent* CloneAndInitializeCanvas(UiEntityContext* entityContext, const AZStd::string& assetIdPathname, const AZ::Vector2* canvasSize = nullptr);
  207. //! Deactivate all elements. Used when queuing a canvas up for deletion
  208. void DeactivateElements();
  209. AZ::Vector2 GetTargetCanvasSize();
  210. //! Get the mapping from editor EntityId to game EntityId. This will be empty for canvases loaded for editing
  211. AZ::SliceComponent::EntityIdToEntityIdMap GetEditorToGameEntityIdMap() { return m_editorToGameEntityIdMap; }
  212. void ScheduleElementForTransformRecompute(UiElementComponent* elementComponent);
  213. void UnscheduleElementForTransformRecompute(UiElementComponent* elementComponent);
  214. //! Queue an element to be destroyed at end of frame
  215. void ScheduleElementDestroy(AZ::EntityId entityId);
  216. bool IsRenderGraphDirty() { return m_renderGraph.GetDirtyFlag(); }
  217. void GetRenderTargets(LyShine::AttachmentImagesAndDependencies& attachmentImagesAndDependencies);
  218. #ifndef _RELEASE
  219. struct DebugInfoNumElements
  220. {
  221. int m_numElements;
  222. int m_numEnabledElements;
  223. int m_numRenderElements;
  224. int m_numRenderControlElements;
  225. int m_numImageElements;
  226. int m_numTextElements;
  227. int m_numMaskElements;
  228. int m_numFaderElements;
  229. int m_numInteractableElements;
  230. int m_numUpdateElements;
  231. };
  232. void GetDebugInfoInteractables(AZ::EntityId& activeInteractable, AZ::EntityId& hoverInteractable) const;
  233. void GetDebugInfoNumElements(DebugInfoNumElements& info) const;
  234. void GetDebugInfoRenderGraph(LyShineDebug::DebugInfoRenderGraph& info) const;
  235. void DebugInfoCountChildren(const AZ::EntityId entity, bool parentEnabled, DebugInfoNumElements& info) const;
  236. void DebugReportDrawCalls(AZ::IO::HandleType fileHandle, LyShineDebug::DebugInfoDrawCallReport& reportInfo, void* context) const;
  237. void DebugDisplayElemBounds(IDraw2d* draw2d) const;
  238. void DebugDisplayChildElemBounds(IDraw2d* draw2d, const AZ::EntityId entity) const;
  239. #endif
  240. public: // static member functions
  241. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  242. {
  243. provided.push_back(AZ_CRC("UiCanvasService", 0x2c8e8f87));
  244. }
  245. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  246. {
  247. incompatible.push_back(AZ_CRC("UiCanvasService", 0x2c8e8f87));
  248. }
  249. static void GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
  250. {
  251. }
  252. static void Reflect(AZ::ReflectContext* context);
  253. // TODO: Move these static functions into a CanvasManager class
  254. static void Initialize();
  255. static void Shutdown();
  256. static UiCanvasComponent* CreateCanvasInternal(UiEntityContext* entityContext, bool forEditor);
  257. static UiCanvasComponent* LoadCanvasInternal(const AZStd::string& pathToOpen, bool forEditor, const AZStd::string& assetIdPathname, UiEntityContext* entityContext,
  258. const AZ::SliceComponent::EntityIdToEntityIdMap* previousRemapTable = nullptr, AZ::EntityId previousCanvasId = AZ::EntityId());
  259. static UiCanvasComponent* FixupReloadedCanvasForEditorInternal(AZ::Entity* newCanvasEntity,
  260. AZ::Entity* rootSliceEntity, UiEntityContext* entityContext,
  261. LyShine::CanvasId existingId, const AZStd::string& existingPathname);
  262. protected: // member functions
  263. // AZ::Component
  264. void Init() override;
  265. void Activate() override;
  266. void Deactivate() override;
  267. // ~AZ::Component
  268. private: // member functions
  269. AZ_DISABLE_COPY_MOVE(UiCanvasComponent);
  270. // Texture Atlas loading
  271. void LoadAtlases();
  272. void UnloadAtlases();
  273. void ReloadAtlases();
  274. // handle events for this canvas
  275. bool HandleHoverInputEvent(AZ::Vector2 point);
  276. bool HandleKeyInputEvent(const AzFramework::InputChannel::Snapshot& inputSnapshot, AzFramework::ModifierKeyMask activeModifierKeys = AzFramework::ModifierKeyMask::None);
  277. bool HandleNavigationInputEvent(UiNavigationHelpers::Command command, const AzFramework::InputChannel::Snapshot& inputSnapshot);
  278. bool HandleEnterInputEvent(UiNavigationHelpers::Command command, const AzFramework::InputChannel::Snapshot& inputSnapshot);
  279. bool HandleBackInputEvent(UiNavigationHelpers::Command command, const AzFramework::InputChannel::Snapshot& inputSnapshot);
  280. // A key was pressed to deactivate the active interactable
  281. bool DeactivateInteractableByKeyInput(const AzFramework::InputChannel::Snapshot& inputSnapshot);
  282. // A key was pressed to transfer hover to the ancestor interactable
  283. bool PassHoverToAncestorByKeyInput(const AzFramework::InputChannel::Snapshot& inputSnapshot);
  284. // Code shared by all positional input events
  285. bool HandlePrimaryPress(AZ::Vector2 point);
  286. bool HandlePrimaryUpdate(AZ::Vector2 point);
  287. bool HandlePrimaryRelease(AZ::Vector2 point);
  288. bool HandleMultiTouchPress(AZ::Vector2 point, int multiTouchIndex);
  289. bool HandleMultiTouchRelease(AZ::Vector2 point, int multiTouchIndex);
  290. bool HandleMultiTouchUpdated(AZ::Vector2 point, int multiTouchIndex);
  291. bool IsInteractableActiveOrPressed(AZ::EntityId interactableId) const;
  292. // Functions to change the hover and active interactables
  293. void SetHoverInteractable(AZ::EntityId interactableId);
  294. void ClearHoverInteractable();
  295. void SetActiveInteractable(AZ::EntityId newActiveInteractable, bool shouldStayActive);
  296. void ClearActiveInteractable();
  297. //! Check if the hover interactable is set to auto-activate, and if so activate it
  298. void CheckHoverInteractableAndAutoActivate(AZ::EntityId prevHoverInteractable = AZ::EntityId(), UiNavigationHelpers::Command command = UiNavigationHelpers::Command::Unknown, bool forceAutoActivate = false);
  299. //! Check if the active interactable has a descendant interactable. If it does,
  300. //! make the descendant the hover interactable and clear the active interactable
  301. void CheckActiveInteractableAndPassHoverToDescendant(AZ::EntityId prevHoverInteractable = AZ::EntityId(), UiNavigationHelpers::Command command = UiNavigationHelpers::Command::Unknown);
  302. //! Find the first interactable ancestor of the specified element
  303. AZ::EntityId FindAncestorInteractable(AZ::EntityId entityId);
  304. //! Get the first hover interactable, defaulting to the one set by the canvas
  305. AZ::EntityId GetFirstHoverInteractable();
  306. //! Find the first interactable to receive focus
  307. AZ::EntityId FindFirstHoverInteractable(AZ::EntityId parentElement = AZ::EntityId());
  308. //! Set the hover interactable on canvas load
  309. void SetFirstHoverInteractable();
  310. //! Due to differences in their serialization systems we need to do some work before save
  311. void PrepareAnimationSystemForCanvasSave();
  312. //! Due to differences in their serialization systems we need to do some work after load
  313. void RestoreAnimationSystemAfterCanvasLoad(bool remapIds, UiElementComponent::EntityIdMap* entityIdMap);
  314. //! Get a list of entity IDs for this element and all its descendant elements
  315. AZStd::vector<AZ::EntityId> GetEntityIdsOfElementAndDescendants(AZ::Entity* entity);
  316. //! Calculate the target canvas size and uniform scale
  317. void SetTargetCanvasSizeAndUniformScale(bool isInGame, AZ::Vector2 canvasSize);
  318. //! Check if an element name is unique
  319. bool IsElementNameUnique(const AZStd::string& elementName, const LyShine::EntityArray& elements);
  320. //! Methods used for controlling the Edit Context (the properties pane)
  321. using EntityComboBoxVec = AZStd::vector< AZStd::pair< AZ::EntityId, AZStd::string > >;
  322. EntityComboBoxVec PopulateNavigableEntityList();
  323. EntityComboBoxVec PopulateTooltipDisplayEntityList();
  324. void OnPixelAlignmentChange();
  325. void OnTextPixelAlignmentChange();
  326. void CreateRenderTarget();
  327. void DestroyRenderTarget();
  328. bool SaveCanvasToFile(const AZStd::string& pathname, AZ::DataStream::StreamType streamType);
  329. bool SaveCanvasToStream(AZ::IO::GenericStream& stream, AZ::DataStream::StreamType streamType);
  330. //! Notify elements that their canvas space rect has changed since the last update, and recompute invalid layouts
  331. void SendRectChangeNotificationsAndRecomputeLayouts();
  332. //! Notify elements that their canvas space rect has changed since the last update
  333. void SendRectChangeNotifications();
  334. //! Compute the layout for all elements. Parents are computed first, then children.
  335. //! Called on canvas initialization
  336. void InitializeLayouts();
  337. //! Call InGamePostActivate on children first, then parent
  338. void InGamePostActivateBottomUp(AZ::Entity* entity);
  339. //! Internal function for cloning an element
  340. AZ::Entity* CloneAndAddElementInternal(AZ::Entity* sourceEntity, AZ::Entity* parentEntity, AZ::Entity* insertBeforeEntity);
  341. //! Get any orphaned elements caused by old bugs
  342. void GetOrphanedElements(AZ::SliceComponent::EntityList& orphanedEntities);
  343. void DestroyScheduledElements();
  344. //! Notify LyShine pass that it needs to rebuild its Rtt child passes
  345. void QueueRttPassRebuild();
  346. private: // static member functions
  347. static AZ::u64 CreateUniqueId();
  348. static UiCanvasComponent* FixupPostLoad(AZ::Entity* canvasEntity, AZ::Entity* rootSliceEntity, bool forEditor, UiEntityContext* entityContext,
  349. const AZ::Vector2* canvasSize = nullptr, const AZ::SliceComponent::EntityIdToEntityIdMap* previousRemapTable = nullptr, AZ::EntityId previousCanvasId = AZ::EntityId());
  350. static bool VersionConverter(AZ::SerializeContext& context,
  351. AZ::SerializeContext::DataElementNode& classElement);
  352. private: // types
  353. typedef std::vector<UiCanvasComponent*> CanvasList; //!< Sorted by draw order
  354. private: // data
  355. AZStd::string m_pathname; //! This is an asset ID pathname
  356. AZ::u64 m_uniqueId;
  357. AZ::EntityId m_rootElement;
  358. LyShine::ElementId m_lastElementId;
  359. bool m_isPixelAligned = true; //! if true all visual elements have their vertices snapped to the nearest pixel
  360. bool m_isTextPixelAligned = true; //! if true all text is snapped to the nearest pixel
  361. AZ::EntityId m_firstHoverInteractable;
  362. bool m_isPositionalInputSupported = true;
  363. bool m_isConsumingAllInputEvents = false;
  364. bool m_isMultiTouchSupported = true;
  365. bool m_isNavigationSupported = true;
  366. float m_navigationThreshold = 0.4f;
  367. AZ::u64 m_navigationRepeatDelay = 300;
  368. AZ::u64 m_navigationRepeatPeriod = 150;
  369. AzFramework::LocalUserId m_localUserIdInputFilter = AzFramework::LocalUserIdAny;
  370. AZ::EntityId m_tooltipDisplayElement;
  371. AZ::Matrix4x4 m_canvasToViewportMatrix;
  372. AZ::Matrix4x4 m_viewportToCanvasMatrix;
  373. AZStd::vector <AzFramework::SimpleAssetReference<TextureAtlasNamespace::TextureAtlasAsset>> m_atlasPathNames; //! This is a list of filepaths for TextureAtlases
  374. AZStd::vector<TextureAtlasNamespace::TextureAtlas*> m_atlases;
  375. // In the comments below an "interactable entity" is an entity that is connected to the
  376. // UiInteractableBus
  377. //! The hover interactable is the interactable entity that the mouse cursor is currently over
  378. //! (or is selected by keyboard/controller navigation). The canvas tracks it so that it can tell
  379. //! the hover interactable that it is no longer in hover state when the cursor moves outside its bounds
  380. AZ::EntityId m_hoverInteractable;
  381. //! The active interactable is the interactable entity that the canvas considers "active".
  382. //! The active interactable is initially the interactable that handled the pressed event.
  383. //! An interactable can request to be stay active after the released event by returning
  384. //! "shouldStayActive" from HandlePressed. In this case the active interactable remains
  385. //! the active interactable until another interactable becomes active
  386. //! or until the active interactable itself requests to cancel its active status.
  387. //! If there is an active interactable when a released event is received then it
  388. //! is sent to the active interactable.
  389. //! The active interactable gets sent the mouse/touch position each frame (to support drag).
  390. //! The active interactable gets sent any character input received by the canvas.
  391. AZ::EntityId m_activeInteractable;
  392. //! If this is true the active interactable stays active after the release event
  393. bool m_activeInteractableShouldStayActive;
  394. //! True if the mouse is pressed or the enter key is down and there is an active interactable
  395. bool m_isActiveInteractablePressed;
  396. //! The last mouse position. Used to detect mouse movement
  397. AZ::Vector2 m_lastMousePosition;
  398. //! A map of all interactables that have handled a multi-touch (non-primary) pressed
  399. //! event but that are still waiting to receive the corresponding released event
  400. AZStd::unordered_map<int, AZ::EntityId> m_multiTouchInteractablesByTouchIndex;
  401. struct NavigationStatus
  402. {
  403. AZ::u64 lastNavigationTime;
  404. int navigationCount;
  405. bool allowNavigation;
  406. };
  407. //! The status of navigation in each direction
  408. AZStd::unordered_map<UiNavigationHelpers::Command, NavigationStatus> m_navCommandStatus;
  409. LyShine::CanvasId m_id;
  410. int m_drawOrder;
  411. //! The authored canvas size, in pixels
  412. //
  413. //! While in the editor, this is the resolution that we display the canvas at. While in
  414. //! game, the authored canvas size is used to calculate m_uniformDeviceScale, which is
  415. //! used to apply the "scale to device" feature.
  416. AZ::Vector2 m_canvasSize;
  417. //! The target size of the canvas in pixels
  418. //
  419. //! The resolution that we display the canvas at. While in-game, we assume the canvas
  420. //! occupies the entire screen, so it is set to the viewport size. In the Editor, we
  421. //! set the target size to be the authored canvas size.
  422. AZ::Vector2 m_targetCanvasSize;
  423. //! The scale that will convert from canvasSize to viewportSize.
  424. //! In the editor this is always 1.0f
  425. //! In game it is the closer value to 1.0f of the two values m_viewportSize.x/m_canvasSize.x
  426. //! and m_viewportSize.y/m_canvasSize.y
  427. AZ::Vector2 m_deviceScale;
  428. //! True if this canvas is loaded in game (including for Ctrl-G in Sandbox), false if open in the UI Editor
  429. bool m_isLoadedInGame;
  430. //! This flag allows some UI canvases to stay loaded when transitioning from one level to another
  431. bool m_keepLoadedOnLevelUnload;
  432. //! True (default) if the canvas is visible and updated each frame, false otherwise
  433. bool m_enabled;
  434. //! Each canvas has its own animation system to manage all its animation sequences
  435. UiAnimationSystem m_uiAnimationSystem;
  436. UiSerialize::AnimationData m_serializedAnimationData;
  437. //! If true the canvas is not rendered to the screen but is instead rendered to a texture
  438. bool m_renderToTexture;
  439. //! The user-specified asset for the attachment image that we render to if m_renderToTexture is true
  440. AZ::Data::Asset<AZ::RPI::AttachmentImageAsset> m_attachmentImageAsset;
  441. //! When rendering to a texture this is the attachment image for the render target
  442. AZ::RHI::AttachmentId m_attachmentImageId;
  443. //! Each canvas has a layout manager to track and recompute layouts
  444. UiLayoutManager* m_layoutManager = nullptr;
  445. bool m_isSnapEnabled;
  446. float m_snapDistance;
  447. float m_snapRotationDegrees;
  448. //! guides (editor-only)
  449. AZStd::vector<float> m_horizontalGuidePositions;
  450. AZStd::vector<float> m_verticalGuidePositions;
  451. AZ::Color m_guideColor;
  452. bool m_guidesAreLocked;
  453. UiEntityContext* m_entityContext;
  454. AZ::SliceComponent::EntityIdToEntityIdMap m_editorToGameEntityIdMap;
  455. //! This is an optimization to avoid visiting all elements multiple times every frame to see if any of them need recomputing
  456. //! We use an intrusive_slist to avoid any memory allocations and also to cheaply be able to tell if an element is already in list
  457. using ElementComponentSlist = AZStd::intrusive_slist<UiElementComponent, AZStd::slist_base_hook<UiElementComponent>>;
  458. ElementComponentSlist m_elementsNeedingTransformRecompute;
  459. //! Holds elements that are queued up to be deleted at end of frame
  460. AZStd::vector<AZ::EntityId> m_elementsScheduledForDestroy;
  461. private: // static data
  462. //! If true update which element should be the hover interactable based on input position
  463. //! and notify the active interactable of position changes. Set to false when a key event
  464. //! occurs and back to true on mouse/touch activity.
  465. static bool s_handleHoverInputEvents;
  466. //! If true, when handling hover input events, allow clearing the hover interactable if the mouse isn't
  467. //! over any interactables. Set to false when a key event occurs and back to true when handling hover
  468. //! input events and the input position hovers over an interactable.
  469. static bool s_allowClearingHoverInteractableOnHoverInput;
  470. LyShine::RenderGraph m_renderGraph; //!< the render graph for rendering the canvas, can be cached between frames
  471. bool m_isRendering = false;
  472. bool m_renderInEditor = false; //!< indicates whether this canvas will render in the Editor viewport or the Game viewport
  473. //! Map of attachments used by this canvas's elements
  474. AZStd::unordered_map<AZ::RHI::AttachmentId, AZ::Data::Instance<AZ::RPI::AttachmentImage>> m_attachmentImageMap;
  475. };