Add project settings window

This commit is contained in:
GriffinR 2023-08-23 02:32:32 -04:00
parent 0148580bd2
commit 4d8f5ef150
14 changed files with 810 additions and 48 deletions

View file

@ -3017,6 +3017,7 @@
<addaction name="actionUse_Poryscript"/>
<addaction name="actionOpen_Recent_Project_On_Launch"/>
<addaction name="separator"/>
<addaction name="actionEdit_Project_Settings"/>
<addaction name="actionEdit_Preferences"/>
<addaction name="actionEdit_Shortcuts"/>
</widget>
@ -3326,6 +3327,11 @@
<string>Import Map from Advance Map 1.92...</string>
</property>
</action>
<action name="actionEdit_Project_Settings">
<property name="text">
<string>Edit Project Settings...</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View file

@ -0,0 +1,486 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProjectSettingsEditor</class>
<widget class="QMainWindow" name="ProjectSettingsEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>570</width>
<height>1041</height>
</rect>
</property>
<property name="windowTitle">
<string>Project Settings</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>9</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>544</width>
<height>994</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QGroupBox" name="groupBox_UserConfig">
<property name="title">
<string>User config</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="checkBox_UsePoryscript">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Use Poryscript</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_ShowWildEncounterTables">
<property name="text">
<string>Show Wild Encounter Tables</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_DefaultTilesets">
<property name="title">
<string>Default Tilesets</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_NewMapDefaults">
<property name="title">
<string>New Map Defaults</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QLabel" name="label_FillMetatile">
<property name="toolTip">
<string>The default metatile value that will be used to fill new maps</string>
</property>
<property name="text">
<string>Fill Metatile</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_Elevation">
<property name="toolTip">
<string>The default elevation that will be used to fill new maps</string>
</property>
<property name="text">
<string>Elevation</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_BorderMetatiles">
<property name="toolTip">
<string>A comma-separated list of metatile values that will be used to fill new map borders</string>
</property>
<property name="text">
<string>Border Metatiles</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_Elevation"/>
</item>
<item row="2" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLineEdit" name="lineEdit_FillMetatile"/>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="lineEdit_BorderMetatiles"/>
</item>
<item row="3" column="0" colspan="3">
<widget class="QCheckBox" name="checkBox_CreateTextFile">
<property name="toolTip">
<string>Whether a separate text.inc or text.pory file will be created for new maps, alongside the scripts file</string>
</property>
<property name="text">
<string>Create separate text file</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_Prefabs">
<property name="title">
<string>Prefabs</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_PrefabsPath">
<property name="text">
<string>Prefabs Path</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="checkBox_PrefabImportPrompted">
<property name="text">
<string>Prefab import prompted</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_PrefabsPath"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line_Warning">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_Warning">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:13pt; color:#d7000c;&quot;&gt;WARNING: &lt;/span&gt;&lt;span style=&quot; font-weight:400;&quot;&gt;The settings from this point below require project changes to function properly. Do not modify these settings without the necessary changes. &lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_BaseGameVersionBox" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QWidget" name="widget_BaseGameVersion" native="true">
<layout class="QFormLayout" name="layout_BaseGameVersion"/>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_TilesetsMetatiles">
<property name="title">
<string>Tilesets / Metatiles</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="0">
<widget class="QLabel" name="label_BehaviorMask">
<property name="toolTip">
<string>The mask used to read/write Metatile Behavior from the metatile's attributes data. If 0, this attribute is disabled.</string>
</property>
<property name="text">
<string>Behavior mask</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_AttributesSize">
<property name="toolTip">
<string>The number of bytes used per metatile for metatile attributes</string>
</property>
<property name="text">
<string>Attributes size (in bytes)</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_LayerTypeMask">
<property name="toolTip">
<string>The mask used to read/write Layer Type from the metatile's attributes data. If 0, this attribute is disabled.</string>
</property>
<property name="text">
<string>Layer Type mask</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_TerrainTypeMask">
<property name="toolTip">
<string>The mask used to read/write Terrain Type from the metatile's attributes data. If 0, this attribute is disabled.</string>
</property>
<property name="text">
<string>Terrain Type mask</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_EnableTripleLayerMetatiles">
<property name="text">
<string>Enable Triple Layer Metatiles</string>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>15</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_EncounterTypeMask"/>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_LayerTypeMask"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_EncounterTypeMask">
<property name="toolTip">
<string>The mask used to read/write Encounter Type from the metatile's attributes data. If 0, this attribute is disabled.</string>
</property>
<property name="text">
<string>Encounter Type mask</string>
</property>
</widget>
</item>
<item row="7" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_TerrainTypeMask"/>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_BehaviorMask"/>
</item>
<item row="2" column="1">
<widget class="QWidget" name="widget_SizeDropdown" native="true"/>
</item>
<item row="3" column="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="9" column="0">
<widget class="QCheckBox" name="checkBox_OutputCallback">
<property name="toolTip">
<string>Whether the C data outputted for new tilesets will include the &quot;callback&quot; field</string>
</property>
<property name="text">
<string>Output 'callback' field</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QCheckBox" name="checkBox_OutputIsCompressed">
<property name="toolTip">
<string>Whether the C data outputted for new tilesets will include the &quot;isCompressed&quot; field</string>
</property>
<property name="text">
<string>Output 'isCompressed' field</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_Events">
<property name="title">
<string>Events</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox_EnableRequiresItemfinder">
<property name="text">
<string>Enable 'Requires Itemfinder' for Hidden Items</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_EnableQuantity">
<property name="text">
<string>Enable 'Quantity' for Hidden Items</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_EnableSecretBases">
<property name="text">
<string>Enable Secret Bases</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBox_EnableWeatherTriggers">
<property name="text">
<string>Enable Weather Triggers</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_EnableCloneObjects">
<property name="text">
<string>Enable Clone Objects</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBox_EnableRespawn">
<property name="text">
<string>Enable 'Respawn Map/NPC' for Heal Locations</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_Maps">
<property name="title">
<string>Maps</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_EnableAllowFlags">
<property name="toolTip">
<string>Whether &quot;Allow Running&quot;, &quot;Allow Biking&quot; and &quot;Allow Dig &amp; Escape Rope&quot; are default options for Map Headers</string>
</property>
<property name="text">
<string>Enable 'Allow Running/Biking/Escaping'</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_EnableFloorNumber">
<property name="toolTip">
<string>Whether &quot;Floor Number&quot; is a default option for Map Headers</string>
</property>
<property name="text">
<string>Enable 'Floor Number'</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_EnableCustomBorderSize">
<property name="toolTip">
<string>Whether the dimensions of the border can be changed. If not set, all borders are 2x2</string>
</property>
<property name="text">
<string>Enable Custom Border Size</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -289,7 +289,7 @@
</widget>
</item>
<item row="9" column="0">
<widget class="QComboBox" name="comboBox_encounterType"/>
<widget class="NoScrollComboBox" name="comboBox_encounterType"/>
</item>
<item row="2" column="0" colspan="3">
<widget class="QLabel" name="label_metatileBehavior">
@ -299,10 +299,10 @@
</widget>
</item>
<item row="11" column="0">
<widget class="QComboBox" name="comboBox_terrainType"/>
<widget class="NoScrollComboBox" name="comboBox_terrainType"/>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="comboBox_layerType"/>
<widget class="NoScrollComboBox" name="comboBox_layerType"/>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_terrainType">

