UiCanvasAssetRefComponent.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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 "UiCanvasAssetRefComponent.h"
  9. #include <AzCore/Serialization/SerializeContext.h>
  10. #include <AzCore/Serialization/EditContext.h>
  11. #include <AzCore/Interface/Interface.h>
  12. #include <AzCore/RTTI/BehaviorContext.h>
  13. #include <LyShine/Bus/UiCanvasBus.h>
  14. #include <LyShine/LyShineBus.h>
  15. #include <LyShine/ILyShine.h>
  16. ////////////////////////////////////////////////////////////////////////////////////////////////////
  17. //! UiCanvasAssetRefNotificationBus Behavior context handler class
  18. class UiCanvasAssetRefNotificationBusBehaviorHandler
  19. : public UiCanvasAssetRefNotificationBus::Handler
  20. , public AZ::BehaviorEBusHandler
  21. {
  22. public:
  23. AZ_EBUS_BEHAVIOR_BINDER(UiCanvasAssetRefNotificationBusBehaviorHandler, "{CA397C92-9C0B-436C-9C71-38A1918929EC}", AZ::SystemAllocator,
  24. OnCanvasLoadedIntoEntity);
  25. void OnCanvasLoadedIntoEntity(AZ::EntityId uiCanvasEntity) override
  26. {
  27. Call(FN_OnCanvasLoadedIntoEntity, uiCanvasEntity);
  28. }
  29. };
  30. ////////////////////////////////////////////////////////////////////////////////////////////////////
  31. //! UiCanvasRefNotificationBus Behavior context handler class
  32. class UiCanvasRefNotificationBusBehaviorHandler
  33. : public UiCanvasRefNotificationBus::Handler
  34. , public AZ::BehaviorEBusHandler
  35. {
  36. public:
  37. AZ_EBUS_BEHAVIOR_BINDER(UiCanvasRefNotificationBusBehaviorHandler, "{728D7B02-D5D1-493A-8DD1-3AE5EA595A79}", AZ::SystemAllocator,
  38. OnCanvasRefChanged);
  39. void OnCanvasRefChanged(AZ::EntityId uiCanvasRefEntity, AZ::EntityId uiCanvasEntity) override
  40. {
  41. Call(FN_OnCanvasRefChanged, uiCanvasRefEntity, uiCanvasEntity);
  42. }
  43. };
  44. ////////////////////////////////////////////////////////////////////////////////////////////////////
  45. // PUBLIC MEMBER FUNCTIONS
  46. ////////////////////////////////////////////////////////////////////////////////////////////////////
  47. ////////////////////////////////////////////////////////////////////////////////////////////////////
  48. UiCanvasAssetRefComponent::UiCanvasAssetRefComponent()
  49. : m_isAutoLoad(false)
  50. , m_shouldLoadDisabled(false)
  51. {}
  52. ////////////////////////////////////////////////////////////////////////////////////////////////////
  53. AZ::EntityId UiCanvasAssetRefComponent::GetCanvas()
  54. {
  55. return m_canvasEntityId;
  56. }
  57. ////////////////////////////////////////////////////////////////////////////////////////////////////
  58. AZStd::string UiCanvasAssetRefComponent::GetCanvasPathname()
  59. {
  60. return m_canvasAssetRef.GetAssetPath();
  61. }
  62. ////////////////////////////////////////////////////////////////////////////////////////////////////
  63. void UiCanvasAssetRefComponent::SetCanvasPathname(const AZStd::string& pathname)
  64. {
  65. m_canvasAssetRef.SetAssetPath(pathname.c_str());
  66. }
  67. ////////////////////////////////////////////////////////////////////////////////////////////////////
  68. bool UiCanvasAssetRefComponent::GetIsAutoLoad()
  69. {
  70. return m_isAutoLoad;
  71. }
  72. ////////////////////////////////////////////////////////////////////////////////////////////////////
  73. void UiCanvasAssetRefComponent::SetIsAutoLoad(bool isAutoLoad)
  74. {
  75. m_isAutoLoad = isAutoLoad;
  76. }
  77. ////////////////////////////////////////////////////////////////////////////////////////////////////
  78. bool UiCanvasAssetRefComponent::GetShouldLoadDisabled()
  79. {
  80. return m_shouldLoadDisabled;
  81. }
  82. ////////////////////////////////////////////////////////////////////////////////////////////////////
  83. void UiCanvasAssetRefComponent::SetShouldLoadDisabled(bool shouldLoadDisabled)
  84. {
  85. m_shouldLoadDisabled = shouldLoadDisabled;
  86. }
  87. ////////////////////////////////////////////////////////////////////////////////////////////////////
  88. AZ::EntityId UiCanvasAssetRefComponent::LoadCanvas()
  89. {
  90. AZStd::string canvasPath = m_canvasAssetRef.GetAssetPath();
  91. if (!canvasPath.empty())
  92. {
  93. // Check if we already have a referenced UI canvas, if so release it
  94. if (m_canvasEntityId.IsValid())
  95. {
  96. AZ::Interface<ILyShine>::Get()->ReleaseCanvasDeferred(m_canvasEntityId);
  97. m_canvasEntityId.SetInvalid();
  98. }
  99. m_canvasEntityId = AZ::Interface<ILyShine>::Get()->LoadCanvas(canvasPath.c_str());
  100. UiCanvasAssetRefNotificationBus::Event(
  101. GetEntityId(), &UiCanvasAssetRefNotificationBus::Events::OnCanvasLoadedIntoEntity, m_canvasEntityId);
  102. UiCanvasRefNotificationBus::Event(
  103. GetEntityId(), &UiCanvasRefNotificationBus::Events::OnCanvasRefChanged, GetEntityId(), m_canvasEntityId);
  104. }
  105. return m_canvasEntityId;
  106. }
  107. ////////////////////////////////////////////////////////////////////////////////////////////////////
  108. void UiCanvasAssetRefComponent::UnloadCanvas()
  109. {
  110. if (m_canvasEntityId.IsValid())
  111. {
  112. AZ::Interface<ILyShine>::Get()->ReleaseCanvasDeferred(m_canvasEntityId);
  113. m_canvasEntityId.SetInvalid();
  114. UiCanvasRefNotificationBus::Event(
  115. GetEntityId(), &UiCanvasRefNotificationBus::Events::OnCanvasRefChanged, GetEntityId(), m_canvasEntityId);
  116. }
  117. }
  118. ////////////////////////////////////////////////////////////////////////////////////////////////////
  119. void UiCanvasAssetRefComponent::OnCanvasUnloaded(AZ::EntityId canvasEntityId)
  120. {
  121. if (canvasEntityId == m_canvasEntityId)
  122. {
  123. // this canvas has been unloaded (e.g. from script), set our canvas entity ID to invalid
  124. // and tell anyone watching this assert ref that it changed
  125. m_canvasEntityId.SetInvalid();
  126. UiCanvasRefNotificationBus::Event(
  127. GetEntityId(), &UiCanvasRefNotificationBus::Events::OnCanvasRefChanged, GetEntityId(), m_canvasEntityId);
  128. }
  129. }
  130. ////////////////////////////////////////////////////////////////////////////////////////////////////
  131. // PUBLIC STATIC MEMBER FUNCTIONS
  132. ////////////////////////////////////////////////////////////////////////////////////////////////////
  133. ////////////////////////////////////////////////////////////////////////////////////////////////////
  134. void UiCanvasAssetRefComponent::Reflect(AZ::ReflectContext* context)
  135. {
  136. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  137. if (serializeContext)
  138. {
  139. serializeContext->Class<UiCanvasAssetRefComponent, AZ::Component>()
  140. ->Version(1)
  141. ->Field("CanvasAssetRef", &UiCanvasAssetRefComponent::m_canvasAssetRef)
  142. ->Field("IsAutoLoad", &UiCanvasAssetRefComponent::m_isAutoLoad)
  143. ->Field("ShouldLoadDisabled", &UiCanvasAssetRefComponent::m_shouldLoadDisabled);
  144. AZ::EditContext* editContext = serializeContext->GetEditContext();
  145. if (editContext)
  146. {
  147. auto editInfo = editContext->Class<UiCanvasAssetRefComponent>("UI Canvas Asset Ref", "The UI Canvas Asset Ref component allows you to associate a UI Canvas with an entity");
  148. editInfo->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  149. ->Attribute(AZ::Edit::Attributes::Category, "UI")
  150. ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/UiCanvasAssetRef.svg")
  151. ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/UiCanvasAssetRef.svg")
  152. ->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/ui/canvas-asset-ref/")
  153. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c));
  154. editInfo->DataElement("CanvasAssetRef", &UiCanvasAssetRefComponent::m_canvasAssetRef,
  155. "Canvas pathname", "The pathname of the canvas.")
  156. ->Attribute("BrowseIcon", ":/stylesheet/img/UI20/browse-edit-select-files.svg")
  157. ->Attribute("EditButton", "")
  158. ->Attribute("EditDescription", "Open in UI Editor")
  159. ->Attribute("EditCallback", &UiCanvasAssetRefComponent::LaunchUIEditor);
  160. editInfo->DataElement(AZ::Edit::UIHandlers::CheckBox, &UiCanvasAssetRefComponent::m_isAutoLoad,
  161. "Load automatically", "When checked, the canvas is loaded when this component is activated.")
  162. ->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshEntireTree", 0xefbc823c));
  163. editInfo->DataElement(AZ::Edit::UIHandlers::CheckBox, &UiCanvasAssetRefComponent::m_shouldLoadDisabled,
  164. "Load in disabled state", "When checked and loading automatically, the canvas is loaded in a disabled state.")
  165. ->Attribute(AZ::Edit::Attributes::Visibility, &UiCanvasAssetRefComponent::m_isAutoLoad);
  166. }
  167. }
  168. AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
  169. if (behaviorContext)
  170. {
  171. behaviorContext->EBus<UiCanvasAssetRefBus>("UiCanvasAssetRefBus")
  172. ->Event("LoadCanvas", &UiCanvasAssetRefBus::Events::LoadCanvas)
  173. ->Event("UnloadCanvas", &UiCanvasAssetRefBus::Events::UnloadCanvas);
  174. behaviorContext->EBus<UiCanvasRefBus>("UiCanvasRefBus")
  175. ->Event("GetCanvas", &UiCanvasRefBus::Events::GetCanvas);
  176. behaviorContext->EBus<UiCanvasAssetRefNotificationBus>("UiCanvasAssetRefNotificationBus")
  177. ->Handler<UiCanvasAssetRefNotificationBusBehaviorHandler>();
  178. behaviorContext->EBus<UiCanvasRefNotificationBus>("UiCanvasRefNotificationBus")
  179. ->Handler<UiCanvasRefNotificationBusBehaviorHandler>();
  180. }
  181. }
  182. ////////////////////////////////////////////////////////////////////////////////////////////////////
  183. // PROTECTED MEMBER FUNCTIONS
  184. ////////////////////////////////////////////////////////////////////////////////////////////////////
  185. ////////////////////////////////////////////////////////////////////////////////////////////////////
  186. void UiCanvasAssetRefComponent::LaunchUIEditor([[maybe_unused]] const AZ::Data::AssetId& assetId, const AZ::Data::AssetType&)
  187. {
  188. LyShine::LyShineRequestBus::Broadcast(&LyShine::LyShineRequests::EditUICanvas, GetCanvasPathname());
  189. }
  190. ////////////////////////////////////////////////////////////////////////////////////////////////////
  191. void UiCanvasAssetRefComponent::Activate()
  192. {
  193. if (!gEnv->IsDedicated())
  194. {
  195. UiCanvasRefBus::Handler::BusConnect(GetEntityId());
  196. UiCanvasAssetRefBus::Handler::BusConnect(GetEntityId());
  197. UiCanvasManagerNotificationBus::Handler::BusConnect();
  198. if (m_isAutoLoad)
  199. {
  200. LoadCanvas();
  201. if (m_shouldLoadDisabled)
  202. {
  203. UiCanvasBus::Event(m_canvasEntityId, &UiCanvasBus::Events::SetEnabled, false);
  204. }
  205. }
  206. }
  207. }
  208. ////////////////////////////////////////////////////////////////////////////////////////////////////
  209. void UiCanvasAssetRefComponent::Deactivate()
  210. {
  211. if (gEnv && !gEnv->IsDedicated())
  212. {
  213. if (m_canvasEntityId.IsValid())
  214. {
  215. AZ::Interface<ILyShine>::Get()->ReleaseCanvasDeferred(m_canvasEntityId);
  216. m_canvasEntityId.SetInvalid();
  217. }
  218. UiCanvasAssetRefBus::Handler::BusDisconnect();
  219. UiCanvasRefBus::Handler::BusDisconnect();
  220. UiCanvasManagerNotificationBus::Handler::BusDisconnect();
  221. }
  222. }