add drag-drop reordering for maps in groups
This commit is contained in:
parent
a14e70ef53
commit
0ec8f4fee5
9 changed files with 242 additions and 39 deletions
|
@ -154,7 +154,7 @@
|
|||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="mapList">
|
||||
<widget class="MapTree" name="mapList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
|
@ -289,7 +289,7 @@
|
|||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="areaList">
|
||||
<widget class="MapTree" name="areaList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
|
@ -424,7 +424,7 @@
|
|||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="layoutList">
|
||||
<widget class="MapTree" name="layoutList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
|
@ -3607,6 +3607,11 @@
|
|||
<extends>QWidget</extends>
|
||||
<header>mapview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>MapTree</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>maplistmodels.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources/images.qrc"/>
|
||||
|
|
12
include/ui/eventfilters.h
Normal file
12
include/ui/eventfilters.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include <QObject>
|
||||
#include <QEvent>
|
||||
|
||||
|
||||
|
||||
class WheelFilter : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
WheelFilter(QObject *parent) : QObject(parent) {}
|
||||
virtual ~WheelFilter() {}
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
};
|
|
@ -2,6 +2,8 @@
|
|||
#ifndef MAPLISTMODELS_H
|
||||
#define MAPLISTMODELS_H
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QFontDatabase>
|
||||
#include <QStandardItemModel>
|
||||
#include <QMap>
|
||||
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "montabwidget.h"
|
||||
#include "imageexport.h"
|
||||
#include "maplistmodels.h"
|
||||
#include "eventfilters.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QClipboard>
|
||||
|
@ -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<int> &){
|
||||
// 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() {
|
||||
|
|
10
src/ui/eventfilters.cpp
Normal file
10
src/ui/eventfilters.cpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "eventfilters.h"
|
||||
|
||||
|
||||
|
||||
bool WheelFilter::eventFilter(QObject *, QEvent *event) {
|
||||
if (event->type() == QEvent::Wheel) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -1,6 +1,18 @@
|
|||
#include "maplistmodels.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
#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<QStandardItem *> 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<QString, int> mapGroups;
|
||||
QList<QStringList> 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<QStringList> 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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue