From 895c9466d75dd48abb4710720570dd9060b88c1e Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 26 Jan 2024 15:29:48 -0500 Subject: [PATCH] Center selection when zooming --- include/mainwindow.h | 2 ++ include/ui/metatileselector.h | 3 ++- src/mainwindow.cpp | 43 ++++++++++++++++++++++++----------- src/ui/metatileselector.cpp | 13 ++++++----- src/ui/tileseteditor.cpp | 6 +++-- 5 files changed, 45 insertions(+), 22 deletions(-) diff --git a/include/mainwindow.h b/include/mainwindow.h index 7d939595..6f969eba 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -390,7 +390,9 @@ private: void openProjectSettingsEditor(int tab); bool isProjectOpen(); void showExportMapImageWindow(ImageExporterMode mode); + double getMetatilesZoomScale(); void redrawMetatileSelection(); + void scrollMetatileSelectorToSelection(); QObjectList shortcutableObjects() const; void addCustomHeaderValue(QString key, QJsonValue value, bool isNew = false); diff --git a/include/ui/metatileselector.h b/include/ui/metatileselector.h index eaf357ca..ec2c49f4 100644 --- a/include/ui/metatileselector.h +++ b/include/ui/metatileselector.h @@ -45,13 +45,14 @@ public: QPoint getSelectionDimensions(); void draw(); bool select(uint16_t metatile); - bool selectFromMap(uint16_t metatileId, uint16_t collision, uint16_t elevation); + void selectFromMap(uint16_t metatileId, uint16_t collision, uint16_t elevation); void setTilesets(Tileset*, Tileset*); MetatileSelection getMetatileSelection(); void setPrefabSelection(MetatileSelection selection); void setExternalSelection(int, int, QList, QList>); QPoint getMetatileIdCoordsOnWidget(uint16_t); void setMap(Map*); + bool isInternalSelection() const { return (!this->externalSelection && !this->prefabSelection); } Tileset *primaryTileset; Tileset *secondaryTileset; protected: diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 109233f3..33f11d54 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1366,32 +1366,48 @@ void MainWindow::updateTilesetEditor() { } } -void MainWindow::redrawMetatileSelection() -{ - double scale = pow(3.0, static_cast(porymapConfig.getMetatilesZoom() - 30) / 30.0); +double MainWindow::getMetatilesZoomScale() { + return pow(3.0, static_cast(porymapConfig.getMetatilesZoom() - 30) / 30.0); +} + +void MainWindow::redrawMetatileSelection() { + auto scale = getMetatilesZoomScale(); QTransform transform; transform.scale(scale, scale); ui->graphicsView_currentMetatileSelection->setTransform(transform); ui->graphicsView_currentMetatileSelection->setFixedSize(editor->current_metatile_selection_item->pixmap().width() * scale, editor->current_metatile_selection_item->pixmap().height() * scale); ui->scrollAreaWidgetContents_SelectedMetatiles->adjustSize(); - - QPoint size = editor->metatile_selector_item->getSelectionDimensions(); - if (size.x() == 1 && size.y() == 1) { - MetatileSelection selection = editor->metatile_selector_item->getMetatileSelection(); - QPoint pos = editor->metatile_selector_item->getMetatileIdCoordsOnWidget(selection.metatileItems.first().metatileId); - pos *= scale; - ui->scrollArea_MetatileSelector->ensureVisible(pos.x(), pos.y(), 8 * scale, 8 * scale); - } } -void MainWindow::currentMetatilesSelectionChanged() -{ +void MainWindow::scrollMetatileSelectorToSelection() { + // Internal selections or 1x1 external selections can be scrolled to + if (!editor->metatile_selector_item->isInternalSelection() && editor->metatile_selector_item->getSelectionDimensions() != QPoint(1, 1)) + return; + + MetatileSelection selection = editor->metatile_selector_item->getMetatileSelection(); + if (selection.metatileItems.isEmpty()) + return; + + QPoint pos = editor->metatile_selector_item->getMetatileIdCoordsOnWidget(selection.metatileItems.first().metatileId); + QPoint size = editor->metatile_selector_item->getSelectionDimensions(); + pos += QPoint(size.x() - 1, size.y() - 1) * 16 / 2; // We want to focus on the center of the whole selection + pos *= getMetatilesZoomScale(); + + auto viewport = ui->scrollArea_MetatileSelector->viewport(); + ui->scrollArea_MetatileSelector->ensureVisible(pos.x(), pos.y(), viewport->width() / 2, viewport->height() / 2); +} + +void MainWindow::currentMetatilesSelectionChanged() { redrawMetatileSelection(); if (this->tilesetEditor) { MetatileSelection selection = editor->metatile_selector_item->getMetatileSelection(); this->tilesetEditor->selectMetatile(selection.metatileItems.first().metatileId); } + + // Don't scroll to internal selections here, it will disrupt the user while they make their selection. + if (!editor->metatile_selector_item->isInternalSelection()) + scrollMetatileSelectorToSelection(); } void MainWindow::on_mapList_activated(const QModelIndex &index) @@ -2836,6 +2852,7 @@ void MainWindow::on_horizontalSlider_MetatileZoom_valueChanged(int value) { ui->scrollAreaWidgetContents_BorderMetatiles->adjustSize(); redrawMetatileSelection(); + scrollMetatileSelectorToSelection(); } void MainWindow::on_horizontalSlider_CollisionZoom_valueChanged(int value) { diff --git a/src/ui/metatileselector.cpp b/src/ui/metatileselector.cpp index 2c4a5fb3..074b7758 100644 --- a/src/ui/metatileselector.cpp +++ b/src/ui/metatileselector.cpp @@ -59,12 +59,9 @@ bool MetatileSelector::select(uint16_t metatileId) { return true; } -bool MetatileSelector::selectFromMap(uint16_t metatileId, uint16_t collision, uint16_t elevation) { - if (!Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset)) return false; - this->select(metatileId); - this->selection.collisionItems.append(CollisionSelectionItem{true, collision, elevation}); - this->selection.hasCollision = true; - return true; +void MetatileSelector::selectFromMap(uint16_t metatileId, uint16_t collision, uint16_t elevation) { + QPair movePermissions(collision, elevation); + this->setExternalSelection(1, 1, {metatileId}, {movePermissions}); } void MetatileSelector::setTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) { @@ -100,6 +97,10 @@ void MetatileSelector::setExternalSelection(int width, int height, QListselection.metatileItems.append(MetatileSelectionItem{true, metatileId}); } + if (this->selection.metatileItems.length() == 1) { + QPoint coords = this->getMetatileIdCoords(this->selection.metatileItems.first().metatileId); + SelectablePixmapItem::select(coords.x(), coords.y(), 0, 0); + } this->draw(); emit selectedMetatilesChanged(); diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp index 5e089635..ff79066b 100644 --- a/src/ui/tileseteditor.cpp +++ b/src/ui/tileseteditor.cpp @@ -1206,7 +1206,8 @@ void TilesetEditor::redrawMetatileSelector() { pos *= scale; this->ui->scrollAreaWidgetContents_Metatiles->adjustSize(); - this->ui->scrollArea_Metatiles->ensureVisible(pos.x(), pos.y(), 8 * scale, 8 * scale); + auto viewport = this->ui->scrollArea_Metatiles->viewport(); + this->ui->scrollArea_Metatiles->ensureVisible(pos.x(), pos.y(), viewport->width() / 2, viewport->height() / 2); } void TilesetEditor::on_horizontalSlider_TilesZoom_valueChanged(int value) { @@ -1231,6 +1232,7 @@ void TilesetEditor::redrawTileSelector() { if (!tiles.isEmpty()) { QPoint pos = this->tileSelector->getTileCoordsOnWidget(tiles[0].tileId); pos *= scale; - this->ui->scrollArea_Tiles->ensureVisible(pos.x(), pos.y(), 8 * scale, 8 * scale); + auto viewport = this->ui->scrollArea_Tiles->viewport(); + this->ui->scrollArea_Tiles->ensureVisible(pos.x(), pos.y(), viewport->width() / 2, viewport->height() / 2); } }