diff --git a/editor/explorermodel.cpp b/editor/explorermodel.cpp index 00ca0fc..b620e0b 100644 --- a/editor/explorermodel.cpp +++ b/editor/explorermodel.cpp @@ -1,5 +1,6 @@ #include "explorermodel.h" #include "objects/base/instance.h" +#include "qabstractitemmodel.h" #include "qcontainerfwd.h" #include "qicon.h" #include "qimage.h" @@ -8,6 +9,8 @@ #include "qwidget.h" #include "common.h" #include +#include +#include #include #include "objects/base/instance.h" @@ -116,6 +119,14 @@ QVariant ExplorerModel::data(const QModelIndex &index, int role) const { return {}; } +bool ExplorerModel::setData(const QModelIndex &index, const QVariant &value, int role) { + if (!index.isValid() || role != Qt::EditRole) return false; + + Instance* inst = static_cast(index.internalPointer()); + inst->name = value.toString().toStdString(); + return true; +} + QVariant ExplorerModel::headerData(int section, Qt::Orientation orientation, int role) const { @@ -124,8 +135,11 @@ QVariant ExplorerModel::headerData(int section, Qt::Orientation orientation, Qt::ItemFlags ExplorerModel::flags(const QModelIndex &index) const { + //return index.isValid() + // ? QAbstractItemModel::flags(index) : Qt::ItemFlags(Qt::NoItemFlags); return index.isValid() - ? QAbstractItemModel::flags(index) : Qt::ItemFlags(Qt::NoItemFlags); + ? QAbstractItemModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled + : Qt::NoItemFlags | Qt::ItemIsDropEnabled; } QImage ExplorerModel::iconOf(InstanceType* type) const { @@ -137,4 +151,55 @@ QImage ExplorerModel::iconOf(InstanceType* type) const { QImage icon("assets/icons/" + QString::fromStdString(currentClass->explorerIcon)); instanceIconCache[type->className] = icon; return icon; +} + +bool ExplorerModel::moveRows(const QModelIndex &sourceParentIdx, int sourceRow, int count, const QModelIndex &destinationParentIdx, int destinationChild) { + Instance* sourceParent = sourceParentIdx.isValid() ? static_cast(sourceParentIdx.internalPointer()) : workspace.get(); + Instance* destinationParent = destinationParentIdx.isValid() ? static_cast(destinationParentIdx.internalPointer()) : workspace.get(); + + printf("Moved %d from %s\n", count, sourceParent->name.c_str()); + + if ((sourceRow + count) >= sourceParent->GetChildren().size()) { + fprintf(stderr, "Attempt to move rows %d-%d from %s (%s) while it only has %d children.\n", sourceRow, sourceRow + count, sourceParent->name.c_str(), sourceParent->GetClass()->className.c_str(), sourceParent->GetChildren().size()); + return false; + } + + for (int i = sourceRow; i < (sourceRow + count); i++) { + sourceParent->GetChildren()[i]->SetParent(destinationParent->shared_from_this()); + } + + return true; +} + +bool ExplorerModel::removeRows(int row, int count, const QModelIndex& parentIdx) { + Instance* parent = parentIdx.isValid() ? static_cast(parentIdx.internalPointer()) : workspace.get(); + + for (int i = row; i < (row + count); i++) { + //parent->GetChildren()[i]->SetParent(nullptr); + } + + return true; +} + +bool ExplorerModel::insertRows(int row, int count, const QModelIndex & parentIdx) { + //Instance* parent = parentIdx.isValid() ? static_cast(parentIdx.internalPointer()) : workspace.get(); + //beginInsertRows(parentIdx, parent->GetChildren().size(), parent->GetChildren().size() + count); + //for () + //endInsertRows(); + //return true; + return false; +} + +Qt::DropActions ExplorerModel::supportedDragActions() const { + return Qt::DropAction::MoveAction; +} + +Qt::DropActions ExplorerModel::supportedDropActions() const { + return Qt::DropAction::MoveAction; +} + + +InstanceRef ExplorerModel::fromIndex(const QModelIndex index) { + if (!index.isValid()) return workspace; + return static_cast(index.internalPointer())->shared_from_this(); } \ No newline at end of file diff --git a/editor/explorermodel.h b/editor/explorermodel.h index 6317625..6f057de 100644 --- a/editor/explorermodel.h +++ b/editor/explorermodel.h @@ -5,6 +5,7 @@ #include "objects/part.h" #include "qabstractitemmodel.h" #include "qevent.h" +#include "qnamespace.h" #include #include #include @@ -18,6 +19,7 @@ public: ~ExplorerModel() override; QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; Qt::ItemFlags flags(const QModelIndex &index) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; @@ -26,7 +28,12 @@ public: QModelIndex parent(const QModelIndex &index) const override; int rowCount(const QModelIndex &parent = {}) const override; int columnCount(const QModelIndex &parent = {}) const override; - + 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; + Qt::DropActions supportedDragActions() const override; + Qt::DropActions supportedDropActions() const override; + InstanceRef fromIndex(const QModelIndex index); private: InstanceRef rootItem; QModelIndex toIndex(InstanceRef item); diff --git a/editor/mainwindow.cpp b/editor/mainwindow.cpp index 22f2cee..37c7526 100644 --- a/editor/mainwindow.cpp +++ b/editor/mainwindow.cpp @@ -11,24 +11,63 @@ #include #include #include +#include #include "common.h" #include "physics/simulation.h" #include "objects/part.h" #include "explorermodel.h" -#include "wayland-pointer-constraints-unstable-v1-client-protocol.h" +#include "qabstractitemview.h" +#include "qevent.h" +#include "qnamespace.h" +#include "qobject.h" + +class ExplorerEventFilter : public QObject { + +private: + QTreeView* explorerView; + ExplorerModel* model; + + bool keyPress(QObject* object, QKeyEvent *event) { + switch (event->key()) { + case Qt::Key_Delete: + QModelIndexList selectedIndexes = explorerView->selectionModel()->selectedIndexes(); + for (QModelIndex index : selectedIndexes) { + model->fromIndex(index)->SetParent(std::nullopt); + } + break; + } + + return QObject::eventFilter(object, event); + } + + bool eventFilter(QObject *object, QEvent *event) { + if (event->type() == QEvent::KeyPress) + return keyPress(object, dynamic_cast(event)); + return QObject::eventFilter(object, event); + } +public: + ExplorerEventFilter(QTreeView* explorerView, ExplorerModel* model): explorerView(explorerView), model(model) {} +}; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) + , explorerModel(ExplorerModel(std::dynamic_pointer_cast(workspace))) { ui->setupUi(this); timer.start(33, this); setMouseTracking(true); - ui->explorerView->setModel(new ExplorerModel(std::dynamic_pointer_cast(workspace))); + ui->explorerView->setModel(&explorerModel); ui->explorerView->setRootIsDecorated(false); + ui->explorerView->setDragDropMode(QAbstractItemView::InternalMove); + ui->explorerView->setSelectionMode(QAbstractItemView::ExtendedSelection); + ui->explorerView->setDragEnabled(true); + ui->explorerView->setAcceptDrops(true); + ui->explorerView->setDropIndicatorShown(true); + ui->explorerView->installEventFilter(new ExplorerEventFilter(ui->explorerView, &explorerModel)); simulationInit(); @@ -44,6 +83,7 @@ MainWindow::MainWindow(QWidget *parent) }, .anchored = true, })); + ui->mainWidget->lastPart->name = "Baseplate"; syncPartPhysics(ui->mainWidget->lastPart); workspace->AddChild(ui->mainWidget->lastPart = Part::New({ diff --git a/editor/mainwindow.h b/editor/mainwindow.h index 62f881a..79695b4 100644 --- a/editor/mainwindow.h +++ b/editor/mainwindow.h @@ -1,6 +1,7 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +#include "explorermodel.h" #include "qbasictimer.h" #include "qcoreevent.h" #include @@ -21,6 +22,7 @@ public: ~MainWindow(); private: + ExplorerModel explorerModel; Ui::MainWindow *ui; QBasicTimer timer; diff --git a/run.sh b/run.sh index c7a5653..60ceda8 100755 --- a/run.sh +++ b/run.sh @@ -1 +1,7 @@ -cmake . && cmake --build . && ./bin/$1 +[ "$2" = "-debug" ] && CMAKE_OPTS=-DCMAKE_BUILD_TYPE=Debug +[ "$2" = "-release" ] && CMAKE_OPTS=-DCMAKE_BUILD_TYPE=Release +[ "$2" = "-reldbg" ] && CMAKE_OPTS=-DCMAKE_BUILD_TYPE=RelWithDebInfo + +[ "$3" = "-gdb" ] && PRE_COMMAND="gdb -ex run " + +cmake $CMAKE_OPTS . && cmake --build . && $PRE_COMMAND ./bin/$1