From f767d257f0e17f07eb88165ee299c1f3eba37ad0 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Sun, 30 Sep 2018 13:51:50 -0500 Subject: [PATCH 1/5] Start work on tileset editor --- src/mainwindow.ui | 33 +++--- src/porymap.pro | 9 +- src/tileseteditor.ui | 232 +++++++++++++++++++++++++++++++++++++++ src/ui/tileseteditor.cpp | 14 +++ src/ui/tileseteditor.h | 22 ++++ 5 files changed, 294 insertions(+), 16 deletions(-) create mode 100644 src/tileseteditor.ui create mode 100644 src/ui/tileseteditor.cpp create mode 100644 src/ui/tileseteditor.h diff --git a/src/mainwindow.ui b/src/mainwindow.ui index b42acbaf..6448478f 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -378,8 +378,8 @@ 0 0 - 469 - 608 + 481 + 606 @@ -687,8 +687,8 @@ 0 0 - 324 - 77 + 300 + 70 @@ -799,8 +799,8 @@ 0 0 - 307 - 387 + 304 + 372 @@ -1116,8 +1116,8 @@ 0 0 - 381 - 657 + 385 + 655 @@ -1294,8 +1294,8 @@ 0 0 - 432 - 596 + 428 + 586 @@ -1914,8 +1914,8 @@ 0 0 - 826 - 557 + 829 + 552 @@ -2087,7 +2087,7 @@ 0 0 1117 - 21 + 20 @@ -2127,6 +2127,8 @@ + + @@ -2268,6 +2270,11 @@ P + + + Tileset Editor + + diff --git a/src/porymap.pro b/src/porymap.pro index 2bfd2dcc..e9b476e5 100644 --- a/src/porymap.pro +++ b/src/porymap.pro @@ -44,7 +44,8 @@ SOURCES += core/block.cpp \ mainwindow.cpp \ project.cpp \ settings.cpp \ - ui/mapsceneeventfilter.cpp + ui/mapsceneeventfilter.cpp \ + ui/tileseteditor.cpp HEADERS += core/block.h \ core/blockdata.h \ @@ -77,10 +78,12 @@ HEADERS += core/block.h \ mainwindow.h \ project.h \ settings.h \ - ui/mapsceneeventfilter.h + ui/mapsceneeventfilter.h \ + ui/tileseteditor.h FORMS += mainwindow.ui \ - eventpropertiesframe.ui + eventpropertiesframe.ui \ + tileseteditor.ui RESOURCES += \ resources/images.qrc diff --git a/src/tileseteditor.ui b/src/tileseteditor.ui new file mode 100644 index 00000000..81727bc1 --- /dev/null +++ b/src/tileseteditor.ui @@ -0,0 +1,232 @@ + + + TilesetEditor + + + + 0 + 0 + 1022 + 386 + + + + Dialog + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + 1 + 0 + + + + true + + + + + 0 + 0 + 329 + 339 + + + + + + + Qt::Horizontal + + + + 26 + 20 + + + + + + + + + + + Qt::Horizontal + + + + 26 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 120 + + + + + + + + + + + + + 2 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 1 + 0 + + + + true + + + + + 0 + 0 + 316 + 319 + + + + + + + Qt::Horizontal + + + + 21 + 20 + + + + + + + + + + + Qt::Horizontal + + + + 21 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 100 + + + + + + + + + + + + + 1 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + + + buttonBox + accepted() + TilesetEditor + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + TilesetEditor + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp new file mode 100644 index 00000000..b4be9766 --- /dev/null +++ b/src/ui/tileseteditor.cpp @@ -0,0 +1,14 @@ +#include "tileseteditor.h" +#include "ui_tileseteditor.h" + +TilesetEditor::TilesetEditor(QWidget *parent) : + QDialog(parent), + ui(new Ui::TilesetEditor) +{ + ui->setupUi(this); +} + +TilesetEditor::~TilesetEditor() +{ + delete ui; +} diff --git a/src/ui/tileseteditor.h b/src/ui/tileseteditor.h new file mode 100644 index 00000000..7befc465 --- /dev/null +++ b/src/ui/tileseteditor.h @@ -0,0 +1,22 @@ +#ifndef TILESETEDITOR_H +#define TILESETEDITOR_H + +#include + +namespace Ui { +class TilesetEditor; +} + +class TilesetEditor : public QDialog +{ + Q_OBJECT + +public: + explicit TilesetEditor(QWidget *parent = nullptr); + ~TilesetEditor(); + +private: + Ui::TilesetEditor *ui; +}; + +#endif // TILESETEDITOR_H From 6269d4822ab47dd4ed9106e0f615d8840235e7f0 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 2 Oct 2018 21:46:08 -0500 Subject: [PATCH 2/5] Add filter to UI --- forms/mainwindow.ui | 168 +++++++++++++++--- {src => forms}/tileseteditor.ui | 0 include/core/filterchildrenproxymodel.h | 17 ++ include/mainwindow.h | 1 + {src => include}/ui/tileseteditor.h | 0 porymap.pro | 2 + ...folder_image.ico => folder_map_edited.ico} | Bin resources/icons/folder_map_opened.ico | Bin 0 -> 5430 bytes resources/icons/{image.ico => map_edited.ico} | Bin resources/icons/map_opened.ico | Bin 0 -> 1150 bytes resources/icons/sort_alphabet.ico | Bin 0 -> 1150 bytes resources/icons/sort_map.ico | Bin 0 -> 1150 bytes resources/icons/sort_number.ico | Bin 0 -> 1150 bytes resources/images.qrc | 9 +- src/core/filterchildrenproxymodel.cpp | 35 ++++ src/mainwindow.cpp | 34 ++-- 16 files changed, 219 insertions(+), 47 deletions(-) rename {src => forms}/tileseteditor.ui (100%) create mode 100644 include/core/filterchildrenproxymodel.h rename {src => include}/ui/tileseteditor.h (100%) rename resources/icons/{folder_image.ico => folder_map_edited.ico} (100%) create mode 100644 resources/icons/folder_map_opened.ico rename resources/icons/{image.ico => map_edited.ico} (100%) create mode 100644 resources/icons/map_opened.ico create mode 100644 resources/icons/sort_alphabet.ico create mode 100644 resources/icons/sort_map.ico create mode 100644 resources/icons/sort_number.ico create mode 100644 src/core/filterchildrenproxymodel.cpp diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index 6448478f..93f5756e 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -26,28 +26,144 @@ Qt::Horizontal - + + + true + 0 0 - - - 100 - 0 - - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectItems - - - false - + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 3 + + + 3 + + + 3 + + + + + true + + + + 0 + 0 + + + + + :/icons/sort_alphabet.ico:/icons/sort_alphabet.ico + + + + 16 + 16 + + + + QToolButton::MenuButtonPopup + + + Qt::ToolButtonIconOnly + + + true + + + Qt::NoArrow + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 24 + 20 + + + + + + + + true + + + + 0 + 0 + + + + + + + Filter maps... + + + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectItems + + + false + + + + @@ -73,7 +189,7 @@ - + :/icons/map.ico:/icons/map.ico @@ -177,7 +293,7 @@ Paint - + :/icons/pencil.ico:/icons/pencil.ico @@ -203,7 +319,7 @@ Select - + :/icons/cursor.ico:/icons/cursor.ico @@ -220,7 +336,7 @@ Fill - + :/icons/fill_color.ico:/icons/fill_color.ico @@ -237,7 +353,7 @@ Dropper - + :/icons/pipette.ico:/icons/pipette.ico @@ -254,7 +370,7 @@ ... - + :/icons/move.ico:/icons/move.ico @@ -271,7 +387,7 @@ Shift - + :/icons/shift.ico:/icons/shift.ico @@ -1355,7 +1471,7 @@ New Object - + :/icons/add.ico:/icons/add.ico @@ -1384,7 +1500,7 @@ Delete - + :/icons/delete.ico:/icons/delete.ico @@ -2295,7 +2411,7 @@ - + diff --git a/src/tileseteditor.ui b/forms/tileseteditor.ui similarity index 100% rename from src/tileseteditor.ui rename to forms/tileseteditor.ui diff --git a/include/core/filterchildrenproxymodel.h b/include/core/filterchildrenproxymodel.h new file mode 100644 index 00000000..b73cbd62 --- /dev/null +++ b/include/core/filterchildrenproxymodel.h @@ -0,0 +1,17 @@ +#ifndef FILTERCHILDRENPROXYMODEL_H +#define FILTERCHILDRENPROXYMODEL_H + +#include + +class FilterChildrenProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + explicit FilterChildrenProxyModel(QObject *parent = nullptr); +protected: + bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const; + +}; + +#endif // FILTERCHILDRENPROXYMODEL_H diff --git a/include/mainwindow.h b/include/mainwindow.h index 7dd7c773..732f96b1 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -130,6 +130,7 @@ private: QMap mapListIndexes; Editor *editor = nullptr; QIcon* mapIcon; + QIcon* mapEditedIcon; void setMap(QString, bool scrollTreeView = false); void redrawMapScene(); void loadDataStructures(); diff --git a/src/ui/tileseteditor.h b/include/ui/tileseteditor.h similarity index 100% rename from src/ui/tileseteditor.h rename to include/ui/tileseteditor.h diff --git a/porymap.pro b/porymap.pro index 3a027a4c..dc94f6eb 100644 --- a/porymap.pro +++ b/porymap.pro @@ -17,6 +17,7 @@ ICON = resources/icons/porymap-icon-1.ico SOURCES += src/core/block.cpp \ src/core/blockdata.cpp \ src/core/event.cpp \ + src/core/filterchildrenproxymodel.cpp \ src/core/heallocation.cpp \ src/core/historyitem.cpp \ src/core/map.cpp \ @@ -50,6 +51,7 @@ SOURCES += src/core/block.cpp \ HEADERS += include/core/block.h \ include/core/blockdata.h \ include/core/event.h \ + include/core/filterchildrenproxymodel.h \ include/core/heallocation.h \ include/core/history.h \ include/core/historyitem.h \ diff --git a/resources/icons/folder_image.ico b/resources/icons/folder_map_edited.ico similarity index 100% rename from resources/icons/folder_image.ico rename to resources/icons/folder_map_edited.ico diff --git a/resources/icons/folder_map_opened.ico b/resources/icons/folder_map_opened.ico new file mode 100644 index 0000000000000000000000000000000000000000..2b23226afb04e67ce8ec3db731ccdf293acb8c52 GIT binary patch literal 5430 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 literal 0 HcmV?d00001 diff --git a/resources/icons/sort_alphabet.ico b/resources/icons/sort_alphabet.ico new file mode 100644 index 0000000000000000000000000000000000000000..27744f8366d4517b5dc6315ef937559888bca327 GIT binary patch literal 1150 zcmbVLK~EDw7#$LC9^~ZNqjyefXd~X}4X7~+-b_d|cv1AAF%nVl^ z`v|m-7>hw*@bjm4g7i;?d;^n@Qph|`BOdD}*F@8IfPnl&3g_c-oI87lv~Tq5t8WDN z{o2LFWWUK>xqOMp^EB%8`xxl!Gd!T7-KrU{uS9-(e(jX8Fqg%h(ObAXdYc*_i9`Yr zeY1{{8`rs>1FvfDb$@^BcgsJ)Bz+n~gM((=s1@Oh-tZoh1N~_17VQ3e=eK^Ru#NGD z_i>@82a~BWc$FWhk#oy=#JXdKpBNuQy_5_6Zw1vN>qDZF`-(rmHsKbx;Ou-u<@*Lo z_K2gCAa`Q7e~> zMNsBZ?a6ti{`hb7QowRPJeIQ4Vf|0H6t(lqs^R~4_y%OfA8>X3fRm1+HSvh|FL(-u AQ2+n{ literal 0 HcmV?d00001 diff --git a/resources/icons/sort_map.ico b/resources/icons/sort_map.ico new file mode 100644 index 0000000000000000000000000000000000000000..5c64e855b8dc7faa04384267e8b3b8b38853cf26 GIT binary patch literal 1150 zcmbW0&r4KM9K~L1 z?~v?kXRks^+gP*`kKH6c9=e{>35ZfkrCwI==bMLwD&AdBGHSua~RlHwOeV3HF ztdwe_lOkhyf>O*~(Apc-189_PUz~m=1$BEw`j)6h>P~$=o5A634uWU-GtbSUf82lX z{=(EG=H6%MYh`gROO>xgM+lvsGlOWneUN%Y<7y(xOp{*SGEdLuF={j`NA2BUiz zR1lPX2%fX3Zf*IC(A1Bcbl_nm{TyAf4vh$WRJ;;Eesm;_t6iPQyc`8W({FWY_ME=r z78!>~UGLTX!m@)CpZbccc_HuKxeby!zq(k}oBezCAy6)1V4$CCQtQ}Abazwl;Nw&l zj~)(UXz&4Rj*b3weWQ1+edda|kxBus4bRRqWKXYvWKWOQTuUYqI#x}+bCg4R_z5~= zF_a7YDCU1@_w7BrNDm_(j}xE4vvwl=XF)Z``4F>zZ=iIr1vkHq!tN%l+ztd}-cwNG>g>sW tW&ZeYB-oYXT-)Ze6Vd!n)GcbHm#)$OS9<}nq7T_Uc*>yZVlEod{sp!Dh}!@F literal 0 HcmV?d00001 diff --git a/resources/images.qrc b/resources/images.qrc index ac1ff8cb..8f1a09aa 100644 --- a/resources/images.qrc +++ b/resources/images.qrc @@ -3,9 +3,7 @@ icons/folder.ico icons/folder_closed.ico icons/folder_closed_map.ico - icons/folder_image.ico icons/folder_map.ico - icons/image.ico icons/map.ico icons/cursor.ico icons/fill_color.ico @@ -23,5 +21,12 @@ icons/shift.ico icons/shift_cursor.ico icons/porymap-icon-1.ico + icons/folder_map_edited.ico + icons/folder_map_opened.ico + icons/map_edited.ico + icons/map_opened.ico + icons/sort_alphabet.ico + icons/sort_map.ico + icons/sort_number.ico diff --git a/src/core/filterchildrenproxymodel.cpp b/src/core/filterchildrenproxymodel.cpp new file mode 100644 index 00000000..faff6a23 --- /dev/null +++ b/src/core/filterchildrenproxymodel.cpp @@ -0,0 +1,35 @@ +#include "filterchildrenproxymodel.h" + +FilterChildrenProxyModel::FilterChildrenProxyModel(QObject *parent) : + QSortFilterProxyModel(parent) +{ + +} + +bool FilterChildrenProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + // custom behaviour : + if(filterRegExp().isEmpty() == false) + { + // get source-model index for current row + QModelIndex source_index = sourceModel()->index(source_row, this->filterKeyColumn(), source_parent) ; + if(source_index.isValid()) + { + // if any of children matches the filter, then current index matches the filter as well + int i, nb = sourceModel()->rowCount(source_index); + for (i = 0; i < nb; ++i) + { + if (filterAcceptsRow(i, source_index)) + { + return true; + } + } + // check current index itself + QString key = sourceModel()->data(source_index, filterRole()).toString(); + QString parentKey = sourceModel()->data(source_parent, filterRole()).toString(); + return key.contains(filterRegExp()) || parentKey.contains(filterRegExp()); + } + } + // parent call for initial behaviour + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); +} diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 70d875f3..e5e1115e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -180,6 +180,10 @@ void MainWindow::setMap(QString map_name, bool scrollTreeView) { if (map_name.isNull()) { return; } + if (editor->map != nullptr && !editor->map->name.isNull()) { + ui->mapList->setExpanded(mapListIndexes.value(editor->map->name), false); + } + ui->mapList->setExpanded(mapListIndexes.value(map_name), true); editor->setMap(map_name); redrawMapScene(); displayMapProperties(); @@ -418,26 +422,19 @@ void MainWindow::populateMapList() { QIcon folderIcon; folderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off); + folderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On); mapIcon = new QIcon; mapIcon->addFile(QStringLiteral(":/icons/map.ico"), QSize(), QIcon::Normal, QIcon::Off); - mapIcon->addFile(QStringLiteral(":/icons/image.ico"), QSize(), QIcon::Normal, QIcon::On); + mapIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal, QIcon::On); + + mapEditedIcon = new QIcon; + mapEditedIcon->addFile(QStringLiteral(":/icons/map_edited.ico"), QSize(), QIcon::Normal, QIcon::Off); + mapEditedIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal , QIcon::On); mapListModel = new QStandardItemModel; mapGroupsModel = new QList; - QStandardItem *entry = new QStandardItem; - entry->setText(project->getProjectTitle()); - entry->setIcon(folderIcon); - entry->setEditable(false); - mapListModel->appendRow(entry); - - QStandardItem *maps = new QStandardItem; - maps->setText("maps"); - maps->setIcon(folderIcon); - maps->setEditable(false); - entry->appendRow(maps); - project->readMapGroups(); for (int i = 0; i < project->groupNames->length(); i++) { QString group_name = project->groupNames->value(i); @@ -448,7 +445,7 @@ void MainWindow::populateMapList() { group->setData(group_name, Qt::UserRole); group->setData("map_group", MapListUserRoles::TypeRole); group->setData(i, MapListUserRoles::GroupRole); - maps->appendRow(group); + mapListModel->appendRow(group); mapGroupsModel->append(group); QStringList names = project->groupedMapNames.value(i); for (int j = 0; j < names.length(); j++) { @@ -466,7 +463,7 @@ void MainWindow::populateMapList() { ui->mapList->setModel(mapListModel); ui->mapList->setUpdatesEnabled(true); - ui->mapList->expandToDepth(2); + ui->mapList->expandToDepth(0); ui->mapList->repaint(); } @@ -563,10 +560,9 @@ void MainWindow::markEdited(QModelIndex index) { QString map_name = data.toString(); if (editor->project) { if (editor->project->map_cache->contains(map_name)) { - // Just mark anything that's been opened for now. - // TODO if (project->getMap()->saved) - //ui->mapList->setExpanded(index, true); - ui->mapList->setExpanded(index, editor->project->map_cache->value(map_name)->hasUnsavedChanges()); + if (editor->project->map_cache->value(map_name)->hasUnsavedChanges()) { + mapListModel->itemFromIndex(mapListIndexes.value(map_name))->setIcon(*mapEditedIcon); + } } } } From 0e58fed23b1532390a5387ae80bfa6e0c6c99db7 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Fri, 5 Oct 2018 01:02:40 -0500 Subject: [PATCH 3/5] Add map list sorting and filtering --- forms/mainwindow.ui | 61 ++++++++---- include/mainwindow.h | 22 ++++- include/project.h | 3 + src/mainwindow.cpp | 221 +++++++++++++++++++++++++++++++++++-------- src/project.cpp | 30 ++++++ 5 files changed, 275 insertions(+), 62 deletions(-) diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index 93f5756e..7f85664d 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -10,12 +10,6 @@ 747 - - - 0 - 0 - - porymap @@ -71,12 +65,6 @@ true - - - 0 - 0 - - :/icons/sort_alphabet.ico:/icons/sort_alphabet.ico @@ -88,7 +76,7 @@ - QToolButton::MenuButtonPopup + QToolButton::InstantPopup Qt::ToolButtonIconOnly @@ -111,7 +99,7 @@ - 24 + 12 20 @@ -122,12 +110,6 @@ true - - - 0 - 0 - - @@ -2391,6 +2373,45 @@ Tileset Editor + + + true + + + + :/icons/sort_alphabet.ico:/icons/sort_alphabet.ico + + + Sort by &Name + + + + + true + + + + :/icons/sort_number.ico:/icons/sort_number.ico + + + Sort by &Group + + + Sort by Group + + + + + true + + + + :/icons/sort_map.ico:/icons/sort_map.ico + + + Sort by &Layout + + diff --git a/include/mainwindow.h b/include/mainwindow.h index 1eb1ed43..7e295e19 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -13,6 +13,7 @@ #include "map.h" #include "editor.h" #include "tileseteditor.h" +#include "filterchildrenproxymodel.h" namespace Ui { class MainWindow; @@ -128,19 +129,32 @@ private slots: void on_actionTileset_Editor_triggered(); + void mapSortOrder_changed(QAction *action); + + void on_lineEdit_filterBox_textChanged(const QString &arg1); + private: Ui::MainWindow *ui; TilesetEditor *tilesetEditor = nullptr; + FilterChildrenProxyModel *mapListProxyModel; QStandardItemModel *mapListModel; - QList *mapGroupsModel; + QList *mapGroupItemsList; QMap mapListIndexes; Editor *editor = nullptr; QIcon* mapIcon; QIcon* mapEditedIcon; + + enum MapSortOrder { + Group = 0, + Name = 1, + Layout = 2, + } mapSortOrder; + void setMap(QString, bool scrollTreeView = false); void redrawMapScene(); void loadDataStructures(); void populateMapList(); + void sortMapList(); QString getExistingDirectory(QString); void openProject(QString dir); QString getDefaultMap(); @@ -157,14 +171,18 @@ private: void initExtraShortcuts(); void initExtraSignals(); void initEditor(); + void initMiscHeapObjects(); + void initMapSortOrder(); void loadUserSettings(); void openRecentProject(); void updateTilesetEditor(); + + bool isProjectOpen(); }; enum MapListUserRoles { GroupRole = Qt::UserRole + 1, // Used to hold the map group number. - TypeRole = Qt::UserRole + 2, // Used to differentiate between the different layers of the map list tree view. + TypeRole, // Used to differentiate between the different layers of the map list tree view. }; #endif // MAINWINDOW_H diff --git a/include/project.h b/include/project.h index fa4ee2ed..c3d1bc66 100644 --- a/include/project.h +++ b/include/project.h @@ -64,6 +64,9 @@ public: QString getNewMapName(); QString getProjectTitle(); + QString readMapLayoutId(QString map_name); + QString readMapLocation(QString map_name); + QList* getLabelMacros(QList*, QString); QStringList* getLabelValues(QList*, QString); void readMapHeader(Map*); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8dbc04e3..3d7579b0 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -39,6 +39,8 @@ MainWindow::MainWindow(QWidget *parent) : this->initExtraSignals(); this->initExtraShortcuts(); this->initEditor(); + this->initMiscHeapObjects(); + this->initMapSortOrder(); this->openRecentProject(); on_toolButton_Paint_clicked(); @@ -72,12 +74,89 @@ void MainWindow::initEditor() { this->loadUserSettings(); } +void MainWindow::initMiscHeapObjects() { + mapIcon = new QIcon; + mapIcon->addFile(QStringLiteral(":/icons/map.ico"), QSize(), QIcon::Normal, QIcon::Off); + mapIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal, QIcon::On); + + mapEditedIcon = new QIcon; + mapEditedIcon->addFile(QStringLiteral(":/icons/map_edited.ico"), QSize(), QIcon::Normal, QIcon::Off); + mapEditedIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal , QIcon::On); + + mapListModel = new QStandardItemModel; + mapGroupItemsList = new QList; + mapListProxyModel = new FilterChildrenProxyModel; + + mapListProxyModel->setSourceModel(mapListModel); + ui->mapList->setModel(mapListProxyModel); +} + +void MainWindow::initMapSortOrder() { + QMenu *mapSortOrderMenu = new QMenu(); + QActionGroup *mapSortOrderActionGroup = new QActionGroup(ui->toolButton_MapSortOrder); + + mapSortOrderMenu->addAction(ui->actionSort_by_Group); + mapSortOrderMenu->addAction(ui->actionSort_by_Name); + mapSortOrderMenu->addAction(ui->actionSort_by_Layout); + ui->toolButton_MapSortOrder->setMenu(mapSortOrderMenu); + + mapSortOrderActionGroup->addAction(ui->actionSort_by_Group); + mapSortOrderActionGroup->addAction(ui->actionSort_by_Name); + mapSortOrderActionGroup->addAction(ui->actionSort_by_Layout); + + connect(ui->toolButton_MapSortOrder, &QToolButton::triggered, this, &MainWindow::mapSortOrder_changed); + + QAction* sortOrder = ui->toolButton_MapSortOrder->menu()->actions()[mapSortOrder]; + ui->toolButton_MapSortOrder->setIcon(sortOrder->icon()); + sortOrder->setChecked(true); +} + +void MainWindow::mapSortOrder_changed(QAction *action) +{ + QSettings settings; + + QList items = ui->toolButton_MapSortOrder->menu()->actions(); + int i = 0; + for (; i < items.count(); i++) + { + if(items[i] == action) + { + break; + } + } + + if (i != mapSortOrder) + { + ui->toolButton_MapSortOrder->setIcon(action->icon()); + mapSortOrder = static_cast(i); + settings.setValue("map_sort_order", i); + + if (isProjectOpen()) + { + sortMapList(); + } + } +} + +void MainWindow::on_lineEdit_filterBox_textChanged(const QString &arg1) +{ + mapListProxyModel->setFilterRegExp(QRegExp(arg1, Qt::CaseInsensitive, QRegExp::FixedString)); + ui->mapList->expandToDepth(0); + ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(editor->map->name)), true); +} + void MainWindow::loadUserSettings() { QSettings settings; bool betterCursors = settings.contains("cursor_mode") && settings.value("cursor_mode") != "0"; ui->actionBetter_Cursors->setChecked(betterCursors); this->editor->settings->betterCursors = betterCursors; + + if (!settings.contains("map_sort_order")) + { + settings.setValue("map_sort_order", 0); + } + mapSortOrder = static_cast(settings.value("map_sort_order").toInt()); } void MainWindow::openRecentProject() { @@ -99,11 +178,7 @@ void MainWindow::openProject(QString dir) { this->statusBar()->showMessage(QString("Opening project %1").arg(dir)); - bool already_open = ( - (editor && editor != nullptr) - && (editor->project && editor->project != nullptr) - && (editor->project->root == dir) - ); + bool already_open = isProjectOpen() && (editor->project->root == dir); if (!already_open) { editor->project = new Project; editor->project->root = dir; @@ -120,6 +195,11 @@ void MainWindow::openProject(QString dir) { this->statusBar()->showMessage(QString("Opened project %1").arg(dir)); } +bool MainWindow::isProjectOpen() { + return (editor && editor != nullptr) + && (editor->project && editor->project != nullptr); +} + QString MainWindow::getDefaultMap() { if (editor && editor->project) { QList names = editor->project->groupedMapNames; @@ -181,15 +261,15 @@ void MainWindow::setMap(QString map_name, bool scrollTreeView) { return; } if (editor->map != nullptr && !editor->map->name.isNull()) { - ui->mapList->setExpanded(mapListIndexes.value(editor->map->name), false); + ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(editor->map->name)), false); } - ui->mapList->setExpanded(mapListIndexes.value(map_name), true); + ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(map_name)), true); editor->setMap(map_name); redrawMapScene(); displayMapProperties(); if (scrollTreeView) { - ui->mapList->setCurrentIndex(mapListIndexes.value(map_name)); + ui->mapList->setCurrentIndex(mapListProxyModel->mapFromSource(mapListIndexes.value(map_name))); ui->mapList->scrollTo(ui->mapList->currentIndex(), QAbstractItemView::PositionAtCenter); } @@ -258,6 +338,7 @@ void MainWindow::openWarpMap(QString map_name, QString warp_num) { } // Open the destination map, and select the target warp event. + mapListProxyModel->setFilterRegExp(QString::null); setMap(map_name, true); QList warp_events = editor->map->events["warp_event_group"]; if (warp_events.length() > warpNum) { @@ -416,6 +497,11 @@ void MainWindow::loadDataStructures() { } void MainWindow::populateMapList() { + editor->project->readMapGroups(); + sortMapList(); +} + +void MainWindow::sortMapList() { Project *project = editor->project; QIcon mapFolderIcon; @@ -424,37 +510,93 @@ void MainWindow::populateMapList() { QIcon folderIcon; folderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off); - folderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On); + //folderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On); - mapIcon = new QIcon; - mapIcon->addFile(QStringLiteral(":/icons/map.ico"), QSize(), QIcon::Normal, QIcon::Off); - mapIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal, QIcon::On); + ui->mapList->setUpdatesEnabled(false); + mapListModel->clear(); + mapGroupItemsList->clear(); + QStandardItem *root = mapListModel->invisibleRootItem(); - mapEditedIcon = new QIcon; - mapEditedIcon->addFile(QStringLiteral(":/icons/map_edited.ico"), QSize(), QIcon::Normal, QIcon::Off); - mapEditedIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal , QIcon::On); - - mapListModel = new QStandardItemModel; - mapGroupsModel = new QList; - - project->readMapGroups(); - for (int i = 0; i < project->groupNames->length(); i++) { - QString group_name = project->groupNames->value(i); - QStandardItem *group = new QStandardItem; - group->setText(group_name); - group->setIcon(mapFolderIcon); - group->setEditable(false); - group->setData(group_name, Qt::UserRole); - group->setData("map_group", MapListUserRoles::TypeRole); - group->setData(i, MapListUserRoles::GroupRole); - mapListModel->appendRow(group); - mapGroupsModel->append(group); - QStringList names = project->groupedMapNames.value(i); - for (int j = 0; j < names.length(); j++) { - QString map_name = names.value(j); - QStandardItem *map = createMapItem(map_name, i, j); - group->appendRow(map); - mapListIndexes.insert(map_name, map->index()); + switch (mapSortOrder) + { + case MapSortOrder::Group: + for (int i = 0; i < project->groupNames->length(); i++) { + QString group_name = project->groupNames->value(i); + QStandardItem *group = new QStandardItem; + group->setText(group_name); + group->setIcon(mapFolderIcon); + group->setEditable(false); + group->setData(group_name, Qt::UserRole); + group->setData("map_group", MapListUserRoles::TypeRole); + group->setData(i, MapListUserRoles::GroupRole); + root->appendRow(group); + mapGroupItemsList->append(group); + QStringList names = project->groupedMapNames.value(i); + for (int j = 0; j < names.length(); j++) { + QString map_name = names.value(j); + QStandardItem *map = createMapItem(map_name, i, j); + group->appendRow(map); + mapListIndexes.insert(map_name, map->index()); + } + } + break; + case MapSortOrder::Name: + { + QMap mapsecToGroupNum; + for (int i = 0; i < project->regionMapSections->length(); i++) { + QString mapsec_name = project->regionMapSections->value(i); + QStandardItem *mapsec = new QStandardItem; + mapsec->setText(mapsec_name); + mapsec->setIcon(folderIcon); + mapsec->setEditable(false); + mapsec->setData(mapsec_name, Qt::UserRole); + mapsec->setData("map_sec", MapListUserRoles::TypeRole); + mapsec->setData(i, MapListUserRoles::GroupRole); + root->appendRow(mapsec); + mapGroupItemsList->append(mapsec); + mapsecToGroupNum.insert(mapsec_name, i); + } + for (int i = 0; i < project->groupNames->length(); i++) { + QStringList names = project->groupedMapNames.value(i); + for (int j = 0; j < names.length(); j++) { + QString map_name = names.value(j); + QStandardItem *map = createMapItem(map_name, i, j); + QString location = project->readMapLocation(map_name); + QStandardItem *mapsecItem = mapGroupItemsList->at(mapsecToGroupNum[location]); + mapsecItem->setIcon(mapFolderIcon); + mapsecItem->appendRow(map); + mapListIndexes.insert(map_name, map->index()); + } + } + break; + } + case MapSortOrder::Layout: + { + for (int i = 0; i < project->mapLayoutsTable.length(); i++) { + QString layoutName = project->mapLayoutsTable.value(i); + QStandardItem *layout = new QStandardItem; + layout->setText(layoutName); + layout->setIcon(folderIcon); + layout->setEditable(false); + layout->setData(layoutName, Qt::UserRole); + layout->setData("map_layout", MapListUserRoles::TypeRole); + layout->setData(i, MapListUserRoles::GroupRole); + root->appendRow(layout); + mapGroupItemsList->append(layout); + } + for (int i = 0; i < project->groupNames->length(); i++) { + QStringList names = project->groupedMapNames.value(i); + for (int j = 0; j < names.length(); j++) { + QString map_name = names.value(j); + QStandardItem *map = createMapItem(map_name, i, j); + QString layoutId = project->readMapLayoutId(map_name); + QStandardItem *layoutItem = mapGroupItemsList->at(layoutId.toInt() - 1); + layoutItem->setIcon(mapFolderIcon); + layoutItem->appendRow(map); + mapListIndexes.insert(map_name, map->index()); + } + } + break; } } @@ -463,7 +605,6 @@ void MainWindow::populateMapList() { connect(ui->mapList, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onOpenMapListContextMenu(const QPoint &))); - ui->mapList->setModel(mapListModel); ui->mapList->setUpdatesEnabled(true); ui->mapList->expandToDepth(0); ui->mapList->repaint(); @@ -481,7 +622,7 @@ QStandardItem* MainWindow::createMapItem(QString mapName, int groupNum, int inGr void MainWindow::onOpenMapListContextMenu(const QPoint &point) { - QModelIndex index = ui->mapList->indexAt(point); + QModelIndex index = mapListProxyModel->mapToSource(ui->mapList->indexAt(point)); if (!index.isValid()) { return; } @@ -507,7 +648,7 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) void MainWindow::onAddNewMapToGroupClick(QAction* triggeredAction) { int groupNum = triggeredAction->data().toInt(); - QStandardItem* groupItem = mapGroupsModel->at(groupNum); + QStandardItem* groupItem = mapGroupItemsList->at(groupNum); QString newMapName = editor->project->getNewMapName(); Map* newMap = editor->project->addNewMapToGroup(newMapName, groupNum); diff --git a/src/project.cpp b/src/project.cpp index f1168123..7b298d5c 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -189,6 +189,36 @@ void Project::readMapHeader(Map* map) { map->battle_scene = header->value(12); } +QString Project::readMapLayoutId(QString map_name) { + if (map_cache->contains(map_name)) { + return map_cache->value(map_name)->layout_id; + } + + ParseUtil *parser = new ParseUtil; + + QString header_text = readTextFile(root + "/data/maps/" + map_name + "/header.inc"); + if (header_text.isNull()) { + return QString::null; + } + QStringList *header = getLabelValues(parser->parseAsm(header_text), map_name); + return header->value(5); +} + +QString Project::readMapLocation(QString map_name) { + if (map_cache->contains(map_name)) { + return map_cache->value(map_name)->location; + } + + ParseUtil *parser = new ParseUtil; + + QString header_text = readTextFile(root + "/data/maps/" + map_name + "/header.inc"); + if (header_text.isNull()) { + return QString::null; + } + QStringList *header = getLabelValues(parser->parseAsm(header_text), map_name); + return header->value(6); +} + void Project::setNewMapHeader(Map* map, int mapIndex) { map->layout_label = QString("%1_Layout").arg(map->name); map->events_label = QString("%1_MapEvents").arg(map->name);; From 8a7a4c1e8efb24a6be5ca9042af5d57e520405a4 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Fri, 5 Oct 2018 11:23:40 -0500 Subject: [PATCH 4/5] Change filter clearing logic --- src/mainwindow.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3d7579b0..8ffbeb48 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -263,16 +263,19 @@ void MainWindow::setMap(QString map_name, bool scrollTreeView) { if (editor->map != nullptr && !editor->map->name.isNull()) { ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(editor->map->name)), false); } - ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(map_name)), true); editor->setMap(map_name); redrawMapScene(); displayMapProperties(); if (scrollTreeView) { + // Make sure we clear the filter first so we actually have a scroll target + mapListProxyModel->setFilterRegExp(QString::null); ui->mapList->setCurrentIndex(mapListProxyModel->mapFromSource(mapListIndexes.value(map_name))); ui->mapList->scrollTo(ui->mapList->currentIndex(), QAbstractItemView::PositionAtCenter); } + ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(map_name)), true); + setWindowTitle(map_name + " - " + editor->project->getProjectTitle()); connect(editor->map, SIGNAL(mapChanged(Map*)), this, SLOT(onMapChanged(Map *))); @@ -338,7 +341,6 @@ void MainWindow::openWarpMap(QString map_name, QString warp_num) { } // Open the destination map, and select the target warp event. - mapListProxyModel->setFilterRegExp(QString::null); setMap(map_name, true); QList warp_events = editor->map->events["warp_event_group"]; if (warp_events.length() > warpNum) { From 7a6354cc0acd862967107f5da25e027e586df41d Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Fri, 5 Oct 2018 13:26:25 -0500 Subject: [PATCH 5/5] Redo metatile count fix --- src/project.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/project.cpp b/src/project.cpp index 7b298d5c..9ee2acab 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -991,9 +991,9 @@ void Project::loadTilesetMetatiles(Tileset* tileset) { int num_metatiles = tileset->metatiles->count(); int num_metatileAttrs = data.length() / 2; if (num_metatiles != num_metatileAttrs) { - qDebug() << QString("Metatile count %1 does not match metatile attribute count %2").arg(num_metatiles).arg(num_metatileAttrs); - if (num_metatiles > num_metatileAttrs) - num_metatiles = num_metatileAttrs; + qDebug() << QString("Metatile count %1 does not match metatile attribute count %2 in %3").arg(num_metatiles).arg(num_metatileAttrs).arg(tileset->name); + if (num_metatileAttrs > num_metatiles) + num_metatileAttrs = num_metatiles; } for (int i = 0; i < num_metatileAttrs; i++) { int value = (static_cast(data.at(i * 2 + 1)) << 8) | static_cast(data.at(i * 2));