Add detail view
This commit is contained in:
parent
da50e7b8fa
commit
d1c5a5641a
@ -46,6 +46,9 @@ set(PROJECT_SOURCES
|
||||
Keys/MoveToScratchpadKeyListener.h
|
||||
Keys/RestoreKeyListener.h
|
||||
Keys/MainWindowAwareKeyListener.h
|
||||
Keys/ToggleDetailsKeyListener.h
|
||||
sway_bindings/SwayRecords.cpp
|
||||
sway_bindings/SwayRecords.h
|
||||
)
|
||||
|
||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
|
@ -53,7 +53,7 @@ protected:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
MainWindow *window;
|
||||
|
||||
[[nodiscard]] SwayTreeModel* getModel() const {
|
||||
|
@ -85,7 +85,7 @@ public:
|
||||
}
|
||||
|
||||
std::string getKeyText() override {
|
||||
return "ENTER";
|
||||
return "Enter";
|
||||
}
|
||||
|
||||
[[nodiscard]] bool canAcceptKey(int key) const override {
|
||||
|
34
Keys/ToggleDetailsKeyListener.h
Normal file
34
Keys/ToggleDetailsKeyListener.h
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// Created by grimmauld on 12.03.24.
|
||||
//
|
||||
|
||||
#ifndef SWAYMUX_TOGGLEDETAILSKEYLISTENER_H
|
||||
#define SWAYMUX_TOGGLEDETAILSKEYLISTENER_H
|
||||
|
||||
#include "MainWindowAwareKeyListener.h"
|
||||
|
||||
class ToggleDetailsKeyListener : public MainWindowAwareKeyListener {
|
||||
public:
|
||||
explicit ToggleDetailsKeyListener(MainWindow *pWindow) : MainWindowAwareKeyListener(pWindow) {}
|
||||
|
||||
void handleKeyEvent(const QKeyEvent *keyEvent) const override {
|
||||
if (window->ui->windowDetails->isHidden())
|
||||
window->ui->windowDetails->show();
|
||||
else
|
||||
window->ui->windowDetails->hide();
|
||||
}
|
||||
|
||||
std::string getDescription() override {
|
||||
return "toggle window detail view";
|
||||
}
|
||||
|
||||
std::string getKeyText() override {
|
||||
return "Tab";
|
||||
}
|
||||
|
||||
[[nodiscard]] bool canAcceptKey(int key) const override {
|
||||
return key == Qt::Key_Tab;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //SWAYMUX_TOGGLEDETAILSKEYLISTENER_H
|
@ -11,6 +11,7 @@
|
||||
#include "Keys/CloseKeyListener.h"
|
||||
#include "Keys/MoveToScratchpadKeyListener.h"
|
||||
#include "Keys/RestoreKeyListener.h"
|
||||
#include "Keys/ToggleDetailsKeyListener.h"
|
||||
#include <QTimer>
|
||||
#include <iostream>
|
||||
|
||||
@ -34,6 +35,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
swayTreeKeyHandler->addListener(new CloseKeyListener(this));
|
||||
swayTreeKeyHandler->addListener(new MoveToScratchpadKeyListener(this));
|
||||
swayTreeKeyHandler->addListener(new RestoreKeyListener(this));
|
||||
swayTreeKeyHandler->addListener(new ToggleDetailsKeyListener(this));
|
||||
|
||||
closeHelpKeyHandler = new KeyHandler(ui->tree_page);
|
||||
closeHelpKeyHandler->addListener(new CloseHelpKeyListener(ui->tree_page));
|
||||
@ -44,6 +46,12 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
ui->tableView->setModel(swayTreeKeyHandler);
|
||||
ui->tableView->resizeColumnsToContents();
|
||||
ui->tableView->installEventFilter(closeHelpKeyHandler);
|
||||
|
||||
ui->windowDetails->hide();
|
||||
selChanged();
|
||||
|
||||
connect( ui->treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
||||
this, SLOT(selChanged()), Qt::DirectConnection ) ;
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
@ -54,6 +62,7 @@ MainWindow::~MainWindow() {
|
||||
}
|
||||
|
||||
void MainWindow::updateModel() const {
|
||||
ui->windowDetails->setModel(nullptr);
|
||||
ui->treeView->setModel(nullptr);
|
||||
auto *focused = model->getRoot() == nullptr ? nullptr : model->getRoot()->findFocused();
|
||||
int id;
|
||||
@ -74,4 +83,15 @@ void MainWindow::updateModel() const {
|
||||
ui->treeView->selectionModel()->setCurrentIndex(model->findIndexByNode(focused), QItemSelectionModel::ClearAndSelect);
|
||||
for (int c = 0; c < model->columnCount(); ++c)
|
||||
ui->treeView->resizeColumnToContents(c);
|
||||
|
||||
selChanged();
|
||||
}
|
||||
|
||||
void MainWindow::selChanged() const {
|
||||
auto current = ui->treeView->selectionModel()->currentIndex();
|
||||
auto *selected = model->getSelectedNode(current);
|
||||
ui->windowDetails->setModel(nullptr);
|
||||
ui->windowDetails->setModel(&selected->node);
|
||||
ui->windowDetails->resizeColumnsToContents();
|
||||
ui->windowDetails->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
|
||||
}
|
@ -23,9 +23,9 @@ public:
|
||||
|
||||
SwayTreeModel* model;
|
||||
Ui::MainWindow *ui;
|
||||
|
||||
public slots:
|
||||
void selChanged() const;
|
||||
private:
|
||||
// QTimer* modelUpdateTimer{};
|
||||
KeyHandler* swayTreeKeyHandler;
|
||||
KeyHandler* closeHelpKeyHandler;
|
||||
};
|
||||
|
@ -26,6 +26,11 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
@ -41,13 +46,10 @@
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayoutTree">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTreeView" name="treeView">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTreeView" name="treeView"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QTableView" name="windowDetails"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@ -59,14 +61,8 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayoutKeys">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTableView" name="tableView">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="2" column="0">
|
||||
<widget class="QTableView" name="tableView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
23
sway_bindings/SwayRecords.cpp
Normal file
23
sway_bindings/SwayRecords.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by grimmauld on 12.03.24.
|
||||
//
|
||||
|
||||
#include "SwayRecords.h"
|
||||
|
||||
QVariant SwayRecord::data(const QModelIndex &index, int role) const {
|
||||
if (!index.isValid() || role != Qt::DisplayRole)
|
||||
return {};
|
||||
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
return QString::fromStdString(jsonFields[index.row()].first);
|
||||
case 1:
|
||||
return QString::fromStdString(jsonFields[index.row()].second);
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
bool SwayRecord::shouldIgnoreKey(const std::string &key) {
|
||||
return key == "floating_nodes" || key == "nodes";
|
||||
}
|
224
sway_bindings/SwayRecords.h
Normal file
224
sway_bindings/SwayRecords.h
Normal file
@ -0,0 +1,224 @@
|
||||
//
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
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
|
@ -20,7 +20,7 @@ struct swaymsg {
|
||||
explicit swaymsg(const unsigned int payloadType, const char *msg, const unsigned int payload_len)
|
||||
: payload_len(payload_len), payload_type(payloadType) {
|
||||
|
||||
this->msg = static_cast<char *>(std::malloc(payload_len));
|
||||
this->msg = new char[payload_len];
|
||||
std::memcpy(this->msg, msg, payload_len);
|
||||
|
||||
buff = new unsigned char [size()];
|
||||
|
120
tree/swaytree.h
120
tree/swaytree.h
@ -9,124 +9,11 @@
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
#include "../sway_bindings/SwayRecords.h"
|
||||
#include "AbstractTreeNode.h"
|
||||
#include "../sway_bindings/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;
|
||||
}
|
||||
}
|
||||
|
||||
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(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"]) {};
|
||||
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;
|
||||
}
|
||||
private:
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
class SwayTreeNode : public AbstractTreeNode<SwayTreeNode> {
|
||||
public:
|
||||
@ -151,8 +38,7 @@ public:
|
||||
|
||||
explicit SwayTreeNode(SwayTreeNode *parent = nullptr) : node(SwayRecord()), AbstractTreeNode(parent) {};
|
||||
|
||||
explicit SwayTreeNode(SwayRecord node, SwayTreeNode *parent = nullptr) : node(std::move(node)),
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user