feat: More interactive explorer
This commit is contained in:
parent
4ebf8002a5
commit
6931aa5b7e
|
@ -1,5 +1,6 @@
|
||||||
#include "explorermodel.h"
|
#include "explorermodel.h"
|
||||||
#include "objects/base/instance.h"
|
#include "objects/base/instance.h"
|
||||||
|
#include "qabstractitemmodel.h"
|
||||||
#include "qcontainerfwd.h"
|
#include "qcontainerfwd.h"
|
||||||
#include "qicon.h"
|
#include "qicon.h"
|
||||||
#include "qimage.h"
|
#include "qimage.h"
|
||||||
|
@ -8,6 +9,8 @@
|
||||||
#include "qwidget.h"
|
#include "qwidget.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "objects/base/instance.h"
|
#include "objects/base/instance.h"
|
||||||
|
|
||||||
|
@ -116,6 +119,14 @@ QVariant ExplorerModel::data(const QModelIndex &index, int role) const {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ExplorerModel::setData(const QModelIndex &index, const QVariant &value, int role) {
|
||||||
|
if (!index.isValid() || role != Qt::EditRole) return false;
|
||||||
|
|
||||||
|
Instance* inst = static_cast<Instance*>(index.internalPointer());
|
||||||
|
inst->name = value.toString().toStdString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QVariant ExplorerModel::headerData(int section, Qt::Orientation orientation,
|
QVariant ExplorerModel::headerData(int section, Qt::Orientation orientation,
|
||||||
int role) const
|
int role) const
|
||||||
{
|
{
|
||||||
|
@ -124,8 +135,11 @@ QVariant ExplorerModel::headerData(int section, Qt::Orientation orientation,
|
||||||
|
|
||||||
Qt::ItemFlags ExplorerModel::flags(const QModelIndex &index) const
|
Qt::ItemFlags ExplorerModel::flags(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
|
//return index.isValid()
|
||||||
|
// ? QAbstractItemModel::flags(index) : Qt::ItemFlags(Qt::NoItemFlags);
|
||||||
return index.isValid()
|
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 {
|
QImage ExplorerModel::iconOf(InstanceType* type) const {
|
||||||
|
@ -137,4 +151,55 @@ QImage ExplorerModel::iconOf(InstanceType* type) const {
|
||||||
QImage icon("assets/icons/" + QString::fromStdString(currentClass->explorerIcon));
|
QImage icon("assets/icons/" + QString::fromStdString(currentClass->explorerIcon));
|
||||||
instanceIconCache[type->className] = icon;
|
instanceIconCache[type->className] = icon;
|
||||||
return icon;
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExplorerModel::moveRows(const QModelIndex &sourceParentIdx, int sourceRow, int count, const QModelIndex &destinationParentIdx, int destinationChild) {
|
||||||
|
Instance* sourceParent = sourceParentIdx.isValid() ? static_cast<Instance*>(sourceParentIdx.internalPointer()) : workspace.get();
|
||||||
|
Instance* destinationParent = destinationParentIdx.isValid() ? static_cast<Instance*>(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<Instance*>(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<Instance*>(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<Instance*>(index.internalPointer())->shared_from_this();
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
#include "objects/part.h"
|
#include "objects/part.h"
|
||||||
#include "qabstractitemmodel.h"
|
#include "qabstractitemmodel.h"
|
||||||
#include "qevent.h"
|
#include "qevent.h"
|
||||||
|
#include "qnamespace.h"
|
||||||
#include <QOpenGLWidget>
|
#include <QOpenGLWidget>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -18,6 +19,7 @@ public:
|
||||||
~ExplorerModel() override;
|
~ExplorerModel() override;
|
||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role) const 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;
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
QVariant headerData(int section, Qt::Orientation orientation,
|
QVariant headerData(int section, Qt::Orientation orientation,
|
||||||
int role = Qt::DisplayRole) const override;
|
int role = Qt::DisplayRole) const override;
|
||||||
|
@ -26,7 +28,12 @@ public:
|
||||||
QModelIndex parent(const QModelIndex &index) const override;
|
QModelIndex parent(const QModelIndex &index) const override;
|
||||||
int rowCount(const QModelIndex &parent = {}) const override;
|
int rowCount(const QModelIndex &parent = {}) const override;
|
||||||
int columnCount(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:
|
private:
|
||||||
InstanceRef rootItem;
|
InstanceRef rootItem;
|
||||||
QModelIndex toIndex(InstanceRef item);
|
QModelIndex toIndex(InstanceRef item);
|
||||||
|
|
|
@ -11,24 +11,63 @@
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
#include <QAbstractItemView>
|
#include <QAbstractItemView>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "physics/simulation.h"
|
#include "physics/simulation.h"
|
||||||
#include "objects/part.h"
|
#include "objects/part.h"
|
||||||
#include "explorermodel.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<QKeyEvent*>(event));
|
||||||
|
return QObject::eventFilter(object, event);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
ExplorerEventFilter(QTreeView* explorerView, ExplorerModel* model): explorerView(explorerView), model(model) {}
|
||||||
|
};
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
, ui(new Ui::MainWindow)
|
, ui(new Ui::MainWindow)
|
||||||
|
, explorerModel(ExplorerModel(std::dynamic_pointer_cast<Instance>(workspace)))
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
timer.start(33, this);
|
timer.start(33, this);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
ui->explorerView->setModel(new ExplorerModel(std::dynamic_pointer_cast<Instance>(workspace)));
|
ui->explorerView->setModel(&explorerModel);
|
||||||
ui->explorerView->setRootIsDecorated(false);
|
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();
|
simulationInit();
|
||||||
|
|
||||||
|
@ -44,6 +83,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
},
|
},
|
||||||
.anchored = true,
|
.anchored = true,
|
||||||
}));
|
}));
|
||||||
|
ui->mainWidget->lastPart->name = "Baseplate";
|
||||||
syncPartPhysics(ui->mainWidget->lastPart);
|
syncPartPhysics(ui->mainWidget->lastPart);
|
||||||
|
|
||||||
workspace->AddChild(ui->mainWidget->lastPart = Part::New({
|
workspace->AddChild(ui->mainWidget->lastPart = Part::New({
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef MAINWINDOW_H
|
#ifndef MAINWINDOW_H
|
||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include "explorermodel.h"
|
||||||
#include "qbasictimer.h"
|
#include "qbasictimer.h"
|
||||||
#include "qcoreevent.h"
|
#include "qcoreevent.h"
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
@ -21,6 +22,7 @@ public:
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ExplorerModel explorerModel;
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
QBasicTimer timer;
|
QBasicTimer timer;
|
||||||
|
|
||||||
|
|
8
run.sh
8
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
|
||||||
|
|
Loading…
Reference in a new issue