feat: More interactive explorer
This commit is contained in:
		
							parent
							
								
									4ebf8002a5
								
							
						
					
					
						commit
						6931aa5b7e
					
				
					 5 changed files with 125 additions and 5 deletions
				
			
		|  | @ -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 { | ||||||
|  | @ -138,3 +152,54 @@ QImage ExplorerModel::iconOf(InstanceType* type) const { | ||||||
|     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…
	
	Add table
		
		Reference in a new issue