Przeglądaj źródła

Merge pull request #11537 from aws-lumberyard-dev/Atom/guthadam/material_canvas/support_for_saving_custom_window_layouts

Material Canvas: Support for saving custom window layouts
Guthrie Adams 3 lat temu
rodzic
commit
f48180107f

+ 3 - 0
Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Window/AtomToolsMainWindow.h

@@ -63,6 +63,9 @@ namespace AtomToolsFramework
         void showEvent(QShowEvent* showEvent) override;
         void closeEvent(QCloseEvent* closeEvent) override;
 
+        void BuildDockingMenu();
+        void BuildLayoutsMenu();
+
         virtual void SetupMetrics();
         virtual void UpdateMetrics();
         virtual void UpdateWindowTitle();

+ 1 - 1
Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.cpp

@@ -40,7 +40,7 @@ namespace AtomToolsFramework
         m_ui->m_searchWidget->Setup(true, true);
         m_ui->m_searchWidget->setMinimumSize(QSize(150, 0));
 
-        m_ui->m_viewOptionButton->setIcon(QIcon(":/Icons/view.svg"));
+        m_ui->m_viewOptionButton->setIcon(QIcon(":/Icons/menu.svg"));
         m_ui->m_splitter->setSizes(QList<int>() << 400 << 200);
         m_ui->m_splitter->setStretchFactor(0, 1);
 

+ 1 - 1
Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.qrc

@@ -1,5 +1,5 @@
 <RCC>
     <qresource prefix="/">
-        <file>Icons/view.svg</file>
+        <file>Icons/menu.svg</file>
     </qresource>
 </RCC>

+ 18 - 0
Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/Icons/menu.svg

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="12px" viewBox="0 0 20 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 63.1 (92452) - https://sketch.com -->
+    <title>Buttons / Dropdown button with Icon / Default</title>
+    <desc>Created with Sketch.</desc>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="component-header" transform="translate(-426.000000, -6.000000)" fill="#FFFFFF">
+            <g id="Buttons-/-Dropdown-button-with-Icon-/-Default" transform="translate(424.000000, 4.000000)">
+                <polygon id="Triangle" transform="translate(19.000000, 8.500000) scale(1, -1) translate(-19.000000, -8.500000) " points="20 9 23 12 17 12"></polygon>
+                <g id="Sky-Icon-/-System-/-Menu">
+                    <rect id="Rectangle-11" x="2" y="2" width="12" height="2"></rect>
+                    <rect id="Rectangle-11" x="2" y="7" width="12" height="2"></rect>
+                    <rect id="Rectangle-11" x="2" y="12" width="12" height="2"></rect>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 0 - 8
Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/Icons/view.svg

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <title>Icons / System / View</title>
-    <g id="Icons-/-System-/-View" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <rect id="Icon-Background" x="0" y="0" width="24" height="24"></rect>
-        <path d="M11.9842667,6 C14.2018891,6 17.5404669,8 22,12 C17.5404669,16 14.2018891,18 11.9842667,18 C9.76664426,18 6.43855537,16 2,12 C6.43855537,8 9.76664426,6 11.9842667,6 Z M12,7.5 C9.51471863,7.5 7.5,9.51471863 7.5,12 C7.5,14.4852814 9.51471863,16.5 12,16.5 C14.4852814,16.5 16.5,14.4852814 16.5,12 C16.5,9.51471863 14.4852814,7.5 12,7.5 Z M12,9 C13.6568542,9 15,10.3431458 15,12 C15,13.6568542 13.6568542,15 12,15 C10.3431458,15 9,13.6568542 9,12 C9,10.3431458 10.3431458,9 12,9 Z" id="Combined-Shape" fill="#FFFFFF"></path>
-    </g>
-</svg>

+ 105 - 30
Gems/Atom/Tools/AtomToolsFramework/Code/Source/Window/AtomToolsMainWindow.cpp

@@ -14,12 +14,14 @@
 #include <AtomToolsFramework/Window/AtomToolsMainWindowNotificationBus.h>
 #include <AzCore/Name/Name.h>
 #include <AzCore/Utils/Utils.h>
+#include <AzCore/std/containers/map.h>
 #include <AzCore/std/sort.h>
 #include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
 #include <AzToolsFramework/PythonTerminal/ScriptTermDialog.h>
 
 #include <QCloseEvent>
 #include <QFileDialog>
+#include <QInputDialog>
 #include <QMenu>
 #include <QMenuBar>
 #include <QMessageBox>
@@ -201,7 +203,7 @@ namespace AtomToolsFramework
 
                     // Instead of destroying and recreating the menu bar, destroying the individual child menus to prevent the UI from
                     // popping when the menu bar is recreated
