diff --git a/forms/projectsettingseditor.ui b/forms/projectsettingseditor.ui index 05598b8f..c840d331 100644 --- a/forms/projectsettingseditor.ui +++ b/forms/projectsettingseditor.ui @@ -39,7 +39,7 @@ 0 0 570 - 692 + 680 @@ -94,7 +94,7 @@ ... - + :/icons/folder.ico:/icons/folder.ico @@ -164,7 +164,7 @@ ... - + :/icons/folder.ico:/icons/folder.ico @@ -248,7 +248,7 @@ ... - + :/icons/folder.ico:/icons/folder.ico @@ -1197,23 +1197,62 @@ 0 0 570 - 840 + 927 + + + + Tab Icon + + + + + + false + + + ... + + + + :/icons/folder.ico:/icons/folder.ico + + + + + + + false + + + <html><head/><body><p>The image file path to use for the icon of the Events tab.</p></body></html> + + + true + + + + + + + <html><head/><body><p>The icon that will be displayed for the Events tab in the editor. If 'Automatic' is chosen, the icon will be a random player character from the project's base game version. If 'Custom' is chosen an image file path may be specified.</p></body></html> + + + false + + + + + + Default Icons - - - - Triggers - - - @@ -1221,23 +1260,31 @@ - - + + - <html><head/><body><p>The icon that will be used to represent Warp events</p></body></html> + <html><head/><body><p>The icon that will be used to represent BG events</p></body></html> true - - - - <html><head/><body><p>The icon that will be used to represent Heal Location events</p></body></html> + + + + ... - - true + + + :/icons/folder.ico:/icons/folder.ico + + + + + + + Objects @@ -1248,6 +1295,24 @@ + + + + Triggers + + + + + + + ... + + + + :/icons/folder.ico:/icons/folder.ico + + + @@ -1265,10 +1330,56 @@ - - + + + + <html><head/><body><p>The icon that will be used to represent Warp events</p></body></html> + + + true + + + + + - Objects + ... + + + + :/icons/folder.ico:/icons/folder.ico + + + + + + + <html><head/><body><p>The icon that will be used to represent Heal Location events</p></body></html> + + + true + + + + + + + ... + + + + :/icons/folder.ico:/icons/folder.ico + + + + + + + ... + + + + :/icons/folder.ico:/icons/folder.ico @@ -1282,71 +1393,6 @@ - - - - <html><head/><body><p>The icon that will be used to represent BG events</p></body></html> - - - true - - - - - - - ... - - - - :/icons/folder.ico:/icons/folder.ico - - - - - - - ... - - - - :/icons/folder.ico:/icons/folder.ico - - - - - - - ... - - - - :/icons/folder.ico:/icons/folder.ico - - - - - - - ... - - - - :/icons/folder.ico:/icons/folder.ico - - - - - - - ... - - - - :/icons/folder.ico:/icons/folder.ico - - - @@ -1365,7 +1411,7 @@ ... - + :/icons/delete.ico:/icons/delete.ico @@ -1418,7 +1464,7 @@ ... - + :/icons/add.ico:/icons/add.ico @@ -1628,7 +1674,7 @@ 0 0 544 - 338 + 341 @@ -1657,7 +1703,7 @@ Add Global Constants File... - + :/icons/add.ico:/icons/add.ico @@ -1668,7 +1714,7 @@ ... - + :/icons/help.ico:/icons/help.ico @@ -1708,7 +1754,7 @@ ... - + :/icons/help.ico:/icons/help.ico @@ -1745,7 +1791,7 @@ 0 0 544 - 421 + 425 @@ -1774,7 +1820,7 @@ Add Global Constant... - + :/icons/add.ico:/icons/add.ico @@ -1840,8 +1886,6 @@
uintspinbox.h
- - - + diff --git a/include/config.h b/include/config.h index 3f441229..2e99dc3e 100644 --- a/include/config.h +++ b/include/config.h @@ -335,6 +335,7 @@ public: this->filePaths.clear(); this->eventIconPaths.clear(); this->pokemonIconPaths.clear(); + this->eventsTabIconPath = QString(); this->collisionSheetPath = QString(); this->collisionSheetSize = QSize(2, 16); this->playerViewDistance = QMargins(GBA_H_DIST_TO_CENTER, GBA_V_DIST_TO_CENTER, GBA_H_DIST_TO_CENTER, GBA_V_DIST_TO_CENTER); @@ -356,6 +357,9 @@ public: static const QStringList versionStrings; static BaseGameVersion stringToBaseGameVersion(const QString &string); + static QString getPlayerIconPath(BaseGameVersion baseGameVersion, int character); + static QIcon getPlayerIcon(BaseGameVersion baseGameVersion, int character); + void reset(BaseGameVersion baseGameVersion); void setFilePath(ProjectFilePath pathId, const QString &path); void setFilePath(const QString &pathId, const QString &path); @@ -415,6 +419,7 @@ public: uint16_t unusedTileCovered; uint16_t unusedTileSplit; bool mapAllowFlagsEnabled; + QString eventsTabIconPath; QString collisionSheetPath; QSize collisionSheetSize; QMargins playerViewDistance; diff --git a/resources/icons/player/brendan_em.ico b/resources/icons/player/brendan_em.ico new file mode 100644 index 00000000..2c896c44 Binary files /dev/null and b/resources/icons/player/brendan_em.ico differ diff --git a/resources/icons/player/brendan_rs.ico b/resources/icons/player/brendan_rs.ico new file mode 100644 index 00000000..c3385a4d Binary files /dev/null and b/resources/icons/player/brendan_rs.ico differ diff --git a/resources/icons/player/green.ico b/resources/icons/player/green.ico new file mode 100644 index 00000000..3cdada55 Binary files /dev/null and b/resources/icons/player/green.ico differ diff --git a/resources/icons/player/may_em.ico b/resources/icons/player/may_em.ico new file mode 100644 index 00000000..ffa56bab Binary files /dev/null and b/resources/icons/player/may_em.ico differ diff --git a/resources/icons/player/may_rs.ico b/resources/icons/player/may_rs.ico new file mode 100644 index 00000000..7450d620 Binary files /dev/null and b/resources/icons/player/may_rs.ico differ diff --git a/resources/icons/viewsprites.ico b/resources/icons/player/red.ico similarity index 100% rename from resources/icons/viewsprites.ico rename to resources/icons/player/red.ico diff --git a/resources/images.qrc b/resources/images.qrc index 41789a6e..8d6af6fd 100644 --- a/resources/images.qrc +++ b/resources/images.qrc @@ -46,9 +46,14 @@ icons/sort_number.ico icons/tall_grass.ico icons/minimap.ico - icons/viewsprites.ico icons/application_form_edit.ico icons/connections.ico + icons/player/brendan_em.ico + icons/player/brendan_rs.ico + icons/player/green.ico + icons/player/may_em.ico + icons/player/may_rs.ico + icons/player/red.ico icons/ui/dark/checkbox_checked_disabled.png icons/ui/dark/checkbox_checked_disabled@2x.png icons/ui/dark/checkbox_checked.png diff --git a/src/config.cpp b/src/config.cpp index 45144a2d..7914cdce 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -731,6 +731,32 @@ BaseGameVersion ProjectConfig::stringToBaseGameVersion(const QString &string) { return version; } +QString ProjectConfig::getPlayerIconPath(BaseGameVersion baseGameVersion, int character) { + switch (baseGameVersion) { + case BaseGameVersion::pokeemerald: { + static const QStringList paths = { QStringLiteral(":/icons/player/brendan_em.ico"), + QStringLiteral(":/icons/player/may_em.ico"), }; + return paths.value(character); + } + case BaseGameVersion::pokefirered: { + static const QStringList paths = { QStringLiteral(":/icons/player/red.ico"), + QStringLiteral(":/icons/player/green.ico"), }; + return paths.value(character); + } + case BaseGameVersion::pokeruby: { + static const QStringList paths = { QStringLiteral(":/icons/player/brendan_rs.ico"), + QStringLiteral(":/icons/player/may_rs.ico"), }; + return paths.value(character); + } + default: break; + } + return QString(); +} + +QIcon ProjectConfig::getPlayerIcon(BaseGameVersion baseGameVersion, int character) { + return QIcon(getPlayerIconPath(baseGameVersion, character)); +} + ProjectConfig projectConfig; QString ProjectConfig::getConfigFilepath() { @@ -868,6 +894,8 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) { this->eventIconPaths[Event::Group::Heal] = value; } else if (key.startsWith("pokemon_icon_path/")) { this->pokemonIconPaths.insert(key.mid(QStringLiteral("pokemon_icon_path/").length()), value); + } else if (key == "events_tab_icon_path") { + this->eventsTabIconPath = value; } else if (key == "collision_sheet_path") { this->collisionSheetPath = value; } else if (key == "collision_sheet_width") { @@ -987,6 +1015,7 @@ QMap ProjectConfig::getKeyValueMap() { for (auto it = this->identifiers.constBegin(); it != this->identifiers.constEnd(); it++) { map.insert("ident/"+defaultIdentifiers.value(it.key()).first, it.value()); } + map.insert("events_tab_icon_path", this->eventsTabIconPath); map.insert("collision_sheet_path", this->collisionSheetPath); map.insert("collision_sheet_width", QString::number(this->collisionSheetSize.width())); map.insert("collision_sheet_height", QString::number(this->collisionSheetSize.height())); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 16b24f1e..6a54bce1 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -249,7 +249,7 @@ void MainWindow::initCustomUI() { static const QMap mainTabIcons = { {MainTab::Map, QIcon(QStringLiteral(":/icons/minimap.ico"))}, - {MainTab::Events, QIcon(QStringLiteral(":/icons/viewsprites.ico"))}, + {MainTab::Events, ProjectConfig::getPlayerIcon(BaseGameVersion::pokefirered, 0)}, // Arbitrary default {MainTab::Header, QIcon(QStringLiteral(":/icons/application_form_edit.ico"))}, {MainTab::Connections, QIcon(QStringLiteral(":/icons/connections.ico"))}, {MainTab::WildPokemon, QIcon(QStringLiteral(":/icons/tall_grass.ico"))}, @@ -1305,6 +1305,21 @@ bool MainWindow::setProjectUI() { ui->mapCustomAttributesFrame->table()->setRestrictedKeys(project->getTopLevelMapFields()); + // Set a version dependent player icon (or user-chosen icon) for the Events tab. + QIcon eventTabIcon; + if (!projectConfig.eventsTabIconPath.isEmpty()) { + eventTabIcon = QIcon(project->getExistingFilepath(projectConfig.eventsTabIconPath)); + if (eventTabIcon.isNull()) { + logWarn(QString("Failed to load custom Events tab icon '%1'.").arg(projectConfig.eventsTabIconPath)); + } + } + if (eventTabIcon.isNull()) { + // We randomly choose between the available characters for ~flavor~. + // For now, this correctly assumes all versions have 2 icons. + eventTabIcon = ProjectConfig::getPlayerIcon(projectConfig.baseGameVersion, QRandomGenerator::global()->bounded(0, 2)); + } + ui->mainTabBar->setTabIcon(MainTab::Events, eventTabIcon); + return true; } diff --git a/src/ui/projectsettingseditor.cpp b/src/ui/projectsettingseditor.cpp index 166874ee..fa2d3ee2 100644 --- a/src/ui/projectsettingseditor.cpp +++ b/src/ui/projectsettingseditor.cpp @@ -67,6 +67,7 @@ void ProjectSettingsEditor::connectSignals() { connect(ui->button_BGsIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_BGsIcon); }); connect(ui->button_HealLocationsIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_HealLocationsIcon); }); connect(ui->button_PokemonIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_PokemonIcon); }); + connect(ui->button_EventsTabIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_EventsTabIcon); }); // Display a warning if a mask value overlaps with another mask in its group. @@ -113,6 +114,20 @@ void ProjectSettingsEditor::initUi() { ui->comboBox_BaseGameVersion->addItems(ProjectConfig::versionStrings); ui->comboBox_AttributesSize->addItems({"1", "2", "4"}); + ui->comboBox_EventsTabIcon->addItem("Automatic", ""); + ui->comboBox_EventsTabIcon->addItem("Brendan (Emerald)", ProjectConfig::getPlayerIconPath(BaseGameVersion::pokeemerald, 0)); + ui->comboBox_EventsTabIcon->addItem("Brendan (R/S)", ProjectConfig::getPlayerIconPath(BaseGameVersion::pokeruby, 0)); + ui->comboBox_EventsTabIcon->addItem("May (Emerald)", ProjectConfig::getPlayerIconPath(BaseGameVersion::pokeemerald, 1)); + ui->comboBox_EventsTabIcon->addItem("May (R/S)", ProjectConfig::getPlayerIconPath(BaseGameVersion::pokeruby, 1)); + ui->comboBox_EventsTabIcon->addItem("Red", ProjectConfig::getPlayerIconPath(BaseGameVersion::pokefirered, 0)); + ui->comboBox_EventsTabIcon->addItem("Green", ProjectConfig::getPlayerIconPath(BaseGameVersion::pokefirered, 1)); + ui->comboBox_EventsTabIcon->addItem("Custom", "Custom"); + connect(ui->comboBox_EventsTabIcon, QOverload::of(&NoScrollComboBox::currentIndexChanged), [this](int index) { + bool usingCustom = (index == ui->comboBox_EventsTabIcon->findText("Custom")); + ui->lineEdit_EventsTabIcon->setVisible(usingCustom); + ui->button_EventsTabIcon->setVisible(usingCustom); + }); + // Validate that the border metatiles text is a comma-separated list of metatile values static const QString regex_Hex = "(0[xX])?[A-Fa-f0-9]+"; static const QRegularExpression expression_HexList(QString("^(%1,)*%1$").arg(regex_Hex)); // Comma-separated list of hex values @@ -520,6 +535,15 @@ void ProjectSettingsEditor::refresh() { } this->setWarpBehaviorsList(behaviorNames); + int index = ui->comboBox_EventsTabIcon->findData(projectConfig.eventsTabIconPath); + if (index < 0) { + index = ui->comboBox_EventsTabIcon->findData("Custom"); + ui->lineEdit_EventsTabIcon->setText(projectConfig.eventsTabIconPath); + } else { + ui->lineEdit_EventsTabIcon->setText(""); + } + ui->comboBox_EventsTabIcon->setCurrentIndex(index); + this->refreshing = false; // Allow signals } @@ -608,6 +632,16 @@ void ProjectSettingsEditor::save() { for (auto i = this->editedPokemonIconPaths.cbegin(), end = this->editedPokemonIconPaths.cend(); i != end; i++) projectConfig.setPokemonIconPath(i.key(), i.value()); + QString eventsTabIconPath; + QVariant data = ui->comboBox_EventsTabIcon->currentData(); + if (data.isValid() && data.canConvert()) { + eventsTabIconPath = data.toString(); + if (eventsTabIconPath == "Custom") { + eventsTabIconPath = ui->lineEdit_EventsTabIcon->text(); + } + } + projectConfig.eventsTabIconPath = eventsTabIconPath; + projectConfig.save(); userConfig.save(); porymapConfig.save();