fix: Hierarchy now updates properly

This commit is contained in:
maelstrom 2025-01-18 16:27:43 +01:00
parent 1f6ba1752f
commit fc063ad39f
6 changed files with 56 additions and 2 deletions

View file

@ -3,12 +3,35 @@
#include "qcontainerfwd.h"
#include "qobject.h"
#include "qwidget.h"
#include "common.h"
#include <algorithm>
#include <optional>
// https://doc.qt.io/qt-6/qtwidgets-itemviews-simpletreemodel-example.html#testing-the-model
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;
@ -26,6 +49,18 @@ QModelIndex ExplorerModel::index(int row, int column, const QModelIndex &parent)
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 {};

View file

@ -29,6 +29,7 @@ public:
private:
InstanceRef rootItem;
QModelIndex toIndex(InstanceRef item);
};
#endif // EXPLORERMODEL_H

View file

@ -8,6 +8,8 @@
#include <QTimerEvent>
#include <QMouseEvent>
#include <QWidget>
#include <QTreeView>
#include <QAbstractItemView>
#include <memory>
#include "common.h"

View file

@ -5,4 +5,6 @@
Camera camera(glm::vec3(0.0, 0.0, 3.0));
//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;

View file

@ -1,8 +1,17 @@
#pragma once
#include "objects/workspace.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
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;

View file

@ -1,4 +1,5 @@
#include "instance.h"
#include "../../common.h"
#include <algorithm>
#include <memory>
#include <optional>
@ -25,6 +26,8 @@ Instance::~Instance () {
}
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 (this->parent.has_value() && !this->parent.value().expired()) {
auto oldParent = this->parent.value().lock();
@ -36,6 +39,8 @@ void Instance::SetParent(std::optional<std::shared_ptr<Instance>> newParent) {
}
this->parent = newParent;
// 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() {