Compare commits
No commits in common. "4ebf8002a52ecffa84bd4fbda2571c4df5333b2b" and "1daed5bb83d2a38c5d1570e22d46dc2870ecbb8f" have entirely different histories.
4ebf8002a5
...
1daed5bb83
15 changed files with 6 additions and 250 deletions
|
@ -1,22 +0,0 @@
|
||||||
Silk icon set 1.3
|
|
||||||
|
|
||||||
_________________________________________
|
|
||||||
Mark James
|
|
||||||
http://www.famfamfam.com/lab/icons/silk/
|
|
||||||
_________________________________________
|
|
||||||
|
|
||||||
This work is licensed under a
|
|
||||||
Creative Commons Attribution 2.5 License.
|
|
||||||
[ http://creativecommons.org/licenses/by/2.5/ ]
|
|
||||||
|
|
||||||
This means you may use it for any purpose,
|
|
||||||
and make any changes you like.
|
|
||||||
All I ask is that you include a link back
|
|
||||||
to this page in your credits.
|
|
||||||
|
|
||||||
Are you using this icon set? Send me an email
|
|
||||||
(including a link or picture if available) to
|
|
||||||
mjames@gmail.com
|
|
||||||
|
|
||||||
Any other questions about this icon set please
|
|
||||||
contact mjames@gmail.com
|
|
Binary file not shown.
Before Width: | Height: | Size: 353 B |
Binary file not shown.
Before Width: | Height: | Size: 452 B |
Binary file not shown.
Before Width: | Height: | Size: 748 B |
Binary file not shown.
Before Width: | Height: | Size: 923 B |
|
@ -25,8 +25,6 @@ set(PROJECT_SOURCES
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
mainglwidget.h
|
mainglwidget.h
|
||||||
mainglwidget.cpp
|
mainglwidget.cpp
|
||||||
explorermodel.h
|
|
||||||
explorermodel.cpp
|
|
||||||
${TS_FILES}
|
${TS_FILES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
#include "explorermodel.h"
|
|
||||||
#include "objects/base/instance.h"
|
|
||||||
#include "qcontainerfwd.h"
|
|
||||||
#include "qicon.h"
|
|
||||||
#include "qimage.h"
|
|
||||||
#include "qnamespace.h"
|
|
||||||
#include "qobject.h"
|
|
||||||
#include "qwidget.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include <algorithm>
|
|
||||||
#include <optional>
|
|
||||||
#include "objects/base/instance.h"
|
|
||||||
|
|
||||||
// https://doc.qt.io/qt-6/qtwidgets-itemviews-simpletreemodel-example.html#testing-the-model
|
|
||||||
|
|
||||||
std::map<std::string, QImage> instanceIconCache;
|
|
||||||
|
|
||||||
ExplorerModel::ExplorerModel(InstanceRef dataRoot, QWidget *parent)
|
|
||||||
: QAbstractItemModel(parent)
|
|
||||||
, rootItem(dataRoot) {
|
|
||||||
// TODO: Don't use lambdas and handlers like that
|
|
||||||
hierarchyPreUpdateHandler = [&](InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent) {
|
|
||||||
if (oldParent.has_value()) {
|
|
||||||
auto children = oldParent.value()->GetChildren();
|
|
||||||
size_t idx = std::find(children.begin(), children.end(), object) - children.end();
|
|
||||||
beginRemoveRows(toIndex(oldParent.value()), idx, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newParent.has_value()) {
|
|
||||||
size_t size = newParent.value()->GetChildren().size();
|
|
||||||
beginInsertRows(toIndex(newParent.value()), size, size);
|
|
||||||
} else {
|
|
||||||
// TODO:
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
hierarchyPostUpdateHandler = [&](InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent) {
|
|
||||||
if (newParent.has_value()) endInsertRows();
|
|
||||||
if (oldParent.has_value()) endRemoveRows();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ExplorerModel::~ExplorerModel() = default;
|
|
||||||
|
|
||||||
QModelIndex ExplorerModel::index(int row, int column, const QModelIndex &parent) const {
|
|
||||||
if (!hasIndex(row, column, parent))
|
|
||||||
return {};
|
|
||||||
|
|
||||||
Instance* parentItem = parent.isValid()
|
|
||||||
? static_cast<Instance*>(parent.internalPointer())
|
|
||||||
: rootItem.get();
|
|
||||||
|
|
||||||
if (parentItem->GetChildren().size() >= row)
|
|
||||||
return createIndex(row, column, parentItem->GetChildren()[row].get());
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex ExplorerModel::toIndex(InstanceRef item) {
|
|
||||||
if (item == rootItem)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
InstanceRef parentItem = item->GetParent().value();
|
|
||||||
// Check above ensures this item is not root, so value() must be valid
|
|
||||||
for (int i = 0; i < parentItem->GetChildren().size(); i++)
|
|
||||||
if (parentItem->GetChildren()[i] == item)
|
|
||||||
return createIndex(i, 0, item.get());
|
|
||||||
return QModelIndex{};
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex ExplorerModel::parent(const QModelIndex &index) const {
|
|
||||||
if (!index.isValid())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
Instance* childItem = static_cast<Instance*>(index.internalPointer());
|
|
||||||
// NORISK: The parent must exist if the child was obtained from it during this frame
|
|
||||||
InstanceRef parentItem = childItem->GetParent().value();
|
|
||||||
|
|
||||||
if (parentItem == rootItem)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
// Check above ensures this item is not root, so value() must be valid
|
|
||||||
InstanceRef parentParent = parentItem->GetParent().value();
|
|
||||||
for (int i = 0; i < parentParent->GetChildren().size(); i++)
|
|
||||||
if (parentParent->GetChildren()[i] == parentItem)
|
|
||||||
return createIndex(i, 0, parentItem.get());
|
|
||||||
return QModelIndex{};
|
|
||||||
}
|
|
||||||
|
|
||||||
int ExplorerModel::rowCount(const QModelIndex &parent) const {
|
|
||||||
if (parent.column() > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
Instance* parentItem = parent.isValid()
|
|
||||||
? static_cast<Instance*>(parent.internalPointer())
|
|
||||||
: rootItem.get();
|
|
||||||
|
|
||||||
return parentItem->GetChildren().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
int ExplorerModel::columnCount(const QModelIndex &parent) const {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant ExplorerModel::data(const QModelIndex &index, int role) const {
|
|
||||||
if (!index.isValid())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
Instance *item = static_cast<Instance*>(index.internalPointer());
|
|
||||||
|
|
||||||
switch (role) {
|
|
||||||
case Qt::DisplayRole:
|
|
||||||
return QString::fromStdString(item->name);
|
|
||||||
case Qt::DecorationRole:
|
|
||||||
return iconOf(item->GetClass());
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant ExplorerModel::headerData(int section, Qt::Orientation orientation,
|
|
||||||
int role) const
|
|
||||||
{
|
|
||||||
return QString("Idk lol \u00AF\u005C\u005F\u0028\u30C4\u0029\u005F\u002F\u00AF");
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::ItemFlags ExplorerModel::flags(const QModelIndex &index) const
|
|
||||||
{
|
|
||||||
return index.isValid()
|
|
||||||
? QAbstractItemModel::flags(index) : Qt::ItemFlags(Qt::NoItemFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage ExplorerModel::iconOf(InstanceType* type) const {
|
|
||||||
if (instanceIconCache.count(type->className)) return instanceIconCache[type->className];
|
|
||||||
|
|
||||||
InstanceType* currentClass = type;
|
|
||||||
while (currentClass->explorerIcon.empty()) currentClass = currentClass->super;
|
|
||||||
|
|
||||||
QImage icon("assets/icons/" + QString::fromStdString(currentClass->explorerIcon));
|
|
||||||
instanceIconCache[type->className] = icon;
|
|
||||||
return icon;
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
#ifndef EXPLORERMODEL_H
|
|
||||||
#define EXPLORERMODEL_H
|
|
||||||
|
|
||||||
#include "objects/base/instance.h"
|
|
||||||
#include "objects/part.h"
|
|
||||||
#include "qabstractitemmodel.h"
|
|
||||||
#include "qevent.h"
|
|
||||||
#include <QOpenGLWidget>
|
|
||||||
#include <QWidget>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class ExplorerModel : public QAbstractItemModel {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
Q_DISABLE_COPY_MOVE(ExplorerModel)
|
|
||||||
|
|
||||||
explicit ExplorerModel(InstanceRef dataRoot, QWidget *parent = nullptr);
|
|
||||||
~ExplorerModel() override;
|
|
||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role) const 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 rootItem;
|
|
||||||
QModelIndex toIndex(InstanceRef item);
|
|
||||||
QImage iconOf(InstanceType* type) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EXPLORERMODEL_H
|
|
|
@ -8,14 +8,10 @@
|
||||||
#include <QTimerEvent>
|
#include <QTimerEvent>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QTreeView>
|
|
||||||
#include <QAbstractItemView>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#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 "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
|
@ -27,9 +23,6 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
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->setRootIsDecorated(false);
|
|
||||||
|
|
||||||
simulationInit();
|
simulationInit();
|
||||||
|
|
||||||
// Baseplate
|
// Baseplate
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1027</width>
|
<width>800</width>
|
||||||
<height>600</height>
|
<height>600</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -40,27 +40,12 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1027</width>
|
<width>800</width>
|
||||||
<height>29</height>
|
<height>29</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
<widget class="QDockWidget" name="explorerWidget">
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Explorer</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="dockWidgetArea">
|
|
||||||
<number>2</number>
|
|
||||||
</attribute>
|
|
||||||
<widget class="QWidget" name="dockWidgetContents">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QTreeView" name="explorerView"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|
|
@ -5,6 +5,4 @@
|
||||||
|
|
||||||
Camera camera(glm::vec3(0.0, 0.0, 3.0));
|
Camera camera(glm::vec3(0.0, 0.0, 3.0));
|
||||||
//std::vector<Part> parts;
|
//std::vector<Part> parts;
|
||||||
std::shared_ptr<Workspace> workspace = Workspace::New();
|
std::shared_ptr<Workspace> workspace = Workspace::New();
|
||||||
std::optional<HierarchyPreUpdateHandler> hierarchyPreUpdateHandler;
|
|
||||||
std::optional<HierarchyPostUpdateHandler> hierarchyPostUpdateHandler;
|
|
11
src/common.h
11
src/common.h
|
@ -1,17 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "objects/workspace.h"
|
#include "objects/workspace.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class Instance;
|
|
||||||
// typedef std::function<void(std::shared_ptr<Instance> element, std::optional<std::shared_ptr<Instance>> newParent)> HierarchyUpdateHandler;
|
|
||||||
typedef std::function<void(InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent)> HierarchyPreUpdateHandler;
|
|
||||||
typedef std::function<void(InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent)> HierarchyPostUpdateHandler;
|
|
||||||
|
|
||||||
// TEMPORARY COMMON DATA FOR DIFFERENT INTERNAL COMPONENTS
|
// TEMPORARY COMMON DATA FOR DIFFERENT INTERNAL COMPONENTS
|
||||||
|
|
||||||
extern Camera camera;
|
extern Camera camera;
|
||||||
extern std::shared_ptr<Workspace> workspace;
|
extern std::shared_ptr<Workspace> workspace;
|
||||||
extern std::optional<HierarchyPreUpdateHandler> hierarchyPreUpdateHandler;
|
|
||||||
extern std::optional<HierarchyPostUpdateHandler> hierarchyPostUpdateHandler;
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include "instance.h"
|
#include "instance.h"
|
||||||
#include "../../common.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -9,7 +8,6 @@ static InstanceType TYPE_ {
|
||||||
.super = NULL,
|
.super = NULL,
|
||||||
.className = "Instance",
|
.className = "Instance",
|
||||||
.constructor = NULL, // Instance is abstract and therefore not creatable
|
.constructor = NULL, // Instance is abstract and therefore not creatable
|
||||||
.explorerIcon = "instance",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
InstanceType* Instance::TYPE = &TYPE_;
|
InstanceType* Instance::TYPE = &TYPE_;
|
||||||
|
@ -27,8 +25,6 @@ Instance::~Instance () {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::SetParent(std::optional<std::shared_ptr<Instance>> newParent) {
|
void Instance::SetParent(std::optional<std::shared_ptr<Instance>> newParent) {
|
||||||
auto lastParent = GetParent();
|
|
||||||
if (hierarchyPreUpdateHandler.has_value()) hierarchyPreUpdateHandler.value()(this->shared_from_this(), lastParent, newParent);
|
|
||||||
// If we currently have a parent, remove ourselves from it before adding ourselves to the new one
|
// If we currently have a parent, remove ourselves from it before adding ourselves to the new one
|
||||||
if (this->parent.has_value() && !this->parent.value().expired()) {
|
if (this->parent.has_value() && !this->parent.value().expired()) {
|
||||||
auto oldParent = this->parent.value().lock();
|
auto oldParent = this->parent.value().lock();
|
||||||
|
@ -40,8 +36,6 @@ void Instance::SetParent(std::optional<std::shared_ptr<Instance>> newParent) {
|
||||||
}
|
}
|
||||||
this->parent = newParent;
|
this->parent = newParent;
|
||||||
// TODO: Add code for sending signals for parent updates
|
// TODO: Add code for sending signals for parent updates
|
||||||
// TODO: Yeahhh maybe this isn't the best way of doing this?
|
|
||||||
if (hierarchyPostUpdateHandler.has_value()) hierarchyPostUpdateHandler.value()(this->shared_from_this(), lastParent, newParent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::shared_ptr<Instance>> Instance::GetParent() {
|
std::optional<std::shared_ptr<Instance>> Instance::GetParent() {
|
||||||
|
|
|
@ -9,14 +9,10 @@ struct InstanceType {
|
||||||
InstanceType* super; // May be null
|
InstanceType* super; // May be null
|
||||||
std::string className;
|
std::string className;
|
||||||
InstanceConstructor constructor;
|
InstanceConstructor constructor;
|
||||||
std::string explorerIcon = "";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for all instances in the data model
|
// Base class for all instances in the data model
|
||||||
// Note: enable_shared_from_this HAS to be public or else its field will not be populated
|
class Instance : std::enable_shared_from_this<Instance> {
|
||||||
// Maybe this could be replaced with a friendship? But that seems unnecessary.
|
|
||||||
// https://stackoverflow.com/q/56415222/16255372
|
|
||||||
class Instance : public std::enable_shared_from_this<Instance> {
|
|
||||||
private:
|
private:
|
||||||
std::optional<std::weak_ptr<Instance>> parent;
|
std::optional<std::weak_ptr<Instance>> parent;
|
||||||
std::vector<std::shared_ptr<Instance>> children;
|
std::vector<std::shared_ptr<Instance>> children;
|
||||||
|
@ -34,7 +30,7 @@ public:
|
||||||
inline const std::vector<std::shared_ptr<Instance>> GetChildren() { return children; }
|
inline const std::vector<std::shared_ptr<Instance>> GetChildren() { return children; }
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
inline void AddChild(std::shared_ptr<Instance> object) { object->SetParent(this->shared_from_this()); }
|
inline void AddChild(std::shared_ptr<Instance> object) { children.push_back(object); }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Instance> InstanceRef;
|
typedef std::shared_ptr<Instance> InstanceRef;
|
||||||
|
|
|
@ -5,7 +5,6 @@ static InstanceType TYPE_ {
|
||||||
.super = Instance::TYPE,
|
.super = Instance::TYPE,
|
||||||
.className = "Part",
|
.className = "Part",
|
||||||
.constructor = &Part::CreateGeneric,
|
.constructor = &Part::CreateGeneric,
|
||||||
.explorerIcon = "part",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
InstanceType* Part::TYPE = &TYPE_;
|
InstanceType* Part::TYPE = &TYPE_;
|
||||||
|
|
Loading…
Add table
Reference in a new issue