diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index 9ecc927f..fe6a0ca2 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -154,7 +154,7 @@ - + 0 @@ -289,7 +289,7 @@ - + 0 @@ -424,7 +424,7 @@ - + 0 @@ -3607,6 +3607,11 @@ QWidget
mapview.h
+ + MapTree + QTreeView +
maplistmodels.h
+
diff --git a/include/ui/eventfilters.h b/include/ui/eventfilters.h new file mode 100644 index 00000000..984ce23a --- /dev/null +++ b/include/ui/eventfilters.h @@ -0,0 +1,12 @@ +#include +#include + + + +class WheelFilter : public QObject { + Q_OBJECT +public: + WheelFilter(QObject *parent) : QObject(parent) {} + virtual ~WheelFilter() {} + bool eventFilter(QObject *obj, QEvent *event) override; +}; diff --git a/include/ui/maplistmodels.h b/include/ui/maplistmodels.h index 2465cc29..6a5c1e92 100644 --- a/include/ui/maplistmodels.h +++ b/include/ui/maplistmodels.h @@ -2,6 +2,8 @@ #ifndef MAPLISTMODELS_H #define MAPLISTMODELS_H +#include +#include #include #include @@ -17,6 +19,20 @@ enum MapListRoles { +class MapTree : public QTreeView { + Q_OBJECT +public: + MapTree(QWidget *parent) : QTreeView(parent) { + this->setDropIndicatorShown(true); + this->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); + } + +public slots: + void removeSelected(); +}; + + + class MapGroupModel : public QStandardItemModel { Q_OBJECT @@ -26,11 +42,16 @@ public: QVariant data(const QModelIndex &index, int role) const override; + Qt::DropActions supportedDropActions() const override; + QStringList mimeTypes() const override; + virtual QMimeData *mimeData(const QModelIndexList &indexes) const override; + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; + public: void setMap(QString mapName) { this->openMap = mapName; } QStandardItem *createGroupItem(QString groupName, int groupIndex); - QStandardItem *createMapItem(QString mapName, int groupIndex, int mapIndex); + QStandardItem *createMapItem(QString mapName, QStandardItem *fromItem = nullptr); QStandardItem *insertMapItem(QString mapName, QString groupName); @@ -39,6 +60,9 @@ public: void initialize(); +private: + void updateProject(); + private: Project *project; QStandardItem *root = nullptr; @@ -50,7 +74,7 @@ private: QString openMap; signals: - void edited(); + void dragMoveCompleted(); }; diff --git a/include/ui/montabwidget.h b/include/ui/montabwidget.h index 4b66969c..6d916068 100644 --- a/include/ui/montabwidget.h +++ b/include/ui/montabwidget.h @@ -32,8 +32,6 @@ public slots: void deactivateTab(int tabIndex); private: - bool eventFilter(QObject *object, QEvent *event); - void actionCopyTab(int index); void actionAddDeleteTab(int index); diff --git a/porymap.pro b/porymap.pro index a6df6224..04fc6e00 100644 --- a/porymap.pro +++ b/porymap.pro @@ -57,6 +57,7 @@ SOURCES += src/core/block.cpp \ src/ui/cursortilerect.cpp \ src/ui/customattributestable.cpp \ src/ui/eventframes.cpp \ + src/ui/eventfilters.cpp \ src/ui/filterchildrenproxymodel.cpp \ src/ui/maplistmodels.cpp \ src/ui/graphicsview.cpp \ @@ -147,6 +148,7 @@ HEADERS += include/core/block.h \ include/ui/cursortilerect.h \ include/ui/customattributestable.h \ include/ui/eventframes.h \ + include/ui/eventfilters.h \ include/ui/filterchildrenproxymodel.h \ include/ui/maplistmodels.h \ include/ui/graphicsview.h \ diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 18b7d9b9..6445d010 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -20,6 +20,7 @@ #include "montabwidget.h" #include "imageexport.h" #include "maplistmodels.h" +#include "eventfilters.h" #include #include @@ -212,6 +213,10 @@ void MainWindow::initCustomUI() { ui->mainTabBar->setTabIcon(3, QIcon(QStringLiteral(":/icons/connections.ico"))); ui->mainTabBar->addTab("Wild Pokemon"); ui->mainTabBar->setTabIcon(4, QIcon(QStringLiteral(":/icons/tall_grass.ico"))); + + WheelFilter *wheelFilter = new WheelFilter(this); + ui->mainTabBar->installEventFilter(wheelFilter); + this->ui->mapListContainer->tabBar()->installEventFilter(wheelFilter); } void MainWindow::initExtraSignals() { @@ -1110,6 +1115,16 @@ bool MainWindow::populateMapList() { groupListProxyModel->setSourceModel(this->mapGroupModel); ui->mapList->setModel(groupListProxyModel); + // + // connect(this->mapGroupModel, &QStandardItemModel::dataChanged, [=](const QModelIndex &, const QModelIndex &, const QList &){ + // qDebug() << "mapGroupModel dataChanged"; + // }); + + // connect(this->mapGroupModel, &MapGroupModel::edited, [=, this](){ + // qDebug() << "model edited with" << this->ui->mapList->selectionModel()->selection().size() << "items"; + // }); removeSelected + connect(this->mapGroupModel, &MapGroupModel::dragMoveCompleted, this->ui->mapList, &MapTree::removeSelected); + this->mapAreaModel = new MapAreaModel(editor->project); this->areaListProxyModel = new FilterChildrenProxyModel(); areaListProxyModel->setSourceModel(this->mapAreaModel); @@ -1121,10 +1136,11 @@ bool MainWindow::populateMapList() { ui->layoutList->setModel(layoutListProxyModel); /// !TODO - // ui->mapList->setSelectionMode(QAbstractItemView::ExtendedSelection); - // ui->mapList->setDragEnabled(true); - // ui->mapList->setAcceptDrops(true); - // ui->mapList->setDropIndicatorShown(true); + ui->mapList->setSelectionMode(QAbstractItemView::ExtendedSelection); + ui->mapList->setDragEnabled(true); + ui->mapList->setAcceptDrops(true); + ui->mapList->setDropIndicatorShown(true); + ui->mapList->setDragDropMode(QAbstractItemView::InternalMove); return success; } @@ -1244,19 +1260,11 @@ void MainWindow::onNewMapCreated() { editor->project->saveMap(newMap); editor->project->saveAllDataStructures(); - // !TODO - // QStandardItem* groupItem = mapGroupItemsList->at(newMapGroup); - // int numMapsInGroup = groupItem->rowCount(); - + // Add new Map / Layout to the mapList models this->mapGroupModel->insertMapItem(newMapName, editor->project->groupNames[newMapGroup]); this->mapAreaModel->insertMapItem(newMapName, newMap->location, newMapGroup); this->layoutTreeModel->insertMapItem(newMapName, newMap->layout->id); - // QStandardItem *newMapItem = createMapItem(newMapName, newMapGroup, numMapsInGroup); - // groupItem->appendRow(newMapItem); - // mapListIndexes.insert(newMapName, newMapItem->index()); - - // sortMapList(); setMap(newMapName, true); if (newMap->needsHealLocation) { @@ -1512,11 +1520,18 @@ void MainWindow::updateMapList() { mapAreaModel->setMap(this->editor->map->name); areaListProxyModel->layoutChanged(); } + else { + // !TODO + qDebug() << "need to clear map list"; + } if (this->editor->layout) { layoutTreeModel->setLayout(this->editor->layout->id); layoutListProxyModel->layoutChanged(); } + else { + qDebug() << "need to clear layout list"; + } } void MainWindow::on_action_Save_Project_triggered() { diff --git a/src/ui/eventfilters.cpp b/src/ui/eventfilters.cpp new file mode 100644 index 00000000..24f2e0bd --- /dev/null +++ b/src/ui/eventfilters.cpp @@ -0,0 +1,10 @@ +#include "eventfilters.h" + + + +bool WheelFilter::eventFilter(QObject *, QEvent *event) { + if (event->type() == QEvent::Wheel) { + return true; + } + return false; +} diff --git a/src/ui/maplistmodels.cpp b/src/ui/maplistmodels.cpp index 71c4caf1..dd0b254d 100644 --- a/src/ui/maplistmodels.cpp +++ b/src/ui/maplistmodels.cpp @@ -1,6 +1,18 @@ #include "maplistmodels.h" +#include + #include "project.h" +#include "filterchildrenproxymodel.h" + + + +void MapTree::removeSelected() { + while (!this->selectedIndexes().isEmpty()) { + QModelIndex i = this->selectedIndexes().takeLast(); + this->model()->removeRow(i.row(), i.parent()); + } +} @@ -11,6 +23,122 @@ MapGroupModel::MapGroupModel(Project *project, QObject *parent) : QStandardItemM initialize(); } +Qt::DropActions MapGroupModel::supportedDropActions() const { + return Qt::MoveAction; +} + +QStringList MapGroupModel::mimeTypes() const { + QStringList types; + types << "application/porymap.mapgroupmodel.map" + << "application/porymap.mapgroupmodel.group"; + return types; +} + +QMimeData *MapGroupModel::mimeData(const QModelIndexList &indexes) const { + QMimeData *mimeData = QStandardItemModel::mimeData(indexes); + QByteArray encodedData; + + QDataStream stream(&encodedData, QIODevice::WriteOnly); + + for (const QModelIndex &index : indexes) { + if (index.isValid()) { + QString mapName = data(index, Qt::UserRole).toString(); + stream << mapName; + } + } + + mimeData->setData("application/porymap.mapgroupmodel.map", encodedData); + return mimeData; +} + +bool MapGroupModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parentIndex) { + if (action == Qt::IgnoreAction) + return true; + + if (!data->hasFormat("application/porymap.mapgroupmodel.map")) + return false; + + if (!parentIndex.isValid()) + return false; + + int firstRow = 0; + + if (row != -1) { + firstRow = row; + } + else if (parentIndex.isValid()) { + firstRow = rowCount(parentIndex); + } + + QByteArray encodedData = data->data("application/porymap.mapgroupmodel.map"); + QDataStream stream(&encodedData, QIODevice::ReadOnly); + QStringList droppedMaps; + int rowCount = 0; + + QList newItems; + + while (!stream.atEnd()) { + QString mapName; + stream >> mapName; + droppedMaps << mapName; + rowCount++; + } + + this->insertRows(firstRow, rowCount, parentIndex); + + int newItemIndex = 0; + for (QString mapName : droppedMaps) { + QModelIndex mapIndex = index(firstRow, 0, parentIndex); + QStandardItem *mapItem = this->itemFromIndex(mapIndex); + createMapItem(mapName, mapItem); + firstRow++; + } + + // updateProject(); + + emit dragMoveCompleted(); + + return false; +} + + +/* + QStringList groupNames; + QMap mapGroups; + QList groupedMapNames; + QStringList mapNames; +*/ +void MapGroupModel::updateProject() { + // + QStringList groups; + int numGroups = this->root->rowCount(); + qDebug() << "group count:" << numGroups; + + for (int g = 0; g < this->root->rowCount(); g++) { + QStandardItem *groupItem = this->item(g); + qDebug() << g << "group item" << groupItem->text(); //data(Qt::UserRole).toString(); + for (int m = 0; m < groupItem->rowCount(); m++) { + // + QStandardItem *mapItem = groupItem->child(m); + qDebug() << " " << m << "map item" << mapItem->data(Qt::UserRole).toString(); + } + } + + QList maps; + for (auto mapName : this->mapItems.keys()) { + // + QStandardItem *mapItem = this->mapItems[mapName]; + QStandardItem *groupItem = mapItem->parent(); + if (!groupItem) { + qDebug() << "FAIL: no parent" << mapName; + continue; + } + auto mapIndex = this->indexFromItem(mapItem).row(); + auto groupIndex = this->indexFromItem(groupItem).row(); + // qDebug().nospace() << "map: " << mapName << "[" << parentIndex.row() << "." << mapIndex.row() << "]"; + } +} + QStandardItem *MapGroupModel::createGroupItem(QString groupName, int groupIndex) { QStandardItem *group = new QStandardItem; group->setText(groupName); @@ -18,31 +146,30 @@ QStandardItem *MapGroupModel::createGroupItem(QString groupName, int groupIndex) group->setData(groupName, Qt::UserRole); group->setData("map_group", MapListRoles::TypeRole); group->setData(groupIndex, MapListRoles::GroupRole); - // group->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); + group->setFlags(Qt::ItemIsEditable | /* Qt::ItemIsSelectable | */ Qt::ItemIsEnabled | /* Qt::ItemIsDragEnabled | */ Qt::ItemIsDropEnabled); this->groupItems.insert(groupName, group); return group; } -QStandardItem *MapGroupModel::createMapItem(QString mapName, int groupIndex, int mapIndex) { - QStandardItem *map = new QStandardItem; - map->setText(QString("[%1.%2] ").arg(groupIndex).arg(mapIndex, 2, 10, QLatin1Char('0')) + mapName); +QStandardItem *MapGroupModel::createMapItem(QString mapName, QStandardItem *map) { + if (!map) map = new QStandardItem; map->setEditable(false); map->setData(mapName, Qt::UserRole); map->setData("map_name", MapListRoles::TypeRole); - map->setData(groupIndex, MapListRoles::GroupRole); - // map->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); - this->mapItems.insert(mapName, map); + // map->setData(groupIndex, MapListRoles::GroupRole); + map->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); + this->mapItems[mapName] = map; return map; } QStandardItem *MapGroupModel::insertMapItem(QString mapName, QString groupName) { - int groupIndex = this->project->groupNames.indexOf(groupName); + //int groupIndex = this->project->groupNames.indexOf(groupName); QStandardItem *group = this->groupItems[groupName]; if (!group) { return nullptr; } - int mapIndex = group->rowCount(); - QStandardItem *map = createMapItem(mapName, groupIndex, mapIndex); + //int mapIndex = group->rowCount(); + QStandardItem *map = createMapItem(mapName); group->appendRow(map); return map; } @@ -54,10 +181,12 @@ void MapGroupModel::initialize() { QString group_name = this->project->groupNames.value(i); QStandardItem *group = createGroupItem(group_name, i); root->appendRow(group); + //this->setItem(0, i, group); QStringList names = this->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); + QStandardItem *map = createMapItem(map_name); + //this->setItem(i, j, map); group->appendRow(map); } } @@ -90,10 +219,13 @@ QVariant MapGroupModel::data(const QModelIndex &index, int role) const { static QIcon mapOpenedIcon = QIcon(QStringLiteral(":/icons/map_opened.ico")); static QIcon mapFolderIcon; + static QIcon folderIcon; static bool loaded = false; if (!loaded) { mapFolderIcon.addFile(QStringLiteral(":/icons/folder_closed_map.ico"), QSize(), QIcon::Normal, QIcon::Off); mapFolderIcon.addFile(QStringLiteral(":/icons/folder_map.ico"), QSize(), QIcon::Normal, QIcon::On); + folderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off); + folderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On); loaded = true; } @@ -101,6 +233,9 @@ QVariant MapGroupModel::data(const QModelIndex &index, int role) const { QString type = item->data(MapListRoles::TypeRole).toString(); if (type == "map_group") { + if (!item->hasChildren()) { + return folderIcon; + } return mapFolderIcon; } else if (type == "map_name") { QString mapName = item->data(Qt::UserRole).toString(); @@ -118,6 +253,14 @@ QVariant MapGroupModel::data(const QModelIndex &index, int role) const { return mapGrayIcon; } } + else if (role == Qt::DisplayRole) { + // + QStandardItem *item = this->getItem(index)->child(row, col); + + if (item->data(MapListRoles::TypeRole).toString() == "map_name") { + return QString("[%1.%2] ").arg(this->getItem(index)->row()).arg(row, 2, 10, QLatin1Char('0')) + item->data(Qt::UserRole).toString(); + } + } return QStandardItemModel::data(index, role); } diff --git a/src/ui/montabwidget.cpp b/src/ui/montabwidget.cpp index 6845a02b..e31739bd 100644 --- a/src/ui/montabwidget.cpp +++ b/src/ui/montabwidget.cpp @@ -3,6 +3,7 @@ #include "editor.h" #include "encountertablemodel.h" #include "encountertabledelegates.h" +#include "eventfilters.h" @@ -11,20 +12,13 @@ static WildMonInfo encounterClipboard; MonTabWidget::MonTabWidget(Editor *editor, QWidget *parent) : QTabWidget(parent) { this->editor = editor; populate(); - this->tabBar()->installEventFilter(this); + this->tabBar()->installEventFilter(new WheelFilter(this)); } MonTabWidget::~MonTabWidget() { } -bool MonTabWidget::eventFilter(QObject *, QEvent *event) { - if (event->type() == QEvent::Wheel) { - return true; - } - return false; -} - void MonTabWidget::populate() { EncounterFields fields = editor->project->wildMonFields; activeTabs.resize(fields.size());