From 027cb57373e9e28ea5565e32e5dd8044503ff86f Mon Sep 17 00:00:00 2001 From: codereader Date: Sat, 6 Aug 2022 10:07:23 +0200 Subject: [PATCH] #6045: Save/restore a few MaterialEditor settings --- .../ui/materials/editor/MaterialEditor.cpp | 62 +++++++++++++++- radiant/ui/materials/editor/MaterialEditor.h | 3 + .../ui/materials/editor/MaterialPreview.cpp | 73 +++++++++++++++++-- radiant/ui/materials/editor/MaterialPreview.h | 14 ++++ 4 files changed, 140 insertions(+), 12 deletions(-) diff --git a/radiant/ui/materials/editor/MaterialEditor.cpp b/radiant/ui/materials/editor/MaterialEditor.cpp index a593c77dd7..6da1656d59 100644 --- a/radiant/ui/materials/editor/MaterialEditor.cpp +++ b/radiant/ui/materials/editor/MaterialEditor.cpp @@ -38,7 +38,6 @@ #include "CheckBoxBinding.h" #include "MapExpressionEntry.h" #include "TexturePreview.h" -#include "string/trim.h" #include "ui/common/ShaderChooser.h" namespace ui @@ -48,14 +47,20 @@ namespace { const char* const DIALOG_TITLE = N_("Material Editor"); - const char* const ICON_STAGE_VISIBLE = "visible.png"; - const char* const ICON_STAGE_INVISIBLE = "invisible.png"; - const char* const ICON_GLOBAL_SETTINGS = "icon_texture.png"; + constexpr const char* const ICON_STAGE_VISIBLE = "visible.png"; + constexpr const char* const ICON_STAGE_INVISIBLE = "invisible.png"; + constexpr const char* const ICON_GLOBAL_SETTINGS = "icon_texture.png"; const std::string RKEY_ROOT = "user/ui/materialEditor/"; const std::string RKEY_SPLIT_POS = RKEY_ROOT + "splitPos"; const std::string RKEY_WINDOW_STATE = RKEY_ROOT + "window"; + const std::string RKEY_LIGHTING_MODE_ENABLED = RKEY_ROOT + "lightModeEnabled"; + const std::string RKEY_LAST_SELECTED_MATERIAL = RKEY_ROOT + "lastSelectedMaterial"; + const std::string RKEY_PREVIEW_LIGHT_CLASSNAME = RKEY_ROOT + "previewLightClassname"; + const std::string RKEY_PREVIEW_ROOM_MATERIAL = RKEY_ROOT + "previewRoomMaterial"; + const std::string RKEY_PREVIEW_OBJECT_TYPE = RKEY_ROOT + "previewObjectType"; + const char* const CUSTOM_BLEND_TYPE = N_("Custom"); // Columns for the stages list @@ -213,8 +218,12 @@ int MaterialEditor::ShowModal() _treeView->SetSelectedDeclName(_materialToPreselect); } + loadSettings(); + int returnCode = DialogBase::ShowModal(); + saveSettings(); + // Tell the position tracker to save the information _windowPosition.saveToPath(RKEY_WINDOW_STATE); @@ -235,6 +244,51 @@ int MaterialEditor::ShowModal(const std::string& materialToPreselect) return ShowModal(); } +void MaterialEditor::loadSettings() +{ + if (_materialToPreselect.empty()) + { + _materialToPreselect = registry::getValue(RKEY_LAST_SELECTED_MATERIAL); + + if (!_materialToPreselect.empty()) + { + _treeView->SetSelectedDeclName(_materialToPreselect); + } + } + + _preview->setStartupLightingMode(registry::getValue(RKEY_LIGHTING_MODE_ENABLED)); + + auto storedClassname = registry::getValue(RKEY_PREVIEW_LIGHT_CLASSNAME); + + if (!storedClassname.empty()) + { + _preview->setLightClassname(storedClassname); + } + + auto storedRoomMaterial = registry::getValue(RKEY_PREVIEW_ROOM_MATERIAL); + + if (!storedRoomMaterial.empty()) + { + _preview->setRoomMaterial(storedRoomMaterial); + } + + auto storedTestModelType = registry::getValue(RKEY_PREVIEW_OBJECT_TYPE); + + if (!storedTestModelType.empty()) + { + _preview->setTestModelType(MaterialPreview::GetTestModelType(storedTestModelType)); + } +} + +void MaterialEditor::saveSettings() +{ + registry::setValue(RKEY_LAST_SELECTED_MATERIAL, _treeView->GetSelectedDeclName()); + registry::setValue(RKEY_LIGHTING_MODE_ENABLED, _preview->getLightingModeEnabled()); + registry::setValue(RKEY_PREVIEW_LIGHT_CLASSNAME, _preview->getLightClassname()); + registry::setValue(RKEY_PREVIEW_ROOM_MATERIAL, _preview->getRoomMaterial()); + registry::setValue(RKEY_PREVIEW_OBJECT_TYPE, MaterialPreview::GetTestModelTypeName(_preview->getTestModelType())); +} + void MaterialEditor::setupSourceTextPanel(wxWindow* previewPanel) { auto sourceTextPanel = new wxCollapsiblePane(previewPanel, wxID_ANY, _("Material Source Text")); diff --git a/radiant/ui/materials/editor/MaterialEditor.h b/radiant/ui/materials/editor/MaterialEditor.h index 1f12e5e713..d3148f5b49 100644 --- a/radiant/ui/materials/editor/MaterialEditor.h +++ b/radiant/ui/materials/editor/MaterialEditor.h @@ -105,6 +105,9 @@ class MaterialEditor : bool _onDeleteEvent() override; private: + void loadSettings(); + void saveSettings(); + // Asks user to save each unmodified material. // Returns true if it is safe to go ahead and close the dialog bool okToCloseDialog(); diff --git a/radiant/ui/materials/editor/MaterialPreview.cpp b/radiant/ui/materials/editor/MaterialPreview.cpp index eec3307446..4d586fc503 100644 --- a/radiant/ui/materials/editor/MaterialPreview.cpp +++ b/radiant/ui/materials/editor/MaterialPreview.cpp @@ -29,7 +29,8 @@ MaterialPreview::MaterialPreview(wxWindow* parent) : RenderPreview(parent, true), _sceneIsReady(false), _roomMaterial(game::current::getValue(GKEY_DEFAULT_ROOM_MATERIAL)), - _defaultCamDistanceFactor(2.0f) + _defaultCamDistanceFactor(2.0f), + _lightClassname(getDefaultLightDef()) { _testModelSkin = std::make_unique("model"); _testRoomSkin = std::make_unique("room"); @@ -48,7 +49,7 @@ MaterialPreview::~MaterialPreview() void MaterialPreview::setupToolbar() { - // Add one additional toolbar for particle-related stuff + // Add one additional toolbar wxToolBar* toolbar = new wxToolBar(_mainPanel, wxID_ANY); toolbar->SetToolBitmapSize(wxSize(16, 16)); @@ -103,6 +104,44 @@ void MaterialPreview::setRoomMaterial(const std::string& material) signal_SceneChanged().emit(); } +MaterialPreview::TestModel MaterialPreview::getTestModelType() +{ + if (_testModelCubeButton->IsToggled()) return TestModel::Cube; + if (_testModelSphereButton->IsToggled()) return TestModel::Sphere; + if (_testModelTilesButton->IsToggled()) return TestModel::Tiles; + + return TestModel::Cube; +} + +void MaterialPreview::setTestModelType(TestModel type) +{ + _testModelCubeButton->SetToggle(type == TestModel::Cube); + _testModelSphereButton->SetToggle(type == TestModel::Sphere); + _testModelTilesButton->SetToggle(type == TestModel::Tiles); + + setupTestModel(); +} + +std::string MaterialPreview::GetTestModelTypeName(TestModel type) +{ + switch (type) + { + case TestModel::Cube: return "Cube"; + case TestModel::Sphere: return "Sphere"; + case TestModel::Tiles: return "Tiles"; + default: throw std::invalid_argument("Unknown preview model type"); + } +} + +MaterialPreview::TestModel MaterialPreview::GetTestModelType(const std::string& typeName) +{ + if (typeName == "Cube") return TestModel::Cube; + if (typeName == "Sphere") return TestModel::Sphere; + if (typeName == "Tiles") return TestModel::Tiles; + + return TestModel::Cube; // in case bad serialization data reaches this point +} + std::string MaterialPreview::getDefaultLightDef() { auto className = game::current::getValue(GKEY_DEFAULT_LIGHT_DEF); @@ -237,8 +276,7 @@ void MaterialPreview::setupSceneGraph() getScene()->setRoot(_rootNode); // Set up the light - _light = GlobalEntityModule().createEntity( - GlobalEntityClassManager().findClass(getDefaultLightDef())); + _light = GlobalEntityModule().createEntity(GlobalEntityClassManager().findClass(_lightClassname)); Node_getEntity(_light)->setKeyValue("light_radius", "750 750 750"); Node_getEntity(_light)->setKeyValue("origin", "150 150 150"); @@ -276,6 +314,8 @@ void MaterialPreview::setupRoom() void MaterialPreview::setupTestModel() { + if (!_entity) return; // too early + if (_entity && _model) { scene::removeNodeFromParent(_model); @@ -304,7 +344,21 @@ void MaterialPreview::setupTestModel() void MaterialPreview::onTestModelSelectionChanged(wxCommandEvent& ev) { - setupTestModel(); + if (!ev.IsChecked()) return; // ígnore un-check events + + if (ev.GetId() == _testModelCubeButton->GetId()) + { + setTestModelType(TestModel::Cube); + } + else if (ev.GetId() == _testModelSphereButton->GetId()) + { + setTestModelType(TestModel::Sphere); + } + else if (ev.GetId() == _testModelTilesButton->GetId()) + { + setTestModelType(TestModel::Tiles); + } + queueDraw(); } @@ -315,14 +369,17 @@ sigc::signal& MaterialPreview::signal_SceneChanged() std::string MaterialPreview::getLightClassname() { - return _light ? Node_getEntity(_light)->getEntityClass()->getDeclName() : ""; + return _lightClassname; } void MaterialPreview::setLightClassname(const std::string& className) { - if (!_light || className.empty()) return; + // Store this value locally, even if we don't have any light to adjust yet + _lightClassname = className; + + if (!_light || _lightClassname.empty()) return; - _light = changeEntityClassname(_light, className); + _light = changeEntityClassname(_light, _lightClassname); signal_SceneChanged().emit(); } diff --git a/radiant/ui/materials/editor/MaterialPreview.h b/radiant/ui/materials/editor/MaterialPreview.h index f8643a9343..5e82b2463c 100644 --- a/radiant/ui/materials/editor/MaterialPreview.h +++ b/radiant/ui/materials/editor/MaterialPreview.h @@ -34,6 +34,7 @@ class MaterialPreview : std::shared_ptr _testRoomSkin; std::string _roomMaterial; + std::string _lightClassname; float _defaultCamDistanceFactor; @@ -44,6 +45,13 @@ class MaterialPreview : sigc::signal _sigSceneChanged; public: + enum class TestModel + { + Cube, + Sphere, + Tiles, + }; + MaterialPreview(wxWindow* parent); virtual ~MaterialPreview(); @@ -63,6 +71,12 @@ class MaterialPreview : const std::string& getRoomMaterial(); void setRoomMaterial(const std::string& material); + TestModel getTestModelType(); + void setTestModelType(TestModel type); + + static std::string GetTestModelTypeName(TestModel type); + static TestModel GetTestModelType(const std::string& typeName); + sigc::signal& signal_SceneChanged(); protected: