swaymux/tree/swaytree.h
2024-03-12 11:48:43 +01:00

111 lines
3.9 KiB
C++

//
// Created by grimmauld on 03.03.24.
//
#ifndef SWAYMUX_SWAYTREE_H
#define SWAYMUX_SWAYTREE_H
#include <nlohmann/json.hpp>
#include <utility>
#include <iostream>
using json = nlohmann::json;
#include "../sway_bindings/SwayRecords.h"
#include "AbstractTreeNode.h"
class SwayTreeNode : public AbstractTreeNode<SwayTreeNode> {
public:
SwayRecord node;
explicit SwayTreeNode(const json &rep, SwayTreeNode *parent = nullptr) : node(SwayRecord(rep)),
AbstractTreeNode(parent) {
for (const auto &child: rep["nodes"]) {
if (child.contains("app_id") && !child["app_id"].is_null() && ((std::string) child["app_id"]) == "swaymux")
continue;
auto childNode = std::make_unique<SwayTreeNode>(child, this);
this->appendChild(childNode);
}
for (const auto &child: rep["floating_nodes"]) {
if (child.contains("app_id") && !child["app_id"].is_null() && ((std::string) child["app_id"]) == "swaymux")
continue;
auto childNode = std::make_unique<SwayTreeNode>(child, this);
this->appendChild(childNode);
}
}
explicit SwayTreeNode(SwayTreeNode *parent = nullptr) : node(SwayRecord()), AbstractTreeNode(parent) {};
// explicit SwayTreeNode(SwayRecord node, SwayTreeNode *parent = nullptr) : node(std::move(node)), AbstractTreeNode(parent) {};
[[nodiscard]] bool operator<(const SwayTreeNode &other) const {
return this->node < other.node;
}
[[nodiscard]] QVariant data(int column) const override;
[[nodiscard]] QVariant headerData(int column) const override;
[[nodiscard]] int columnCount() const override { return 1; };
[[nodiscard]] SwayTreeNode *findFocused() {
std::function<bool(const SwayTreeNode *)> focused = [](const SwayTreeNode *testNode) {
return testNode->node.focused;
};
return this->findChildRecursive(focused);
}
[[nodiscard]] inline const SwayTreeNode *findRoot() const {
return this->findParentRecursive(matchNodeType(NodeType::root));
}
[[nodiscard]] inline const SwayTreeNode *findOutput() const {
return this->findParentRecursive(matchNodeType(NodeType::output));
}
[[nodiscard]] inline const SwayTreeNode *findWorkspace() const {
return this->findParentRecursive(matchNodeType(NodeType::workspace));
}
[[nodiscard]] inline std::set<SwayTreeNode *> accumulateContainers() const {
return accumulateMatchingChildrenRecursive(matchNodeType({NodeType::con, NodeType::floating_con}));
}
[[nodiscard]] std::set<std::string> accumulateWorkspaces() const {
auto workspaces = accumulateMatchingChildrenRecursive(matchNodeType(NodeType::workspace));
std::set<std::string> result;
std::transform(workspaces.begin(), workspaces.end(), std::inserter(result, result.begin()),
[](const SwayTreeNode *workspace) { return workspace->node.name; });
return result;
}
[[nodiscard]] SwayTreeNode * findById(const int id) {
return const_cast<SwayTreeNode *>(findChildRecursive([id](const SwayTreeNode *test) {
return test->node.id == id;
}));
}
private:
[[nodiscard]] static std::function<bool(const SwayTreeNode *)> matchNodeType(NodeType::NodeType type) {
return matchNodeType(std::vector{type});
}
[[nodiscard]] static std::function<bool(const SwayTreeNode *)>
matchNodeType(const std::vector<NodeType::NodeType>& types) {
return [types](const SwayTreeNode *testNode) {
return std::ranges::any_of(types.begin(), types.end(), [testNode](const auto t) {
return testNode->node.type == t;
});
};
}
[[nodiscard]] bool operator==(const SwayTreeNode * other) const {
return this->node == other->node;
}
};
#endif //SWAYMUX_SWAYTREE_H