View file

@ -225,6 +225,7 @@ public:
this->filePaths.clear();
this->readKeys.clear();
}
static const QStringList baseGameVersions;
void setBaseGameVersion(BaseGameVersion baseGameVersion);
BaseGameVersion getBaseGameVersion();
QString getBaseGameVersionString();
@ -256,10 +257,12 @@ public:
int getNumTilesInMetatile();
void setNewMapMetatileId(int metatileId);
int getNewMapMetatileId();
QString getNewMapMetatileIdString();
void setNewMapElevation(int elevation);
int getNewMapElevation();
void setNewMapBorderMetatileIds(QList<int> metatileIds);
QList<int> getNewMapBorderMetatileIds();
QString getNewMapBorderMetatileIdsString();
QString getDefaultPrimaryTileset();
QString getDefaultSecondaryTileset();
void setFilePath(ProjectFilePath pathId, QString path);
@ -277,6 +280,7 @@ public:
uint32_t getMetatileTerrainTypeMask();
uint32_t getMetatileEncounterTypeMask();
uint32_t getMetatileLayerTypeMask();
static QString getMaskString(uint32_t mask);
bool getMapAllowFlagsEnabled();
protected:
virtual QString getConfigFilepath() override;

View file

@ -25,6 +25,7 @@
#include "newtilesetdialog.h"
#include "shortcutseditor.h"
#include "preferenceeditor.h"
#include "projectsettingseditor.h"
@ -286,6 +287,7 @@ private slots:
void on_actionRegion_Map_Editor_triggered();
void on_actionEdit_Preferences_triggered();
void togglePreferenceSpecificUi();
void on_actionEdit_Project_Settings_triggered();
public:
Ui::MainWindow *ui;
@ -299,6 +301,7 @@ private:
QPointer<MapImageExporter> mapImageExporter = nullptr;
QPointer<NewMapPopup> newMapPrompt = nullptr;
QPointer<PreferenceEditor> preferenceEditor = nullptr;
QPointer<ProjectSettingsEditor> projectSettingsEditor = nullptr;
FilterChildrenProxyModel *mapListProxyModel;
QStandardItemModel *mapListModel;
QList<QStandardItem*> *mapGroupItemsList;

