diff --git a/include/config/porymapconfig.h b/include/config/porymapconfig.h index e0075578..94e48e89 100644 --- a/include/config/porymapconfig.h +++ b/include/config/porymapconfig.h @@ -45,7 +45,6 @@ public: bool reopenOnLaunch = true; bool projectManuallyClosed = false; - int mapListTab = 0; bool mapListEditGroupsEnabled = false; OrderedSet mapListTabsHidingEmptyFolders; bool mapListLayoutsSorted = true; @@ -80,7 +79,6 @@ public: QString textEditorOpenFolder; QString textEditorGotoLine; int paletteEditorBitDepth = 24; - int projectSettingsTab = 0; ScriptAutocompleteMode scriptAutocompleteMode = ScriptAutocompleteMode::MapOnly; bool warpBehaviorWarningDisabled = false; bool eventDeleteWarningDisabled = false; @@ -113,7 +111,6 @@ public: m_fm = std::make_shared(); m_fm->addField(&this->reopenOnLaunch, "reopen_on_launch"); m_fm->addField(&this->projectManuallyClosed, "project_manually_closed"); - m_fm->addField(&this->mapListTab, "map_list_tab", 0, 2); m_fm->addField(&this->mapListEditGroupsEnabled, "map_list_edit_groups_enabled"); m_fm->addField(&this->mapListTabsHidingEmptyFolders, "map_list_tabs_hiding_empty_folders"); m_fm->addField(&this->mapListLayoutsSorted, "map_list_layouts_sorted"); @@ -148,7 +145,6 @@ public: m_fm->addField(&this->textEditorOpenFolder, "text_editor_open_folder"); m_fm->addField(&this->textEditorGotoLine, "text_editor_goto_line"); m_fm->addField(&this->paletteEditorBitDepth, "palette_editor_bit_depth", {24,15}); - m_fm->addField(&this->projectSettingsTab, "project_settings_tab"); m_fm->addField(&this->scriptAutocompleteMode, "script_autocomplete_mode"); m_fm->addField(&this->warpBehaviorWarningDisabled, "warp_behavior_warning_disabled"); m_fm->addField(&this->eventDeleteWarningDisabled, "event_delete_warning_disabled"); @@ -179,6 +175,11 @@ protected: virtual QJsonObject getDefaultJson() const override; private: + static QList findChildrenWithStates(const QWidget* widget); + static QByteArray getWidgetState(const QWidget* widget); + static void restoreWidgetState(QWidget* widget, const QByteArray& state); + + std::shared_ptr m_fm = nullptr; QStringList recentProjects; QMap savedGeometryMap; diff --git a/include/mainwindow.h b/include/mainwindow.h index 69125f11..19360006 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -302,7 +302,6 @@ private slots: void on_actionOpen_Manual_triggered(); void on_actionCheck_for_Updates_triggered(); void togglePreferenceSpecificUi(); - void on_actionProject_Settings_triggered(); void on_actionPlugins_triggered(); void reloadScriptEngine(); void on_actionShow_Grid_triggered(); @@ -420,7 +419,7 @@ private: void setMapListSorted(MapTree *list, bool sort); void updateMapList(); void openMapListItem(const QModelIndex &index); - void onMapListTabChanged(int index); + void setMapListTab(int index); QString getActiveItemName(); void recordMapNavigation(const QString &itemName); void resetMapNavigation(); @@ -456,7 +455,7 @@ private: void initShortcutsEditor(); void initPluginEditor(); void connectSubEditorsToShortcutsEditor(); - void openProjectSettingsEditor(int tab); + void openProjectSettingsEditor(int tab = -1); bool isProjectOpen(); void showExportMapImageWindow(ImageExporterMode mode); double getMetatilesZoomScale(); diff --git a/include/ui/projectsettingseditor.h b/include/ui/projectsettingseditor.h index 5305d5e3..30121ca1 100644 --- a/include/ui/projectsettingseditor.h +++ b/include/ui/projectsettingseditor.h @@ -81,7 +81,6 @@ private slots: void updateAttributeLimits(const QString &attrSize); void updatePokemonIconPath(const QString &species); void markEdited(); - void on_mainTabs_tabBarClicked(int index); void updateBlockMaskOverlapWarning(); void updateAttributeMaskOverlapWarning(); void updateWarpBehaviorsList(bool adding); diff --git a/src/config/legacy.cpp b/src/config/legacy.cpp index 767fcaec..6a6c0520 100644 --- a/src/config/legacy.cpp +++ b/src/config/legacy.cpp @@ -89,8 +89,6 @@ bool PorymapConfig::parseLegacyKeyValue(const QString &key, const QString &value this->reopenOnLaunch = toBool(value); } else if (key == "pretty_cursors") { this->prettyCursors = toBool(value); - } else if (key == "map_list_tab") { - this->mapListTab = toInt(value, 0, 2, 0); } else if (key == "map_list_edit_groups_enabled") { this->mapListEditGroupsEnabled = toBool(value); } else if (key.startsWith("map_list_hide_empty_enabled/")) { @@ -161,8 +159,6 @@ bool PorymapConfig::parseLegacyKeyValue(const QString &key, const QString &value if (bitDepth == 15 || bitDepth == 24){ this->paletteEditorBitDepth = bitDepth; } - } else if (key == "project_settings_tab") { - this->projectSettingsTab = toInt(value, 0); } else if (key == "load_all_event_scripts") { // Old setting replaced by script_autocomplete_mode this->scriptAutocompleteMode = toBool(value) ? ScriptAutocompleteMode::All : ScriptAutocompleteMode::MapOnly; } else if (key == "script_autocomplete_mode") { diff --git a/src/config/porymapconfig.cpp b/src/config/porymapconfig.cpp index 70eeb0d7..b8881c73 100644 --- a/src/config/porymapconfig.cpp +++ b/src/config/porymapconfig.cpp @@ -58,49 +58,82 @@ const QStringList& PorymapConfig::getRecentProjects() const { return this->recentProjects; } +QList PorymapConfig::findChildrenWithStates(const QWidget* widget) { + QList children; + for (const auto& c : widget->findChildren()) children.append(qobject_cast(c)); + for (const auto& c : widget->findChildren()) children.append(qobject_cast(c)); + return children; +} + void PorymapConfig::saveGeometry(const QWidget* widget, const QString& keyPrefix, bool recursive) { if (!widget || widget->objectName().isEmpty()) return; const QString key = keyPrefix + widget->objectName(); - this->savedGeometryMap.insert(key, widget->saveGeometry()); + if (!widget->parentWidget()) { // Only save geometry for top-level widgets; + this->savedGeometryMap.insert(key, widget->saveGeometry()); + } // In addition to geometry, some widgets have other states that can be saved/restored. - const QString stateKey = key + QStringLiteral("/State"); - auto mainWindow = qobject_cast(widget); - if (mainWindow) this->savedGeometryMap.insert(stateKey, mainWindow->saveState()); - else { - auto splitter = qobject_cast(widget); - if (splitter) this->savedGeometryMap.insert(stateKey, splitter->saveState()); + const QByteArray state = getWidgetState(widget); + if (!state.isEmpty()) { + this->savedGeometryMap.insert(key + QStringLiteral("/State"), state); } + if (recursive) { - for (const auto& splitter : widget->findChildren()) { - saveGeometry(splitter, key + "_", false); + for (const auto& child : findChildrenWithStates(widget)) { + saveGeometry(child, key + "_", false); } } } +QByteArray PorymapConfig::getWidgetState(const QWidget* widget) { + auto mainWindow = qobject_cast(widget); + if (mainWindow) return mainWindow->saveState(); + + auto splitter = qobject_cast(widget); + if (splitter) return splitter->saveState(); + + auto tabWidget = qobject_cast(widget); + if (tabWidget) return QString::number(tabWidget->currentIndex()).toUtf8(); + + return QByteArray(); +} + bool PorymapConfig::restoreGeometry(QWidget* widget, const QString& keyPrefix, bool recursive) const { if (!widget || widget->objectName().isEmpty()) return false; const QString key = keyPrefix + widget->objectName(); auto it = this->savedGeometryMap.constFind(key); - if (it == this->savedGeometryMap.constEnd()) return false; - widget->restoreGeometry(it.value()); + if (it != this->savedGeometryMap.constEnd()) { + widget->restoreGeometry(it.value()); + } // In addition to geometry, some widgets have other states that can be saved/restored. it = this->savedGeometryMap.constFind(key + QStringLiteral("/State")); - if (it != this->savedGeometryMap.constEnd()) { - auto mainWindow = qobject_cast(widget); - if (mainWindow) mainWindow->restoreState(it.value()); - else { - auto splitter = qobject_cast(widget); - if (splitter) splitter->restoreState(it.value()); - } - } + if (it != this->savedGeometryMap.constEnd()) restoreWidgetState(widget, it.value()); + if (recursive) { - for (const auto& splitter : widget->findChildren()) { - restoreGeometry(splitter, key + "_", false); + for (const auto& child : findChildrenWithStates(widget)) { + restoreGeometry(child, key + "_", false); } } return true; } + +void PorymapConfig::restoreWidgetState(QWidget* widget, const QByteArray& state) { + auto mainWindow = qobject_cast(widget); + if (mainWindow) { + mainWindow->restoreState(state); + return; + } + auto splitter = qobject_cast(widget); + if (splitter) { + splitter->restoreState(state); + return; + } + auto tabWidget = qobject_cast(widget); + if (tabWidget) { + tabWidget->setCurrentIndex(QString::fromUtf8(state).toInt()); + return; + } +} diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ec97bcb6..7d4de337 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -398,6 +398,7 @@ void MainWindow::initExtraSignals() { connect(ui->actionDuplicate_Current_Layout, &QAction::triggered, [this] { if (this->editor->layout) openDuplicateLayoutDialog(this->editor->layout->id); }); + connect(ui->actionProject_Settings, &QAction::triggered, this, &MainWindow::openProjectSettingsEditor); } void MainWindow::on_actionCheck_for_Updates_triggered() { @@ -501,8 +502,6 @@ void MainWindow::initMiscHeapObjects() { } void MainWindow::initMapList() { - ui->mapListContainer->setCurrentIndex(porymapConfig.mapListTab); - auto noScrollFilter = new NoScrollFilter(this, false); ui->mainTabBar->installEventFilter(noScrollFilter); ui->mapListContainer->tabBar()->installEventFilter(noScrollFilter); @@ -624,7 +623,7 @@ void MainWindow::initMapList() { connect(ui->mapListToolBar_Locations, &MapListToolBar::addFolderClicked, this, &MainWindow::openNewLocationDialog); connect(ui->mapListToolBar_Layouts, &MapListToolBar::addFolderClicked, this, &MainWindow::openNewLayoutDialog); - connect(ui->mapListContainer, &QTabWidget::currentChanged, this, &MainWindow::onMapListTabChanged); + connect(ui->mapListContainer, &QTabWidget::tabBarClicked, this, &MainWindow::setMapListTab); } void MainWindow::updateWindowTitle() { @@ -1241,7 +1240,7 @@ bool MainWindow::userSetLayout(const QString &layoutId) { recordMapNavigation(prevItem); // Only the Layouts tab of the map list shows Layouts, so if we're not already on that tab we'll open it now. - ui->mapListContainer->setCurrentIndex(MapListTab::Layouts); + setMapListTab(MapListTab::Layouts); return true; } @@ -1897,16 +1896,14 @@ void MainWindow::currentMetatilesSelectionChanged() { scrollMetatileSelectorToSelection(); } -void MainWindow::onMapListTabChanged(int index) { +void MainWindow::setMapListTab(int index) { auto newToolbar = getMapListToolBar(index); - auto oldToolbar = getMapListToolBar(porymapConfig.mapListTab); + auto oldToolbar = getMapListToolBar(ui->mapListContainer->currentIndex()); + ui->mapListContainer->setCurrentIndex(index); if (newToolbar && oldToolbar && newToolbar != oldToolbar) { newToolbar->applyFilter(oldToolbar->filterText()); } - // Save current tab for future sessions. - porymapConfig.mapListTab = index; - // After changing a map list tab the old tab's search widget can keep focus, which isn't helpful // (and might be a little confusing to the user, because they don't know that each search bar is secretly a separate object). // When we change tabs we'll automatically focus in on the search bar. This should also make finding maps a little quicker. @@ -3072,14 +3069,10 @@ void MainWindow::openProjectSettingsEditor(int tab) { connect(this->projectSettingsEditor, &ProjectSettingsEditor::reloadProject, this, &MainWindow::on_action_Reload_Project_triggered); } - this->projectSettingsEditor->setTab(tab); + if (tab >= 0) this->projectSettingsEditor->setTab(tab); Util::show(this->projectSettingsEditor); } -void MainWindow::on_actionProject_Settings_triggered() { - this->openProjectSettingsEditor(porymapConfig.projectSettingsTab); -} - void MainWindow::onWarpBehaviorWarningClicked() { static const QString informative = QStringLiteral( "

" diff --git a/src/ui/preferenceeditor.cpp b/src/ui/preferenceeditor.cpp index a25e08f8..9fbeb182 100644 --- a/src/ui/preferenceeditor.cpp +++ b/src/ui/preferenceeditor.cpp @@ -2,6 +2,7 @@ #include "ui_preferenceeditor.h" #include "message.h" #include "tile.h" +#include "eventfilters.h" #include #include @@ -36,6 +37,7 @@ PreferenceEditor::PreferenceEditor(QWidget *parent) : initFields(); updateFields(); + installEventFilter(new GeometrySaver(this)); } PreferenceEditor::~PreferenceEditor() diff --git a/src/ui/projectsettingseditor.cpp b/src/ui/projectsettingseditor.cpp index 6e81ba02..34824306 100644 --- a/src/ui/projectsettingseditor.cpp +++ b/src/ui/projectsettingseditor.cpp @@ -211,14 +211,8 @@ BaseGame::Version ProjectSettingsEditor::getBaseGameVersion() const { return static_cast(ui->comboBox_BaseGameVersion->currentData().toInt()); } -// Remember the current settings tab for future sessions -void ProjectSettingsEditor::on_mainTabs_tabBarClicked(int index) { - porymapConfig.projectSettingsTab = index; -} - void ProjectSettingsEditor::setTab(int index) { ui->mainTabs->setCurrentIndex(index); - porymapConfig.projectSettingsTab = index; } void ProjectSettingsEditor::setBorderMetatilesUi(bool customSize) {