// // Created by grimmauld on 03.03.24. // #ifndef SWAYMUX_SWAYTREE_H #define SWAYMUX_SWAYTREE_H #include #include #include using json = nlohmann::json; #include "../sway_bindings/SwayRecords.h" #include "AbstractTreeNode.h" class SwayTreeNode : public AbstractTreeNode { 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(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(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 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 accumulateContainers() const { return accumulateMatchingChildrenRecursive(matchNodeType({NodeType::con, NodeType::floating_con})); } [[nodiscard]] std::set accumulateWorkspaces() const { return accumulateMatchingChildrenRecursive(matchNodeType(NodeType::workspace)); } [[nodiscard]] std::set accumulateWorkspacesStr() const { auto workspaces = accumulateWorkspaces(); std::set 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(findChildRecursive([id](const SwayTreeNode *test) { return test->node.id == id; })); } [[nodiscard]] SwayTreeNode * findWorkspaceByName(const std::string& name) { return const_cast(findChildRecursive([name](const SwayTreeNode *test) { return test->node.name == name && test->node.type == NodeType::workspace; })); } private: [[nodiscard]] static std::function matchNodeType(NodeType::NodeType type) { return matchNodeType(std::vector{type}); } [[nodiscard]] static std::function matchNodeType(const std::vector& 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