View file

@ -11,8 +11,10 @@ public:
explicit NoScrollComboBox(QWidget *parent = nullptr);
void wheelEvent(QWheelEvent *event);
void setTextItem(const QString &text);
void setNumberItem(int value);
private:
void setItem(int index, const QString &text);
};
#endif // NOSCROLLCOMBOBOX_H

View file

@ -0,0 +1,41 @@
#ifndef PROJECTSETTINGSEDITOR_H
#define PROJECTSETTINGSEDITOR_H
#include <QMainWindow>
#include "project.h"
class NoScrollComboBox;
class QAbstractButton;
namespace Ui {
class ProjectSettingsEditor;
}
class ProjectSettingsEditor : public QMainWindow
{
Q_OBJECT
public:
explicit ProjectSettingsEditor(QWidget *parent = nullptr, Project *project = nullptr);
~ProjectSettingsEditor();
signals:
void saved();
private:
Ui::ProjectSettingsEditor *ui;
Project *project;
NoScrollComboBox *combo_defaultPrimaryTileset;
NoScrollComboBox *combo_defaultSecondaryTileset;
NoScrollComboBox *combo_baseGameVersion;
NoScrollComboBox *combo_attributesSize;
void initUi();
void saveFields();
private slots:
void dialogButtonClicked(QAbstractButton *button);
};
#endif // PROJECTSETTINGSEDITOR_H

View file

@ -138,7 +138,6 @@ private:
void copyMetatile(bool cut);
void pasteMetatile(const Metatile * toPaste, QString label);
bool replaceMetatile(uint16_t metatileId, const Metatile * src, QString label);
void setComboValue(QComboBox * combo, int value);
void commitMetatileChange(Metatile * prevMetatile);
void commitMetatileAndLabelChange(Metatile * prevMetatile, QString prevLabel);

View file

@ -49,6 +49,7 @@ SOURCES += src/core/block.cpp \
src/ui/currentselectedmetatilespixmapitem.cpp \
src/ui/overlay.cpp \
src/ui/prefab.cpp \
src/ui/projectsettingseditor.cpp \
src/ui/regionmaplayoutpixmapitem.cpp \
src/ui/regionmapentriespixmapitem.cpp \
src/ui/cursortilerect.cpp \
@ -134,6 +135,7 @@ HEADERS += include/core/block.h \
include/ui/connectionpixmapitem.h \
include/ui/currentselectedmetatilespixmapitem.h \
include/ui/prefabframe.h \
include/ui/projectsettingseditor.h \
include/ui/regionmaplayoutpixmapitem.h \
include/ui/regionmapentriespixmapitem.h \
include/ui/cursortilerect.h \
@ -201,7 +203,8 @@ FORMS += forms/mainwindow.ui \
forms/shortcutseditor.ui \
forms/preferenceeditor.ui \
forms/regionmappropertiesdialog.ui \
forms/colorpicker.ui
forms/colorpicker.ui \
forms/projectsettingseditor.ui
RESOURCES += \
resources/images.qrc \

View file

