diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e36595..496a745 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,8 @@ find_package(ReactPhysics3D REQUIRED) file(MAKE_DIRECTORY bin) +include_directories("include") + file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h") add_library(openblocks ${SOURCES}) set_target_properties(openblocks PROPERTIES OUTPUT_NAME "openblocks") diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 1055c7e..fd0a0d7 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -29,6 +29,10 @@ set(PROJECT_SOURCES panes/explorerview.cpp panes/explorermodel.h panes/explorermodel.cpp + panes/propertiesview.h + panes/propertiesview.cpp + panes/propertiesmodel.h + panes/propertiesmodel.cpp ${TS_FILES} ) diff --git a/editor/mainwindow.cpp b/editor/mainwindow.cpp index ceb5ab9..ced9974 100644 --- a/editor/mainwindow.cpp +++ b/editor/mainwindow.cpp @@ -10,10 +10,12 @@ #include #include #include +#include #include "common.h" #include "physics/simulation.h" #include "objects/part.h" +#include "qitemselectionmodel.h" #include "qobject.h" MainWindow::MainWindow(QWidget *parent) @@ -24,6 +26,15 @@ MainWindow::MainWindow(QWidget *parent) timer.start(33, this); setMouseTracking(true); + connect(ui->explorerView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [&](const QItemSelection &selected, const QItemSelection &deselected) { + if (selected.count() == 0) return; + + std::optional inst = selected.count() == 0 ? std::nullopt + : std::make_optional(((Instance*)selected.indexes()[0].internalPointer())->shared_from_this()); + + ui->propertiesView->setSelected(inst); + }); + // ui->explorerView->Init(ui); simulationInit(); diff --git a/editor/mainwindow.ui b/editor/mainwindow.ui index fab6cfc..05b8225 100644 --- a/editor/mainwindow.ui +++ b/editor/mainwindow.ui @@ -66,13 +66,28 @@ 2 - + + + + Properties + + + 2 + + + + + + + + + @@ -85,6 +100,11 @@ QTreeView
panes/explorerview.h
+ + PropertiesView + QTreeView +
panes/propertiesview.h
+
diff --git a/editor/panes/explorermodel.cpp b/editor/panes/explorermodel.cpp index 17aa4bc..bf133a0 100644 --- a/editor/panes/explorermodel.cpp +++ b/editor/panes/explorermodel.cpp @@ -112,6 +112,7 @@ QVariant ExplorerModel::data(const QModelIndex &index, int role) const { Instance *item = static_cast(index.internalPointer()); switch (role) { + case Qt::EditRole: case Qt::DisplayRole: return QString::fromStdString(item->name); case Qt::DecorationRole: diff --git a/editor/panes/propertiesmodel.cpp b/editor/panes/propertiesmodel.cpp new file mode 100644 index 0000000..e038994 --- /dev/null +++ b/editor/panes/propertiesmodel.cpp @@ -0,0 +1,76 @@ +#include "propertiesmodel.h" +#include "qnamespace.h" + +PropertiesModel::PropertiesModel(InstanceRef selectedItem, QWidget *parent) + : QAbstractItemModel(parent) + , selectedItem(selectedItem) { + this->propertiesList = selectedItem->GetProperties(); +} + +PropertiesModel::~PropertiesModel() = default; + + +QVariant PropertiesModel::data(const QModelIndex &index, int role) const { + if (!index.isValid()) + return {}; + + std::string propertyName = propertiesList[index.row()]; + + switch (role) { + case Qt::EditRole: + case Qt::DisplayRole: + if (index.column() == 0) + return QString::fromStdString(propertyName); + else if (index.column() == 1) + return QString::fromStdString(selectedItem->GetPropertyValue(propertyName).value()); + // case Qt::DecorationRole: + // return iconOf(item->GetClass()); + } + + return {}; +} + +bool PropertiesModel::setData(const QModelIndex &index, const QVariant &value, int role) { + if (index.column() != 1 && role != Qt::EditRole) return false; + + selectedItem->SetPropertyValue(propertiesList[index.row()], value.toString().toStdString()); + return true; +} + +Qt::ItemFlags PropertiesModel::flags(const QModelIndex &index) const { + if (!index.isValid()) + return Qt::NoItemFlags; + + if (index.column() == 0) + return Qt::ItemIsEnabled; + + if (index.column() == 1) + return Qt::ItemIsEnabled | Qt::ItemIsEditable; + + return Qt::NoItemFlags; +}; + +QVariant PropertiesModel::headerData(int section, Qt::Orientation orientation, + int role) const { + return QString(""); +} + +QModelIndex PropertiesModel::index(int row, int column, + const QModelIndex &parent) const { + if (!hasIndex(row, column, parent)) + return {}; + + return createIndex(row, column); +} + +QModelIndex PropertiesModel::parent(const QModelIndex &index) const { + return {}; +} + +int PropertiesModel::rowCount(const QModelIndex &parent) const { + return !parent.isValid() ? selectedItem->GetProperties().size() : 0; +} + +int PropertiesModel::columnCount(const QModelIndex &parent) const { + return 2; +} \ No newline at end of file diff --git a/editor/panes/propertiesmodel.h b/editor/panes/propertiesmodel.h new file mode 100644 index 0000000..9d6e0f7 --- /dev/null +++ b/editor/panes/propertiesmodel.h @@ -0,0 +1,36 @@ +#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 +#include +#include + +class PropertiesModel : public QAbstractItemModel { + Q_OBJECT +public: + Q_DISABLE_COPY_MOVE(PropertiesModel) + + explicit PropertiesModel(InstanceRef selectedItem, QWidget *parent = nullptr); + ~PropertiesModel() 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; + QModelIndex index(int row, int column, + const QModelIndex &parent = {}) const override; + QModelIndex parent(const QModelIndex &index) const override; + int rowCount(const QModelIndex &parent = {}) const override; + int columnCount(const QModelIndex &parent = {}) const override; + +private: + InstanceRef selectedItem; + std::vector propertiesList; +}; \ No newline at end of file diff --git a/editor/panes/propertiesview.cpp b/editor/panes/propertiesview.cpp new file mode 100644 index 0000000..abe630d --- /dev/null +++ b/editor/panes/propertiesview.cpp @@ -0,0 +1,20 @@ +#include "propertiesview.h" +#include "propertiesmodel.h" +#include "qaction.h" + +PropertiesView::PropertiesView(QWidget* parent): + QTreeView(parent) { + this->setStyleSheet(QString("QTreeView::branch { border: none; }")); +} + +PropertiesView::~PropertiesView() { +} + +void PropertiesView::setSelected(std::optional instance) { + if (instance.has_value()) { + this->setModel(new PropertiesModel(instance.value())); + } else { + if (this->model()) delete this->model(); + this->setModel(nullptr); + } +} \ No newline at end of file diff --git a/editor/panes/propertiesview.h b/editor/panes/propertiesview.h new file mode 100644 index 0000000..4570c23 --- /dev/null +++ b/editor/panes/propertiesview.h @@ -0,0 +1,22 @@ +#pragma once + +#include "objects/base/instance.h" +#include "objects/part.h" +#include "qevent.h" +#include "qmenu.h" +#include "qnamespace.h" +#include "qtreeview.h" +#include +#include +#include +#include "explorermodel.h" + +class Ui_MainWindow; + +class PropertiesView : public QTreeView { +public: + PropertiesView(QWidget* parent = nullptr); + ~PropertiesView() override; + + void setSelected(std::optional instance); +}; \ No newline at end of file diff --git a/src/objects/base/instance.cpp b/src/objects/base/instance.cpp index 0d63a87..6204191 100644 --- a/src/objects/base/instance.cpp +++ b/src/objects/base/instance.cpp @@ -1,6 +1,5 @@ #include "instance.h" #include "../../common.h" -#include "objects/base/member.h" #include #include #include diff --git a/src/objects/base/instance.h b/src/objects/base/instance.h index ab1aa27..2f85efe 100644 --- a/src/objects/base/instance.h +++ b/src/objects/base/instance.h @@ -12,7 +12,7 @@ #include #include <../include/expected.hpp> -#include "objects/base/member.h" +#include "member.h" class Instance; typedef std::shared_ptr(*InstanceConstructor)();