swaymux/tree/AbstractTreeNode.h

110 lines
3.1 KiB
C
Raw Normal View History

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>
#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) {}
[[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;
[[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)); }
[[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;
};
[[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;
}
[[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;
};
[[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-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