mirror of
https://github.com/huderlem/porymap.git
synced 2026-06-30 19:49:46 -05:00
Finish new layout dialog redesign
This commit is contained in:
parent
e7df829843
commit
d0101d807e
|
|
@ -2926,7 +2926,7 @@
|
|||
<addaction name="actionMap_Shift"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_NewMap"/>
|
||||
<addaction name="actionNew_Layout"/>
|
||||
<addaction name="action_NewLayout"/>
|
||||
<addaction name="actionNew_Tileset"/>
|
||||
<addaction name="actionTileset_Editor"/>
|
||||
<addaction name="actionRegion_Map_Editor"/>
|
||||
|
|
@ -3283,7 +3283,7 @@
|
|||
<string>Grid Settings...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNew_Layout">
|
||||
<action name="action_NewLayout">
|
||||
<property name="text">
|
||||
<string>New Layout...</string>
|
||||
</property>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,16 @@
|
|||
<ui version="4.0">
|
||||
<class>NewLayoutDialog</class>
|
||||
<widget class="QDialog" name="NewLayoutDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>264</width>
|
||||
<height>173</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>New Map Options</string>
|
||||
<string>New Layout Options</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
|
|
@ -17,13 +25,46 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>238</width>
|
||||
<height>146</height>
|
||||
<height>106</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="verticalSpacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_NameError">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="NewLayoutForm" name="newLayoutForm" native="true"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_LayoutID">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The constant that will be used to refer to this layout. It cannot be the same as any other existing layout.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_Name">
|
||||
<property name="text">
|
||||
<string>Layout Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_LayoutID">
|
||||
<property name="text">
|
||||
|
|
@ -34,20 +75,13 @@
|
|||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_Name">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The name of the new map. The name cannot be the same as any other existing map.</p></body></html></string>
|
||||
<string><html><head/><body><p>The name of the new layout. The name cannot be the same as any other existing layout.</p></body></html></string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_Name">
|
||||
<property name="text">
|
||||
<string>Layout Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_LayoutIDError">
|
||||
<property name="visible">
|
||||
|
|
@ -64,32 +98,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_NameError">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_LayoutID">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The constant that will be used to refer to this map. It cannot be the same as any other existing map, and it must start with the specified prefix.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="NewLayoutForm" name="newLayoutForm" native="true"/>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
|
@ -107,6 +115,19 @@
|
|||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_GenericError">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
|
|
|
|||
|
|
@ -2,6 +2,14 @@
|
|||
<ui version="4.0">
|
||||
<class>NewMapDialog</class>
|
||||
<widget class="QDialog" name="NewMapDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>255</width>
|
||||
<height>320</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>New Map Options</string>
|
||||
</property>
|
||||
|
|
@ -17,32 +25,51 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>229</width>
|
||||
<height>254</height>
|
||||
<height>306</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="verticalSpacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_MapID">
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_MapIDError">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Map ID</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
<item row="6" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_LayoutID">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertPolicy::NoInsert</enum>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="label_LayoutIDError">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_NameError">
|
||||
|
|
@ -60,17 +87,21 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="comboBox_LayoutID">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertPolicy::NoInsert</enum>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_MapID">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The constant that will be used to refer to this map. It cannot be the same as any other existing map, and it must start with the specified prefix.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="2">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_MapID">
|
||||
<property name="text">
|
||||
<string>Map ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0" colspan="2">
|
||||
<widget class="QWidget" name="widget_HeaderData" native="true">
|
||||
<layout class="QVBoxLayout" name="layout_HeaderData">
|
||||
<property name="leftMargin">
|
||||
|
|
@ -88,39 +119,20 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_MapIDError">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_Name">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The name of the new map. The name cannot be the same as any other existing map.</p></body></html></string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_CanFlyTo">
|
||||
<property name="text">
|
||||
<string>Can Fly To</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_Name">
|
||||
<property name="text">
|
||||
<string>Map Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_Group">
|
||||
<property name="toolTip">
|
||||
|
|
@ -134,10 +146,23 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_Group">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_Name">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The name of the new map. The name cannot be the same as any other existing map.</p></body></html></string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_CanFlyTo">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If checked, a Heal Location will be added to this map automatically.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Map Group</string>
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -157,20 +182,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_Name">
|
||||
<property name="text">
|
||||
<string>Map Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<widget class="NewLayoutForm" name="newLayoutForm" native="true"/>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_CanFlyTo">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If checked, a Heal Location will be added to this map automatically.</p></body></html></string>
|
||||
</property>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_Group">
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>Map Group</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -181,20 +199,36 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_MapID">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The constant that will be used to refer to this map. It cannot be the same as any other existing map, and it must start with the specified prefix.</p></body></html></string>
|
||||
<item row="14" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<widget class="NewLayoutForm" name="newLayoutForm" native="true"/>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_GenericError">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class Layout : public QObject {
|
|||
public:
|
||||
Layout() {}
|
||||
|
||||
static QString layoutNameFromMapName(const QString &mapName);
|
||||
static QString layoutConstantFromName(QString mapName);
|
||||
|
||||
bool loaded = false;
|
||||
|
|
@ -83,10 +84,10 @@ public:
|
|||
QString primaryTilesetLabel;
|
||||
QString secondaryTilesetLabel;
|
||||
};
|
||||
Settings settings() const;
|
||||
|
||||
public:
|
||||
Layout *copy();
|
||||
void copyFrom(Layout *other);
|
||||
Layout *copy() const;
|
||||
void copyFrom(const Layout *other);
|
||||
|
||||
int getWidth() const { return width; }
|
||||
int getHeight() const { return height; }
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
#include "mapimageexporter.h"
|
||||
#include "filterchildrenproxymodel.h"
|
||||
#include "maplistmodels.h"
|
||||
#include "newmapdialog.h"
|
||||
#include "newlayoutdialog.h"
|
||||
#include "newtilesetdialog.h"
|
||||
#include "shortcutseditor.h"
|
||||
#include "preferenceeditor.h"
|
||||
|
|
@ -188,8 +186,6 @@ private slots:
|
|||
void onLayoutChanged(Layout *layout);
|
||||
void onOpenConnectedMap(MapConnection*);
|
||||
void onTilesetsSaved(QString, QString);
|
||||
void openNewMapDialog();
|
||||
void openNewLayoutDialog();
|
||||
void onNewMapCreated(Map *newMap, const QString &groupName);
|
||||
void onNewMapGroupCreated(const QString &groupName);
|
||||
void onNewLayoutCreated(Layout *layout);
|
||||
|
|
@ -199,7 +195,6 @@ private slots:
|
|||
void markMapEdited();
|
||||
void markSpecificMapEdited(Map*);
|
||||
|
||||
void on_action_NewMap_triggered();
|
||||
void on_actionNew_Tileset_triggered();
|
||||
void on_action_Save_triggered();
|
||||
void on_action_Exit_triggered();
|
||||
|
|
@ -306,8 +301,6 @@ private:
|
|||
QPointer<RegionMapEditor> regionMapEditor = nullptr;
|
||||
QPointer<ShortcutsEditor> shortcutsEditor = nullptr;
|
||||
QPointer<MapImageExporter> mapImageExporter = nullptr;
|
||||
QPointer<NewMapDialog> newMapDialog = nullptr;
|
||||
QPointer<NewLayoutDialog> newLayoutDialog = nullptr;
|
||||
QPointer<PreferenceEditor> preferenceEditor = nullptr;
|
||||
QPointer<ProjectSettingsEditor> projectSettingsEditor = nullptr;
|
||||
QPointer<GridSettingsDialog> gridSettingsDialog = nullptr;
|
||||
|
|
@ -353,6 +346,8 @@ private:
|
|||
bool setProjectUI();
|
||||
void clearProjectUI();
|
||||
|
||||
void openNewMapDialog();
|
||||
void openNewLayoutDialog();
|
||||
void openSubWindow(QWidget * window);
|
||||
void scrollMapList(MapTree *list, QString itemName);
|
||||
void scrollMapListToCurrentMap(MapTree *list);
|
||||
|
|
@ -371,7 +366,6 @@ private:
|
|||
|
||||
void updateMapList();
|
||||
void mapListAddGroup();
|
||||
void mapListAddLayout();
|
||||
void mapListAddArea();
|
||||
void openMapListItem(const QModelIndex &index);
|
||||
void saveMapListTab(int index);
|
||||
|
|
|
|||
|
|
@ -82,8 +82,8 @@ public:
|
|||
bool saveEmptyMapsec;
|
||||
|
||||
struct NewMapSettings {
|
||||
QString mapName;
|
||||
QString mapId;
|
||||
QString name;
|
||||
QString id;
|
||||
QString group;
|
||||
bool canFlyTo;
|
||||
Layout::Settings layout;
|
||||
|
|
@ -133,9 +133,9 @@ public:
|
|||
void addNewMap(Map* newMap, const QString &groupName);
|
||||
void addNewMapGroup(const QString &groupName);
|
||||
void addNewLayout(Layout* newLayout);
|
||||
QString getNewMapName();
|
||||
QString getNewLayoutName();
|
||||
bool isLayoutNameUnique(const QString &name);
|
||||
NewMapSettings getNewMapSettings() const;
|
||||
Layout::Settings getNewLayoutSettings() const;
|
||||
bool isIdentifierUnique(const QString &identifier) const;
|
||||
QString getProjectTitle();
|
||||
|
||||
bool readWildMonData();
|
||||
|
|
@ -159,7 +159,7 @@ public:
|
|||
bool loadMapData(Map*);
|
||||
bool readMapLayouts();
|
||||
Layout *loadLayout(QString layoutId);
|
||||
Layout *createNewLayout(const Layout::Settings &layoutSettings);
|
||||
Layout *createNewLayout(const Layout::Settings &layoutSettings, const Layout* toDuplicate = nullptr);
|
||||
bool loadLayout(Layout *);
|
||||
bool loadMapLayout(Map*);
|
||||
bool loadLayoutTilesets(Layout *);
|
||||
|
|
@ -234,8 +234,6 @@ public:
|
|||
|
||||
static QString getExistingFilepath(QString filepath);
|
||||
void applyParsedLimits();
|
||||
void initNewMapSettings();
|
||||
void initNewLayoutSettings();
|
||||
|
||||
static QString getDynamicMapDefineName();
|
||||
static QString getDynamicMapName();
|
||||
|
|
|
|||
|
|
@ -32,11 +32,13 @@ public:
|
|||
MapHeader headerData() const;
|
||||
|
||||
void setLocations(QStringList locations);
|
||||
void setLocationsDisabled(bool disabled);
|
||||
void setLocationDisabled(bool disabled);
|
||||
bool isLocationDisabled() const { return m_locationDisabled; }
|
||||
|
||||
private:
|
||||
Ui::MapHeaderForm *ui;
|
||||
QPointer<MapHeader> m_header = nullptr;
|
||||
bool m_locationDisabled = false;
|
||||
|
||||
void updateUi();
|
||||
void updateSong();
|
||||
|
|
|
|||
|
|
@ -18,10 +18,11 @@ class NewLayoutDialog : public QDialog
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NewLayoutDialog(QWidget *parent = nullptr, Project *project = nullptr);
|
||||
explicit NewLayoutDialog(Project *project, QWidget *parent = nullptr);
|
||||
explicit NewLayoutDialog(Project *project, const Layout *layoutToCopy, QWidget *parent = nullptr);
|
||||
~NewLayoutDialog();
|
||||
void copyFrom(const Layout &);
|
||||
void accept() override;
|
||||
|
||||
virtual void accept() override;
|
||||
|
||||
signals:
|
||||
void applied(const QString &newLayoutId);
|
||||
|
|
@ -30,18 +31,21 @@ private:
|
|||
Ui::NewLayoutDialog *ui;
|
||||
Project *project;
|
||||
Layout *importedLayout = nullptr;
|
||||
Layout::Settings *settings = nullptr;
|
||||
|
||||
static Layout::Settings settings;
|
||||
static bool initializedSettings;
|
||||
|
||||
// Each of these validation functions will allow empty names up until `OK` is selected,
|
||||
// because clearing the text during editing is common and we don't want to flash errors for this.
|
||||
bool validateLayoutID(bool allowEmpty = false);
|
||||
bool validateName(bool allowEmpty = false);
|
||||
|
||||
void refresh();
|
||||
|
||||
void saveSettings();
|
||||
bool isExistingLayout() const;
|
||||
|
||||
private slots:
|
||||
//void on_comboBox_Layout_currentTextChanged(const QString &text);//TODO
|
||||
void dialogButtonClicked(QAbstractButton *button);
|
||||
void on_lineEdit_Name_textChanged(const QString &);
|
||||
void on_lineEdit_LayoutID_textChanged(const QString &);
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ class NewMapDialog : public QDialog
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NewMapDialog(QWidget *parent = nullptr, Project *project = nullptr);
|
||||
explicit NewMapDialog(Project *project, QWidget *parent = nullptr);
|
||||
explicit NewMapDialog(Project *project, int mapListTab, const QString &mapListItem, QWidget *parent = nullptr);
|
||||
explicit NewMapDialog(Project *project, const Map *mapToCopy, QWidget *parent = nullptr);
|
||||
~NewMapDialog();
|
||||
void init();
|
||||
void init(int tabIndex, QString data);
|
||||
void init(Layout *);
|
||||
void accept() override;
|
||||
|
||||
virtual void accept() override;
|
||||
|
||||
signals:
|
||||
void applied(const QString &newMapName);
|
||||
|
|
@ -33,25 +33,29 @@ private:
|
|||
Project *project;
|
||||
CollapsibleSection *headerSection;
|
||||
MapHeaderForm *headerForm;
|
||||
Layout *importedLayout = nullptr;
|
||||
Project::NewMapSettings *settings = nullptr;
|
||||
Map *importedMap = nullptr;
|
||||
|
||||
static Project::NewMapSettings settings;
|
||||
static bool initializedSettings;
|
||||
|
||||
// Each of these validation functions will allow empty names up until `OK` is selected,
|
||||
// because clearing the text during editing is common and we don't want to flash errors for this.
|
||||
bool validateMapID(bool allowEmpty = false);
|
||||
bool validateName(bool allowEmpty = false);
|
||||
bool validateGroup(bool allowEmpty = false);
|
||||
bool validateLayoutID(bool allowEmpty = false);
|
||||
|
||||
void refresh();
|
||||
|
||||
void saveSettings();
|
||||
bool isExistingLayout() const;
|
||||
void useLayoutSettings(const Layout *mapLayout);
|
||||
void useLayoutIdSettings(const QString &layoutId);
|
||||
|
||||
private slots:
|
||||
void dialogButtonClicked(QAbstractButton *button);
|
||||
void on_lineEdit_Name_textChanged(const QString &);
|
||||
void on_lineEdit_MapID_textChanged(const QString &);
|
||||
void on_comboBox_Group_currentTextChanged(const QString &text);
|
||||
void on_comboBox_LayoutID_currentTextChanged(const QString &text);
|
||||
};
|
||||
|
||||
#endif // NEWMAPDIALOG_H
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@
|
|||
|
||||
|
||||
|
||||
Layout *Layout::copy() {
|
||||
Layout *Layout::copy() const {
|
||||
Layout *layout = new Layout;
|
||||
layout->copyFrom(this);
|
||||
return layout;
|
||||
}
|
||||
|
||||
void Layout::copyFrom(Layout *other) {
|
||||
void Layout::copyFrom(const Layout *other) {
|
||||
this->id = other->id;
|
||||
this->name = other->name;
|
||||
this->width = other->width;
|
||||
|
|
@ -30,19 +30,30 @@ void Layout::copyFrom(Layout *other) {
|
|||
this->border = other->border;
|
||||
}
|
||||
|
||||
QString Layout::layoutNameFromMapName(const QString &mapName) {
|
||||
return QString("%1_Layout").arg(mapName);
|
||||
}
|
||||
|
||||
QString Layout::layoutConstantFromName(QString mapName) {
|
||||
// Transform map names of the form 'GraniteCave_B1F` into layout constants like 'LAYOUT_GRANITE_CAVE_B1F'.
|
||||
static const QRegularExpression caseChange("([a-z])([A-Z])");
|
||||
QString nameWithUnderscores = mapName.replace(caseChange, "\\1_\\2");
|
||||
QString withMapAndUppercase = "LAYOUT_" + nameWithUnderscores.toUpper();
|
||||
static const QRegularExpression underscores("_+");
|
||||
QString constantName = withMapAndUppercase.replace(underscores, "_");
|
||||
return withMapAndUppercase.replace(underscores, "_");
|
||||
}
|
||||
|
||||
// Handle special cases.
|
||||
// SSTidal should be SS_TIDAL, rather than SSTIDAL
|
||||
constantName = constantName.replace("SSTIDAL", "SS_TIDAL");
|
||||
|
||||
return constantName;
|
||||
Layout::Settings Layout::settings() const {
|
||||
Layout::Settings settings;
|
||||
settings.id = this->id;
|
||||
settings.name = this->name;
|
||||
settings.width = this->width;
|
||||
settings.height = this->height;
|
||||
settings.borderWidth = this->border_width;
|
||||
settings.borderHeight = this->border_height;
|
||||
settings.primaryTilesetLabel = this->tileset_primary_label;
|
||||
settings.secondaryTilesetLabel = this->tileset_secondary_label;
|
||||
return settings;
|
||||
}
|
||||
|
||||
bool Layout::isWithinBounds(int x, int y) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include "newmapconnectiondialog.h"
|
||||
#include "config.h"
|
||||
#include "filedialog.h"
|
||||
#include "newmapdialog.h"
|
||||
#include "newlayoutdialog.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QDirIterator>
|
||||
|
|
@ -291,7 +293,8 @@ void MainWindow::initExtraSignals() {
|
|||
label_MapRulerStatus->setTextFormat(Qt::PlainText);
|
||||
label_MapRulerStatus->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
|
||||
connect(ui->actionNew_Layout, &QAction::triggered, this, &MainWindow::openNewLayoutDialog);
|
||||
connect(ui->action_NewMap, &QAction::triggered, this, &MainWindow::openNewMapDialog);
|
||||
connect(ui->action_NewLayout, &QAction::triggered, this, &MainWindow::openNewLayoutDialog);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionCheck_for_Updates_triggered() {
|
||||
|
|
@ -406,7 +409,7 @@ void MainWindow::initMapList() {
|
|||
// Create add map/layout button
|
||||
// TODO: Tool tip
|
||||
QPushButton *buttonAdd = new QPushButton(QIcon(":/icons/add.ico"), "");
|
||||
connect(buttonAdd, &QPushButton::clicked, this, &MainWindow::on_action_NewMap_triggered);
|
||||
connect(buttonAdd, &QPushButton::clicked, this, &MainWindow::openNewMapDialog);
|
||||
layout->addWidget(buttonAdd);
|
||||
|
||||
/* TODO: Remove button disabled, no current support for deleting maps/layouts
|
||||
|
|
@ -932,6 +935,10 @@ bool MainWindow::userSetLayout(QString layoutId) {
|
|||
msgBox.critical(nullptr, "Error Opening Layout", errorMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only the Layouts tab of the map list shows Layouts, so if we're not already on that tab we'll open it now.
|
||||
ui->mapListContainer->setCurrentIndex(MapListTab::Layouts);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1228,8 +1235,9 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) {
|
|||
if (addToFolderAction) {
|
||||
// All folders only contain maps, so adding an item to any folder is adding a new map.
|
||||
connect(addToFolderAction, &QAction::triggered, [this, itemName] {
|
||||
openNewMapDialog();
|
||||
this->newMapDialog->init(ui->mapListContainer->currentIndex(), itemName);
|
||||
auto dialog = new NewMapDialog(this->editor->project, ui->mapListContainer->currentIndex(), itemName, this);
|
||||
connect(dialog, &NewMapDialog::applied, this, &MainWindow::userSetMap);
|
||||
dialog->open();
|
||||
});
|
||||
}
|
||||
if (deleteFolderAction) {
|
||||
|
|
@ -1267,8 +1275,8 @@ void MainWindow::mapListAddGroup() {
|
|||
|
||||
connect(&newItemButtonBox, &QDialogButtonBox::accepted, [&](){
|
||||
const QString mapGroupName = newNameEdit->text();
|
||||
if (this->editor->project->groupNames.contains(mapGroupName)) {
|
||||
errorMessageLabel->setText(QString("A map group with the name '%1' already exists").arg(mapGroupName));
|
||||
if (!this->editor->project->isIdentifierUnique(mapGroupName)) {
|
||||
errorMessageLabel->setText(QString("The name '%1' is not unique.").arg(mapGroupName));
|
||||
errorMessageLabel->setVisible(true);
|
||||
} else {
|
||||
dialog.accept();
|
||||
|
|
@ -1288,126 +1296,6 @@ void MainWindow::mapListAddGroup() {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Pull this all out into a custom window. Connect that to an action in the main menu as well.
|
||||
// (or, re-use the new map dialog with some tweaks)
|
||||
// TODO: This needs to take the same default settings you would get for a new map (tilesets, dimensions, etc.)
|
||||
// and initialize it with the same fill settings (default metatile/collision/elevation, default border)
|
||||
// TODO: Remove
|
||||
void MainWindow::mapListAddLayout() {
|
||||
/*
|
||||
if (!editor || !editor->project) return;
|
||||
|
||||
QDialog dialog(this, Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
|
||||
dialog.setWindowModality(Qt::ApplicationModal);
|
||||
QDialogButtonBox newItemButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
|
||||
connect(&newItemButtonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
|
||||
|
||||
QLineEdit *newNameEdit = new QLineEdit(&dialog);
|
||||
newNameEdit->setClearButtonEnabled(true);
|
||||
|
||||
static const QRegularExpression re_validChars("[A-Za-z_]+[\\w]*");
|
||||
newNameEdit->setValidator(new QRegularExpressionValidator(re_validChars, newNameEdit));
|
||||
|
||||
// TODO: Support arbitrary LAYOUT_ ID names (Note from GriffinR: This is already handled in an unopened PR)
|
||||
QLabel *newId = new QLabel("LAYOUT_", &dialog);
|
||||
connect(newNameEdit, &QLineEdit::textChanged, [&](QString text){
|
||||
newId->setText(Layout::layoutConstantFromName(text.remove("_Layout")));
|
||||
});
|
||||
|
||||
NoScrollComboBox *useExistingCombo = new NoScrollComboBox(&dialog);
|
||||
useExistingCombo->addItems(this->editor->project->layoutIds);
|
||||
useExistingCombo->setEnabled(false);
|
||||
|
||||
QCheckBox *useExistingCheck = new QCheckBox(&dialog);
|
||||
|
||||
QLabel *errorMessageLabel = new QLabel(&dialog);
|
||||
errorMessageLabel->setVisible(false);
|
||||
errorMessageLabel->setStyleSheet("QLabel { background-color: rgba(255, 0, 0, 25%) }");
|
||||
|
||||
QComboBox *primaryCombo = new QComboBox(&dialog);
|
||||
primaryCombo->addItems(this->editor->project->primaryTilesetLabels);
|
||||
QComboBox *secondaryCombo = new QComboBox(&dialog);
|
||||
secondaryCombo->addItems(this->editor->project->secondaryTilesetLabels);
|
||||
|
||||
QSpinBox *widthSpin = new QSpinBox(&dialog);
|
||||
QSpinBox *heightSpin = new QSpinBox(&dialog);
|
||||
|
||||
widthSpin->setMinimum(1);
|
||||
heightSpin->setMinimum(1);
|
||||
widthSpin->setMaximum(this->editor->project->getMaxMapWidth());
|
||||
heightSpin->setMaximum(this->editor->project->getMaxMapHeight());
|
||||
|
||||
connect(useExistingCheck, &QCheckBox::stateChanged, [&](int state){
|
||||
bool useExisting = (state == Qt::Checked);
|
||||
useExistingCombo->setEnabled(useExisting);
|
||||
primaryCombo->setEnabled(!useExisting);
|
||||
secondaryCombo->setEnabled(!useExisting);
|
||||
widthSpin->setEnabled(!useExisting);
|
||||
heightSpin->setEnabled(!useExisting);
|
||||
});
|
||||
|
||||
QFormLayout form(&dialog);
|
||||
form.addRow("New Layout Name", newNameEdit);
|
||||
form.addRow("New Layout ID", newId);
|
||||
form.addRow("Copy Existing Layout", useExistingCheck);
|
||||
form.addRow("", useExistingCombo);
|
||||
form.addRow("Primary Tileset", primaryCombo);
|
||||
form.addRow("Secondary Tileset", secondaryCombo);
|
||||
form.addRow("Layout Width", widthSpin);
|
||||
form.addRow("Layout Height", heightSpin);
|
||||
form.addRow("", errorMessageLabel);
|
||||
|
||||
connect(&newItemButtonBox, &QDialogButtonBox::accepted, [&](){
|
||||
// verify some things
|
||||
QString errorMessage;
|
||||
QString tryLayoutName = newNameEdit->text();
|
||||
// name not empty
|
||||
if (tryLayoutName.isEmpty()) {
|
||||
errorMessage = "Name cannot be empty";
|
||||
}
|
||||
// unique layout name & id
|
||||
else if (this->editor->project->layoutIds.contains(newId->text())
|
||||
|| this->editor->project->layoutIdsToNames.find(tryLayoutName) != this->editor->project->layoutIdsToNames.end()) {
|
||||
errorMessage = "Layout Name / ID is not unique";
|
||||
}
|
||||
// from id is existing value
|
||||
else if (useExistingCheck->isChecked()) {
|
||||
if (!this->editor->project->layoutIds.contains(useExistingCombo->currentText())) {
|
||||
errorMessage = "Existing layout ID is not valid";
|
||||
}
|
||||
}
|
||||
|
||||
if (!errorMessage.isEmpty()) {
|
||||
// show error
|
||||
errorMessageLabel->setText(errorMessage);
|
||||
errorMessageLabel->setVisible(true);
|
||||
}
|
||||
else {
|
||||
dialog.accept();
|
||||
}
|
||||
});
|
||||
|
||||
form.addRow(&newItemButtonBox);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
Layout::SimpleSettings layoutSettings;
|
||||
QString layoutName = newNameEdit->text();
|
||||
layoutSettings.name = layoutName;
|
||||
layoutSettings.id = Layout::layoutConstantFromName(layoutName.remove("_Layout"));
|
||||
if (useExistingCheck->isChecked()) {
|
||||
layoutSettings.from_id = useExistingCombo->currentText();
|
||||
} else {
|
||||
layoutSettings.width = widthSpin->value();
|
||||
layoutSettings.height = heightSpin->value();
|
||||
layoutSettings.tileset_primary_label = primaryCombo->currentText();
|
||||
layoutSettings.tileset_secondary_label = secondaryCombo->currentText();
|
||||
}
|
||||
Layout *newLayout = this->editor->project->createNewLayout(layoutSettings);
|
||||
setLayout(newLayout->id);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void MainWindow::mapListAddArea() {
|
||||
QDialog dialog(this, Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
|
||||
dialog.setWindowModality(Qt::ApplicationModal);
|
||||
|
|
@ -1433,8 +1321,8 @@ void MainWindow::mapListAddArea() {
|
|||
|
||||
connect(&newItemButtonBox, &QDialogButtonBox::accepted, [&](){
|
||||
const QString newAreaName = newNameDisplay->text();
|
||||
if (this->editor->project->mapSectionIdNames.contains(newAreaName)){
|
||||
errorMessageLabel->setText(QString("An area with the name '%1' already exists").arg(newAreaName));
|
||||
if (!this->editor->project->isIdentifierUnique(newAreaName)) {
|
||||
errorMessageLabel->setText(QString("The name '%1' is not unique.").arg(newAreaName));
|
||||
errorMessageLabel->setVisible(true);
|
||||
} else {
|
||||
dialog.accept();
|
||||
|
|
@ -1485,6 +1373,7 @@ void MainWindow::onNewMapCreated(Map *newMap, const QString &groupName) {
|
|||
}
|
||||
}
|
||||
|
||||
// Called any time a new layout is created (including as a byproduct of creating a new map)
|
||||
void MainWindow::onNewLayoutCreated(Layout *layout) {
|
||||
logInfo(QString("Created a new layout named %1.").arg(layout->name));
|
||||
|
||||
|
|
@ -1504,31 +1393,16 @@ void MainWindow::onNewMapGroupCreated(const QString &groupName) {
|
|||
this->mapGroupModel->insertGroupItem(groupName);
|
||||
}
|
||||
|
||||
// TODO: This and the new layout dialog are modal. We shouldn't need to reference their dialogs outside these open functions,
|
||||
// so we should be able to remove them as members of MainWindow.
|
||||
// (plus, the opening then init() call after showing for NewMapDialog is Bad)
|
||||
void MainWindow::openNewMapDialog() {
|
||||
if (!this->newMapDialog) {
|
||||
this->newMapDialog = new NewMapDialog(this, this->editor->project);
|
||||
connect(this->newMapDialog, &NewMapDialog::applied, this, &MainWindow::userSetMap);
|
||||
}
|
||||
|
||||
openSubWindow(this->newMapDialog);
|
||||
}
|
||||
|
||||
void MainWindow::on_action_NewMap_triggered() {
|
||||
openNewMapDialog();
|
||||
//this->newMapDialog->initUi();//TODO
|
||||
this->newMapDialog->init();
|
||||
auto dialog = new NewMapDialog(this->editor->project, this);
|
||||
connect(dialog, &NewMapDialog::applied, this, &MainWindow::userSetMap);
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
void MainWindow::openNewLayoutDialog() {
|
||||
if (!this->newLayoutDialog) {
|
||||
this->newLayoutDialog = new NewLayoutDialog(this, this->editor->project);
|
||||
connect(this->newLayoutDialog, &NewLayoutDialog::applied, this, &MainWindow::userSetLayout);
|
||||
}
|
||||
|
||||
openSubWindow(this->newLayoutDialog);
|
||||
auto dialog = new NewLayoutDialog(this->editor->project, this);
|
||||
connect(dialog, &NewLayoutDialog::applied, this, &MainWindow::userSetLayout);
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
// Insert label for newly-created tileset into sorted list of existing labels
|
||||
|
|
@ -2732,8 +2606,9 @@ void MainWindow::on_actionImport_Layout_from_Advance_Map_1_92_triggered() {
|
|||
return;
|
||||
}
|
||||
|
||||
openNewLayoutDialog();
|
||||
this->newLayoutDialog->copyFrom(*mapLayout);
|
||||
auto dialog = new NewLayoutDialog(this->editor->project, mapLayout, this);
|
||||
connect(dialog, &NewLayoutDialog::applied, this, &MainWindow::userSetLayout);
|
||||
dialog->open();
|
||||
delete mapLayout;
|
||||
}
|
||||
|
||||
|
|
@ -2756,7 +2631,7 @@ void MainWindow::on_pushButton_AddConnection_clicked() {
|
|||
|
||||
auto dialog = new NewMapConnectionDialog(this, this->editor->map, this->editor->project->mapNames);
|
||||
connect(dialog, &NewMapConnectionDialog::accepted, this->editor, &Editor::addConnection);
|
||||
dialog->exec();
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
void MainWindow::on_pushButton_NewWildMonGroup_clicked() {
|
||||
|
|
@ -3244,10 +3119,6 @@ bool MainWindow::closeSupplementaryWindows() {
|
|||
return false;
|
||||
this->mapImageExporter = nullptr;
|
||||
|
||||
if (this->newMapDialog && !this->newMapDialog->close())
|
||||
return false;
|
||||
this->newMapDialog = nullptr;
|
||||
|
||||
if (this->shortcutsEditor && !this->shortcutsEditor->close())
|
||||
return false;
|
||||
this->shortcutsEditor = nullptr;
|
||||
|
|
|
|||
165
src/project.cpp
165
src/project.cpp
|
|
@ -107,7 +107,6 @@ bool Project::load() {
|
|||
&& readSongNames()
|
||||
&& readMapGroups();
|
||||
applyParsedLimits();
|
||||
initNewMapSettings();
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
@ -348,12 +347,7 @@ bool Project::loadMapData(Map* map) {
|
|||
const QString direction = ParseUtil::jsonToQString(connectionObj["direction"]);
|
||||
const int offset = ParseUtil::jsonToInt(connectionObj["offset"]);
|
||||
const QString mapConstant = ParseUtil::jsonToQString(connectionObj["map"]);
|
||||
if (this->mapConstantsToMapNames.contains(mapConstant)) {
|
||||
// Successully read map connection
|
||||
map->loadConnection(new MapConnection(this->mapConstantsToMapNames.value(mapConstant), direction, offset));
|
||||
} else {
|
||||
logError(QString("Failed to find connected map for map constant '%1'").arg(mapConstant));
|
||||
}
|
||||
map->loadConnection(new MapConnection(this->mapConstantsToMapNames.value(mapConstant, mapConstant), direction, offset));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -369,40 +363,7 @@ bool Project::loadMapData(Map* map) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
void Project::addNewLayout(Layout* newLayout) {
|
||||
|
||||
if (newLayout->blockdata.isEmpty()) {
|
||||
// Fill layout using default fill settings
|
||||
setNewLayoutBlockdata(newLayout);
|
||||
}
|
||||
if (newLayout->border.isEmpty()) {
|
||||
// Fill border using default fill settings
|
||||
setNewLayoutBorder(newLayout);
|
||||
}
|
||||
|
||||
emit layoutAdded(newLayout);
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO: Fold back into createNewLayout?
|
||||
/*
|
||||
Layout *Project::duplicateLayout(const Layout *toDuplicate) {
|
||||
//TODO
|
||||
if (!settings.from_id.isEmpty()) {
|
||||
// load from layout
|
||||
loadLayout(mapLayouts[settings.from_id]);
|
||||
layout = mapLayouts[settings.from_id]->copy();
|
||||
layout->name = settings.name;
|
||||
layout->id = settings.id;
|
||||
layout->border_path = QString("%1%2/border.bin").arg(basePath, layout->name);
|
||||
layout->blockdata_path = QString("%1%2/map.bin").arg(basePath, layout->name);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO: Refactor, we're duplicating logic between here, the new map dialog, and addNewLayout
|
||||
Layout *Project::createNewLayout(const Layout::Settings &settings) {
|
||||
Layout *Project::createNewLayout(const Layout::Settings &settings, const Layout *toDuplicate) {
|
||||
Layout *layout = new Layout;
|
||||
layout->id = settings.id;
|
||||
layout->name = settings.name;
|
||||
|
|
@ -413,6 +374,13 @@ Layout *Project::createNewLayout(const Layout::Settings &settings) {
|
|||
layout->tileset_primary_label = settings.primaryTilesetLabel;
|
||||
layout->tileset_secondary_label = settings.secondaryTilesetLabel;
|
||||
|
||||
if (toDuplicate) {
|
||||
// If we're duplicating an existing layout we'll copy over the blockdata.
|
||||
// Otherwise addNewLayout will fill our new layout using the default settings.
|
||||
layout->blockdata = toDuplicate->blockdata;
|
||||
layout->border = toDuplicate->border;
|
||||
}
|
||||
|
||||
const QString basePath = projectConfig.getFilePath(ProjectFilePath::data_layouts_folders);
|
||||
layout->border_path = QString("%1%2/border.bin").arg(basePath, layout->name);
|
||||
layout->blockdata_path = QString("%1%2/map.bin").arg(basePath, layout->name);
|
||||
|
|
@ -1276,6 +1244,7 @@ void Project::saveMap(Map *map) {
|
|||
}
|
||||
appendTextFile(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_event_scripts), text);
|
||||
|
||||
// TODO: Either simplify this redundancy or explain why we need it (to create folders without the _Layout suffix)
|
||||
if (map->needsLayoutDir()) {
|
||||
QString newLayoutDir = QString(root + "/%1%2").arg(projectConfig.getFilePath(ProjectFilePath::data_layouts_folders), map->name());
|
||||
if (!QDir::root().mkdir(newLayoutDir)) {
|
||||
|
|
@ -1314,19 +1283,15 @@ void Project::saveMap(Map *map) {
|
|||
mapObj["battle_scene"] = map->header()->battleScene();
|
||||
|
||||
// Connections
|
||||
auto connections = map->getConnections();
|
||||
const auto connections = map->getConnections();
|
||||
if (connections.length() > 0) {
|
||||
OrderedJson::array connectionsArr;
|
||||
for (auto connection : connections) {
|
||||
if (this->mapNamesToMapConstants.contains(connection->targetMapName())) {
|
||||
OrderedJson::object connectionObj;
|
||||
connectionObj["map"] = this->mapNamesToMapConstants.value(connection->targetMapName());
|
||||
connectionObj["offset"] = connection->offset();
|
||||
connectionObj["direction"] = connection->direction();
|
||||
connectionsArr.append(connectionObj);
|
||||
} else {
|
||||
logError(QString("Failed to write map connection. '%1' is not a valid map name").arg(connection->targetMapName()));
|
||||
}
|
||||
for (const auto &connection : connections) {
|
||||
OrderedJson::object connectionObj;
|
||||
connectionObj["map"] = this->mapNamesToMapConstants.value(connection->targetMapName(), connection->targetMapName());
|
||||
connectionObj["offset"] = connection->offset();
|
||||
connectionObj["direction"] = connection->direction();
|
||||
connectionsArr.append(connectionObj);
|
||||
}
|
||||
mapObj["connections"] = connectionsArr;
|
||||
} else {
|
||||
|
|
@ -1986,31 +1951,81 @@ void Project::addNewMapGroup(const QString &groupName) {
|
|||
emit mapGroupAdded(groupName);
|
||||
}
|
||||
|
||||
QString Project::getNewMapName() {
|
||||
// Ensure default name doesn't already exist.
|
||||
Project::NewMapSettings Project::getNewMapSettings() const {
|
||||
// Ensure default name/ID doesn't already exist.
|
||||
int i = 0;
|
||||
QString newMapName;
|
||||
QString newMapId;
|
||||
do {
|
||||
newMapName = QString("NewMap%1").arg(++i);
|
||||
} while (this->mapNames.contains(newMapName));
|
||||
newMapId = Map::mapConstantFromName(newMapName);
|
||||
} while (!isIdentifierUnique(newMapName) || !isIdentifierUnique(newMapId));
|
||||
|
||||
return newMapName;
|
||||
NewMapSettings settings;
|
||||
settings.name = newMapName;
|
||||
settings.id = newMapId;
|
||||
settings.group = this->groupNames.at(0);
|
||||
settings.canFlyTo = false;
|
||||
settings.layout = getNewLayoutSettings();
|
||||
settings.layout.id = Layout::layoutConstantFromName(newMapName);
|
||||
settings.layout.name = Layout::layoutNameFromMapName(newMapName);
|
||||
settings.header.setSong(this->defaultSong);
|
||||
settings.header.setLocation(this->mapSectionIdNames.value(0, "0"));
|
||||
settings.header.setRequiresFlash(false);
|
||||
settings.header.setWeather(this->weatherNames.value(0, "0"));
|
||||
settings.header.setType(this->mapTypes.value(0, "0"));
|
||||
settings.header.setBattleScene(this->mapBattleScenes.value(0, "0"));
|
||||
settings.header.setShowsLocationName(true);
|
||||
settings.header.setAllowsRunning(false);
|
||||
settings.header.setAllowsBiking(false);
|
||||
settings.header.setAllowsEscaping(false);
|
||||
settings.header.setFloorNumber(0);
|
||||
return settings;
|
||||
}
|
||||
|
||||
QString Project::getNewLayoutName() {
|
||||
// Ensure default name doesn't already exist.
|
||||
Layout::Settings Project::getNewLayoutSettings() const {
|
||||
// Ensure default name/ID doesn't already exist.
|
||||
int i = 0;
|
||||
QString newLayoutName;
|
||||
QString newLayoutId;
|
||||
do {
|
||||
newLayoutName = QString("NewLayout%1").arg(++i);
|
||||
} while (!isLayoutNameUnique(newLayoutName));
|
||||
newLayoutId = Layout::layoutConstantFromName(newLayoutName);
|
||||
} while (!isIdentifierUnique(newLayoutId) || !isIdentifierUnique(newLayoutName));
|
||||
|
||||
return newLayoutName;
|
||||
Layout::Settings settings;
|
||||
settings.name = newLayoutName;
|
||||
settings.id = newLayoutId;
|
||||
settings.width = getDefaultMapDimension();
|
||||
settings.height = getDefaultMapDimension();
|
||||
settings.borderWidth = DEFAULT_BORDER_WIDTH;
|
||||
settings.borderHeight = DEFAULT_BORDER_HEIGHT;
|
||||
settings.primaryTilesetLabel = getDefaultPrimaryTilesetLabel();
|
||||
settings.secondaryTilesetLabel = getDefaultSecondaryTilesetLabel();
|
||||
return settings;
|
||||
}
|
||||
|
||||
bool Project::isLayoutNameUnique(const QString &name) {
|
||||
// When we ask the user to provide a new identifier for something (like a map/layout name or ID)
|
||||
// we use this to make sure that it doesn't collide with any known identifiers first.
|
||||
// Porymap knows of many more identifiers than this, but for simplicity we only check the lists that users can add to via Porymap.
|
||||
// In general this only matters to Porymap if the identifier will be added to the group it collides with,
|
||||
// but name collisions are likely undesirable in the project.
|
||||
// TODO: Use elsewhere
|
||||
bool Project::isIdentifierUnique(const QString &identifier) const {
|
||||
if (this->mapNames.contains(identifier))
|
||||
return false;
|
||||
if (this->mapConstantsToMapNames.contains(identifier))
|
||||
return false;
|
||||
if (this->groupNames.contains(identifier))
|
||||
return false;
|
||||
if (this->mapSectionIdNames.contains(identifier))
|
||||
return false;
|
||||
if (this->tilesetLabelsOrdered.contains(identifier))
|
||||
return false;
|
||||
if (this->layoutIds.contains(identifier))
|
||||
return false;
|
||||
for (const auto &layout : this->mapLayouts) {
|
||||
if (layout->name == name) {
|
||||
if (layout->name == identifier) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -3056,32 +3071,6 @@ void Project::applyParsedLimits() {
|
|||
projectConfig.collisionSheetWidth = qMin(projectConfig.collisionSheetWidth, Block::getMaxCollision() + 1);
|
||||
}
|
||||
|
||||
void Project::initNewMapSettings() {
|
||||
this->newMapSettings.group = this->groupNames.at(0);
|
||||
this->newMapSettings.canFlyTo = false;
|
||||
this->newMapSettings.header.setSong(this->defaultSong);
|
||||
this->newMapSettings.header.setLocation(this->mapSectionIdNames.value(0, "0"));
|
||||
this->newMapSettings.header.setRequiresFlash(false);
|
||||
this->newMapSettings.header.setWeather(this->weatherNames.value(0, "0"));
|
||||
this->newMapSettings.header.setType(this->mapTypes.value(0, "0"));
|
||||
this->newMapSettings.header.setBattleScene(this->mapBattleScenes.value(0, "0"));
|
||||
this->newMapSettings.header.setShowsLocationName(true);
|
||||
this->newMapSettings.header.setAllowsRunning(false);
|
||||
this->newMapSettings.header.setAllowsBiking(false);
|
||||
this->newMapSettings.header.setAllowsEscaping(false);
|
||||
this->newMapSettings.header.setFloorNumber(0);
|
||||
initNewLayoutSettings();
|
||||
}
|
||||
|
||||
void Project::initNewLayoutSettings() {
|
||||
this->newMapSettings.layout.width = getDefaultMapDimension();
|
||||
this->newMapSettings.layout.height = getDefaultMapDimension();
|
||||
this->newMapSettings.layout.borderWidth = DEFAULT_BORDER_WIDTH;
|
||||
this->newMapSettings.layout.borderHeight = DEFAULT_BORDER_HEIGHT;
|
||||
this->newMapSettings.layout.primaryTilesetLabel = getDefaultPrimaryTilesetLabel();
|
||||
this->newMapSettings.layout.secondaryTilesetLabel = getDefaultSecondaryTilesetLabel();
|
||||
}
|
||||
|
||||
bool Project::hasUnsavedChanges() {
|
||||
if (this->hasUnsavedDataChanges)
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -154,9 +154,10 @@ MapHeader MapHeaderForm::headerData() const {
|
|||
return header;
|
||||
}
|
||||
|
||||
void MapHeaderForm::setLocationsDisabled(bool disabled) {
|
||||
ui->label_Location->setDisabled(disabled);
|
||||
ui->comboBox_Location->setDisabled(disabled);
|
||||
void MapHeaderForm::setLocationDisabled(bool disabled) {
|
||||
m_locationDisabled = disabled;
|
||||
ui->label_Location->setDisabled(m_locationDisabled);
|
||||
ui->comboBox_Location->setDisabled(m_locationDisabled);
|
||||
}
|
||||
|
||||
void MapHeaderForm::updateSong() {
|
||||
|
|
|
|||
|
|
@ -9,31 +9,55 @@
|
|||
|
||||
const QString lineEdit_ErrorStylesheet = "QLineEdit { background-color: rgba(255, 0, 0, 25%) }";
|
||||
|
||||
NewLayoutDialog::NewLayoutDialog(QWidget *parent, Project *project) :
|
||||
Layout::Settings NewLayoutDialog::settings = {};
|
||||
bool NewLayoutDialog::initializedSettings = false;
|
||||
|
||||
NewLayoutDialog::NewLayoutDialog(Project *project, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::NewLayoutDialog)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setModal(true);
|
||||
ui->setupUi(this);
|
||||
ui->label_GenericError->setVisible(false);
|
||||
this->project = project;
|
||||
this->settings = &project->newMapSettings.layout;
|
||||
|
||||
ui->lineEdit_Name->setText(project->getNewLayoutName());
|
||||
|
||||
Layout::Settings newSettings = project->getNewLayoutSettings();
|
||||
if (!initializedSettings) {
|
||||
// The first time this dialog is opened we initialize all the default settings.
|
||||
settings = newSettings;
|
||||
initializedSettings = true;
|
||||
} else {
|
||||
// On subsequent openings we only initialize the settings that should be unique,
|
||||
// preserving all other settings from the last time the dialog was open.
|
||||
settings.name = newSettings.name;
|
||||
settings.id = newSettings.id;
|
||||
}
|
||||
ui->newLayoutForm->initUi(project);
|
||||
ui->newLayoutForm->setSettings(*this->settings);
|
||||
|
||||
// Names and IDs can only contain word characters, and cannot start with a digit.
|
||||
// Identifiers can only contain word characters, and cannot start with a digit.
|
||||
static const QRegularExpression re("[A-Za-z_]+[\\w]*");
|
||||
auto validator = new QRegularExpressionValidator(re, this);
|
||||
ui->lineEdit_Name->setValidator(validator);
|
||||
ui->lineEdit_LayoutID->setValidator(validator);
|
||||
|
||||
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &NewLayoutDialog::dialogButtonClicked);
|
||||
|
||||
refresh();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
// Creating new layout from AdvanceMap import
|
||||
// TODO: Re-use for a "Duplicate Layout" option
|
||||
NewLayoutDialog::NewLayoutDialog(Project *project, const Layout *layout, QWidget *parent) :
|
||||
NewLayoutDialog(project, parent)
|
||||
{
|
||||
if (layout) {
|
||||
this->importedLayout = layout->copy();
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
NewLayoutDialog::~NewLayoutDialog()
|
||||
{
|
||||
saveSettings();
|
||||
|
|
@ -41,33 +65,24 @@ NewLayoutDialog::~NewLayoutDialog()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
// Creating new layout from AdvanceMap import
|
||||
// TODO: Re-use for a "Duplicate Layout" option?
|
||||
void NewLayoutDialog::copyFrom(const Layout &layoutToCopy) {
|
||||
if (this->importedLayout)
|
||||
delete this->importedLayout;
|
||||
void NewLayoutDialog::refresh() {
|
||||
if (this->importedLayout) {
|
||||
// If we're importing a layout then some settings will be enforced.
|
||||
ui->newLayoutForm->setSettings(this->importedLayout->settings());
|
||||
ui->newLayoutForm->setDisabled(true);
|
||||
} else {
|
||||
ui->newLayoutForm->setSettings(settings);
|
||||
ui->newLayoutForm->setDisabled(false);
|
||||
}
|
||||
|
||||
this->importedLayout = new Layout();
|
||||
this->importedLayout->blockdata = layoutToCopy.blockdata;
|
||||
if (!layoutToCopy.border.isEmpty())
|
||||
this->importedLayout->border = layoutToCopy.border;
|
||||
|
||||
this->settings->width = layoutToCopy.width;
|
||||
this->settings->height = layoutToCopy.height;
|
||||
this->settings->borderWidth = layoutToCopy.border_width;
|
||||
this->settings->borderHeight = layoutToCopy.border_height;
|
||||
this->settings->primaryTilesetLabel = layoutToCopy.tileset_primary_label;
|
||||
this->settings->secondaryTilesetLabel = layoutToCopy.tileset_secondary_label;
|
||||
|
||||
// Don't allow changes to the layout settings
|
||||
ui->newLayoutForm->setSettings(*this->settings);
|
||||
ui->newLayoutForm->setDisabled(true);
|
||||
ui->lineEdit_Name->setText(settings.name);
|
||||
ui->lineEdit_LayoutID->setText(settings.id);
|
||||
}
|
||||
|
||||
void NewLayoutDialog::saveSettings() {
|
||||
*this->settings = ui->newLayoutForm->settings();
|
||||
this->settings->id = ui->lineEdit_LayoutID->text();
|
||||
this->settings->name = ui->lineEdit_Name->text();
|
||||
settings = ui->newLayoutForm->settings();
|
||||
settings.id = ui->lineEdit_LayoutID->text();
|
||||
settings.name = ui->lineEdit_Name->text();
|
||||
}
|
||||
|
||||
bool NewLayoutDialog::validateLayoutID(bool allowEmpty) {
|
||||
|
|
@ -76,8 +91,8 @@ bool NewLayoutDialog::validateLayoutID(bool allowEmpty) {
|
|||
QString errorText;
|
||||
if (id.isEmpty()) {
|
||||
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_LayoutID->text());
|
||||
} else if (this->project->mapLayouts.contains(id)) {
|
||||
errorText = QString("%1 '%2' is already in use.").arg(ui->label_LayoutID->text()).arg(id);
|
||||
} else if (!this->project->isIdentifierUnique(id)) {
|
||||
errorText = QString("%1 '%2' is not unique.").arg(ui->label_LayoutID->text()).arg(id);
|
||||
}
|
||||
|
||||
bool isValid = errorText.isEmpty();
|
||||
|
|
@ -97,8 +112,8 @@ bool NewLayoutDialog::validateName(bool allowEmpty) {
|
|||
QString errorText;
|
||||
if (name.isEmpty()) {
|
||||
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_Name->text());
|
||||
} else if (!this->project->isLayoutNameUnique(name)) {
|
||||
errorText = QString("%1 '%2' is already in use.").arg(ui->label_Name->text()).arg(name);
|
||||
} else if (!this->project->isIdentifierUnique(name)) {
|
||||
errorText = QString("%1 '%2' is not unique.").arg(ui->label_Name->text()).arg(name);
|
||||
}
|
||||
|
||||
bool isValid = errorText.isEmpty();
|
||||
|
|
@ -110,6 +125,8 @@ bool NewLayoutDialog::validateName(bool allowEmpty) {
|
|||
|
||||
void NewLayoutDialog::on_lineEdit_Name_textChanged(const QString &text) {
|
||||
validateName(true);
|
||||
|
||||
// Changing the layout name updates the layout ID field to match.
|
||||
ui->lineEdit_LayoutID->setText(Layout::layoutConstantFromName(text));
|
||||
}
|
||||
|
||||
|
|
@ -118,8 +135,8 @@ void NewLayoutDialog::dialogButtonClicked(QAbstractButton *button) {
|
|||
if (role == QDialogButtonBox::RejectRole){
|
||||
reject();
|
||||
} else if (role == QDialogButtonBox::ResetRole) {
|
||||
this->project->initNewLayoutSettings(); // TODO: Don't allow this to change locked settings
|
||||
ui->newLayoutForm->setSettings(*this->settings);
|
||||
settings = this->project->getNewLayoutSettings();
|
||||
refresh();
|
||||
} else if (role == QDialogButtonBox::AcceptRole) {
|
||||
accept();
|
||||
}
|
||||
|
|
@ -137,18 +154,13 @@ void NewLayoutDialog::accept() {
|
|||
// Update settings from UI
|
||||
saveSettings();
|
||||
|
||||
/*
|
||||
if (this->importedLayout) {
|
||||
// Copy layout data from imported layout
|
||||
layout->blockdata = this->importedLayout->blockdata;
|
||||
if (!this->importedLayout->border.isEmpty())
|
||||
layout->border = this->importedLayout->border;
|
||||
}
|
||||
*/
|
||||
|
||||
Layout *layout = this->project->createNewLayout(*this->settings);
|
||||
if (!layout)
|
||||
Layout *layout = this->project->createNewLayout(settings, this->importedLayout);
|
||||
if (!layout) {
|
||||
ui->label_GenericError->setText(QString("Failed to create layout. See %1 for details.").arg(getLogPath()));
|
||||
ui->label_GenericError->setVisible(true);
|
||||
return;
|
||||
}
|
||||
ui->label_GenericError->setVisible(false);
|
||||
|
||||
emit applied(layout->id);
|
||||
QDialog::accept();
|
||||
|
|
|
|||
|
|
@ -10,23 +10,36 @@
|
|||
|
||||
const QString lineEdit_ErrorStylesheet = "QLineEdit { background-color: rgba(255, 0, 0, 25%) }";
|
||||
|
||||
NewMapDialog::NewMapDialog(QWidget *parent, Project *project) :
|
||||
Project::NewMapSettings NewMapDialog::settings = {};
|
||||
bool NewMapDialog::initializedSettings = false;
|
||||
|
||||
NewMapDialog::NewMapDialog(Project *project, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::NewMapDialog)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setModal(true);
|
||||
ui->setupUi(this);
|
||||
ui->label_GenericError->setVisible(false);
|
||||
this->project = project;
|
||||
this->settings = &project->newMapSettings;
|
||||
|
||||
// Populate UI using data from project
|
||||
this->settings->mapName = project->getNewMapName();
|
||||
Project::NewMapSettings newSettings = project->getNewMapSettings();
|
||||
if (!initializedSettings) {
|
||||
// The first time this dialog is opened we initialize all the default settings.
|
||||
settings = newSettings;
|
||||
initializedSettings = true;
|
||||
} else {
|
||||
// On subsequent openings we only initialize the settings that should be unique,
|
||||
// preserving all other settings from the last time the dialog was open.
|
||||
settings.name = newSettings.name;
|
||||
settings.id = newSettings.id;
|
||||
}
|
||||
ui->newLayoutForm->initUi(project);
|
||||
|
||||
ui->comboBox_Group->addItems(project->groupNames);
|
||||
ui->comboBox_LayoutID->addItems(project->layoutIds);
|
||||
|
||||
// Names and IDs can only contain word characters, and cannot start with a digit.
|
||||
// Identifiers can only contain word characters, and cannot start with a digit.
|
||||
static const QRegularExpression re("[A-Za-z_]+[\\w]*");
|
||||
auto validator = new QRegularExpressionValidator(re, this);
|
||||
ui->lineEdit_Name->setValidator(validator);
|
||||
|
|
@ -37,7 +50,7 @@ NewMapDialog::NewMapDialog(QWidget *parent, Project *project) :
|
|||
// Create a collapsible section that has all the map header data.
|
||||
this->headerForm = new MapHeaderForm();
|
||||
this->headerForm->init(project);
|
||||
this->headerForm->setHeader(&this->settings->header);
|
||||
this->headerForm->setHeader(&settings.header);
|
||||
auto sectionLayout = new QVBoxLayout();
|
||||
sectionLayout->addWidget(this->headerForm);
|
||||
|
||||
|
|
@ -47,103 +60,91 @@ NewMapDialog::NewMapDialog(QWidget *parent, Project *project) :
|
|||
ui->layout_HeaderData->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::Expanding));
|
||||
|
||||
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &NewMapDialog::dialogButtonClicked);
|
||||
connect(ui->comboBox_LayoutID, &QComboBox::currentTextChanged, this, &NewMapDialog::useLayoutIdSettings);
|
||||
|
||||
refresh();
|
||||
adjustSize(); // TODO: Save geometry?
|
||||
}
|
||||
|
||||
// Adding new map to existing map list folder.
|
||||
NewMapDialog::NewMapDialog(Project *project, int mapListTab, const QString &mapListItem, QWidget *parent) :
|
||||
NewMapDialog(project, parent)
|
||||
{
|
||||
switch (mapListTab)
|
||||
{
|
||||
case MapListTab::Groups:
|
||||
settings.group = mapListItem;
|
||||
ui->label_Group->setDisabled(true);
|
||||
ui->comboBox_Group->setDisabled(true);
|
||||
ui->comboBox_Group->setTextItem(settings.group);
|
||||
break;
|
||||
case MapListTab::Areas:
|
||||
settings.header.setLocation(mapListItem);
|
||||
this->headerForm->setLocationDisabled(true);
|
||||
// Header UI is kept in sync automatically by MapHeaderForm
|
||||
break;
|
||||
case MapListTab::Layouts:
|
||||
settings.layout.id = mapListItem;
|
||||
ui->label_LayoutID->setDisabled(true);
|
||||
ui->comboBox_LayoutID->setDisabled(true);
|
||||
ui->comboBox_LayoutID->setTextItem(settings.layout.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use for a "Duplicate Map" option
|
||||
NewMapDialog::NewMapDialog(Project *project, const Map *mapToCopy, QWidget *parent) :
|
||||
NewMapDialog(project, parent)
|
||||
{
|
||||
/*
|
||||
if (this->importedMap)
|
||||
delete this->importedMap;
|
||||
|
||||
this->importedMap = new Map(mapToCopy);
|
||||
useLayoutSettings(this->importedMap->layout());
|
||||
*/
|
||||
}
|
||||
|
||||
NewMapDialog::~NewMapDialog()
|
||||
{
|
||||
saveSettings();
|
||||
delete this->importedLayout;
|
||||
delete this->importedMap;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void NewMapDialog::init() {
|
||||
const QSignalBlocker b_LayoutId(ui->comboBox_LayoutID);
|
||||
ui->comboBox_LayoutID->setCurrentText(this->settings->layout.id);
|
||||
|
||||
ui->lineEdit_Name->setText(this->settings->mapName);
|
||||
ui->comboBox_Group->setTextItem(this->settings->group);
|
||||
ui->checkBox_CanFlyTo->setChecked(this->settings->canFlyTo);
|
||||
ui->newLayoutForm->setSettings(this->settings->layout);
|
||||
}
|
||||
|
||||
// Creating new map by right-clicking in the map list
|
||||
void NewMapDialog::init(int tabIndex, QString fieldName) {
|
||||
switch (tabIndex)
|
||||
{
|
||||
case MapListTab::Groups:
|
||||
this->settings->group = fieldName;
|
||||
ui->label_Group->setDisabled(true);
|
||||
ui->comboBox_Group->setDisabled(true);
|
||||
break;
|
||||
case MapListTab::Areas:
|
||||
this->settings->header.setLocation(fieldName);
|
||||
this->headerForm->setLocationsDisabled(true);
|
||||
break;
|
||||
case MapListTab::Layouts:
|
||||
ui->label_LayoutID->setDisabled(true);
|
||||
ui->comboBox_LayoutID->setDisabled(true);
|
||||
useLayoutIdSettings(fieldName);
|
||||
break;
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
// Creating new map from AdvanceMap import
|
||||
// TODO: Re-use for a "Duplicate Map/Layout" option?
|
||||
void NewMapDialog::init(Layout *layoutToCopy) {
|
||||
if (this->importedLayout)
|
||||
delete this->importedLayout;
|
||||
|
||||
this->importedLayout = new Layout();
|
||||
this->importedLayout->blockdata = layoutToCopy->blockdata;
|
||||
if (!layoutToCopy->border.isEmpty())
|
||||
this->importedLayout->border = layoutToCopy->border;
|
||||
|
||||
useLayoutSettings(this->importedLayout);
|
||||
init();
|
||||
// Sync UI with settings. If any UI elements are disabled (because their settings are being enforced)
|
||||
// then we don't update them using the settings here.
|
||||
void NewMapDialog::refresh() {
|
||||
ui->lineEdit_Name->setText(settings.name);
|
||||
ui->lineEdit_MapID->setText(settings.id);
|
||||
|
||||
ui->comboBox_Group->setTextItem(settings.group);
|
||||
ui->checkBox_CanFlyTo->setChecked(settings.canFlyTo);
|
||||
ui->comboBox_LayoutID->setTextItem(settings.layout.id);
|
||||
ui->newLayoutForm->setSettings(settings.layout);
|
||||
// Header UI is kept in sync automatically by MapHeaderForm
|
||||
}
|
||||
|
||||
void NewMapDialog::saveSettings() {
|
||||
this->settings->mapName = ui->lineEdit_Name->text();
|
||||
this->settings->mapId = ui->lineEdit_MapID->text();
|
||||
this->settings->group = ui->comboBox_Group->currentText();
|
||||
this->settings->canFlyTo = ui->checkBox_CanFlyTo->isChecked();
|
||||
this->settings->layout = ui->newLayoutForm->settings();
|
||||
this->settings->layout.id = ui->comboBox_LayoutID->currentText();
|
||||
this->settings->layout.name = QString("%1_Layout").arg(this->settings->mapName);
|
||||
this->settings->header = this->headerForm->headerData();
|
||||
settings.name = ui->lineEdit_Name->text();
|
||||
settings.id = ui->lineEdit_MapID->text();
|
||||
settings.group = ui->comboBox_Group->currentText();
|
||||
settings.canFlyTo = ui->checkBox_CanFlyTo->isChecked();
|
||||
settings.layout = ui->newLayoutForm->settings();
|
||||
settings.layout.id = ui->comboBox_LayoutID->currentText();
|
||||
// We don't provide full control for naming new layouts here (just via the ID).
|
||||
// If a user wants to explicitly name a layout they can create it individually before creating the map.
|
||||
settings.layout.name = Layout::layoutNameFromMapName(settings.name);
|
||||
settings.header = this->headerForm->headerData();
|
||||
porymapConfig.newMapHeaderSectionExpanded = this->headerSection->isExpanded();
|
||||
}
|
||||
|
||||
void NewMapDialog::useLayoutSettings(const Layout *layout) {
|
||||
if (!layout) {
|
||||
if (layout) {
|
||||
ui->newLayoutForm->setSettings(layout->settings());
|
||||
ui->newLayoutForm->setDisabled(true);
|
||||
} else {
|
||||
ui->newLayoutForm->setDisabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this->settings->layout.width = layout->width;
|
||||
this->settings->layout.height = layout->height;
|
||||
this->settings->layout.borderWidth = layout->border_width;
|
||||
this->settings->layout.borderHeight = layout->border_height;
|
||||
this->settings->layout.primaryTilesetLabel = layout->tileset_primary_label;
|
||||
this->settings->layout.secondaryTilesetLabel = layout->tileset_secondary_label;
|
||||
|
||||
// Don't allow changes to the layout settings
|
||||
ui->newLayoutForm->setSettings(this->settings->layout);
|
||||
ui->newLayoutForm->setDisabled(true);
|
||||
}
|
||||
|
||||
void NewMapDialog::useLayoutIdSettings(const QString &layoutId) {
|
||||
this->settings->layout.id = layoutId;
|
||||
useLayoutSettings(this->project->mapLayouts.value(layoutId));
|
||||
}
|
||||
|
||||
// Return true if the "layout ID" field is specifying a layout that already exists.
|
||||
bool NewMapDialog::isExistingLayout() const {
|
||||
return this->project->mapLayouts.contains(this->settings->layout.id);
|
||||
}
|
||||
|
||||
bool NewMapDialog::validateMapID(bool allowEmpty) {
|
||||
|
|
@ -155,13 +156,8 @@ bool NewMapDialog::validateMapID(bool allowEmpty) {
|
|||
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_MapID->text());
|
||||
} else if (!id.startsWith(expectedPrefix)) {
|
||||
errorText = QString("%1 '%2' must start with '%3'.").arg(ui->label_MapID->text()).arg(id).arg(expectedPrefix);
|
||||
} else {
|
||||
for (auto i = this->project->mapNamesToMapConstants.constBegin(), end = this->project->mapNamesToMapConstants.constEnd(); i != end; i++) {
|
||||
if (id == i.value()) {
|
||||
errorText = QString("%1 '%2' is already in use.").arg(ui->label_MapID->text()).arg(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!this->project->isIdentifierUnique(id)) {
|
||||
errorText = QString("%1 '%2' is not unique.").arg(ui->label_MapID->text()).arg(id);
|
||||
}
|
||||
|
||||
bool isValid = errorText.isEmpty();
|
||||
|
|
@ -181,8 +177,8 @@ bool NewMapDialog::validateName(bool allowEmpty) {
|
|||
QString errorText;
|
||||
if (name.isEmpty()) {
|
||||
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_Name->text());
|
||||
} else if (project->mapNames.contains(name)) {
|
||||
errorText = QString("%1 '%2' is already in use.").arg(ui->label_Name->text()).arg(name);
|
||||
} else if (!this->project->isIdentifierUnique(name)) {
|
||||
errorText = QString("%1 '%2' is not unique.").arg(ui->label_Name->text()).arg(name);
|
||||
}
|
||||
|
||||
bool isValid = errorText.isEmpty();
|
||||
|
|
@ -206,6 +202,8 @@ bool NewMapDialog::validateGroup(bool allowEmpty) {
|
|||
QString errorText;
|
||||
if (groupName.isEmpty()) {
|
||||
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_Group->text());
|
||||
} else if (!this->project->groupNames.contains(groupName) && !this->project->isIdentifierUnique(groupName)) {
|
||||
errorText = QString("%1 must either be the name of an existing map group, or a unique identifier for a new map group.").arg(ui->label_Group->text());
|
||||
}
|
||||
|
||||
bool isValid = errorText.isEmpty();
|
||||
|
|
@ -219,13 +217,43 @@ void NewMapDialog::on_comboBox_Group_currentTextChanged(const QString &) {
|
|||
validateGroup(true);
|
||||
}
|
||||
|
||||
bool NewMapDialog::validateLayoutID(bool allowEmpty) {
|
||||
QString layoutId = ui->comboBox_LayoutID->currentText();
|
||||
|
||||
QString errorText;
|
||||
if (layoutId.isEmpty()) {
|
||||
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_LayoutID->text());
|
||||
} else if (!this->project->layoutIds.contains(layoutId) && !this->project->isIdentifierUnique(layoutId)) {
|
||||
errorText = QString("%1 must either be the ID for an existing layout, or a unique identifier for a new layout.").arg(ui->label_LayoutID->text());
|
||||
}
|
||||
|
||||
bool isValid = errorText.isEmpty();
|
||||
ui->label_LayoutIDError->setText(errorText);
|
||||
ui->label_LayoutIDError->setVisible(!isValid);
|
||||
ui->comboBox_LayoutID->lineEdit()->setStyleSheet(!isValid ? lineEdit_ErrorStylesheet : "");
|
||||
return isValid;
|
||||
}
|
||||
|
||||
void NewMapDialog::on_comboBox_LayoutID_currentTextChanged(const QString &text) {
|
||||
validateLayoutID(true);
|
||||
useLayoutSettings(this->project->mapLayouts.value(text));
|
||||
}
|
||||
|
||||
void NewMapDialog::dialogButtonClicked(QAbstractButton *button) {
|
||||
auto role = ui->buttonBox->buttonRole(button);
|
||||
if (role == QDialogButtonBox::RejectRole){
|
||||
reject();
|
||||
} else if (role == QDialogButtonBox::ResetRole) {
|
||||
this->project->initNewMapSettings(); // TODO: Don't allow this to change locked settings
|
||||
init();
|
||||
auto newSettings = this->project->getNewMapSettings();
|
||||
|
||||
// If the location setting is disabled we need to enforce that setting on the new header.
|
||||
if (this->headerForm->isLocationDisabled())
|
||||
newSettings.header.setLocation(settings.header.location());
|
||||
|
||||
settings = newSettings;
|
||||
this->headerForm->setHeader(&settings.header); // TODO: Unnecessary?
|
||||
refresh();
|
||||
|
||||
} else if (role == QDialogButtonBox::AcceptRole) {
|
||||
accept();
|
||||
}
|
||||
|
|
@ -238,6 +266,7 @@ void NewMapDialog::accept() {
|
|||
if (!validateMapID()) success = false;
|
||||
if (!validateName()) success = false;
|
||||
if (!validateGroup()) success = false;
|
||||
if (!validateLayoutID()) success = false;
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
|
|
@ -245,33 +274,29 @@ void NewMapDialog::accept() {
|
|||
saveSettings();
|
||||
|
||||
Map *newMap = new Map;
|
||||
newMap->setName(this->settings->mapName);
|
||||
newMap->setConstantName(this->settings->mapId);
|
||||
newMap->setHeader(this->settings->header);
|
||||
newMap->setNeedsHealLocation(this->settings->canFlyTo);
|
||||
newMap->setName(settings.name);
|
||||
newMap->setConstantName(settings.id);
|
||||
newMap->setHeader(settings.header);
|
||||
newMap->setNeedsHealLocation(settings.canFlyTo);
|
||||
|
||||
Layout *layout = nullptr;
|
||||
const bool existingLayout = isExistingLayout();
|
||||
if (existingLayout) {
|
||||
layout = this->project->mapLayouts.value(this->settings->layout.id);
|
||||
newMap->setNeedsLayoutDir(false); // TODO: Remove this member
|
||||
Layout *layout = this->project->mapLayouts.value(settings.layout.id);
|
||||
if (layout) {
|
||||
// Layout already exists
|
||||
newMap->setNeedsLayoutDir(false); // TODO: Remove this member?
|
||||
} else {
|
||||
/* TODO: Re-implement (make sure this won't ever override an existing layout)
|
||||
if (this->importedLayout) {
|
||||
// Copy layout data from imported layout
|
||||
layout->blockdata = this->importedLayout->blockdata;
|
||||
if (!this->importedLayout->border.isEmpty())
|
||||
layout->border = this->importedLayout->border;
|
||||
}
|
||||
*/
|
||||
layout = this->project->createNewLayout(this->settings->layout);
|
||||
layout = this->project->createNewLayout(settings.layout);
|
||||
}
|
||||
if (!layout)
|
||||
if (!layout) {
|
||||
ui->label_GenericError->setText(QString("Failed to create layout for map. See %1 for details.").arg(getLogPath()));
|
||||
ui->label_GenericError->setVisible(true);
|
||||
delete newMap;
|
||||
return;
|
||||
}
|
||||
ui->label_GenericError->setVisible(false);
|
||||
|
||||
newMap->setLayout(layout);
|
||||
|
||||
this->project->addNewMap(newMap, this->settings->group);
|
||||
this->project->addNewMap(newMap, settings.group);
|
||||
emit applied(newMap->name());
|
||||
QDialog::accept();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ NewTilesetDialog::NewTilesetDialog(Project* project, QWidget *parent) :
|
|||
this->setFixedSize(this->width(), this->height());
|
||||
this->project = project;
|
||||
//only allow characters valid for a symbol
|
||||
static const QRegularExpression expression("[_A-Za-z0-9]+$");
|
||||
static const QRegularExpression expression("[_A-Za-z0-9]+$"); // TODO: Incorrect, allows digits at beginning
|
||||
QRegularExpressionValidator *validator = new QRegularExpressionValidator(expression);
|
||||
this->ui->nameLineEdit->setValidator(validator);
|
||||
|
||||
|
|
@ -35,6 +35,7 @@ void NewTilesetDialog::SecondaryChanged(){
|
|||
NameOrSecondaryChanged();
|
||||
}
|
||||
|
||||
// TODO: No validation
|
||||
void NewTilesetDialog::NameOrSecondaryChanged() {
|
||||
this->friendlyName = this->ui->nameLineEdit->text();
|
||||
this->fullSymbolName = projectConfig.getIdentifier(ProjectIdentifier::symbol_tilesets_prefix) + this->friendlyName;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user