@ -513,16 +513,22 @@ int PorymapConfig::getPaletteEditorBitDepth() {
return this->paletteEditorBitDepth;
}
const QStringList ProjectConfig::baseGameVersions = {
"pokeruby",
"pokefirered",
"pokeemerald",
};
const QMap<BaseGameVersion, QString> baseGameVersionMap = {
{BaseGameVersion::pokeruby, "pokeruby"},
{BaseGameVersion::pokefirered, "pokefirered"},
{BaseGameVersion::pokeemerald, "pokeemerald"},
{BaseGameVersion::pokeruby, ProjectConfig::baseGameVersions[0]},
{BaseGameVersion::pokefirered, ProjectConfig::baseGameVersions[1]},
{BaseGameVersion::pokeemerald, ProjectConfig::baseGameVersions[2]},
};
const QMap<QString, BaseGameVersion> baseGameVersionReverseMap = {
{"pokeruby", BaseGameVersion::pokeruby},
{"pokefirered", BaseGameVersion::pokefirered},
{"pokeemerald", BaseGameVersion::pokeemerald},
{ProjectConfig::baseGameVersions[0], BaseGameVersion::pokeruby},
{ProjectConfig::baseGameVersions[1], BaseGameVersion::pokefirered},
{ProjectConfig::baseGameVersions[2], BaseGameVersion::pokeemerald},
};
ProjectConfig projectConfig;
@ -578,6 +584,7 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
int metatileId = getConfigInteger(key, metatileIds.at(i), 0, 1023, 0);
this->newMapBorderMetatileIds.append(metatileId);
}
// TODO: If insufficient metatiles are provided, it should loop the provided metatiles instead.
for (; i < maxSize; i++) {
// Set any metatiles not provided to 0
this->newMapBorderMetatileIds.append(0);
@ -675,12 +682,9 @@ QMap<QString, QString> ProjectConfig::getKeyValueMap() {
map.insert("enable_floor_number", QString::number(this->enableFloorNumber));
map.insert("create_map_text_file", QString::number(this->createMapTextFile));
map.insert("enable_triple_layer_metatiles", QString::number(this->enableTripleLayerMetatiles));
map.insert("new_map_metatile", QString::number(this->newMapMetatileId));
map.insert("new_map_metatile", this->getNewMapMetatileIdString());
map.insert("new_map_elevation", QString::number(this->newMapElevation));
QStringList metatiles;
for (auto metatile : this->newMapBorderMetatileIds)
metatiles << QString::number(metatile);
map.insert("new_map_border_metatiles", metatiles.join(","));
map.insert("new_map_border_metatiles", this->getNewMapBorderMetatileIdsString());
map.insert("default_primary_tileset", this->defaultPrimaryTileset);
map.insert("default_secondary_tileset", this->defaultSecondaryTileset);
map.insert("prefabs_filepath", this->prefabFilepath);
@ -691,10 +695,10 @@ QMap<QString, QString> ProjectConfig::getKeyValueMap() {
map.insert("tilesets_have_callback", QString::number(this->tilesetsHaveCallback));
map.insert("tilesets_have_is_compressed", QString::number(this->tilesetsHaveIsCompressed));
map.insert("metatile_attributes_size", QString::number(this->metatileAttributesSize));
map.insert("metatile_behavior_mask", "0x" + QString::number(this->metatileBehaviorMask, 16).toUpper());
map.insert("metatile_terrain_type_mask", "0x" + QString::number(this->metatileTerrainTypeMask, 16).toUpper());
map.insert("metatile_encounter_type_mask", "0x" + QString::number(this->metatileEncounterTypeMask, 16).toUpper());
map.insert("metatile_layer_type_mask", "0x" + QString::number(this->metatileLayerTypeMask, 16).toUpper());
map.insert("metatile_behavior_mask", getMaskString(this->metatileBehaviorMask));
map.insert("metatile_terrain_type_mask", getMaskString(this->metatileTerrainTypeMask));
map.insert("metatile_encounter_type_mask", getMaskString(this->metatileEncounterTypeMask));
map.insert("metatile_layer_type_mask", getMaskString(this->metatileLayerTypeMask));
map.insert("enable_map_allow_flags", QString::number(this->enableMapAllowFlags));
return map;
}
@ -880,6 +884,10 @@ int ProjectConfig::getNewMapMetatileId() {
return this->newMapMetatileId;
}
QString ProjectConfig::getNewMapMetatileIdString() {
return "0x" + QString::number(this->newMapMetatileId, 16).toUpper();
}
void ProjectConfig::setNewMapElevation(int elevation) {
this->newMapElevation = elevation;
this->save();
@ -898,6 +906,14 @@ QList<int> ProjectConfig::getNewMapBorderMetatileIds() {
return this->newMapBorderMetatileIds;
}
QString ProjectConfig::getNewMapBorderMetatileIdsString() {
QStringList metatiles;
for (auto metatileId : this->newMapBorderMetatileIds){
metatiles << ("0x" + QString::number(metatileId, 16).toUpper());
}
return metatiles.join(",");
}
QString ProjectConfig::getDefaultPrimaryTileset() {
return this->defaultPrimaryTileset;
}
@ -965,6 +981,10 @@ uint32_t ProjectConfig::getMetatileLayerTypeMask() {
return this->metatileLayerTypeMask;
}
QString ProjectConfig::getMaskString(uint32_t mask) {
return "0x" + QString::number(mask, 16).toUpper();
}
bool ProjectConfig::getMapAllowFlagsEnabled() {
return this->enableMapAllowFlags;
}

View file

@ -2751,6 +2751,23 @@ void MainWindow::togglePreferenceSpecificUi() {
ui->actionOpen_Project_in_Text_Editor->setEnabled(true);
}
void MainWindow::on_actionEdit_Project_Settings_triggered() {
if (!this->projectSettingsEditor) {
this->projectSettingsEditor = new ProjectSettingsEditor(this, this->editor->project);
connect(this->projectSettingsEditor, &ProjectSettingsEditor::saved,
this, &MainWindow::togglePreferenceSpecificUi);
}
if (!this->projectSettingsEditor->isVisible()) {
this->projectSettingsEditor->show();
} else if (this->projectSettingsEditor->isMinimized()) {
this->projectSettingsEditor->showNormal();
} else {
this->projectSettingsEditor->raise();
this->projectSettingsEditor->activateWindow();
}
}
void MainWindow::on_pushButton_AddCustomHeaderField_clicked()
{
bool ok;

View file

@ -29,11 +29,30 @@ void NoScrollComboBox::wheelEvent(QWheelEvent *event)
QComboBox::wheelEvent(event);
}
void NoScrollComboBox::setItem(int index, const QString &text)
{
if (index >= 0) {
// Valid item
this->setCurrentIndex(index);
} else if (this->isEditable()) {
// Invalid item in editable box, just display the text
this->setCurrentText(text);
} else {
// Invalid item in uneditable box, display text as placeholder
// On Qt < 5.15 this will display an empty box
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
this->setPlaceholderText(text);
#endif
this->setCurrentIndex(index);
}
}
void NoScrollComboBox::setTextItem(const QString &text)
{
int index = this->findText(text);
if (index >= 0)
this->setCurrentIndex(index);
else
this->setCurrentText(text);
this->setItem(this->findText(text), text);
}
void NoScrollComboBox::setNumberItem(int value)
{
this->setItem(this->findData(value), QString::number(value));
}

View file

@ -0,0 +1,177 @@
#include "projectsettingseditor.h"
#include "ui_projectsettingseditor.h"
#include "config.h"
#include "noscrollcombobox.h"
#include <QAbstractButton>
#include <QFormLayout>
/*
Editor for the settings in a user's porymap.project.cfg and porymap.user.cfg files.
*/
ProjectSettingsEditor::ProjectSettingsEditor(QWidget *parent, Project *project) :
QMainWindow(parent),
ui(new Ui::ProjectSettingsEditor),
project(project),
combo_defaultPrimaryTileset(nullptr),
combo_defaultSecondaryTileset(nullptr),
combo_baseGameVersion(nullptr),
combo_attributesSize(nullptr)
{
ui->setupUi(this);
initUi();
setAttribute(Qt::WA_DeleteOnClose);
connect(ui->buttonBox, &QDialogButtonBox::clicked,
this, &ProjectSettingsEditor::dialogButtonClicked);
}
ProjectSettingsEditor::~ProjectSettingsEditor()
{
delete ui;
}
void ProjectSettingsEditor::initUi() {
// Block signals while setting initial UI states
const QSignalBlocker blocker0(combo_defaultPrimaryTileset);
const QSignalBlocker blocker1(combo_defaultSecondaryTileset);
const QSignalBlocker blocker2(combo_baseGameVersion);
const QSignalBlocker blocker3(combo_attributesSize);
const QSignalBlocker blocker4(ui->checkBox_UsePoryscript);
const QSignalBlocker blocker5(ui->checkBox_ShowWildEncounterTables);
const QSignalBlocker blocker6(ui->checkBox_CreateTextFile);
const QSignalBlocker blocker7(ui->checkBox_PrefabImportPrompted);
const QSignalBlocker blocker8(ui->checkBox_EnableTripleLayerMetatiles);
const QSignalBlocker blocker9(ui->checkBox_EnableRequiresItemfinder);
const QSignalBlocker blockerA(ui->checkBox_EnableQuantity);
const QSignalBlocker blockerB(ui->checkBox_EnableCloneObjects);
const QSignalBlocker blockerC(ui->checkBox_EnableWeatherTriggers);
const QSignalBlocker blockerD(ui->checkBox_EnableSecretBases);
const QSignalBlocker blockerE(ui->checkBox_EnableRespawn);
const QSignalBlocker blockerF(ui->checkBox_EnableAllowFlags);
const QSignalBlocker blocker10(ui->checkBox_EnableFloorNumber);
const QSignalBlocker blocker11(ui->checkBox_EnableCustomBorderSize);
const QSignalBlocker blocker12(ui->checkBox_OutputCallback);
const QSignalBlocker blocker13(ui->checkBox_OutputIsCompressed);
const QSignalBlocker blocker14(ui->spinBox_Elevation);
const QSignalBlocker blocker15(ui->lineEdit_BorderMetatiles);
const QSignalBlocker blocker16(ui->lineEdit_FillMetatile);
const QSignalBlocker blocker17(ui->lineEdit_PrefabsPath);
const QSignalBlocker blocker18(ui->lineEdit_BehaviorMask);
const QSignalBlocker blocker19(ui->lineEdit_EncounterTypeMask);
const QSignalBlocker blocker1A(ui->lineEdit_LayerTypeMask);
const QSignalBlocker blocker1B(ui->lineEdit_TerrainTypeMask);
// Create Default Tilesets combo boxes
auto *defaultTilesetsLayout = new QFormLayout(ui->groupBox_DefaultTilesets);
combo_defaultPrimaryTileset = new NoScrollComboBox(ui->groupBox_DefaultTilesets);
combo_defaultSecondaryTileset = new NoScrollComboBox(ui->groupBox_DefaultTilesets);
if (project) combo_defaultPrimaryTileset->addItems(project->primaryTilesetLabels);
if (project) combo_defaultSecondaryTileset->addItems(project->secondaryTilesetLabels);
combo_defaultPrimaryTileset->setTextItem(projectConfig.getDefaultPrimaryTileset());
combo_defaultSecondaryTileset->setTextItem(projectConfig.getDefaultSecondaryTileset());
defaultTilesetsLayout->addRow("Primary Tileset", combo_defaultPrimaryTileset);
defaultTilesetsLayout->addRow("Secondary Tileset", combo_defaultSecondaryTileset);
// Create Base game version combo box
combo_baseGameVersion = new NoScrollComboBox(ui->widget_BaseGameVersion);
combo_baseGameVersion->addItems(ProjectConfig::baseGameVersions);
combo_baseGameVersion->setTextItem(projectConfig.getBaseGameVersionString());
combo_baseGameVersion->setEditable(false);
ui->layout_BaseGameVersion->insertRow(0, "Base game version", combo_baseGameVersion);
// Create Attributes size combo box
auto *attributesSizeLayout = new QFormLayout(ui->widget_SizeDropdown);
combo_attributesSize = new NoScrollComboBox(ui->widget_SizeDropdown);
combo_attributesSize->addItems({"1", "2", "4"});
combo_attributesSize->setTextItem(QString::number(projectConfig.getMetatileAttributesSize()));
combo_attributesSize->setEditable(false);
attributesSizeLayout->addRow("", combo_attributesSize);
// Init check boxes
ui->checkBox_UsePoryscript->setChecked(projectConfig.getUsePoryScript());
ui->checkBox_ShowWildEncounterTables->setChecked(userConfig.getEncounterJsonActive());
ui->checkBox_CreateTextFile->setChecked(projectConfig.getCreateMapTextFileEnabled());
ui->checkBox_PrefabImportPrompted->setChecked(projectConfig.getPrefabImportPrompted());
ui->checkBox_EnableTripleLayerMetatiles->setChecked(projectConfig.getTripleLayerMetatilesEnabled());
ui->checkBox_EnableRequiresItemfinder->setChecked(projectConfig.getHiddenItemRequiresItemfinderEnabled());
ui->checkBox_EnableQuantity->setChecked(projectConfig.getHiddenItemQuantityEnabled());
ui->checkBox_EnableCloneObjects->setChecked(projectConfig.getEventCloneObjectEnabled());
ui->checkBox_EnableWeatherTriggers->setChecked(projectConfig.getEventWeatherTriggerEnabled());
ui->checkBox_EnableSecretBases->setChecked(projectConfig.getEventSecretBaseEnabled());
ui->checkBox_EnableRespawn->setChecked(projectConfig.getHealLocationRespawnDataEnabled());
ui->checkBox_EnableAllowFlags->setChecked(projectConfig.getMapAllowFlagsEnabled());
ui->checkBox_EnableFloorNumber->setChecked(projectConfig.getFloorNumberEnabled());
ui->checkBox_EnableCustomBorderSize->setChecked(projectConfig.getUseCustomBorderSize());
ui->checkBox_OutputCallback->setChecked(projectConfig.getTilesetsHaveCallback());
ui->checkBox_OutputIsCompressed->setChecked(projectConfig.getTilesetsHaveIsCompressed());
// Init spinners
ui->spinBox_Elevation->setRange(0, 15);
ui->spinBox_Elevation->setValue(projectConfig.getNewMapElevation());
// Init text boxes
// TODO: Validator for Border Metatiles and Fill Metatile
ui->lineEdit_BorderMetatiles->setText(projectConfig.getNewMapBorderMetatileIdsString());
ui->lineEdit_FillMetatile->setText(projectConfig.getNewMapMetatileIdString());
ui->lineEdit_PrefabsPath->setText(projectConfig.getPrefabFilepath(false));
QString mask = ProjectConfig::getMaskString(projectConfig.getMetatileBehaviorMask());
ui->lineEdit_BehaviorMask->setText(mask);
mask = ProjectConfig::getMaskString(projectConfig.getMetatileEncounterTypeMask());
ui->lineEdit_EncounterTypeMask->setText(mask);
mask = ProjectConfig::getMaskString(projectConfig.getMetatileLayerTypeMask());
ui->lineEdit_LayerTypeMask->setText(mask);
mask = ProjectConfig::getMaskString(projectConfig.getMetatileTerrainTypeMask());
ui->lineEdit_TerrainTypeMask->setText(mask);
}
void ProjectSettingsEditor::saveFields() {
// TODO
/*
TODO combo_defaultPrimaryTileset
TODO combo_defaultSecondaryTileset
setBaseGameVersion combo_baseGameVersion
TODO combo_attributesSize
setUsePoryScript ui->checkBox_UsePoryscript
userConfig.setEncounterJsonActive ui->checkBox_ShowWildEncounterTables
setCreateMapTextFileEnabled ui->checkBox_CreateTextFile
setPrefabImportPrompted ui->checkBox_PrefabImportPrompted
setTripleLayerMetatilesEnabled ui->checkBox_EnableTripleLayerMetatiles
setHiddenItemRequiresItemfinderEnabled ui->checkBox_EnableRequiresItemfinder
setHiddenItemQuantityEnabled ui->checkBox_EnableQuantity
setEventCloneObjectEnabled ui->checkBox_EnableCloneObjects
setEventWeatherTriggerEnabled ui->checkBox_EnableWeatherTriggers
setEventSecretBaseEnabled ui->checkBox_EnableSecretBases
setHealLocationRespawnDataEnabled ui->checkBox_EnableRespawn
TODO ui->checkBox_EnableAllowFlags
setFloorNumberEnabled ui->checkBox_EnableFloorNumber
setUseCustomBorderSize ui->checkBox_EnableCustomBorderSize
setTilesetsHaveCallback ui->checkBox_OutputCallback
setTilesetsHaveIsCompressed ui->checkBox_OutputIsCompressed
setNewMapElevation ui->spinBox_Elevation
setPrefabFilepath ui->lineEdit_PrefabsPath
TODO ui->lineEdit_BehaviorMask
TODO ui->lineEdit_EncounterTypeMask
TODO ui->lineEdit_LayerTypeMask
TODO ui->lineEdit_TerrainTypeMask
setNewMapMetatileId ui->lineEdit_FillMetatile
setNewMapBorderMetatileIds ui->lineEdit_BorderMetatiles
*/
emit saved();
}
void ProjectSettingsEditor::dialogButtonClicked(QAbstractButton *button) {
auto buttonRole = ui->buttonBox->buttonRole(button);
if (buttonRole == QDialogButtonBox::AcceptRole) {
// TODO: Prompt for unsaved changes
saveFields();
close();
} else if (buttonRole == QDialogButtonBox::ResetRole) {
// TODO
} else if (buttonRole == QDialogButtonBox::ApplyRole) {
saveFields();
} else if (buttonRole == QDialogButtonBox::RejectRole) {
close();
}
// TODO: Save geometry on close
}

View file

@ -128,6 +128,7 @@ void TilesetEditor::setAttributesUi() {
this->ui->comboBox_terrainType->addItem("Grass", TERRAIN_GRASS);
this->ui->comboBox_terrainType->addItem("Water", TERRAIN_WATER);
this->ui->comboBox_terrainType->addItem("Waterfall", TERRAIN_WATERFALL);
this->ui->comboBox_terrainType->setEditable(false);
} else {
this->ui->comboBox_terrainType->setVisible(false);
this->ui->label_terrainType->setVisible(false);
@ -138,6 +139,7 @@ void TilesetEditor::setAttributesUi() {
this->ui->comboBox_encounterType->addItem("None", ENCOUNTER_NONE);
this->ui->comboBox_encounterType->addItem("Land", ENCOUNTER_LAND);
this->ui->comboBox_encounterType->addItem("Water", ENCOUNTER_WATER);
this->ui->comboBox_encounterType->setEditable(false);
} else {
this->ui->comboBox_encounterType->setVisible(false);
this->ui->label_encounterType->setVisible(false);
@ -148,6 +150,7 @@ void TilesetEditor::setAttributesUi() {
this->ui->comboBox_layerType->addItem("Normal - Middle/Top", METATILE_LAYER_MIDDLE_TOP);
this->ui->comboBox_layerType->addItem("Covered - Bottom/Middle", METATILE_LAYER_BOTTOM_MIDDLE);
this->ui->comboBox_layerType->addItem("Split - Bottom/Top", METATILE_LAYER_BOTTOM_TOP);
this->ui->comboBox_layerType->setEditable(false);
if (!Metatile::getLayerTypeMask()) {
// User doesn't have triple layer metatiles, but has no layer type attribute.
// Porymap is still using the layer type value to render metatiles, and with
@ -357,24 +360,6 @@ void TilesetEditor::onHoveredMetatileCleared() {
this->ui->statusbar->clearMessage();
}
void TilesetEditor::setComboValue(QComboBox * combo, int value) {
int index = combo->findData(value);
if (index >= 0) {
// Valid item
combo->setCurrentIndex(index);
} else if (combo->isEditable()) {
// Invalid item in editable box, just display the text
combo->setCurrentText(QString::number(value));
} else {
// Invalid item in uneditable box, display text as placeholder
// On Qt < 5.15 this will display an empty box
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
combo->setPlaceholderText(QString::number(value));
#endif
combo->setCurrentIndex(index);
}
}
void TilesetEditor::onSelectedMetatileChanged(uint16_t metatileId) {
this->metatile = Tileset::getMetatile(metatileId, this->primaryTileset, this->secondaryTileset);
this->metatileLayersItem->setMetatile(metatile);
@ -385,10 +370,10 @@ void TilesetEditor::onSelectedMetatileChanged(uint16_t metatileId) {
this->ui->lineEdit_metatileLabel->setText(labels.owned);
this->ui->lineEdit_metatileLabel->setPlaceholderText(labels.shared);
setComboValue(this->ui->comboBox_metatileBehaviors, this->metatile->behavior);
setComboValue(this->ui->comboBox_layerType, this->metatile->layerType);
setComboValue(this->ui->comboBox_encounterType, this->metatile->encounterType);
setComboValue(this->ui->comboBox_terrainType, this->metatile->terrainType);
this->ui->comboBox_metatileBehaviors->setNumberItem(this->metatile->behavior);
this->ui->comboBox_layerType->setNumberItem(this->metatile->layerType);
this->ui->comboBox_encounterType->setNumberItem(this->metatile->encounterType);
this->ui->comboBox_terrainType->setNumberItem(this->metatile->terrainType);
}
void TilesetEditor::onHoveredTileChanged(uint16_t tile) {