swaymux/sway_bindings/SwayRecords.h

229 lines
6.1 KiB
C++

//
// Created by grimmauld on 12.03.24.
//
#ifndef SWAYMUX_SWAYRECORDS_H
#define SWAYMUX_SWAYRECORDS_H
#include <nlohmann/json.hpp>
#include <QAbstractTableModel>
#include <unordered_map>
#include <unordered_set>
using json = nlohmann::json;
#include "Sway.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;
}
static std::string toString(NodeType nodeType) {
switch (nodeType) {
case output:
return "output";
case workspace:
return "workspace";
case con:
return "con";
case floating_con:
return "floating_con";
default:
return "root";
}
}
static QString toQString(NodeType nodeType) {
return QString::fromStdString(toString(nodeType));
}
[[nodiscard]] static inline bool isContainer(NodeType type) {
return type == con || type == floating_con;
}
}
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;
}
static std::string toString(NodeLayout nodeLayout) {
switch (nodeLayout) {
case splith:
return "splith";
case splitv:
return "splitv";
case stacked:
return "stacked";
case tabbed:
return "tabbed";
default:
return "output";
}
}
static QString toQString(NodeLayout nodeLayout) {
return QString::fromStdString(toString(nodeLayout));
}
}
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;
}
static std::string toString(NodeOrientation nodeOrientation) {
switch (nodeOrientation) {
case vertical:
return "vertical";
case horizontal:
return "horizontal";
default:
return "none";
}
}
static QString toQString(NodeOrientation nodeOrientation) {
return QString::fromStdString(toString(nodeOrientation));
}
}
struct SwayRecord : public QAbstractTableModel {
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),
QAbstractTableModel(nullptr){}
[[nodiscard]] static bool shouldIgnoreKey(const std::string &key);
explicit SwayRecord(const json &rep) :
id(rep["id"]),
name(getName(rep)),
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"]),
QAbstractTableModel(nullptr) {
for (json::const_iterator it = rep.cbegin(); it != rep.cend(); ++it) {
if (!SwayRecord::shouldIgnoreKey(it.key()))
jsonFields.emplace_back(it.key(), it.value().dump());
}
};
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;
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;
}
[[nodiscard]] int rowCount(const QModelIndex &parent) const override {
return (int) jsonFields.size();
}
[[nodiscard]] int columnCount(const QModelIndex &parent) const override {
return 2;
}
[[nodiscard]] QVariant data(const QModelIndex &index, int role) const override;
[[nodiscard]] QVariant headerData(int section, Qt::Orientation qtOrientation,
int role) const override {
if (qtOrientation != Qt::Horizontal || role != Qt::DisplayRole)
return QVariant{};
switch (section) {
case 0:
return "Field";
case 1:
return "State";
default:
return QVariant{};
}
}
private:
std::vector<std::pair<std::string, std::string>> jsonFields;
static std::string getName(const json& rep) {
if(rep["name"].is_null())
return "Untitled Container";
std::string internal = rep["name"];
if (internal == "__i3" && NodeType::fromString(rep["type"]) == NodeType::output)
return "Virtual Display";
if (internal == "__i3_scratch" && NodeType::fromString(rep["type"]) == NodeType::workspace)
return "Scratchpad";
return internal;
}
};
#endif //SWAYMUX_SWAYRECORDS_H