diff --git a/include/mainwindow.h b/include/mainwindow.h index 2de8955b..73408817 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -351,6 +351,7 @@ private: bool isProgrammaticEventTabChange; bool tilesetNeedsRedraw = false; + bool lockMapListAutoScroll = false; bool setLayout(const QString &layoutId); bool setMap(const QString &mapName); @@ -383,7 +384,7 @@ private: void scrollMapList(MapTree *list, const QString &itemName); void scrollMapListToCurrentMap(MapTree *list); void scrollMapListToCurrentLayout(MapTree *list); - void resetMapListFilters(); + void scrollCurrentMapListToItem(const QString &itemName); void showFileWatcherWarning(); QString getExistingDirectory(QString); bool openProject(QString dir, bool initial = false); diff --git a/include/ui/maplisttoolbar.h b/include/ui/maplisttoolbar.h index 77737db6..8e136e53 100644 --- a/include/ui/maplisttoolbar.h +++ b/include/ui/maplisttoolbar.h @@ -32,10 +32,10 @@ public: void expandList(); void collapseList(); + QString filterText() const; void applyFilter(const QString &filterText); + void refreshFilter(); void clearFilter(); - void setFilterLocked(bool locked) { m_filterLocked = locked; } - bool isFilterLocked() const { return m_filterLocked; } void setExpandListForSearch(bool expand) { m_expandListForSearch = expand; } bool getExpandListForSearch() const { return m_expandListForSearch; } @@ -51,7 +51,6 @@ signals: private: Ui::MapListToolBar *ui; QPointer m_list; - bool m_filterLocked = false; bool m_editsAllowed = false; bool m_emptyFoldersVisible = true; bool m_expandListForSearch = true; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cb4ef3fc..027602c5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1127,7 +1127,7 @@ bool MainWindow::setMap(const QString &mapName) { displayMapProperties(); updateWindowTitle(); updateMapList(); - resetMapListFilters(); + scrollCurrentMapListToItem(mapName); // If the map's MAPSEC / layout changes, update the map's position in the map list. // These are doing more work than necessary, rather than rebuilding the entire list they should find and relocate the appropriate row. @@ -1208,7 +1208,7 @@ bool MainWindow::setLayout(const QString &layoutId) { refreshMapScene(); updateWindowTitle(); updateMapList(); - resetMapListFilters(); + scrollCurrentMapListToItem(layoutId); connect(editor->layout, &Layout::needsRedrawing, this, &MainWindow::redrawMapScene, Qt::UniqueConnection); @@ -1485,7 +1485,9 @@ void MainWindow::clearProjectUI() { delete this->locationListProxyModel; delete this->layoutTreeModel; delete this->layoutListProxyModel; - resetMapListFilters(); + ui->mapListToolBar_Groups->clearFilter(); + ui->mapListToolBar_Locations->clearFilter(); + ui->mapListToolBar_Layouts->clearFilter(); resetMapNavigation(); } @@ -1518,6 +1520,21 @@ void MainWindow::scrollMapListToCurrentLayout(MapTree *list) { } } +// Scroll the current map list to the specified map name / layout ID. +// No scrolling occurs if... +// - The map list was in the middle of a search +// - A map/layout is being opened by interacting with the list (in which case `lockMapListAutoScroll` is true) +// - The item is not in the list (e.g. a layout ID for the Groups list) +void MainWindow::scrollCurrentMapListToItem(const QString &itemName) { + if (this->lockMapListAutoScroll) + return; + + auto toolbar = getCurrentMapListToolBar(); + if (toolbar && toolbar->filterText().isEmpty()) { + scrollMapList(toolbar->list(), itemName); + } +} + void MainWindow::onOpenMapListContextMenu(const QPoint &point) { // Get selected item from list auto list = getCurrentMapList(); @@ -1813,14 +1830,19 @@ void MainWindow::currentMetatilesSelectionChanged() { } void MainWindow::onMapListTabChanged(int index) { + auto newToolbar = getMapListToolBar(index); + auto oldToolbar = getMapListToolBar(porymapConfig.mapListTab); + 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. - auto toolbar = getCurrentMapListToolBar(); - if (toolbar) toolbar->setSearchFocus(); + if (newToolbar) newToolbar->setSearchFocus(); } void MainWindow::openMapListItem(const QModelIndex &index) { @@ -1832,10 +1854,9 @@ void MainWindow::openMapListItem(const QModelIndex &index) { return; const QString name = data.toString(); - // Normally when a new map/layout is opened the search filters are cleared and the lists will scroll to display that map/layout in the list. - // We don't want to do this when the user interacts with a list directly, so we temporarily prevent changes to the search filter. - auto toolbar = getCurrentMapListToolBar(); - if (toolbar) toolbar->setFilterLocked(true); + // Normally when a new map/layout is opened the current map list will scroll to display that item in the list. + // We don't want to do this when the user interacts with a list directly, so we temporarily prevent this. + this->lockMapListAutoScroll = true; QString type = index.data(MapListUserRoles::TypeRole).toString(); if (type == "map_name") { @@ -1844,20 +1865,20 @@ void MainWindow::openMapListItem(const QModelIndex &index) { userSetLayout(name); } - if (toolbar) toolbar->setFilterLocked(false); + this->lockMapListAutoScroll = false; } void MainWindow::rebuildMapList_Locations() { this->mapLocationModel->deleteLater(); this->mapLocationModel = new MapLocationModel(this->editor->project); this->locationListProxyModel->setSourceModel(this->mapLocationModel); - resetMapListFilters(); + ui->mapListToolBar_Locations->refreshFilter(); } void MainWindow::rebuildMapList_Layouts() { this->layoutTreeModel->deleteLater(); this->layoutTreeModel = new LayoutTreeModel(this->editor->project); this->layoutListProxyModel->setSourceModel(this->layoutTreeModel); - resetMapListFilters(); + ui->mapListToolBar_Layouts->refreshFilter(); } QString MainWindow::getActiveItemName() { @@ -2873,14 +2894,6 @@ MapTree* MainWindow::getCurrentMapList() { return nullptr; } -// Clear the search filters on all the map lists. -// When the search filter is cleared the map lists will (if possible) display the currently-selected map/layout. -void MainWindow::resetMapListFilters() { - ui->mapListToolBar_Groups->clearFilter(); - ui->mapListToolBar_Locations->clearFilter(); - ui->mapListToolBar_Layouts->clearFilter(); -} - void MainWindow::mapListShortcut_ExpandAll() { auto toolbar = getCurrentMapListToolBar(); if (toolbar) toolbar->expandList(); diff --git a/src/ui/maplisttoolbar.cpp b/src/ui/maplisttoolbar.cpp index 7ef3213c..ab1ad8cd 100644 --- a/src/ui/maplisttoolbar.cpp +++ b/src/ui/maplisttoolbar.cpp @@ -116,10 +116,11 @@ void MapListToolBar::collapseList() { } } -void MapListToolBar::applyFilter(const QString &filterText) { - if (m_filterLocked) - return; +QString MapListToolBar::filterText() const { + return ui->lineEdit_filterBox->text(); +} +void MapListToolBar::applyFilter(const QString &filterText) { const QSignalBlocker b(ui->lineEdit_filterBox); if (ui->lineEdit_filterBox->text() != filterText) { ui->lineEdit_filterBox->setText(filterText); @@ -148,6 +149,10 @@ void MapListToolBar::clearFilter() { applyFilter(""); } +void MapListToolBar::refreshFilter() { + applyFilter(filterText()); +} + void MapListToolBar::setSearchFocus() { ui->lineEdit_filterBox->setFocus(); }