diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h index 71ca975f58..60eae524a5 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h @@ -44,6 +44,7 @@ namespace AtomToolsFramework const AZ::Uuid& instanceClassId, AzToolsFramework::IPropertyEditorNotify* instanceNotificationHandler = {}, QWidget* parent = {}, + const AZ::u32 saveStateKey = {}, const AzToolsFramework::InstanceDataHierarchy::ValueComparisonFunction& valueComparisonFunction = {}); void Refresh() override; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorPropertyGroupWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorPropertyGroupWidget.cpp index c4d78d1acb..b850b4a488 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorPropertyGroupWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorPropertyGroupWidget.cpp @@ -22,6 +22,7 @@ namespace AtomToolsFramework const AZ::Uuid& instanceClassId, AzToolsFramework::IPropertyEditorNotify* instanceNotificationHandler, QWidget* parent, + const AZ::u32 saveStateKey, const AzToolsFramework::InstanceDataHierarchy::ValueComparisonFunction& valueComparisonFunction) : InspectorGroupWidget(parent) { @@ -37,6 +38,7 @@ namespace AtomToolsFramework m_propertyEditor->SetHideRootProperties(true); m_propertyEditor->SetAutoResizeLabels(true); m_propertyEditor->SetValueComparisonFunction(valueComparisonFunction); + m_propertyEditor->SetSavedStateKey(saveStateKey); m_propertyEditor->Setup(context, instanceNotificationHandler, false); m_propertyEditor->AddInstance(instance, instanceClassId, nullptr, instanceToCompare); m_propertyEditor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h index bf572b070a..b28d4d662b 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h @@ -29,9 +29,6 @@ namespace MaterialEditor static void Reflect(AZ::ReflectContext* context); - bool m_enableGrid = true; - bool m_enableShadowCatcher = true; - bool m_enableAlternateSkybox = false; - float m_fieldOfView = 90.0f; + AZStd::vector m_mainWindowState; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp index 12e75f8fcf..e62dae2986 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp @@ -10,46 +10,50 @@ * */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - #include - #include #include #include #include #include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + #include -#include -#include -#include +#include #include #include +#include #include +#include #include -#include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT +#include +#include #include -#include +#include #include -#include #include +#include +#include AZ_POP_DISABLE_WARNING namespace MaterialEditor @@ -57,6 +61,15 @@ namespace MaterialEditor MaterialEditorWindow::MaterialEditorWindow(QWidget* parent /* = 0 */) : AzQtComponents::DockMainWindow(parent) { + resize(1280, 1024); + + // Among other things, we need the window wrapper to save the main window size, position, and state + auto mainWindowWrapper = + new AzQtComponents::WindowDecorationWrapper(AzQtComponents::WindowDecorationWrapper::OptionAutoTitleBarButtons); + mainWindowWrapper->setGuest(this); + mainWindowWrapper->enableSaveRestoreGeometry("amazon", "MaterialEditor", "mainWindowGeometry"); + + // set the style sheet for RPE highlighting and other styling AzQtComponents::StyleManager::setStyleSheet(this, QStringLiteral(":/MaterialEditor.qss")); QApplication::setWindowIcon(QIcon(":/Icons/materialtype.svg")); @@ -75,6 +88,7 @@ namespace MaterialEditor m_advancedDockManager = new AzQtComponents::FancyDocking(this); + setObjectName("MaterialEditorWindow"); setDockNestingEnabled(true); setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); @@ -82,17 +96,21 @@ namespace MaterialEditor setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); m_menuBar = new QMenuBar(this); + m_menuBar->setObjectName("MenuBar"); setMenuBar(m_menuBar); m_toolBar = new MaterialEditorToolBar(this); + m_toolBar->setObjectName("ToolBar"); addToolBar(m_toolBar); m_centralWidget = new QWidget(this); m_tabWidget = new AzQtComponents::TabWidget(m_centralWidget); + m_tabWidget->setObjectName("TabWidget"); m_tabWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); m_tabWidget->setContentsMargins(0, 0, 0, 0); m_materialViewport = new MaterialViewportWidget(m_centralWidget); + m_materialViewport->setObjectName("Viewport"); m_materialViewport->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); QVBoxLayout* vl = new QVBoxLayout(m_centralWidget); @@ -104,7 +122,8 @@ namespace MaterialEditor setCentralWidget(m_centralWidget); m_statusBar = new StatusBarWidget(this); - this->statusBar()->addPermanentWidget(m_statusBar, 1); + m_statusBar->setObjectName("StatusBar"); + statusBar()->addPermanentWidget(m_statusBar, 1); SetupMenu(); SetupTabs(); @@ -119,27 +138,26 @@ namespace MaterialEditor SetDockWidgetVisible("Performance Monitor", false); SetDockWidgetVisible("Python Terminal", false); + // Restore geometry and show the window + mainWindowWrapper->showFromSettings(); + + // Restore additional state for docked windows + auto windowSettings = AZ::UserSettings::CreateFind( + AZ::Crc32("MaterialEditorwindowSettings"), AZ::UserSettings::CT_GLOBAL); + + if (!windowSettings->m_mainWindowState.empty()) + { + QByteArray windowState(windowSettings->m_mainWindowState.data(), windowSettings->m_mainWindowState.size()); + m_advancedDockManager->restoreState(windowState); + } + MaterialEditorWindowRequestBus::Handler::BusConnect(); MaterialDocumentNotificationBus::Handler::BusConnect(); OnDocumentOpened(AZ::Uuid::CreateNull()); - - auto windowState = AZ::UserSettings::Find( - AZ::Crc32("MaterialEditorWindowState"), AZ::UserSettings::CT_GLOBAL); - if (windowState) - { - windowState->RestoreGeometry(this); - } } MaterialEditorWindow::~MaterialEditorWindow() { - auto windowState = AZ::UserSettings::CreateFind( - AZ::Crc32("MaterialEditorWindowState"), AZ::UserSettings::CT_GLOBAL); - if (windowState) - { - windowState->CaptureGeometry(this); - } - MaterialDocumentNotificationBus::Handler::BusDisconnect(); MaterialEditorWindowRequestBus::Handler::BusDisconnect(); } @@ -159,8 +177,9 @@ namespace MaterialEditor } auto dockWidget = new AzQtComponents::StyledDockWidget(name.c_str()); - dockWidget->setObjectName(name.c_str()); + dockWidget->setObjectName(QString("%1_DockWidget").arg(name.c_str())); dockWidget->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable); + widget->setObjectName(name.c_str()); widget->setParent(dockWidget); widget->setMinimumSize(QSize(300, 300)); dockWidget->setWidget(widget); @@ -218,15 +237,16 @@ namespace MaterialEditor QSize requestedWindowSize = size() + offset; resize(requestedWindowSize); - AZ_Assert(m_materialViewport->size() == requestedViewportSize, + AZ_Assert( + m_materialViewport->size() == requestedViewportSize, "Resizing the window did not give the expected viewport size. Requested %d x %d but got %d x %d.", - requestedViewportSize.width(), requestedViewportSize.height(), - m_materialViewport->size().width(), m_materialViewport->size().height()); + requestedViewportSize.width(), requestedViewportSize.height(), m_materialViewport->size().width(), + m_materialViewport->size().height()); QSize newDeviceSize = m_materialViewport->size(); - AZ_Warning("Material Editor", newDeviceSize.width() == width && newDeviceSize.height() == height, - "Resizing the window did not give the expected frame size. Requested %d x %d but got %d x %d.", - width, height, + AZ_Warning( + "Material Editor", newDeviceSize.width() == width && newDeviceSize.height() == height, + "Resizing the window did not give the expected frame size. Requested %d x %d but got %d x %d.", width, height, newDeviceSize.width(), newDeviceSize.height()); } @@ -250,6 +270,13 @@ namespace MaterialEditor return; } + // Capture docking state before shutdown + auto windowSettings = AZ::UserSettings::CreateFind( + AZ::Crc32("MaterialEditorwindowSettings"), AZ::UserSettings::CT_GLOBAL); + + QByteArray windowState = m_advancedDockManager->saveState(); + windowSettings->m_mainWindowState.assign(windowState.begin(), windowState.end()); + MaterialEditorWindowNotificationBus::Broadcast(&MaterialEditorWindowNotifications::OnMaterialEditorWindowClosing); } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp index 3d796a21ad..b0e8533ba4 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp @@ -101,7 +101,6 @@ namespace MaterialEditor m_materialEditorBrowserInteractions.reset(aznew MaterialEditorBrowserInteractions); m_window.reset(aznew MaterialEditorWindow); - m_window->show(); } void MaterialEditorWindowComponent::DestroyMaterialEditorWindow() diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp index a9c928df10..5ea23de8c6 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp @@ -22,11 +22,8 @@ namespace MaterialEditor { serializeContext->Class() ->Version(1) - ->Field("enableGrid", &MaterialEditorWindowSettings::m_enableGrid) - ->Field("enableShadowCatcher", &MaterialEditorWindowSettings::m_enableShadowCatcher) - ->Field("enableAlternateSkybox", &MaterialEditorWindowSettings::m_enableAlternateSkybox) - ->Field("fieldOfView", &MaterialEditorWindowSettings::m_fieldOfView) - ; + ->Field("mainWindowState", &MaterialEditorWindowSettings::m_mainWindowState) + ; if (auto editContext = serializeContext->GetEditContext()) { @@ -34,12 +31,6 @@ namespace MaterialEditor "MaterialEditorWindowSettings", "") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialEditorWindowSettings::m_enableGrid, "Enable Grid", "") - ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialEditorWindowSettings::m_enableShadowCatcher, "Enable Shadow Catcher", "") - ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialEditorWindowSettings::m_enableAlternateSkybox, "Enable Alternate Skybox", "") - ->DataElement(AZ::Edit::UIHandlers::Slider, &MaterialEditorWindowSettings::m_fieldOfView, "Field Of View", "") - ->Attribute(AZ::Edit::Attributes::Min, 60.0f) - ->Attribute(AZ::Edit::Attributes::Max, 120.0f) ; } } @@ -52,10 +43,6 @@ namespace MaterialEditor ->Attribute(AZ::Script::Attributes::Module, "render") ->Constructor() ->Constructor() - ->Property("enableGrid", BehaviorValueProperty(&MaterialEditorWindowSettings::m_enableGrid)) - ->Property("enableShadowCatcher", BehaviorValueProperty(&MaterialEditorWindowSettings::m_enableShadowCatcher)) - ->Property("enableAlternateSkybox", BehaviorValueProperty(&MaterialEditorWindowSettings::m_enableAlternateSkybox)) - ->Property("fieldOfView", BehaviorValueProperty(&MaterialEditorWindowSettings::m_fieldOfView)) ; } } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp index b066c3c7dd..dffbd43702 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp @@ -39,6 +39,7 @@ namespace MaterialEditor void MaterialInspector::Reset() { + m_documentPath.clear(); m_documentId = AZ::Uuid::CreateNull(); m_groups = {}; @@ -55,6 +56,8 @@ namespace MaterialEditor bool isOpen = false; MaterialDocumentRequestBus::EventResult(isOpen, m_documentId, &MaterialDocumentRequestBus::Events::IsOpen); + MaterialDocumentRequestBus::EventResult(m_documentPath, m_documentId, &MaterialDocumentRequestBus::Events::GetAbsolutePath); + if (!m_documentId.IsNull() && isOpen) { // Create the top group for displaying details about the material @@ -89,7 +92,10 @@ namespace MaterialEditor group.m_properties.push_back(property); // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(&group, &group, group.TYPEINFO_Uuid(), this, this, + const AZ::Crc32 saveStateKey( + AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupDisplayName.c_str())); + auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( + &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { AZ_UNUSED(source); const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); @@ -121,7 +127,10 @@ namespace MaterialEditor } // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(&group, &group, group.TYPEINFO_Uuid(), this, this, + const AZ::Crc32 saveStateKey( + AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupDisplayName.c_str())); + auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( + &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { AZ_UNUSED(source); const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); @@ -156,7 +165,10 @@ namespace MaterialEditor } // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(&group, &group, group.TYPEINFO_Uuid(), this, this, + const AZ::Crc32 saveStateKey( + AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupDisplayName.c_str())); + auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( + &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { AZ_UNUSED(source); const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h index efe979e5ea..a7a4dddbaa 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h @@ -64,6 +64,7 @@ namespace MaterialEditor const AtomToolsFramework::DynamicProperty* m_activeProperty = nullptr; AZ::Uuid m_documentId = AZ::Uuid::CreateNull(); + AZStd::string m_documentPath; AZStd::unordered_map m_groups; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp index 22e752dddd..384644f79c 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp @@ -58,9 +58,11 @@ namespace MaterialEditor const AZStd::string groupDisplayName = "General"; const AZStd::string groupDescription = "General"; + const AZ::Crc32 saveStateKey(AZStd::string::format("ViewportSettingsInspector::GeneralGroup")); AddGroup( groupNameId, groupDisplayName, groupDescription, - new AtomToolsFramework::InspectorPropertyGroupWidget(m_viewportSettings.get(), nullptr, m_viewportSettings->TYPEINFO_Uuid(), this)); + new AtomToolsFramework::InspectorPropertyGroupWidget( + m_viewportSettings.get(), nullptr, m_viewportSettings->TYPEINFO_Uuid(), this, this, saveStateKey)); } void ViewportSettingsInspector::AddModelGroup() @@ -92,8 +94,9 @@ namespace MaterialEditor if (m_modelPreset) { + const AZ::Crc32 saveStateKey(AZStd::string::format("ViewportSettingsInspector::ModelGroup")); auto inspectorWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( - m_modelPreset.get(), nullptr, m_modelPreset.get()->TYPEINFO_Uuid(), this, groupWidget); + m_modelPreset.get(), nullptr, m_modelPreset.get()->TYPEINFO_Uuid(), this, groupWidget, saveStateKey); groupWidget->layout()->addWidget(inspectorWidget); } @@ -179,8 +182,9 @@ namespace MaterialEditor if (m_lightingPreset) { + const AZ::Crc32 saveStateKey(AZStd::string::format("ViewportSettingsInspector::LightingGroup")); auto inspectorWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( - m_lightingPreset.get(), nullptr, m_lightingPreset.get()->TYPEINFO_Uuid(), this, groupWidget); + m_lightingPreset.get(), nullptr, m_lightingPreset.get()->TYPEINFO_Uuid(), this, groupWidget, saveStateKey); groupWidget->layout()->addWidget(inspectorWidget); } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp index 03533e142f..1ae0610169 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp @@ -213,7 +213,11 @@ namespace AZ } // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(&group, &group, group.TYPEINFO_Uuid(), this, this, + const AZ::Crc32 saveStateKey(AZStd::string::format( + "MaterialPropertyInspector::PropertyGroup::%s::%s", m_materialAssetId.ToString().c_str(), + groupDisplayName.c_str())); + auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( + &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { AZ_UNUSED(source); const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); @@ -262,7 +266,11 @@ namespace AZ } // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(&group, &group, group.TYPEINFO_Uuid(), this, this, + const AZ::Crc32 saveStateKey(AZStd::string::format( + "MaterialPropertyInspector::PropertyGroup::%s::%s", m_materialAssetId.ToString().c_str(), + groupDisplayName.c_str())); + auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( + &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { AZ_UNUSED(source); const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target);