EditorWindow.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  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 "Animation/UiEditorAnimationBus.h"
  12. #include <LyShine/UiEditorDLLBus.h>
  13. #include "UiEditorInternalBus.h"
  14. #include "UiEditorEntityContext.h"
  15. #include "UiSliceManager.h"
  16. #include "ViewportInteraction.h"
  17. #include <QList>
  18. #include <QMetaObject>
  19. #include <AzCore/Debug/TraceMessageBus.h>
  20. #include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
  21. #include <AzToolsFramework/API/ToolsApplicationAPI.h>
  22. #include <AzQtComponents/Components/Widgets/TabWidget.h>
  23. #include <LyShine/Bus/UiEditorChangeNotificationBus.h>
  24. #include <IFont.h>
  25. #include <IFileUtil.h>
  26. #endif
  27. QT_FORWARD_DECLARE_CLASS(QUndoGroup)
  28. class AssetTreeEntry;
  29. class EditorWindow
  30. : public QMainWindow
  31. , public IEditorNotifyListener
  32. , public UiEditorDLLBus::Handler
  33. , public UiEditorChangeNotificationBus::Handler
  34. , public UiEditorInternalRequestBus::Handler
  35. , public UiEditorInternalNotificationBus::Handler
  36. , public AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationBus::Handler
  37. , public UiEditorEntityContextNotificationBus::Handler
  38. , public AzToolsFramework::EditorEvents::Bus::Handler
  39. , public FontNotificationBus::Handler
  40. , public AZ::Debug::TraceMessageBus::Handler
  41. {
  42. Q_OBJECT
  43. public: // types
  44. struct UiCanvasTabMetadata
  45. {
  46. AZ::EntityId m_canvasEntityId;
  47. };
  48. public: // member functions
  49. explicit EditorWindow(QWidget* parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
  50. virtual ~EditorWindow();
  51. // you are required to implement this to satisfy the unregister/registerclass requirements on "RegisterQtViewPane"
  52. // make sure you pick a unique GUID
  53. static const GUID& GetClassID()
  54. {
  55. // {E72CB9F3-DCB5-4525-AEAC-541A8CC778C5}
  56. static const GUID guid =
  57. {
  58. 0xe72cb9f3, 0xdcb5, 0x4525, { 0xae, 0xac, 0x54, 0x1a, 0x8c, 0xc7, 0x78, 0xc5 }
  59. };
  60. return guid;
  61. }
  62. void OnEditorNotifyEvent(EEditorNotifyEvent ev) override;
  63. // UiEditorDLLInterface
  64. LyShine::EntityArray GetSelectedElements() override;
  65. AZ::EntityId GetActiveCanvasId() override;
  66. UndoStack* GetActiveUndoStack() override;
  67. void OpenSourceCanvasFile(QString absolutePathToFile) override;
  68. // ~UiEditorDLLInterface
  69. // UiEditorChangeNotificationBus
  70. void OnEditorTransformPropertiesNeedRefresh() override;
  71. void OnEditorPropertiesRefreshEntireTree() override;
  72. // ~UiEditorChangeNotificationBus
  73. // UiEditorInternalRequestBus
  74. AzToolsFramework::EntityIdList GetSelectedEntityIds() override;
  75. AZ::Entity::ComponentArrayType GetSelectedComponents() override;
  76. AZ::EntityId GetActiveCanvasEntityId() override;
  77. // ~UiEditorInternalRequestBus
  78. // UiEditorInternalNotificationBus
  79. void OnSelectedEntitiesPropertyChanged() override;
  80. void OnBeginUndoableEntitiesChange() override;
  81. void OnEndUndoableEntitiesChange(const AZStd::string& commandText) override;
  82. // ~UiEditorInternalNotificationBus
  83. // AssetBrowserModelNotificationBus
  84. void EntryAdded(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) override;
  85. void EntryRemoved(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) override;
  86. // ~AssetBrowserModelNotificationBus
  87. // UiEditorEntityContextNotificationBus
  88. void OnSliceInstantiated(const AZ::Data::AssetId& sliceAssetId, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress, const AzFramework::SliceInstantiationTicket& ticket) override;
  89. void OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId, const AzFramework::SliceInstantiationTicket& ticket) override;
  90. // ~UiEditorEntityContextNotificationBus
  91. // EditorEvents
  92. void OnEscape() override;
  93. // ~EditorEvents
  94. // FontNotifications
  95. void OnFontsReloaded() override;
  96. // ~FontNotifications
  97. // TraceMessageEvents
  98. bool OnPreError(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) override;
  99. bool OnPreWarning(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override;
  100. // ~TraceMessageEvents
  101. AZ::EntityId GetCanvas();
  102. HierarchyWidget* GetHierarchy();
  103. ViewportWidget* GetViewport();
  104. PropertiesWidget* GetProperties();
  105. MainToolbar* GetMainToolbar();
  106. ModeToolbar* GetModeToolbar();
  107. EnterPreviewToolbar* GetEnterPreviewToolbar();
  108. PreviewToolbar* GetPreviewToolbar();
  109. NewElementToolbarSection* GetNewElementToolbarSection();
  110. CoordinateSystemToolbarSection* GetCoordinateSystemToolbarSection();
  111. CanvasSizeToolbarSection* GetCanvasSizeToolbarSection();
  112. const QCursor& GetEntityPickerCursor();
  113. bool CanExitNow();
  114. UndoStack* GetActiveStack();
  115. AssetTreeEntry* GetSliceLibraryTree();
  116. //! Returns the current mode of the editor (Edit or Preview)
  117. UiEditorMode GetEditorMode() { return m_editorMode; }
  118. //! Returns the UI canvas for the current mode (Edit or Preview)
  119. AZ::EntityId GetCanvasForCurrentEditorMode();
  120. //! Toggle the editor mode between Edit and Preview
  121. void ToggleEditorMode();
  122. //! Get the copy of the canvas that is used in Preview mode (will return invalid entity ID if not in preview mode)
  123. AZ::EntityId GetPreviewModeCanvas() { return m_previewModeCanvasEntityId; }
  124. //! Get the preview canvas size. (0,0) means use viewport size
  125. AZ::Vector2 GetPreviewCanvasSize();
  126. //! Set the preview canvas size. (0,0) means use viewport size
  127. void SetPreviewCanvasSize(AZ::Vector2 previewCanvasSize);
  128. void SaveEditorWindowSettings();
  129. UiSliceManager* GetSliceManager();
  130. UiEditorEntityContext* GetEntityContext();
  131. void ReplaceEntityContext(UiEditorEntityContext* entityContext);
  132. QMenu* createPopupMenu() override;
  133. AZ::EntityId GetCanvasForEntityContext(const AzFramework::EntityContextId& contextId);
  134. //! Open a new tab and instantiate the given slice asset for editing in a special slice editing mode
  135. void EditSliceInNewTab(AZ::Data::AssetId sliceAssetId);
  136. //! Called if an asset has changed and been reloaded (used to detect if slice being edited is different to the one on disk)
  137. void UpdateChangedStatusOnAssetChange(const AzFramework::EntityContextId& contextId, const AZ::Data::Asset<AZ::Data::AssetData>& asset);
  138. //! Called when any entities have been added to or removed from the active canvas
  139. void EntitiesAddedOrRemoved();
  140. //! Called when any font texture has changed since the last render.
  141. //! Forces a render graph update for each loaded canvas
  142. void FontTextureHasChanged();
  143. void RefreshEditorMenu();
  144. void ShowEntitySearchModal();
  145. signals:
  146. void EditorModeChanged(UiEditorMode mode);
  147. void SignalCoordinateSystemCycle();
  148. void SignalSnapToGridToggle();
  149. protected:
  150. void paintEvent(QPaintEvent* paintEvent) override;
  151. void closeEvent(QCloseEvent* closeEvent) override;
  152. void dragEnterEvent(QDragEnterEvent* event) override;
  153. void dropEvent(QDropEvent* event) override;
  154. public slots:
  155. void RestoreEditorWindowSettings();
  156. private: // types
  157. struct UiCanvasEditState
  158. {
  159. UiCanvasEditState();
  160. // Viewport
  161. ViewportInteraction::TranslationAndScale m_canvasViewportMatrixProps;
  162. bool m_shouldScaleToFitOnViewportResize;
  163. ViewportInteraction::InteractionMode m_viewportInteractionMode;
  164. ViewportInteraction::CoordinateSystem m_viewportCoordinateSystem;
  165. // Hierarchy
  166. int m_hierarchyScrollValue;
  167. EntityHelpers::EntityIdList m_selectedElements;
  168. // Properties
  169. float m_propertiesScrollValue;
  170. // Animation
  171. UiEditorAnimationStateInterface::UiEditorAnimationEditState m_uiAnimationEditState;
  172. bool m_inited;
  173. };
  174. // Data for a loaded UI canvas
  175. struct UiCanvasMetadata
  176. {
  177. UiCanvasMetadata();
  178. ~UiCanvasMetadata();
  179. AZ::EntityId m_canvasEntityId;
  180. AZStd::string m_canvasSourceAssetPathname;
  181. AZStd::string m_canvasDisplayName;
  182. UiEditorEntityContext* m_entityContext;
  183. UndoStack* m_undoStack;
  184. //! Specifies whether this canvas was automatically loaded or loaded by the user
  185. bool m_autoLoaded;
  186. //! Specified whether there were any errors on canvas load
  187. bool m_errorsOnLoad;
  188. //! Specifies whether a canvas has been modified and saved since it was loaded/created
  189. bool m_canvasChangedAndSaved;
  190. //! State of the viewport and other panes (zoom, pan, scroll, selection, ...)
  191. UiCanvasEditState m_canvasEditState;
  192. //! This is true when the canvas tab was opened in order to edit a slice
  193. bool m_isSliceEditing;
  194. //! If m_isSliceEditing is true this is the Asset ID of the slice instance that is being edited
  195. AZ::Data::AssetId m_sliceAssetId;
  196. //! If m_isSliceEditing is true this is the entityId of the one slice instance that is being edited
  197. AZ::EntityId m_sliceEntityId;
  198. };
  199. private: // member functions
  200. QUndoGroup* GetUndoGroup();
  201. bool GetChangesHaveBeenMade(const UiCanvasMetadata& canvasMetadata);
  202. //! Return true when ok.
  203. //! forceAskingForFilename should only be true for "Save As...", not "Save".
  204. bool SaveCanvasToXml(UiCanvasMetadata& canvasMetadata, bool forceAskingForFilename);
  205. //! Saves a slice tab to its slice with a quick push
  206. bool SaveSlice(UiCanvasMetadata& canvasMetadata);
  207. //! Check whether a canvas save should occur even though there were errors on load
  208. bool CanSaveWithErrors(const UiCanvasMetadata& canvasMetadata);
  209. // Called from menu or shortcut key events
  210. void NewCanvas();
  211. void OpenCanvas(const QString& canvasFilename);
  212. void OpenCanvases(const QStringList& canvasFilenames);
  213. void CloseCanvas(AZ::EntityId canvasEntityId);
  214. void CloseAllCanvases();
  215. void CloseAllOtherCanvases(AZ::EntityId canvasEntityId);
  216. bool LoadCanvas(const QString& canvasFilename, bool autoLoad, bool changeActiveCanvasToThis = true);
  217. bool CanUnloadCanvas(UiCanvasMetadata& canvasMetadata);
  218. void UnloadCanvas(AZ::EntityId canvasEntityId);
  219. void UnloadCanvases(const AZStd::vector<AZ::EntityId>& canvasEntityIds);
  220. bool CanChangeActiveCanvas();
  221. void SetActiveCanvas(AZ::EntityId canvasEntityId);
  222. void SaveActiveCanvasEditState();
  223. void RestoreActiveCanvasEditState();
  224. void RestoreActiveCanvasEditStatePostEvents();
  225. void OnCanvasTabCloseButtonPressed(int index);
  226. void OnCurrentCanvasTabChanged(int index);
  227. void OnCanvasTabContextMenuRequested(const QPoint &point);
  228. void UpdateActionsEnabledState();
  229. void SetupShortcuts();
  230. //! Check if the given toolbar should only be shown in preview mode
  231. bool IsPreviewModeToolbar(const QToolBar* toolBar);
  232. //! Check if the given dockwidget should only be shown in preview mode
  233. bool IsPreviewModeDockWidget(const QDockWidget* dockWidget);
  234. QAction* AddMenuAction(const QString& text, bool enabled, QMenu* menu, AZStd::function<void (bool)> function);
  235. void AddMenu_File();
  236. void AddMenuItems_Edit(QMenu* menu);
  237. void AddMenu_Edit();
  238. void AddMenu_View();
  239. void AddMenu_View_LanguageSetting(QMenu* viewMenu);
  240. void AddMenu_Preview();
  241. void AddMenu_PreviewView();
  242. void AddMenu_Help();
  243. void EditorMenu_Open(QString optional_selectedFile);
  244. QAction* CreateSaveCanvasAction(AZ::EntityId canvasEntityId, bool forContextMenu = false);
  245. QAction* CreateSaveCanvasAsAction(AZ::EntityId canvasEntityId, bool forContextMenu = false);
  246. QAction* CreateSaveSliceAction(UiCanvasMetadata *canvasMetadata, bool forContextMenu = false);
  247. QAction* CreateSaveAllCanvasesAction(bool forContextMenu = false);
  248. QAction* CreateCloseCanvasAction(AZ::EntityId canvasEntityId, bool forContextMenu = false);
  249. QAction* CreateCloseAllOtherCanvasesAction(AZ::EntityId canvasEntityId, bool forContextMenu = false);
  250. QAction* CreateCloseAllCanvasesAction(bool forContextMenu = false);
  251. void SaveModeSettings(UiEditorMode mode, bool syncSettings);
  252. void RestoreModeSettings(UiEditorMode mode);
  253. int GetCanvasMaxHierarchyDepth(const LyShine::EntityArray& childElements);
  254. void DeleteSliceLibraryTree();
  255. void DestroyCanvas(const UiCanvasMetadata& canvasMetadata);
  256. bool IsCanvasTabMetadataValidForTabIndex(int index);
  257. AZ::EntityId GetCanvasEntityIdForTabIndex(int index);
  258. int GetTabIndexForCanvasEntityId(AZ::EntityId canvasEntityId);
  259. UiCanvasMetadata* GetCanvasMetadataForTabIndex(int index);
  260. UiCanvasMetadata* GetCanvasMetadata(AZ::EntityId canvasEntityId);
  261. UiCanvasMetadata* GetActiveCanvasMetadata();
  262. AZStd::string GetCanvasDisplayNameFromAssetPath(const AZStd::string& canvasAssetPathname);
  263. void HandleCanvasDisplayNameChanged(const UiCanvasMetadata& canvasMetadata);
  264. void SetupCentralWidget();
  265. void SetupTabbedViewportWidget(QWidget* parent);
  266. void CheckForOrphanedChildren(AZ::EntityId canvasEntityId);
  267. void AddTraceMessage(const char *message, AZStd::list<QString>& messageList);
  268. void ShowTraceMessages(const AZStd::string& canvasName);
  269. void ClearTraceMessages();
  270. private slots:
  271. // Called when the clean state of the active undo stack changes
  272. void CleanChanged(bool clean);
  273. private: // data
  274. QUndoGroup* m_undoGroup;
  275. UiSliceManager* m_sliceManager;
  276. AzQtComponents::TabWidget* m_canvasTabWidget;
  277. QWidget* m_canvasTabSectionWidget;
  278. HierarchyWidget* m_hierarchy;
  279. PropertiesWrapper* m_properties;
  280. ViewportWidget* m_viewport;
  281. CUiAnimViewDialog* m_animationWidget;
  282. PreviewActionLog* m_previewActionLog;
  283. PreviewAnimationList* m_previewAnimationList;
  284. MainToolbar* m_mainToolbar;
  285. ModeToolbar* m_modeToolbar;
  286. EnterPreviewToolbar* m_enterPreviewToolbar;
  287. PreviewToolbar* m_previewToolbar;
  288. QDockWidget* m_hierarchyDockWidget;
  289. QDockWidget* m_propertiesDockWidget;
  290. QDockWidget* m_animationDockWidget;
  291. QDockWidget* m_previewActionLogDockWidget;
  292. QDockWidget* m_previewAnimationListDockWidget;
  293. UiEditorMode m_editorMode;
  294. //! This tree caches the folder view of all the slice assets under the slice library path
  295. AssetTreeEntry* m_sliceLibraryTree = nullptr;
  296. //! Values for setting up undoable canvas/entity changes
  297. SerializeHelpers::SerializedEntryList m_preChangeState;
  298. bool m_haveValidEntitiesPreChangeState = false;
  299. AZStd::string m_canvasUndoXml;
  300. bool m_haveValidCanvasPreChangeState = false;
  301. //! This is used to change the enabled state
  302. //! of these actions as the selection changes.
  303. QList<QAction*> m_actionsEnabledWithSelection;
  304. QAction* m_pasteAsSiblingAction;
  305. QAction* m_pasteAsChildAction;
  306. QList<QAction*> m_actionsEnabledWithAlignAllowed;
  307. AZ::EntityId m_previewModeCanvasEntityId;
  308. AZ::Vector2 m_previewModeCanvasSize;
  309. QMetaObject::Connection m_clipboardConnection;
  310. //! Local copy of QSetting value of startup location of localization folder
  311. QString m_startupLocFolderName;
  312. std::map< AZ::EntityId, UiCanvasMetadata* > m_canvasMetadataMap;
  313. AZ::EntityId m_activeCanvasEntityId;
  314. int m_newCanvasCount;
  315. AZStd::list<QString> m_errors; // the list of errors that occured while loading a canvas
  316. AZStd::list<QString> m_warnings; // the list of warnings that occured while loading a canvas
  317. // Cursor used when picking an element in the hierarchy or viewport during object pick mode
  318. QCursor m_entityPickerCursor;
  319. };
  320. Q_DECLARE_METATYPE(EditorWindow::UiCanvasTabMetadata);