swaymux/tree/AbstractTreeNode.h
LordGrimmauld f3b60a4a2a Add new functions
- move to scratch
- restore (move selected to new workspace)
- close
2024-03-11 13:33:26 +01:00

110 lines
3.0 KiB
C++

//
// 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>
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; };
[[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 {
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 {
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]] T *findChildRecursive(std::function<bool(const T *)> test) {
if (test((T *) this))
return (T*) this;
for (int i = 0; i < childCount(); ++i) {
auto *c = child(i);
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;
return parent->findParentRecursive(test);
};
void removeChild(int i) {
if (i >= 0 && i < childCount()) {
children.erase(std::next(children.begin(), i));
}
}
protected:
T *parent;
};
#endif //SWAYMUX_ABSTRACTTREENODE_H