2024-03-02 22:33:27 +01:00
|
|
|
//
|
|
|
|
// Created by grimmauld on 27.02.24.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef SWAYMUX_ABSTRACTTREENODE_H
|
|
|
|
#define SWAYMUX_ABSTRACTTREENODE_H
|
|
|
|
|
|
|
|
#include <filesystem>
|
|
|
|
#include <set>
|
|
|
|
#include <utility>
|
|
|
|
#include <map>
|
|
|
|
#include <vector>
|
|
|
|
#include <QVariant>
|
2024-03-09 12:55:29 +01:00
|
|
|
#include <iostream>
|
2024-03-02 22:33:27 +01:00
|
|
|
|
|
|
|
template<class T>
|
|
|
|
class AbstractTreeNode {
|
|
|
|
public:
|
|
|
|
std::vector<std::unique_ptr<T>> children{};
|
|
|
|
|
|
|
|
explicit AbstractTreeNode(T *parent = nullptr) : parent(parent) {}
|
|
|
|
|
2024-03-06 23:40:48 +01:00
|
|
|
[[nodiscard]] T *parentItem() const { return parent; };
|
2024-03-02 22:33:27 +01:00
|
|
|
|
|
|
|
[[nodiscard]] size_t childCount() const { return children.size(); };
|
|
|
|
|
|
|
|
[[nodiscard]] T *child(int row) const { return row >= 0 && row < childCount() ? children.at(row).get() : nullptr; };
|
|
|
|
|
|
|
|
[[nodiscard]] virtual QVariant data(int column) const = 0;
|
|
|
|
|
|
|
|
[[nodiscard]] virtual QVariant headerData(int column) const = 0;
|
|
|
|
|
|
|
|
[[nodiscard]] virtual int columnCount() const = 0;
|
|
|
|
|
2024-03-06 23:40:48 +01:00
|
|
|
[[nodiscard]] int row() const {
|
2024-03-02 22:33:27 +01:00
|
|
|
if (parent == nullptr)
|
|
|
|
return 0;
|
|
|
|
const auto it = std::find_if(parent->children.cbegin(), parent->children.cend(),
|
|
|
|
[this](const std::unique_ptr<T> &treeItem) {
|
|
|
|
return treeItem.get() == this;
|
|
|
|
});
|
|
|
|
if (it != parent->children.cend())
|
|
|
|
return std::distance(parent->children.cbegin(), it);
|
|
|
|
Q_ASSERT(false); // should not happen
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendChild(std::unique_ptr<T> &child) { children.push_back(std::move(child)); }
|
|
|
|
|
2024-03-06 23:40:48 +01:00
|
|
|
[[nodiscard]] T *findChild(std::function<bool(const T &)> test) const {
|
2024-03-02 22:33:27 +01:00
|
|
|
|
|
|
|
for (int i = 0; i < childCount(); ++i) {
|
|
|
|
auto* c = child(i);
|
|
|
|
if (test(*c))
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
};
|
|
|
|
|
2024-03-09 12:55:29 +01:00
|
|
|
[[nodiscard]] std::set<T *> accumulateMatchingChildrenRecursive(std::function<bool(const T *)> test) const {
|
|
|
|
std::set<T *> matching;
|
|
|
|
if (test((const T *) this)) {
|
|
|
|
matching.insert((T *) this);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < childCount(); ++i) {
|
|
|
|
auto *c = child(i);
|
|
|
|
for(T * element: c->accumulateMatchingChildrenRecursive(test)) {
|
|
|
|
matching.insert(element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return matching;
|
|
|
|
}
|
|
|
|
|
2024-03-06 23:40:48 +01:00
|
|
|
[[nodiscard]] const T *findChildRecursive(std::function<bool(const T *)> test) const {
|
|
|
|
if (test((const T *) this))
|
|
|
|
return (const T*) this;
|
|
|
|
|
|
|
|
for (int i = 0; i < childCount(); ++i) {
|
|
|
|
auto *c = child(i);
|
|
|
|
const T *r = c->findChildRecursive(test);
|
|
|
|
if (r != nullptr)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
};
|
|
|
|
|
2024-03-07 11:20:26 +01:00
|
|
|
[[nodiscard]] const T *findParentRecursive(std::function<bool(const T *)> test) const {
|
|
|
|
if (test((const T *) this))
|
|
|
|
return (const T*) this;
|
|
|
|
|
|
|
|
if (parent == nullptr)
|
|
|
|
return nullptr;
|
|
|
|
|
2024-03-08 10:53:30 +01:00
|
|
|
return parent->findParentRecursive(test);
|
2024-03-07 11:20:26 +01:00
|
|
|
};
|
|
|
|
|
2024-03-02 22:33:27 +01:00
|
|
|
void removeChild(int i) {
|
|
|
|
if (i >= 0 && i < childCount()) {
|
|
|
|
children.erase(std::next(children.begin(), i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
T *parent;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif //SWAYMUX_ABSTRACTTREENODE_H
|