// // Created by grimmauld on 03.03.24. // #ifndef SWAYMUX_SWAYTREE_H #define SWAYMUX_SWAYTREE_H #include #include using json = nlohmann::json; #include "AbstractTreeNode.h" namespace NodeType { enum NodeType { root, output, workspace, con, floating_con }; static NodeType fromString(const std::string &str) { if (str == "output") { return output; } if (str == "workspace") { return workspace; } if (str == "con") { return con; } if (str == "floating_con") { return floating_con; } return root; } } namespace NodeLayout { enum NodeLayout { splith, splitv, stacked, tabbed, output }; static NodeLayout fromString(const std::string &str) { if (str == "splith") { return splith; } if (str == "splitv") { return splitv; } if (str == "stacked") { return stacked; } if (str == "tabbed") { return tabbed; } return output; } } namespace NodeOrientation { enum NodeOrientation { vertical, horizontal, none }; static NodeOrientation fromString(const std::string &str) { if (str == "vertical") { return vertical; } if (str == "horizontal") { return horizontal; } return none; } } struct SwayRecord { explicit SwayRecord() : id(0), name("rootItem"), type(NodeType::root), current_border_width(0), layout(NodeLayout::output), orientation(NodeOrientation::none), urgent(false), sticky(false), focused(false) {} explicit SwayRecord(const json &rep) : id(rep["id"]), name(rep["name"].is_null() ? "untitled container" : rep["name"]), type(NodeType::fromString(rep["type"])), border(rep["border"]), current_border_width(rep["current_border_width"]), layout(NodeLayout::fromString((rep["layout"]))), orientation(NodeOrientation::fromString(rep["orientation"])), urgent(rep["urgent"]), sticky(rep["sticky"]), focused(rep["focused"]) {}; const int id; const std::string name; const NodeType::NodeType type; const std::string border; const int current_border_width; const NodeLayout::NodeLayout layout; const NodeOrientation::NodeOrientation orientation; const bool urgent; const bool sticky; const bool focused; [[nodiscard]] bool operator<(const SwayRecord &other) const { return this->id < other.id; } [[nodiscard]] bool operator==(const SwayRecord &other) const { return this->id == other.id; } }; class SwayTreeNode : public AbstractTreeNode { public: const SwayRecord node; explicit SwayTreeNode(const json &rep, SwayTreeNode *parent = nullptr) : node(SwayRecord(rep)), AbstractTreeNode(parent) { for (const auto &child: rep["nodes"]) { auto childNode = std::make_unique(child, this); this->appendChild(childNode); } /* for (const auto &child: rep["floating_nodes"]) { 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]] const SwayTreeNode *findFocused() const { 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)); } private: [[nodiscard]] static std::function matchNodeType(const NodeType::NodeType type) { return [type](const SwayTreeNode *testNode) { return testNode->node.type == type; }; } }; #endif //SWAYMUX_SWAYTREE_H