-                    auto menus = menuBar()->findChildren<QMenu*>();
+                    auto menus = menuBar()->findChildren<QMenu*>(QString(), Qt::FindDirectChildrenOnly);
                     for (auto menu : menus)
                     {
                         delete menu;
@@ -229,7 +231,7 @@ namespace AtomToolsFramework
         m_menuHelp = menuBar->addMenu("&Help");
         m_menuHelp->setObjectName("menuHelp");
 
-        m_menuFile->addAction("Run &Python...", [this]() {
+        m_menuFile->addAction(tr("Run &Python..."), [this]() {
             const QString script = QFileDialog::getOpenFileName(
                 this, QObject::tr("Run Script"), QString(AZ::Utils::GetProjectPath().c_str()), QString("*.py"));
             if (!script.isEmpty())
@@ -243,42 +245,25 @@ namespace AtomToolsFramework
 
         m_menuFile->addSeparator();
 
-        m_menuFile->addAction("E&xit", [this]() {
+        m_menuFile->addAction(tr("E&xit"), [this]() {
             close();
         }, QKeySequence::Quit);
 
-        // Add menu options to toggle the visibility of all dock widgets
-        auto dockWidgets = findChildren<QDockWidget*>();
-        AZStd::sort(dockWidgets.begin(), dockWidgets.end(), [](QDockWidget* a, QDockWidget* b) {
-            return a->windowTitle() < b->windowTitle();
-        });
-
-        for (auto dockWidget : dockWidgets)
-        {
-            const auto dockWidgetName = dockWidget->windowTitle();
-            auto dockAction = m_menuTools->addAction(dockWidgetName, [this, dockWidgetName](const bool checked) {
-                SetDockWidgetVisible(dockWidgetName.toUtf8().constData(), checked);
-            });
-            dockAction->setCheckable(true);
-            dockAction->setChecked(dockWidget->isVisible());
-            connect(dockWidget, &QDockWidget::visibilityChanged, dockAction, &QAction::setChecked);
-        }
-
+        BuildDockingMenu();
         m_menuTools->addSeparator();
-        m_menuTools->addAction("Default Layout", [this]() {
-            m_advancedDockManager->restoreState(m_defaultWindowState);
-        });
+
+        BuildLayoutsMenu();
         m_menuTools->addSeparator();
 
-        m_menuTools->addAction("&Settings...", [this]() {
+        m_menuTools->addAction(tr("&Settings..."), [this]() {
             OpenSettingsDialog();
         }, QKeySequence::Preferences);
 
-        m_menuHelp->addAction("&Help...", [this]() {
+        m_menuHelp->addAction(tr("&Help..."), [this]() {
             OpenHelpDialog();
         });
 
-        m_menuHelp->addAction("&About...", [this]() {
+        m_menuHelp->addAction(tr("&About..."), [this]() {
             OpenAboutDialog();
         });
     }
@@ -381,8 +366,7 @@ namespace AtomToolsFramework
             m_shownBefore = true;
             m_defaultWindowState = m_advancedDockManager->saveState();
             m_mainWindowWrapper->showFromSettings();
-            const AZStd::string windowState =
-                GetSettingsObject("/O3DE/AtomToolsFramework/MainWindow/WindowState", AZStd::string());
+            const AZStd::string windowState = GetSettingsObject("/O3DE/AtomToolsFramework/MainWindow/WindowState", AZStd::string());
             m_advancedDockManager->restoreState(QByteArray(windowState.data(), aznumeric_cast<int>(windowState.size())));
         }
 
@@ -394,14 +378,105 @@ namespace AtomToolsFramework
         if (closeEvent->isAccepted())
         {
             const QByteArray windowState = m_advancedDockManager->saveState();
-            SetSettingsObject(
-                "/O3DE/AtomToolsFramework/MainWindow/WindowState", AZStd::string(windowState.begin(), windowState.end()));
+            SetSettingsObject("/O3DE/AtomToolsFramework/MainWindow/WindowState", AZStd::string(windowState.begin(), windowState.end()));
             AtomToolsMainWindowNotificationBus::Event(m_toolId, &AtomToolsMainWindowNotifications::OnMainWindowClosing);
         }
 
         Base::closeEvent(closeEvent);
     }
 
+    void AtomToolsMainWindow::BuildDockingMenu()
+    {
+        auto dockWidgets = findChildren<QDockWidget*>();
+        AZStd::sort(
+            dockWidgets.begin(),
+            dockWidgets.end(),
+            [](QDockWidget* a, QDockWidget* b)
+            {
+                return a->windowTitle() < b->windowTitle();
+            });
+
+        for (auto dockWidget : dockWidgets)
+        {
+            const auto dockWidgetName = dockWidget->windowTitle();
+            if (!dockWidgetName.isEmpty())
+            {
+                auto dockAction = m_menuTools->addAction(
+                    dockWidgetName,
+                    [this, dockWidgetName](const bool checked)
+                    {
+                        SetDockWidgetVisible(dockWidgetName.toUtf8().constData(), checked);
+                    });
+
+                dockAction->setCheckable(true);
+                dockAction->setChecked(dockWidget->isVisible());
+                connect(dockWidget, &QDockWidget::visibilityChanged, dockAction, &QAction::setChecked);
+            }
+        }
+    }
+
+    void AtomToolsMainWindow::BuildLayoutsMenu()
+    {
+        using LayoutSettingsMap = AZStd::map<AZStd::string, AZStd::string>;
+
+        constexpr const char* LayoutSettingsKey = "/O3DE/AtomToolsFramework/MainWindow/Layouts";
+
+        QMenu* layoutSettingsMenu = m_menuTools->addMenu(tr("Layouts"));
+        connect(
+            layoutSettingsMenu,
+            &QMenu::aboutToShow,
+            this,
+            [this, layoutSettingsMenu]()
+            {
+                layoutSettingsMenu->clear();
+
+                const auto& layoutSettings = GetSettingsObject(LayoutSettingsKey, LayoutSettingsMap());
+                for (const auto& layoutSettingsPair : layoutSettings)
+                {
+                    QMenu* layoutMenu = layoutSettingsMenu->addMenu(layoutSettingsPair.first.c_str());
+
+                    layoutMenu->addAction(
+                        tr("Load"),
+                        [this, layoutSettingsPair]()
+                        {
+                            const auto& windowState = layoutSettingsPair.second;
+                            m_advancedDockManager->restoreState(QByteArray(windowState.data(), aznumeric_cast<int>(windowState.size())));
+                        });
+
+                    layoutMenu->addAction(
+                        tr("Delete"),
+                        [layoutSettingsPair]()
+                        {
+                            auto layoutSettings = GetSettingsObject(LayoutSettingsKey, LayoutSettingsMap());
+                            layoutSettings.erase(layoutSettingsPair.first);
+                            SetSettingsObject(LayoutSettingsKey, layoutSettings);
+                        });
+                }
+
+                layoutSettingsMenu->addAction(
+                    tr("Save Layout..."),
+                    [this]()
+                    {
+                        const AZStd::string layoutName =
+                            QInputDialog::getText(this, tr("Layout Name"), QString()).toLower().toUtf8().constData();
+                        if (!layoutName.empty())
+                        {
+                            auto layoutSettings = GetSettingsObject(LayoutSettingsKey, LayoutSettingsMap());
+                            const QByteArray windowState = m_advancedDockManager->saveState();
+                            layoutSettings[layoutName] = AZStd::string(windowState.begin(), windowState.end());
+                            SetSettingsObject(LayoutSettingsKey, layoutSettings);
+                        }
+                    });
+
+                layoutSettingsMenu->addAction(
+                    tr("Restore Default Layout"),
+                    [this]()
+                    {
+                        m_advancedDockManager->restoreState(m_defaultWindowState);
+                    });
+            });
+    }
+
     void AtomToolsMainWindow::SetupMetrics()
     {
         m_statusBarCpuTime = new QLabel(this);

+ 5 - 3
Gems/Atom/Tools/MaterialCanvas/Code/Source/Window/MaterialCanvasMainWindow.cpp

@@ -51,16 +51,18 @@ namespace MaterialCanvas
         // Inject the entity context, scene, content, and controller into the viewport widget
         m_materialViewport->Init(entityContext, viewportScene, viewportContent, viewportController);
 
-        AddDockWidget("Viewport", m_materialViewport, Qt::RightDockWidgetArea);
+        AddDockWidget("Viewport", m_materialViewport, Qt::BottomDockWidgetArea);
 
         m_viewportSettingsInspector = new AtomToolsFramework::EntityPreviewViewportSettingsInspector(m_toolId, this);
         AddDockWidget("Viewport Settings", m_viewportSettingsInspector, Qt::LeftDockWidgetArea);
         SetDockWidgetVisible("Viewport Settings", false);
 
-        AddDockWidget("MiniMap", aznew GraphCanvas::MiniMapDockWidget(m_toolId, this), Qt::RightDockWidgetArea);
-
         m_bookmarkDockWidget = aznew GraphCanvas::BookmarkDockWidget(m_toolId, this);
         AddDockWidget("Bookmarks", m_bookmarkDockWidget, Qt::BottomDockWidgetArea);
+        SetDockWidgetVisible("Bookmarks", false);
+
+        AddDockWidget("MiniMap", aznew GraphCanvas::MiniMapDockWidget(m_toolId, this), Qt::BottomDockWidgetArea);
+        SetDockWidgetVisible("MiniMap", false);
 
         GraphCanvas::NodePaletteConfig nodePaletteConfig;
         nodePaletteConfig.m_rootTreeItem = m_graphViewConfig.m_createNodeTreeItemsFn(m_toolId);