refactor(editor): moved ExplorerView code to its own file

This commit is contained in:
maelstrom 2025-01-23 11:25:07 +01:00
parent 497b24c03f
commit e0eb0ac8bb
8 changed files with 117 additions and 88 deletions

View file

@ -25,8 +25,10 @@ set(PROJECT_SOURCES
mainwindow.ui
mainglwidget.h
mainglwidget.cpp
explorermodel.h
explorermodel.cpp
panes/explorerview.h
panes/explorerview.cpp
panes/explorermodel.h
panes/explorermodel.cpp
${TS_FILES}
)

View file

@ -10,80 +10,21 @@
#include <QWidget>
#include <QTreeView>
#include <QAbstractItemView>
#include <memory>
#include <optional>
#include "common.h"
#include "physics/simulation.h"
#include "objects/part.h"
#include "explorermodel.h"
#include "qabstractitemview.h"
#include "qevent.h"
#include "qnamespace.h"
#include "qobject.h"
#include "qtreeview.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)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, explorerModel(ExplorerModel(std::dynamic_pointer_cast<Instance>(workspace)))
{
ui->setupUi(this);
timer.start(33, this);
setMouseTracking(true);
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));
ui->explorerView->setContextMenuPolicy(Qt::CustomContextMenu);
explorerMenu.addAction(ui->actionDelete);
connect(ui->explorerView, &QTreeView::customContextMenuRequested, this, [&](const QPoint& point) {
QModelIndex index = ui->explorerView->indexAt(point);
explorerMenu.exec(ui->explorerView->viewport()->mapToGlobal(point));
});
connect(ui->actionDelete, &QAction::triggered, this, [&]() {
QModelIndexList selectedIndexes = ui->explorerView->selectionModel()->selectedIndexes();
for (QModelIndex index : selectedIndexes) {
explorerModel.fromIndex(index)->SetParent(std::nullopt);
}
});
// ui->explorerView->Init(ui);
simulationInit();

View file

@ -1,7 +1,7 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "explorermodel.h"
#include "panes/explorerview.h"
#include "qbasictimer.h"
#include "qcoreevent.h"
#include "qmenu.h"
@ -22,10 +22,8 @@ public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
ExplorerModel explorerModel;
QMenu explorerMenu;
Ui::MainWindow *ui;
private:
QBasicTimer timer;
void timerEvent(QTimerEvent*) override;

View file

@ -44,6 +44,18 @@
<height>29</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>Edit</string>
</property>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="explorerWidget">
@ -56,26 +68,11 @@
<widget class="QWidget" name="dockWidgetContents">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTreeView" name="explorerView"/>
<widget class="ExplorerView" name="explorerView"/>
</item>
</layout>
</widget>
</widget>
<action name="actionDelete">
<property name="icon">
<iconset>
<normaloff>assets/icons/editor/delete.png</normaloff>assets/icons/editor/delete.png</iconset>
</property>
<property name="text">
<string>Delete</string>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Deletes a selected object&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="shortcut">
<string>Del</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
@ -83,6 +80,11 @@
<extends>QOpenGLWidget</extends>
<header>mainglwidget.h</header>
</customwidget>
<customwidget>
<class>ExplorerView</class>
<extends>QTreeView</extends>
<header>panes/explorerview.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View file

@ -2,7 +2,6 @@
#include "objects/base/instance.h"
#include "qabstractitemmodel.h"
#include "qcontainerfwd.h"
#include "qicon.h"
#include "qimage.h"
#include "qnamespace.h"
#include "qobject.h"
@ -10,7 +9,6 @@
#include "common.h"
#include <algorithm>
#include <cstdio>
#include <memory>
#include <optional>
#include "objects/base/instance.h"
@ -160,7 +158,7 @@ bool ExplorerModel::moveRows(const QModelIndex &sourceParentIdx, int sourceRow,
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());
fprintf(stderr, "Attempt to move rows %d-%d from %s (%s) while it only has %zu children.\n", sourceRow, sourceRow + count, sourceParent->name.c_str(), sourceParent->GetClass()->className.c_str(), sourceParent->GetChildren().size());
return false;
}

View file

@ -1,15 +1,19 @@
#ifndef EXPLORERMODEL_H
#define EXPLORERMODEL_H
#pragma once
#include "objects/base/instance.h"
#include "objects/part.h"
#include "qabstractitemmodel.h"
#include "qevent.h"
#include "qmenu.h"
#include "qnamespace.h"
#include "qtreeview.h"
#include <QOpenGLWidget>
#include <QWidget>
#include <memory>
// #ifndef EXPLORERMODEL_H
// #define EXPLORERMODEL_H
class ExplorerModel : public QAbstractItemModel {
Q_OBJECT
public:
@ -40,4 +44,4 @@ private:
QImage iconOf(InstanceType* type) const;
};
#endif // EXPLORERMODEL_H
// #endif

View file

@ -0,0 +1,49 @@
#include "explorerview.h"
#include "explorermodel.h"
#include "common.h"
#include "qaction.h"
#include "qnamespace.h"
ExplorerView::ExplorerView(QWidget* parent):
QTreeView(parent),
model(ExplorerModel(std::dynamic_pointer_cast<Instance>(workspace))) {
this->setModel(&model);
this->setRootIsDecorated(false);
this->setDragDropMode(QAbstractItemView::InternalMove);
this->setSelectionMode(QAbstractItemView::ExtendedSelection);
this->setDragEnabled(true);
this->setAcceptDrops(true);
this->setDropIndicatorShown(true);
this->setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &QTreeView::customContextMenuRequested, this, [&](const QPoint& point) {
QModelIndex index = this->indexAt(point);
contextMenu.exec(this->viewport()->mapToGlobal(point));
});
buildContextMenu();
}
ExplorerView::~ExplorerView() {
}
void ExplorerView::keyPressEvent(QKeyEvent* event) {
switch (event->key()) {
case Qt::Key_Delete:
actionDelete->trigger();
break;
}
}
void ExplorerView::buildContextMenu() {
// This will leak memory. Anyway...
contextMenu.addAction(this->actionDelete = new QAction(QIcon("assets/icons/editor/delete"), "Delete"));
connect(actionDelete, &QAction::triggered, this, [&]() {
QModelIndexList selectedIndexes = this->selectionModel()->selectedIndexes();
for (QModelIndex index : selectedIndexes) {
model.fromIndex(index)->SetParent(std::nullopt);
}
});
}

View file

@ -0,0 +1,35 @@
#pragma once
#include "objects/base/instance.h"
#include "objects/part.h"
#include "qevent.h"
#include "qmenu.h"
#include "qnamespace.h"
#include "qtreeview.h"
#include <QOpenGLWidget>
#include <QWidget>
#include <memory>
#include "explorermodel.h"
class Ui_MainWindow;
class ExplorerView : public QTreeView {
public:
ExplorerView(QWidget* parent = nullptr);
~ExplorerView() override;
void keyPressEvent(QKeyEvent* evt) override;
private:
ExplorerModel model;
QMenu contextMenu;
// TODO: Move these to a separate top-level namespace so these can be
// accessed from multiple locations
QAction* actionDelete;
QAction* actionCopy;
QAction* actionCut;
QAction* actionPaste;
QAction* actionPasteInto;
QAction* actionSelectChildren;
void buildContextMenu();
};