swaymux/tree/AbstractTreeModel.h

91 lines
2.9 KiB
C++

//
// Created by grimmauld on 03.03.24.
//
#ifndef SWAYMUX_ABSTRACTTREEMODEL_H
#define SWAYMUX_ABSTRACTTREEMODEL_H
#include <type_traits>
#include "AbstractTreeNode.h"
#include <QAbstractItemModel>
template<class T>
class AbstractTreeModel : public QAbstractItemModel {
static_assert(std::is_base_of<AbstractTreeNode<T>, T>::value,
"Tree node subject class is not derived from AbstractTreeNode");
public:
Q_DISABLE_COPY_MOVE(AbstractTreeModel)
explicit AbstractTreeModel(QObject *parent = nullptr): QAbstractItemModel(parent) {};
~AbstractTreeModel() override = default;
[[nodiscard]] QVariant data(const QModelIndex &index, int role) const override {
if (!index.isValid() || role != Qt::DisplayRole)
return {};
const auto *item = static_cast<const T *>(index.internalPointer());
return item->data(index.column());
}
[[nodiscard]] Qt::ItemFlags flags(const QModelIndex &index) const override {
return index.isValid()
? QAbstractItemModel::flags(index) : Qt::ItemFlags(Qt::NoItemFlags);
}
[[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override {
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
return QVariant{};
return T{}.headerData(section);
}
[[nodiscard]] QModelIndex index(int row, int column,
const QModelIndex &parent = {}) const override {
if (!hasIndex(row, column, parent))
return {};
const T *parentItem = parent.isValid()
? static_cast<T *>(parent.internalPointer())
: getRoot();
if (auto *childItem = parentItem->child(row))
return createIndex(row, column, childItem);
return {};
}
[[nodiscard]] QModelIndex parent(const QModelIndex &index) const override {
if (!index.isValid())
return {};
auto *childItem = static_cast<T *>(index.internalPointer());
T *parentItem = childItem->parentItem();
return parentItem != getRoot()
? createIndex(parentItem->row(), 0, parentItem) : QModelIndex{};
}
[[nodiscard]] int rowCount(const QModelIndex &parent = {}) const override {
if (parent.column() > 0)
return 0;
const T *parentItem = parent.isValid()
? static_cast<const T *>(parent.internalPointer())
: getRoot();
return parentItem->childCount();
}
[[nodiscard]] int columnCount(const QModelIndex &parent = {}) const override {
if (parent.isValid())
return static_cast<T *>(parent.internalPointer())->columnCount();
return T{}.columnCount();
}
[[nodiscard]] virtual const T* getRoot() const = 0;
};
#endif //SWAYMUX_ABSTRACTTREEMODEL_H