feat: drag-and-drop support for explorer
This commit is contained in:
parent
f316b26a83
commit
10999be3b6
16
.vscode/launch.json
vendored
Normal file
16
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug",
|
||||
"program": "${workspaceFolder}/bin/editor",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
}
|
||||
]
|
||||
}
|
|
@ -5,11 +5,14 @@
|
|||
#include "qimage.h"
|
||||
#include "qnamespace.h"
|
||||
#include "qobject.h"
|
||||
#include "qstringview.h"
|
||||
#include "qwidget.h"
|
||||
#include "qmimedata.h"
|
||||
#include "common.h"
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include "objects/base/instance.h"
|
||||
|
||||
// https://doc.qt.io/qt-6/qtwidgets-itemviews-simpletreemodel-example.html#testing-the-model
|
||||
|
@ -23,7 +26,7 @@ ExplorerModel::ExplorerModel(InstanceRef dataRoot, QWidget *parent)
|
|||
hierarchyPreUpdateHandler = [&](InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent) {
|
||||
if (oldParent.has_value()) {
|
||||
auto children = oldParent.value()->GetChildren();
|
||||
size_t idx = std::find(children.begin(), children.end(), object) - children.end();
|
||||
size_t idx = std::find(children.begin(), children.end(), object) - children.begin();
|
||||
beginRemoveRows(toIndex(oldParent.value()), idx, idx);
|
||||
}
|
||||
|
||||
|
@ -197,7 +200,50 @@ Qt::DropActions ExplorerModel::supportedDropActions() const {
|
|||
}
|
||||
|
||||
|
||||
InstanceRef ExplorerModel::fromIndex(const QModelIndex index) {
|
||||
InstanceRef ExplorerModel::fromIndex(const QModelIndex index) const {
|
||||
if (!index.isValid()) return workspace;
|
||||
return static_cast<Instance*>(index.internalPointer())->shared_from_this();
|
||||
}
|
||||
|
||||
struct DragDropSlot {
|
||||
std::vector<InstanceRef> instances;
|
||||
};
|
||||
|
||||
bool ExplorerModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) {
|
||||
// if (action != Qt::InternalMove) return;
|
||||
QByteArray byteData = data->data("application/x-openblocks-instance-pointers");
|
||||
uintptr_t slotPtr = byteData.toULongLong();
|
||||
DragDropSlot* slot = (DragDropSlot*)slotPtr;
|
||||
|
||||
if (!parent.isValid()) {
|
||||
delete slot;
|
||||
return true;
|
||||
}
|
||||
|
||||
InstanceRef parentInst = fromIndex(parent);
|
||||
for (InstanceRef instance : slot->instances) {
|
||||
instance->SetParent(parentInst);
|
||||
}
|
||||
|
||||
delete slot;
|
||||
return true;
|
||||
}
|
||||
|
||||
QMimeData* ExplorerModel::mimeData(const QModelIndexList& indexes) const {
|
||||
// application/x-openblocks-instance-pointers
|
||||
DragDropSlot* slot = new DragDropSlot();
|
||||
|
||||
for (const QModelIndex& index : indexes) {
|
||||
slot->instances.push_back(fromIndex(index));
|
||||
}
|
||||
|
||||
// uintptr_t ptr = (uintptr_t)&slot;
|
||||
|
||||
QMimeData* mimeData = new QMimeData();
|
||||
mimeData->setData("application/x-openblocks-instance-pointers", QByteArray::number((qulonglong)slot));
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
QStringList ExplorerModel::mimeTypes() const {
|
||||
return QStringList("application/x-openblocks-instance-pointers");
|
||||
}
|
|
@ -35,9 +35,12 @@ public:
|
|||
bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
|
||||
bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()) override;
|
||||
bool insertRows(int row, int count, const QModelIndex & parent = QModelIndex()) override;
|
||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||
QMimeData* mimeData(const QModelIndexList& indexes) const override;
|
||||
QStringList mimeTypes() const override;
|
||||
Qt::DropActions supportedDragActions() const override;
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
InstanceRef fromIndex(const QModelIndex index);
|
||||
InstanceRef fromIndex(const QModelIndex index) const;
|
||||
private:
|
||||
InstanceRef rootItem;
|
||||
QModelIndex toIndex(InstanceRef item);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "explorerview.h"
|
||||
#include "explorermodel.h"
|
||||
#include "common.h"
|
||||
#include "qabstractitemmodel.h"
|
||||
#include "qaction.h"
|
||||
#include "qnamespace.h"
|
||||
|
||||
|
@ -9,7 +10,11 @@ ExplorerView::ExplorerView(QWidget* parent):
|
|||
model(ExplorerModel(std::dynamic_pointer_cast<Instance>(workspace))) {
|
||||
|
||||
this->setModel(&model);
|
||||
this->setRootIsDecorated(false);
|
||||
// Disabling the root decoration will cause the expand/collapse chevrons to be hidden too, we don't want that
|
||||
// https://stackoverflow.com/a/4687016/16255372
|
||||
// this->setRootIsDecorated(false);
|
||||
// The branches can be customized like this if you want:
|
||||
// this->setStyleSheet(QString("QTreeView::branch { border: none; }"));
|
||||
this->setDragDropMode(QAbstractItemView::InternalMove);
|
||||
this->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
this->setDragEnabled(true);
|
||||
|
|
|
@ -17,7 +17,9 @@ class ExplorerView : public QTreeView {
|
|||
public:
|
||||
ExplorerView(QWidget* parent = nullptr);
|
||||
~ExplorerView() override;
|
||||
void keyPressEvent(QKeyEvent* evt) override;
|
||||
|
||||
void keyPressEvent(QKeyEvent*) override;
|
||||
// void dropEvent(QDropEvent*) override;
|
||||
private:
|
||||
ExplorerModel model;
|
||||
QMenu contextMenu;
|
||||
|
|
Loading…
Reference in a new issue