diff --git a/forms/projectsettingseditor.ui b/forms/projectsettingseditor.ui
index 7fac991d..49b66cb8 100644
--- a/forms/projectsettingseditor.ui
+++ b/forms/projectsettingseditor.ui
@@ -19,715 +19,1096 @@
9
-
-
-
- true
+
+
+ 0
-
-
-
- 0
- 0
- 585
- 585
-
-
-
+
+
+ General
+
+
-
-
-
- Preferences
+
+
+ true
-
-
-
-
-
- Whether map script files should prefer using .pory
-
-
- Use Poryscript
-
-
-
- -
-
-
- Show Wild Encounter Tables
-
-
-
-
-
-
- -
-
-
- Default Tilesets
-
-
-
-
-
-
- Primary Tileset
-
-
-
- -
-
-
- -
-
-
- Secondary Tileset
-
-
-
- -
-
-
-
-
-
- -
-
-
- New Map Defaults
-
-
-
-
-
-
- The default metatile value that will be used to fill new maps
-
-
- 0x
-
-
- 16
-
-
-
- -
-
-
- Elevation
-
-
-
- -
-
-
- The default elevation that will be used to fill new maps
-
-
-
- -
-
-
- Fill Metatile
-
-
-
- -
-
-
- Whether a separate text.inc or text.pory file will be created for new maps, alongside the scripts file
-
-
- Create separate text file
-
-
-
- -
-
-
-
- 0
+
+
+
+ 0
+ 0
+ 531
+ 805
+
+
+
+
-
+
+
+ Preferences
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- Border Metatiles
-
-
-
- -
-
-
- A comma-separated list of metatile values that will be used to fill new map borders
-
-
-
-
-
-
- -
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- Border Metatiles
-
-
-
- -
-
-
- The default metatile value that will be used for the top-left border metatile on new maps.
-
-
- 0x
-
-
- 16
-
-
-
- -
-
-
- The default metatile value that will be used for the top-right border metatile on new maps.
-
-
- 0x
-
-
- 16
-
-
-
- -
-
-
- The default metatile value that will be used for the bottom-left border metatile on new maps.
-
-
- 0x
-
-
- 16
-
-
-
- -
-
-
- The default metatile value that will be used for the bottom-right border metatile on new maps.
-
-
- 0x
-
-
- 16
-
-
-
-
-
-
-
-
-
- -
-
-
- Prefabs
-
-
-
-
-
-
- ...
-
-
-
- :/icons/folder.ico:/icons/folder.ico
-
-
-
- -
-
-
- Restore the data in the prefabs file to the version defaults. Will create a new file if one doesn't exist.
-
-
- Import Defaults
-
-
-
- -
-
-
- The file that will be used to populate the Prefabs tab
-
-
- prefabs.json
-
-
-
- -
-
-
- Prefabs Path
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
- .QFrame { border: 1px solid red; }
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
-
-
-
- 12
- 75
- true
-
-
-
- <html><head/><body><p><span style=" font-size:13pt; color:#d7000c;">WARNING: </span><span style=" font-weight:400;">The settings from this point below require project changes to function properly. Do not modify these settings without the necessary changes. </span></p></body></html>
-
-
- true
-
-
-
- -
-
-
-
-
-
-
- Base game version
-
-
-
- -
-
-
- false
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
- -
-
-
- Tilesets / Metatiles
-
-
-
-
-
-
- Qt::Vertical
-
-
-
- 20
- 10
-
-
-
-
- -
-
-
- Enable Triple Layer Metatiles
-
-
-
- -
-
-
- The mask used to read/write Terrain Type from the metatile's attributes data. If 0, this attribute is disabled.
-
-
- 0x
-
-
- 16
-
-
- true
-
-
-
- -
-
-
- The number of bytes used per metatile for metatile attributes
-
-
- Attributes size (in bytes)
-
-
-
- -
-
-
- Terrain Type mask
-
-
-
- -
-
-
- false
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 15
-
-
-
-
- -
-
-
- Behavior mask
-
-
-
- -
-
-
- The mask used to read/write Metatile Behavior from the metatile's attributes data. If 0, this attribute is disabled.
-
-
- 0x
-
-
- 16
-
-
- true
-
-
-
- -
-
-
- Whether the C data outputted for new tilesets will include the "callback" field
-
-
- Output 'callback' field
-
-
-
- -
-
-
- Whether the C data outputted for new tilesets will include the "isCompressed" field
-
-
- Output 'isCompressed' field
-
-
-
- -
-
-
- The mask used to read/write Encounter Type from the metatile's attributes data. If 0, this attribute is disabled.
-
-
- 0x
-
-
- 16
-
-
- true
-
-
-
- -
-
-
- Encounter Type mask
-
-
-
- -
-
-
- Layer Type mask
-
-
-
- -
-
-
- The mask used to read/write Layer Type from the metatile's attributes data. If 0, this attribute is disabled.
-
-
- 0x
-
-
- 16
-
-
- true
-
-
-
-
-
-
- -
-
-
-
- 2
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- <html><head/><body><p><a href="https://huderlem.github.io/porymap/manual/project-files.html"><span style=" text-decoration: underline;">Project Files</span></a></p></body></html>
-
-
- Qt::RichText
-
-
- Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft
-
-
- true
-
-
-
- -
-
-
-
- 0
- 320
-
-
-
- 2
-
-
- true
-
-
-
-
- 0
- 0
- 533
- 318
-
+
+
-
+
+
+ Whether map script files should prefer using .pory
-
-
+
+ Use Poryscript
+
+
+
+ -
+
+
+ Show Wild Encounter Tables
+
+
+
+
+
+
+ -
+
+
+ New Map Defaults
+
+
+
-
+
+
+ Fill Metatile
+
+
+
+ -
+
+
+
0
0
- 4
+ 0
+
+ 0
+
+
-
+
+
+ Border Metatiles
+
+
+
+ -
+
+
+ The default metatile value that will be used for the top-left border metatile on new maps.
+
+
+ 0x
+
+
+ 16
+
+
+
+ -
+
+
+ The default metatile value that will be used for the top-right border metatile on new maps.
+
+
+ 0x
+
+
+ 16
+
+
+
+ -
+
+
+ The default metatile value that will be used for the bottom-left border metatile on new maps.
+
+
+ 0x
+
+
+ 16
+
+
+
+ -
+
+
+ The default metatile value that will be used for the bottom-right border metatile on new maps.
+
+
+ 0x
+
+
+ 16
+
+
+
-
-
-
-
-
- -
-
-
- Events
-
-
-
-
-
-
- Enable Weather Triggers
-
-
-
- -
-
-
- Enable Secret Bases
-
-
-
- -
-
-
- Enable Clone Objects
-
-
-
- -
-
-
- Enable 'Requires Itemfinder' for Hidden Items
-
-
-
- -
-
-
- Enable 'Quantity' for Hidden Items
-
-
-
- -
-
-
- Enable 'Respawn Map/NPC' for Heal Locations
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
- -
-
-
- Maps
-
-
-
-
-
-
- Whether "Allow Running", "Allow Biking" and "Allow Dig & Escape Rope" are default options for Map Headers
-
-
- Enable 'Allow Running/Biking/Escaping'
-
-
-
- -
-
-
- Whether "Floor Number" is a default option for Map Headers
-
-
- Enable 'Floor Number'
-
-
-
- -
-
-
- Whether the dimensions of the border can be changed. If not set, all borders are 2x2
-
-
- Enable Custom Border Size
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
-
+
+ -
+
+
+ The default metatile value that will be used to fill new maps
+
+
+ 0x
+
+
+ 16
+
+
+
+ -
+
+
+ The default elevation that will be used to fill new maps
+
+
+
+ -
+
+
+ Whether a separate text.inc or text.pory file will be created for new maps, alongside the scripts file
+
+
+ Create separate text file
+
+
+
+ -
+
+
+ Collision
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Border Metatiles
+
+
+
+ -
+
+
+ A comma-separated list of metatile values that will be used to fill new map borders
+
+
+
+
+
+
+ -
+
+
+ The default collision that will be used to fill new maps
+
+
+
+ -
+
+
+ Elevation
+
+
+
+
+
+
+ -
+
+
+ Prefabs
+
+
+
-
+
+
+ ...
+
+
+
+ :/icons/folder.ico:/icons/folder.ico
+
+
+
+ -
+
+
+ Restore the data in the prefabs file to the version defaults. Will create a new file if one doesn't exist.
+
+
+ Import Defaults
+
+
+
+ -
+
+
+ The file that will be used to populate the Prefabs tab
+
+
+ prefabs.json
+
+
+
+ -
+
+
+ Prefabs Path
+
+
+
+
+
+
+ -
+
+
+ Collision Graphics
+
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ The image sheet that will be used to represent elevation and collision on the Collision tab
+
+
+
+ -
+
+
+ ...
+
+
+
+ :/icons/folder.ico:/icons/folder.ico
+
+
+
+ -
+
+
+ Max Elevation
+
+
+
+ -
+
+
+ The maximum collision value represented with an icon on the image sheet
+
+
+
+ -
+
+
+ Max Collision
+
+
+
+ -
+
+
+ Image Path
+
+
+
+ -
+
+
+ The maximum elevation value represented with an icon on the image sheet
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Maximum
+
+
+
+ 5
+ 20
+
+
+
+
+
+
+
+ -
+
+
+ .QFrame { border: 1px solid red; }
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+
+ 12
+ 75
+ true
+
+
+
+ <html><head/><body><p><span style=" font-size:13pt; color:#d7000c;">WARNING: </span><span style=" font-weight:400;">The settings from this point below require project changes to function properly. Do not modify these settings without the necessary changes. </span></p></body></html>
+
+
+ true
+
+
+
+ -
+
+
+
-
+
+
+ Base game version
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ -
+
+
+ Maps
+
+
+
-
+
+
+ Whether "Allow Running", "Allow Biking" and "Allow Dig & Escape Rope" are default options for Map Headers
+
+
+ Enable 'Allow Running/Biking/Escaping'
+
+
+
+ -
+
+
+ Whether "Floor Number" is a default option for Map Headers
+
+
+ Enable 'Floor Number'
+
+
+
+ -
+
+
+ Whether the dimensions of the border can be changed. If not set, all borders are 2x2
+
+
+ Enable Custom Border Size
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+
+ Tilesets
+
+
+ -
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 528
+ 522
+
+
+
+
-
+
+
+ Default Tilesets
+
+
+
-
+
+
+ Primary Tileset
+
+
+
+ -
+
+
+ -
+
+
+ Secondary Tileset
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ .QFrame { border: 1px solid red; }
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+
+ 12
+ 75
+ true
+
+
+
+ <html><head/><body><p><span style=" font-size:13pt; color:#d7000c;">WARNING: </span><span style=" font-weight:400;">The settings from this point below require project changes to function properly. Do not modify these settings without the necessary changes. </span></p></body></html>
+
+
+ true
+
+
+
+ -
+
+
+ Metatiles
+
+
+
-
+
+
+ Layer Type mask
+
+
+
+ -
+
+
+ The number of bytes used per metatile for metatile attributes
+
+
+ Attributes size (in bytes)
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ The mask used to read/write Encounter Type from the metatile's attributes data. If 0, this attribute is disabled.
+
+
+
+ -
+
+
+ Behavior mask
+
+
+
+ -
+
+
+ The mask used to read/write Terrain Type from the metatile's attributes data. If 0, this attribute is disabled.
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 15
+
+
+
+
+ -
+
+
+ Terrain Type mask
+
+
+
+ -
+
+
+ Encounter Type mask
+
+
+
+ -
+
+
+ The mask used to read/write Metatile Behavior from the metatile's attributes data. If 0, this attribute is disabled.
+
+
+
+ -
+
+
+ The mask used to read/write Layer Type from the metatile's attributes data. If 0, this attribute is disabled.
+
+
+
+ -
+
+
+ Enable Triple Layer Metatiles
+
+
+
+
+
+
+ -
+
+
+ Data Output
+
+
+
-
+
+
+ Whether the C data outputted for new tilesets will include the "callback" field
+
+
+ Output 'callback' field
+
+
+
+ -
+
+
+ Whether the C data outputted for new tilesets will include the "isCompressed" field
+
+
+ Output 'isCompressed' field
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+ Events
+
+
+ -
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 559
+ 490
+
+
+
+
-
+
+
+ Default Icons
+
+
+
-
+
+
+ Triggers
+
+
+
+ -
+
+
+ Warps
+
+
+
+ -
+
+
+ The icon that will be used to represent Warp events
+
+
+
+ -
+
+
+ The icon that will be used to represent Healspot events
+
+
+
+ -
+
+
+ BGs
+
+
+
+ -
+
+
+ Healspots
+
+
+
+ -
+
+
+ The icon that will be used to represent Object events that don't have their own sprite
+
+
+
+ -
+
+
+ Objects
+
+
+
+ -
+
+
+ The icon that will be used to represent Trigger events
+
+
+
+ -
+
+
+ The icon that will be used to represent BG events
+
+
+
+ -
+
+
+ ...
+
+
+
+ :/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
+
+
+
+
+
+
+ -
+
+
+ .QFrame { border: 1px solid red; }
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+
+ 12
+ 75
+ true
+
+
+
+ <html><head/><body><p><span style=" font-size:13pt; color:#d7000c;">WARNING: </span><span style=" font-weight:400;">The settings from this point below require project changes to function properly. Do not modify these settings without the necessary changes. </span></p></body></html>
+
+
+ true
+
+
+
+ -
+
+
+
+
+
+
-
+
+
+ Enable Weather Triggers
+
+
+
+ -
+
+
+ Enable Secret Bases
+
+
+
+ -
+
+
+ Enable Clone Objects
+
+
+
+ -
+
+
+ Enable 'Requires Itemfinder' for Hidden Items
+
+
+
+ -
+
+
+ Enable 'Quantity' for Hidden Items
+
+
+
+ -
+
+
+ Enable 'Respawn Map/NPC' for Heal Locations
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+
+ Project Files
+
+
+ -
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 528
+ 490
+
+
+
+
-
+
+
+ <html><head/><body><p><a href="https://huderlem.github.io/porymap/manual/project-files.html"><span style=" text-decoration: underline;">What are Project Files?</span></a></p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft
+
+
+ true
+
+
+
+ -
+
+
+
+ 2
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ 2
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 502
+ 440
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 4
+
+
+
+
+
+
+
+
+
+
@@ -756,8 +1137,8 @@
- UIntSpinBox
- QAbstractSpinBox
+ UIntHexSpinBox
+ QWidget
diff --git a/include/config.h b/include/config.h
index 16139d53..96cc4911 100644
--- a/include/config.h
+++ b/include/config.h
@@ -67,6 +67,8 @@ public:
this->theme = "default";
this->textEditorOpenFolder = "";
this->textEditorGotoLine = "";
+ this->paletteEditorBitDepth = 24;
+ this->projectSettingsTab = 0;
}
void setRecentProject(QString project);
void setReopenOnLaunch(bool enabled);
@@ -91,6 +93,7 @@ public:
void setTextEditorOpenFolder(const QString &command);
void setTextEditorGotoLine(const QString &command);
void setPaletteEditorBitDepth(int bitDepth);
+ void setProjectSettingsTab(int tab);
QString getRecentProject();
bool getReopenOnLaunch();
MapSortOrder getMapSortOrder();
@@ -114,6 +117,7 @@ public:
QString getTextEditorOpenFolder();
QString getTextEditorGotoLine();
int getPaletteEditorBitDepth();
+ int getProjectSettingsTab();
protected:
virtual QString getConfigFilepath() override;
virtual void parseConfigKeyValue(QString key, QString value) override;
@@ -155,6 +159,7 @@ private:
QString textEditorOpenFolder;
QString textEditorGotoLine;
int paletteEditorBitDepth;
+ int projectSettingsTab;
};
extern PorymapConfig porymapConfig;
diff --git a/include/ui/projectsettingseditor.h b/include/ui/projectsettingseditor.h
index 3bd4d921..5670cb90 100644
--- a/include/ui/projectsettingseditor.h
+++ b/include/ui/projectsettingseditor.h
@@ -48,13 +48,16 @@ private:
void createProjectPathsTable();
QString chooseProjectFile(const QString &defaultFilepath);
+ void choosePrefabsFile();
+ void chooseImageFile(QLineEdit * filepathEdit);
+ void chooseFile(QLineEdit * filepathEdit, const QString &description, const QString &extensions);
private slots:
void dialogButtonClicked(QAbstractButton *button);
- void choosePrefabsFileClicked(bool);
void importDefaultPrefabsClicked(bool);
void updateAttributeLimits(const QString &attrSize);
void markEdited();
+ void on_mainTabs_tabBarClicked(int index);
};
#endif // PROJECTSETTINGSEDITOR_H
diff --git a/include/ui/uintspinbox.h b/include/ui/uintspinbox.h
index dc08c9eb..bc217ec2 100644
--- a/include/ui/uintspinbox.h
+++ b/include/ui/uintspinbox.h
@@ -64,4 +64,15 @@ signals:
void textChanged(const QString &text);
};
+class UIntHexSpinBox : public UIntSpinBox
+{
+ Q_OBJECT
+public:
+ UIntHexSpinBox(QWidget *parent = nullptr) : UIntSpinBox(parent) {
+ this->setPrefix("0x");
+ this->setDisplayIntegerBase(16);
+ this->setHasPadding(true);
+ }
+};
+
#endif // UINTSPINBOX_H
diff --git a/src/config.cpp b/src/config.cpp
index b31beed3..de4499a0 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -269,6 +269,8 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
if (this->paletteEditorBitDepth != 15 && this->paletteEditorBitDepth != 24){
this->paletteEditorBitDepth = 24;
}
+ } else if (key == "project_settings_tab") {
+ this->projectSettingsTab = getConfigInteger(key, value, 0);
} else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
}
@@ -294,7 +296,7 @@ QMap PorymapConfig::getKeyValueMap() {
map.insert("project_settings_editor_state", stringFromByteArray(this->projectSettingsEditorState));
map.insert("custom_scripts_editor_geometry", stringFromByteArray(this->customScriptsEditorGeometry));
map.insert("custom_scripts_editor_state", stringFromByteArray(this->customScriptsEditorState));
- map.insert("collision_opacity", QString("%1").arg(this->collisionOpacity));
+ 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("show_player_view", this->showPlayerView ? "1" : "0");
@@ -306,7 +308,8 @@ QMap PorymapConfig::getKeyValueMap() {
map.insert("theme", this->theme);
map.insert("text_editor_open_directory", this->textEditorOpenFolder);
map.insert("text_editor_goto_line", this->textEditorGotoLine);
- map.insert("palette_editor_bit_depth", QString("%1").arg(this->paletteEditorBitDepth));
+ map.insert("palette_editor_bit_depth", QString::number(this->paletteEditorBitDepth));
+ map.insert("project_settings_tab", QString::number(this->projectSettingsTab));
return map;
}
@@ -451,6 +454,11 @@ void PorymapConfig::setPaletteEditorBitDepth(int bitDepth) {
this->save();
}
+void PorymapConfig::setProjectSettingsTab(int tab) {
+ this->projectSettingsTab = tab;
+ this->save();
+}
+
QString PorymapConfig::getRecentProject() {
return this->recentProject;
}
@@ -575,6 +583,10 @@ int PorymapConfig::getPaletteEditorBitDepth() {
return this->paletteEditorBitDepth;
}
+int PorymapConfig::getProjectSettingsTab() {
+ return this->projectSettingsTab;
+}
+
const QStringList ProjectConfig::versionStrings = {
"pokeruby",
"pokefirered",
@@ -713,10 +725,10 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
} else if (key == "collision_sheet_path") {
this->collisionSheetPath = value;
} else if (key == "collision_sheet_width") {
- // Max for these two keys is if a user specifies blocks with 1 bit for metatile ID and 15 bits for collision or elevation
- this->collisionSheetWidth = getConfigInteger(key, value, 1, 0x7FFF, 2);
+ // TODO: Update max once Block layout can be edited (0x7FFF for 15 bits)
+ this->collisionSheetWidth = getConfigInteger(key, value, 1, 4, 2);
} else if (key == "collision_sheet_height") {
- this->collisionSheetHeight = getConfigInteger(key, value, 1, 0x7FFF, 16);
+ this->collisionSheetHeight = getConfigInteger(key, value, 1, 16, 16);
} else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
}
diff --git a/src/ui/projectsettingseditor.cpp b/src/ui/projectsettingseditor.cpp
index ceb16834..95660a1f 100644
--- a/src/ui/projectsettingseditor.cpp
+++ b/src/ui/projectsettingseditor.cpp
@@ -33,7 +33,6 @@ ProjectSettingsEditor::~ProjectSettingsEditor()
void ProjectSettingsEditor::connectSignals() {
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &ProjectSettingsEditor::dialogButtonClicked);
- connect(ui->button_ChoosePrefabs, &QAbstractButton::clicked, this, &ProjectSettingsEditor::choosePrefabsFileClicked);
connect(ui->button_ImportDefaultPrefabs, &QAbstractButton::clicked, this, &ProjectSettingsEditor::importDefaultPrefabsClicked);
connect(ui->comboBox_BaseGameVersion, &QComboBox::currentTextChanged, this, &ProjectSettingsEditor::promptRestoreDefaults);
connect(ui->comboBox_AttributesSize, &QComboBox::currentTextChanged, this, &ProjectSettingsEditor::updateAttributeLimits);
@@ -45,6 +44,15 @@ void ProjectSettingsEditor::connectSignals() {
this->setBorderMetatilesUi(customSize);
});
+ // Connect file selection buttons
+ connect(ui->button_ChoosePrefabs, &QAbstractButton::clicked, [this](bool) { this->choosePrefabsFile(); });
+ connect(ui->button_CollisionGraphics, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_CollisionGraphics); });
+ connect(ui->button_ObjectsIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_ObjectsIcon); });
+ connect(ui->button_WarpsIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_WarpsIcon); });
+ connect(ui->button_TriggersIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_TriggersIcon); });
+ connect(ui->button_BGsIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_BGsIcon); });
+ connect(ui->button_HealspotsIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_HealspotsIcon); });
+
// Record that there are unsaved changes if any of the settings are modified
for (auto combo : ui->centralwidget->findChildren())
connect(combo, &QComboBox::currentTextChanged, this, &ProjectSettingsEditor::markEdited);
@@ -64,6 +72,11 @@ void ProjectSettingsEditor::markEdited() {
this->hasUnsavedChanges = true;
}
+// Remember the current settings tab for future sessions
+void ProjectSettingsEditor::on_mainTabs_tabBarClicked(int index) {
+ porymapConfig.setProjectSettingsTab(index);
+}
+
void ProjectSettingsEditor::initUi() {
// Populate combo boxes
if (project) ui->comboBox_DefaultPrimaryTileset->addItems(project->primaryTilesetLabels);
@@ -71,6 +84,9 @@ void ProjectSettingsEditor::initUi() {
ui->comboBox_BaseGameVersion->addItems(ProjectConfig::versionStrings);
ui->comboBox_AttributesSize->addItems({"1", "2", "4"});
+ // Select tab from last session
+ ui->mainTabs->setCurrentIndex(porymapConfig.getProjectSettingsTab());
+
// Validate that the border metatiles text is a comma-separated list of metatile values
const QString regex_Hex = "(0[xX])?[A-Fa-f0-9]+";
static const QRegularExpression expression(QString("^(%1,)*%1$").arg(regex_Hex)); // Comma-separated list of hex values
@@ -84,7 +100,10 @@ void ProjectSettingsEditor::initUi() {
ui->spinBox_BorderMetatile2->setMaximum(maxMetatileId);
ui->spinBox_BorderMetatile3->setMaximum(maxMetatileId);
ui->spinBox_BorderMetatile4->setMaximum(maxMetatileId);
- ui->spinBox_Elevation->setMaximum(15);
+ ui->spinBox_Elevation->setMaximum(Project::getMaxElevation());
+ ui->spinBox_Collision->setMaximum(Project::getMaxCollision());
+ ui->spinBox_MaxElevation->setMaximum(Project::getMaxElevation());
+ ui->spinBox_MaxCollision->setMaximum(Project::getMaxCollision());
}
void ProjectSettingsEditor::setBorderMetatilesUi(bool customSize) {
@@ -227,7 +246,10 @@ void ProjectSettingsEditor::refresh() {
// Set spin box values
ui->spinBox_Elevation->setValue(projectConfig.getNewMapElevation());
+ ui->spinBox_Collision->setValue(projectConfig.getNewMapCollision());
ui->spinBox_FillMetatile->setValue(projectConfig.getNewMapMetatileId());
+ ui->spinBox_MaxElevation->setValue(projectConfig.getCollisionSheetHeight() - 1);
+ ui->spinBox_MaxCollision->setValue(projectConfig.getCollisionSheetWidth() - 1);
ui->spinBox_BehaviorMask->setValue(projectConfig.getMetatileBehaviorMask());
ui->spinBox_EncounterTypeMask->setValue(projectConfig.getMetatileEncounterTypeMask());
ui->spinBox_LayerTypeMask->setValue(projectConfig.getMetatileLayerTypeMask());
@@ -240,6 +262,12 @@ void ProjectSettingsEditor::refresh() {
// Set line edit texts
ui->lineEdit_PrefabsPath->setText(projectConfig.getPrefabFilepath());
+ ui->lineEdit_CollisionGraphics->setText(projectConfig.getCollisionSheetPath());
+ ui->lineEdit_ObjectsIcon->setText(projectConfig.getEventIconPath(Event::Group::Object));
+ ui->lineEdit_WarpsIcon->setText(projectConfig.getEventIconPath(Event::Group::Warp));
+ ui->lineEdit_TriggersIcon->setText(projectConfig.getEventIconPath(Event::Group::Coord));
+ ui->lineEdit_BGsIcon->setText(projectConfig.getEventIconPath(Event::Group::Bg));
+ ui->lineEdit_HealspotsIcon->setText(projectConfig.getEventIconPath(Event::Group::Heal));
for (auto lineEdit : ui->scrollAreaContents_ProjectPaths->findChildren())
lineEdit->setText(projectConfig.getFilePath(lineEdit->objectName(), true));
@@ -253,10 +281,13 @@ void ProjectSettingsEditor::save() {
// Prevent a call to save() for each of the config settings
projectConfig.setSaveDisabled(true);
+ // Save combo box settings
projectConfig.setDefaultPrimaryTileset(ui->comboBox_DefaultPrimaryTileset->currentText());
projectConfig.setDefaultSecondaryTileset(ui->comboBox_DefaultSecondaryTileset->currentText());
projectConfig.setBaseGameVersion(projectConfig.stringToBaseGameVersion(ui->comboBox_BaseGameVersion->currentText()));
projectConfig.setMetatileAttributesSize(ui->comboBox_AttributesSize->currentText().toInt());
+
+ // Save check box settings
projectConfig.setUsePoryScript(ui->checkBox_UsePoryscript->isChecked());
userConfig.setEncounterJsonActive(ui->checkBox_ShowWildEncounterTables->isChecked());
projectConfig.setCreateMapTextFileEnabled(ui->checkBox_CreateTextFile->isChecked());
@@ -272,15 +303,30 @@ void ProjectSettingsEditor::save() {
projectConfig.setUseCustomBorderSize(ui->checkBox_EnableCustomBorderSize->isChecked());
projectConfig.setTilesetsHaveCallback(ui->checkBox_OutputCallback->isChecked());
projectConfig.setTilesetsHaveIsCompressed(ui->checkBox_OutputIsCompressed->isChecked());
+
+ // Save spin box settings
projectConfig.setNewMapElevation(ui->spinBox_Elevation->value());
+ projectConfig.setNewMapCollision(ui->spinBox_Collision->value());
projectConfig.setNewMapMetatileId(ui->spinBox_FillMetatile->value());
+ projectConfig.setCollisionSheetHeight(ui->spinBox_MaxElevation->value() + 1);
+ projectConfig.setCollisionSheetWidth(ui->spinBox_MaxCollision->value() + 1);
projectConfig.setMetatileBehaviorMask(ui->spinBox_BehaviorMask->value());
projectConfig.setMetatileTerrainTypeMask(ui->spinBox_TerrainTypeMask->value());
projectConfig.setMetatileEncounterTypeMask(ui->spinBox_EncounterTypeMask->value());
projectConfig.setMetatileLayerTypeMask(ui->spinBox_LayerTypeMask->value());
+
+ // Save line edit settings
projectConfig.setPrefabFilepath(ui->lineEdit_PrefabsPath->text());
+ projectConfig.setCollisionSheetPath(ui->lineEdit_CollisionGraphics->text());
+ projectConfig.setEventIconPath(Event::Group::Object, ui->lineEdit_ObjectsIcon->text());
+ projectConfig.setEventIconPath(Event::Group::Warp, ui->lineEdit_WarpsIcon->text());
+ projectConfig.setEventIconPath(Event::Group::Coord, ui->lineEdit_TriggersIcon->text());
+ projectConfig.setEventIconPath(Event::Group::Bg, ui->lineEdit_BGsIcon->text());
+ projectConfig.setEventIconPath(Event::Group::Heal, ui->lineEdit_HealspotsIcon->text());
for (auto lineEdit : ui->scrollAreaContents_ProjectPaths->findChildren())
projectConfig.setFilePath(lineEdit->objectName(), lineEdit->text());
+
+ // Save border metatile IDs
projectConfig.setNewMapBorderMetatileIds(this->getBorderMetatileIds(ui->checkBox_EnableCustomBorderSize->isChecked()));
projectConfig.setSaveDisabled(false);
@@ -293,14 +339,16 @@ void ProjectSettingsEditor::save() {
}
// Pick a file to use as the new prefabs file path
-void ProjectSettingsEditor::choosePrefabsFileClicked(bool) {
- QString startPath = this->project->importExportPath;
- QFileInfo fileInfo(ui->lineEdit_PrefabsPath->text());
- if (fileInfo.exists() && fileInfo.isFile() && fileInfo.suffix() == "json") {
- // Current setting is a valid JSON file. Start the file dialog there
- startPath = fileInfo.dir().absolutePath();
- }
- QString filepath = QFileDialog::getOpenFileName(this, "Choose Prefabs File", startPath, "JSON Files (*.json)");
+void ProjectSettingsEditor::choosePrefabsFile() {
+ this->chooseFile(ui->lineEdit_PrefabsPath, "Choose Prefabs File", "JSON Files (*.json)");
+}
+
+void ProjectSettingsEditor::chooseImageFile(QLineEdit * filepathEdit) {
+ this->chooseFile(filepathEdit, "Choose Image File", "Images (*.png *.jpg)");
+}
+
+void ProjectSettingsEditor::chooseFile(QLineEdit * filepathEdit, const QString &description, const QString &extensions) {
+ QString filepath = QFileDialog::getOpenFileName(this, description, this->project->importExportPath, extensions);
if (filepath.isEmpty())
return;
this->project->setImportExportPath(filepath);
@@ -308,7 +356,7 @@ void ProjectSettingsEditor::choosePrefabsFileClicked(bool) {
// Display relative path if this file is in the project folder
if (filepath.startsWith(this->baseDir))
filepath.remove(0, this->baseDir.length());
- ui->lineEdit_PrefabsPath->setText(filepath);
+ if (filepathEdit) filepathEdit->setText(filepath);
this->hasUnsavedChanges = true;
}