diff --git a/CHANGELOG.md b/CHANGELOG.md index d1af0629..68fd5e9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,19 +8,27 @@ The **"Breaking Changes"** listed below are changes that have been made in the d ## [Unreleased] ### Added +- Add zoom sliders to the Tileset Editor. - Add `getMetatileBehaviorName` and `setMetatileBehaviorName` to the API. - Add `metatile_behaviors`, `num_primary_palettes`, and `num_secondary_palettes` to `constants` in the API. ### Changed - Metatile ID strings are now padded to their current max, not the overall max. +- Non-existent directories are now removed from the Open Recent Project menu. +- Hovering on the layer view in the Tileset Editor now displays the tile ID. +- Labels in the Script dropdown are now sorted alphabetically. - The name of the Heal Locations table is no longer enforced. - The API functions `addImage` and `createImage` now support project-relative paths. ### Fixed - Fix the metatile selector rectangle jumping when selecting up or left of the origin. -- Fix the event group tabs sometimes showing an event from the wrong group +- Fix the event group tabs sometimes showing an event from the wrong group. - Fix the clear buttons in the Shortcuts Editor not actually removing shortcuts. -- Fix API error reporting +- Fix slow speed for the script label autcomplete. +- Fix deleted script labels still appearing in the autocomplete after project reload. +- Fix the map search bar stealing focus on startup. +- Fix Open Recent Project not clearing the API overlay +- Fix API error reporting. ## [5.2.0] - 2024-01-02 ### Added diff --git a/forms/tileseteditor.ui b/forms/tileseteditor.ui index c1c929d8..34e13d55 100644 --- a/forms/tileseteditor.ui +++ b/forms/tileseteditor.ui @@ -19,38 +19,27 @@ - - - - 1 - 0 - + + + Qt::Horizontal - - - 274 - 0 - + + false - - - 274 - 16777215 - - - - true - - - - - 0 - 0 - 272 - 625 - + + + + 0 + 0 + - + + QFrame::NoFrame + + + QFrame::Plain + + 0 @@ -63,440 +52,151 @@ 0 - - 6 - - - + + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + 0 + 0 + 223 + 593 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + Qt::Horizontal - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 + + + QFrame::NoFrame - - 0 + + QFrame::Raised - - 0 - - - 0 - - - - - - 0 - 166 - - - - QFrame::NoFrame - - - QFrame::Raised - - - - QLayout::SetMinimumSize + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + - - 0 + + + 0 + 166 + - - 0 + + QFrame::NoFrame - - 0 + + QFrame::Raised - - 0 - - - - - - 0 - 0 - - - - Metatile Properties - - - false - - - false - - - - - - - - - - - - true - - - - - - - Metatile Label (Optional) - - - - - - - Metatile Behavior - - - - - - - - 0 - 0 - - - - - 66 - 34 - - - - - 66 - 34 - - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - - - - - Bottom/Top - - - - - - - Encounter Type - - - - - - - Terrain Type - - - - - - - - - - Layer Type - - - - - - - <html><head/><body><p>Copies the full metatile label to the clipboard.</p></body></html> - - - ... - - - - :/icons/clipboard.ico:/icons/clipboard.ico - - - - - - - - - - - - - - 0 - 0 - - - - Tile Properties - - - false - - - - - - Palette - - - - - - - - 0 - 0 - - - - - - - - X Flip - - - - - - - Qt::LeftToRight - - - - - - - - - - Y Flip - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 62 - - - - QFrame::NoFrame - - - QFrame::Plain - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Selection - - - - - - - - 18 - 18 - - - - - 66 - 34 - - - - QFrame::StyledPanel - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - - - - - - - - Qt::Vertical - - - - 20 - 10 - - - - - - - - Qt::Vertical - - - - 20 - 10 - - - - - - - - - - - - - - - 0 - 0 - - - - true - - - - - 0 - 0 - 411 - 272 - - - + + + QLayout::SetMinimumSize + 0 @@ -509,73 +209,444 @@ 0 - - - - Qt::Vertical + + + + Metatile Properties - - - 20 - 40 - + + false - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff + + false + + + + + + 0 + 0 + + + + + 66 + 34 + + + + + 96 + 34 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + + 20 + 1 + + + + + + + + + 0 + 0 + + + + + + + + Metatile Label (Optional) + + + + + + + <html><head/><body><p>Copies the full metatile label to the clipboard.</p></body></html> + + + ... + + + + :/icons/clipboard.ico:/icons/clipboard.ico + + + + + + + + 0 + 0 + + + + + 185 + 0 + + + + + + + + + 0 + 0 + + + + + + + + Layer Type + + + + + + + true + + + + + + + Metatile Behavior + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 10 + 20 + + + + + + + + Encounter Type + + + + + + + Terrain Type + + + + + + + Bottom/Top + + + + - - - - Qt::Horizontal + + + + + 0 + 0 + - - - 40 - 20 - + + Tile Properties - + + false + + + + + + Palette + + + + + + + + + + X Flip + + + + + + + Qt::LeftToRight + + + + + + + + + + Y Flip + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 5 + + + + + + + + + 0 + 0 + + + + + 98 + 62 + + + + QFrame::NoFrame + + + QFrame::Plain + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Selection + + + + + + + + 18 + 18 + + + + + 98 + 34 + + + + QFrame::StyledPanel + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + + + + + + Qt::Vertical + + + + 20 + 10 + + + + + + - - - + + + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + 0 + 0 + 455 + 232 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + + diff --git a/include/config.h b/include/config.h index 4722021e..41e0d252 100644 --- a/include/config.h +++ b/include/config.h @@ -58,6 +58,8 @@ public: this->collisionOpacity = 50; this->collisionZoom = 30; this->metatilesZoom = 30; + this->tilesetEditorMetatilesZoom = 30; + this->tilesetEditorTilesZoom = 30; this->showPlayerView = false; this->showCursorTile = true; this->showBorder = true; @@ -87,6 +89,8 @@ public: void setCollisionOpacity(int opacity); void setCollisionZoom(int zoom); void setMetatilesZoom(int zoom); + void setTilesetEditorMetatilesZoom(int zoom); + void setTilesetEditorTilesZoom(int zoom); void setShowPlayerView(bool enabled); void setShowCursorTile(bool enabled); void setShowBorder(bool enabled); @@ -115,6 +119,8 @@ public: int getCollisionOpacity(); int getCollisionZoom(); int getMetatilesZoom(); + int getTilesetEditorMetatilesZoom(); + int getTilesetEditorTilesZoom(); bool getShowPlayerView(); bool getShowCursorTile(); bool getShowBorder(); @@ -160,6 +166,8 @@ private: int collisionOpacity; int collisionZoom; int metatilesZoom; + int tilesetEditorMetatilesZoom; + int tilesetEditorTilesZoom; bool showPlayerView; bool showCursorTile; bool showBorder; diff --git a/include/project.h b/include/project.h index 3e0eb536..85c8e3de 100644 --- a/include/project.h +++ b/include/project.h @@ -205,8 +205,6 @@ public: static QString getScriptFileExtension(bool usePoryScript); QString getScriptDefaultString(bool usePoryScript, QString mapName) const; QStringList getEventScriptsFilePaths() const; - QCompleter *getEventScriptLabelCompleter(QStringList additionalScriptLabels); - QStringList getGlobalScriptLabels(); QString getDefaultPrimaryTilesetLabel(); QString getDefaultSecondaryTilesetLabel(); @@ -256,9 +254,6 @@ private: static int default_map_size; static int max_object_events; - QStringListModel eventScriptLabelModel; - QCompleter eventScriptLabelCompleter; - signals: void reloadProject(); void uncheckMonitorFilesAction(); diff --git a/include/ui/eventframes.h b/include/ui/eventframes.h index 9cabd585..c11cf8e6 100644 --- a/include/ui/eventframes.h +++ b/include/ui/eventframes.h @@ -31,6 +31,8 @@ public: void invalidateUi(); void invalidateValues(); + void populateScriptDropdown(NoScrollComboBox * combo, Project * project); + virtual void setActive(bool active); public: @@ -87,8 +89,6 @@ public: private: ObjectEvent *object; - - QCompleter *scriptCompleter = nullptr; }; @@ -158,8 +158,6 @@ public: private: TriggerEvent *trigger; - - QCompleter *scriptCompleter = nullptr; }; @@ -203,8 +201,6 @@ public: private: SignEvent *sign; - - QCompleter *scriptCompleter = nullptr; }; diff --git a/include/ui/tileseteditor.h b/include/ui/tileseteditor.h index 692d39e9..b108f4d2 100644 --- a/include/ui/tileseteditor.h +++ b/include/ui/tileseteditor.h @@ -116,6 +116,8 @@ private slots: void on_actionCut_triggered(); void on_actionCopy_triggered(); void on_actionPaste_triggered(); + void on_horizontalSlider_MetatilesZoom_valueChanged(int value); + void on_horizontalSlider_TilesZoom_valueChanged(int value); private: void initUi(); diff --git a/src/config.cpp b/src/config.cpp index 0d6fabe6..dce42b65 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -368,6 +368,10 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) { this->metatilesZoom = getConfigInteger(key, value, 10, 100, 30); } else if (key == "collision_zoom") { this->collisionZoom = getConfigInteger(key, value, 10, 100, 30); + } else if (key == "tileset_editor_metatiles_zoom") { + this->tilesetEditorMetatilesZoom = getConfigInteger(key, value, 10, 100, 30); + } else if (key == "tileset_editor_tiles_zoom") { + this->tilesetEditorTilesZoom = getConfigInteger(key, value, 10, 100, 30); } else if (key == "show_player_view") { this->showPlayerView = getConfigBool(key, value); } else if (key == "show_cursor_tile") { @@ -427,6 +431,8 @@ QMap PorymapConfig::getKeyValueMap() { map.insert("collision_opacity", QString::number(this->collisionOpacity)); map.insert("collision_zoom", QString::number(this->collisionZoom)); map.insert("metatiles_zoom", QString::number(this->metatilesZoom)); + map.insert("tileset_editor_metatiles_zoom", QString::number(this->tilesetEditorMetatilesZoom)); + map.insert("tileset_editor_tiles_zoom", QString::number(this->tilesetEditorTilesZoom)); map.insert("show_player_view", this->showPlayerView ? "1" : "0"); map.insert("show_cursor_tile", this->showCursorTile ? "1" : "0"); map.insert("show_border", this->showBorder ? "1" : "0"); @@ -552,6 +558,16 @@ void PorymapConfig::setMetatilesZoom(int zoom) { // don't auto-save here because this can be called very frequently. } +void PorymapConfig::setTilesetEditorMetatilesZoom(int zoom) { + this->tilesetEditorMetatilesZoom = zoom; + // don't auto-save here because this can be called very frequently. +} + +void PorymapConfig::setTilesetEditorTilesZoom(int zoom) { + this->tilesetEditorTilesZoom = zoom; + // don't auto-save here because this can be called very frequently. +} + void PorymapConfig::setShowPlayerView(bool enabled) { this->showPlayerView = enabled; this->save(); @@ -694,6 +710,14 @@ int PorymapConfig::getMetatilesZoom() { return this->metatilesZoom; } +int PorymapConfig::getTilesetEditorMetatilesZoom() { + return this->tilesetEditorMetatilesZoom; +} + +int PorymapConfig::getTilesetEditorTilesZoom() { + return this->tilesetEditorTilesZoom; +} + bool PorymapConfig::getShowPlayerView() { return this->showPlayerView; } diff --git a/src/core/map.cpp b/src/core/map.cpp index 78e15729..008d62cb 100644 --- a/src/core/map.cpp +++ b/src/core/map.cpp @@ -137,6 +137,7 @@ QStringList Map::getScriptLabels(Event::Group group) const { // Add scripts from map's scripts file, and empty names. scriptLabels.append(scriptsFileLabels); + scriptLabels.sort(Qt::CaseInsensitive); scriptLabels.prepend("0x0"); scriptLabels.prepend("NULL"); diff --git a/src/project.cpp b/src/project.cpp index c2417f11..32b1acfa 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -2454,18 +2454,13 @@ bool Project::readMiscellaneousConstants() { return true; } -QStringList Project::getGlobalScriptLabels() { - return this->eventScriptLabelModel.stringList(); -} - bool Project::readEventScriptLabels() { + globalScriptLabels.clear(); for (const auto &filePath : getEventScriptsFilePaths()) globalScriptLabels << ParseUtil::getGlobalScriptLabels(filePath); - eventScriptLabelModel.setStringList(globalScriptLabels); - eventScriptLabelCompleter.setModel(&eventScriptLabelModel); - eventScriptLabelCompleter.setCaseSensitivity(Qt::CaseInsensitive); - eventScriptLabelCompleter.setFilterMode(Qt::MatchContains); + globalScriptLabels.sort(Qt::CaseInsensitive); + globalScriptLabels.removeDuplicates(); return true; } @@ -2526,13 +2521,6 @@ QStringList Project::getEventScriptsFilePaths() const { return filePaths; } -QCompleter *Project::getEventScriptLabelCompleter(QStringList additionalScriptLabels) { - additionalScriptLabels << globalScriptLabels; - additionalScriptLabels.removeDuplicates(); - eventScriptLabelModel.setStringList(additionalScriptLabels); - return &eventScriptLabelCompleter; -} - void Project::setEventPixmap(Event *event, bool forceLoad) { if (event && (event->getPixmap().isNull() || forceLoad)) event->loadPixmap(this); diff --git a/src/ui/eventframes.cpp b/src/ui/eventframes.cpp index 348045d4..26becf97 100644 --- a/src/ui/eventframes.cpp +++ b/src/ui/eventframes.cpp @@ -168,6 +168,23 @@ void EventFrame::setActive(bool active) { this->blockSignals(!active); } +void EventFrame::populateScriptDropdown(NoScrollComboBox * combo, Project * project) { + // The script dropdown is populated with scripts used by the map's events and from its scripts file. + if (this->event->getMap()) + combo->addItems(this->event->getMap()->getScriptLabels()); + + // The dropdown's autocomplete has all script labels across the full project. + auto completer = new QCompleter(project->globalScriptLabels, combo); + completer->setCaseSensitivity(Qt::CaseInsensitive); + completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel); + completer->setFilterMode(Qt::MatchContains); + + // Improve display speed for the autocomplete popup + auto popup = (QListView *)completer->popup(); + if (popup) popup->setUniformItemSizes(true); + + combo->setCompleter(completer); +} void ObjectFrame::setup() { @@ -367,20 +384,7 @@ void ObjectFrame::populate(Project *project) { this->combo_flag->addItems(project->flagNames); this->combo_trainer_type->addItems(project->trainerTypes); - // The script dropdown is populated with scripts used by the map's events and from its scripts file. - QStringList scriptLabels; - if (this->object->getMap()) { - scriptLabels.append(this->object->getMap()->getScriptLabels()); - this->combo_script->addItems(scriptLabels); - } - - // The dropdown's autocomplete has all script labels across the full project. - scriptLabels.append(project->getGlobalScriptLabels()); - scriptLabels.removeDuplicates(); - this->scriptCompleter = new QCompleter(scriptLabels, this); - this->scriptCompleter->setCaseSensitivity(Qt::CaseInsensitive); - this->scriptCompleter->setFilterMode(Qt::MatchContains); - this->combo_script->setCompleter(this->scriptCompleter); + this->populateScriptDropdown(this->combo_script, project); } @@ -637,20 +641,7 @@ void TriggerFrame::populate(Project *project) { // var combo this->combo_var->addItems(project->varNames); - // The script dropdown is populated with scripts used by the map's events and from its scripts file. - QStringList scriptLabels; - if (this->trigger->getMap()) { - scriptLabels.append(this->trigger->getMap()->getScriptLabels()); - this->combo_script->addItems(scriptLabels); - } - - // The dropdown's autocomplete has all script labels across the full project. - scriptLabels.append(project->getGlobalScriptLabels()); - scriptLabels.removeDuplicates(); - this->scriptCompleter = new QCompleter(scriptLabels, this); - this->scriptCompleter->setCaseSensitivity(Qt::CaseInsensitive); - this->scriptCompleter->setFilterMode(Qt::MatchContains); - this->combo_script->setCompleter(this->scriptCompleter); + this->populateScriptDropdown(this->combo_script, project); } @@ -772,20 +763,7 @@ void SignFrame::populate(Project *project) { // facing dir this->combo_facing_dir->addItems(project->bgEventFacingDirections); - // The script dropdown is populated with scripts used by the map's events and from its scripts file. - QStringList scriptLabels; - if (this->sign->getMap()) { - scriptLabels.append(this->sign->getMap()->getScriptLabels()); - this->combo_script->addItems(scriptLabels); - } - - // The dropdown's autocomplete has all script labels across the full project. - scriptLabels.append(project->getGlobalScriptLabels()); - scriptLabels.removeDuplicates(); - this->scriptCompleter = new QCompleter(scriptLabels, this); - this->scriptCompleter->setCaseSensitivity(Qt::CaseInsensitive); - this->scriptCompleter->setFilterMode(Qt::MatchContains); - this->combo_script->setCompleter(this->scriptCompleter); + this->populateScriptDropdown(this->combo_script, project); } diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp index 8946d1ab..16ffe0f2 100644 --- a/src/ui/tileseteditor.cpp +++ b/src/ui/tileseteditor.cpp @@ -196,7 +196,7 @@ void TilesetEditor::initMetatileSelector() this->metatileSelector->draw(); this->ui->graphicsView_Metatiles->setScene(this->metatilesScene); - this->ui->graphicsView_Metatiles->setFixedSize(this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2); + this->ui->horizontalSlider_MetatilesZoom->setValue(porymapConfig.getTilesetEditorMetatilesZoom()); } void TilesetEditor::initMetatileLayersItem() { @@ -236,7 +236,7 @@ void TilesetEditor::initTileSelector() this->tileSelector->draw(); this->ui->graphicsView_Tiles->setScene(this->tilesScene); - this->ui->graphicsView_Tiles->setFixedSize(this->tileSelector->pixmap().width() + 2, this->tileSelector->pixmap().height() + 2); + this->ui->horizontalSlider_TilesZoom->setValue(porymapConfig.getTilesetEditorTilesZoom()); } void TilesetEditor::initSelectedTileItem() { @@ -1182,3 +1182,31 @@ void TilesetEditor::on_copyButton_metatileLabel_clicked() { QGuiApplication::clipboard()->setText(label); QToolTip::showText(this->ui->copyButton_metatileLabel->mapToGlobal(QPoint(0, 0)), "Copied!"); } + +void TilesetEditor::on_horizontalSlider_MetatilesZoom_valueChanged(int value) { + porymapConfig.setTilesetEditorMetatilesZoom(value); + double scale = pow(3.0, static_cast(value - 30) / 30.0); + + QTransform transform; + transform.scale(scale, scale); + QSize size(this->metatileSelector->pixmap().width(), this->metatileSelector->pixmap().height()); + size *= scale; + + this->ui->graphicsView_Metatiles->setResizeAnchor(QGraphicsView::NoAnchor); + this->ui->graphicsView_Metatiles->setTransform(transform); + this->ui->graphicsView_Metatiles->setFixedSize(size.width() + 2, size.height() + 2); +} + +void TilesetEditor::on_horizontalSlider_TilesZoom_valueChanged(int value) { + porymapConfig.setTilesetEditorTilesZoom(value); + double scale = pow(3.0, static_cast(value - 30) / 30.0); + + QTransform transform; + transform.scale(scale, scale); + QSize size(this->tileSelector->pixmap().width(), this->tileSelector->pixmap().height()); + size *= scale; + + this->ui->graphicsView_Tiles->setResizeAnchor(QGraphicsView::NoAnchor); + this->ui->graphicsView_Tiles->setTransform(transform); + this->ui->graphicsView_Tiles->setFixedSize(size.width() + 2, size.height() + 2); +}