This commit is contained in:
Joey Yakimowich-Payne 2026-01-27 17:01:55 -07:00
commit 94ce8617d6
2 changed files with 83 additions and 31 deletions

View file

@ -19,22 +19,23 @@ GraphEditorWidget::GraphEditorWidget(Potato::PipeWireController *controller, QWi
{ {
const QString nodeStyleJson = R"JSON({ const QString nodeStyleJson = R"JSON({
"NodeStyle": { "NodeStyle": {
"NormalBoundaryColor": [62, 68, 80], "NormalBoundaryColor": [112, 120, 136],
"SelectedBoundaryColor": [42, 132, 194], "SelectedBoundaryColor": [255, 165, 0],
"GradientColor0": [214, 220, 230], "GradientColor0": [76, 82, 92],
"GradientColor1": [202, 208, 220], "GradientColor1": [68, 74, 84],
"GradientColor2": [192, 198, 210], "GradientColor2": [60, 66, 76],
"GradientColor3": [182, 188, 200], "GradientColor3": [54, 60, 70],
"ShadowColor": [0, 0, 0], "ShadowColor": [12, 12, 12],
"FontColor": [28, 32, 38], "ShadowEnabled": true,
"FontColorFaded": [72, 78, 88], "FontColor": [236, 240, 246],
"ConnectionPointColor": [62, 68, 80], "FontColorFaded": [160, 168, 182],
"FilledConnectionPointColor": [42, 132, 194], "ConnectionPointColor": [200, 208, 220],
"WarningColor": [196, 140, 45], "FilledConnectionPointColor": [255, 165, 0],
"ErrorColor": [196, 64, 64], "WarningColor": [230, 180, 70],
"PenWidth": 1.4, "ErrorColor": [220, 70, 70],
"HoveredPenWidth": 2.2, "PenWidth": 1.3,
"ConnectionPointDiameter": 9.0, "HoveredPenWidth": 2.4,
"ConnectionPointDiameter": 10.0,
"Opacity": 1.0 "Opacity": 1.0
} }
})JSON"; })JSON";
@ -42,9 +43,9 @@ GraphEditorWidget::GraphEditorWidget(Potato::PipeWireController *controller, QWi
const QString viewStyleJson = R"JSON({ const QString viewStyleJson = R"JSON({
"GraphicsViewStyle": { "GraphicsViewStyle": {
"BackgroundColor": [26, 28, 34], "BackgroundColor": [28, 30, 34],
"FineGridColor": [46, 50, 60], "FineGridColor": [44, 48, 56],
"CoarseGridColor": [66, 72, 86] "CoarseGridColor": [62, 68, 80]
} }
})JSON"; })JSON";
QtNodes::GraphicsViewStyle::setStyle(viewStyleJson); QtNodes::GraphicsViewStyle::setStyle(viewStyleJson);
@ -53,25 +54,29 @@ GraphEditorWidget::GraphEditorWidget(Potato::PipeWireController *controller, QWi
m_model->loadLayout(); m_model->loadLayout();
m_scene = new QtNodes::BasicGraphicsScene(*m_model, this); m_scene = new QtNodes::BasicGraphicsScene(*m_model, this);
m_view = new QtNodes::GraphicsView(m_scene); m_view = new QtNodes::GraphicsView(m_scene);
m_scene->setBackgroundBrush(QColor(42, 45, 52)); m_scene->setBackgroundBrush(QColor(28, 30, 34));
auto *splitter = new QSplitter(this); auto *splitter = new QSplitter(this);
splitter->setOrientation(Qt::Horizontal); splitter->setOrientation(Qt::Horizontal);
splitter->addWidget(m_view); splitter->addWidget(m_view);
auto *meterPanel = new QWidget(splitter); auto *meterPanel = new QWidget(splitter);
meterPanel->setStyleSheet("background-color: #1f2126; border-left: 1px solid #2b2f38;");
auto *meterLayout = new QVBoxLayout(meterPanel); auto *meterLayout = new QVBoxLayout(meterPanel);
meterLayout->setContentsMargins(12, 12, 12, 12); meterLayout->setContentsMargins(20, 24, 20, 20);
meterLayout->setSpacing(10); meterLayout->setSpacing(16);
auto *meterLabel = new QLabel(QString("Master Meter"), meterPanel); auto *meterLabel = new QLabel(QString("MASTER OUTPUT"), meterPanel);
meterLabel->setStyleSheet("color: #aab2c2; font-weight: 700; font-size: 11px; letter-spacing: 1px; border: none;");
meterLabel->setAlignment(Qt::AlignCenter);
meterLayout->addWidget(meterLabel); meterLayout->addWidget(meterLabel);
m_meter = new AudioLevelMeter(meterPanel); m_meter = new AudioLevelMeter(meterPanel);
meterLayout->addWidget(m_meter, 1); meterLayout->addWidget(m_meter, 1);
meterLayout->addStretch(); meterLayout->addStretch();
meterPanel->setFixedWidth(140); meterPanel->setFixedWidth(160);
splitter->addWidget(meterPanel); splitter->addWidget(meterPanel);
splitter->setStretchFactor(0, 1); splitter->setStretchFactor(0, 1);
splitter->setStretchFactor(1, 0); splitter->setStretchFactor(1, 0);
@ -172,7 +177,8 @@ static bool isAudioEndpoint(const Potato::NodeInfo &node)
{ {
return node.mediaClass == Potato::MediaClass::AudioSink return node.mediaClass == Potato::MediaClass::AudioSink
|| node.mediaClass == Potato::MediaClass::AudioSource || node.mediaClass == Potato::MediaClass::AudioSource
|| node.mediaClass == Potato::MediaClass::AudioDuplex; || node.mediaClass == Potato::MediaClass::AudioDuplex
|| node.mediaClass == Potato::MediaClass::Stream;
} }
void GraphEditorWidget::syncGraph() void GraphEditorWidget::syncGraph()

View file

@ -6,15 +6,18 @@
#include <QtCore/QJsonObject> #include <QtCore/QJsonObject>
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QStandardPaths> #include <QtCore/QStandardPaths>
#include <QVariant>
#include <QtGui/QFont> #include <QtGui/QFont>
#include <QtGui/QFontMetrics> #include <QtGui/QFontMetrics>
#include <QtCore/QRectF> #include <QtCore/QRectF>
#include <QtCore/QSizeF> #include <QtCore/QSizeF>
#include <QtGui/QColor>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QtNodes/NodeStyle>
#include <QtNodes/StyleCollection> #include <QtNodes/StyleCollection>
#include <algorithm> #include <algorithm>
@ -22,6 +25,49 @@
#include <vector> #include <vector>
namespace { namespace {
QVariant nodeStyleVariant(const Potato::NodeInfo &info)
{
QtNodes::NodeStyle style = QtNodes::StyleCollection::nodeStyle();
QColor base;
switch (info.type) {
case Potato::NodeType::Hardware:
base = QColor(72, 94, 118);
break;
case Potato::NodeType::Virtual:
base = QColor(62, 122, 104);
break;
case Potato::NodeType::Application:
base = QColor(138, 104, 72);
break;
case Potato::NodeType::Bus:
base = QColor(86, 92, 128);
break;
default:
base = QColor(86, 94, 108);
break;
}
style.GradientColor0 = base.lighter(120);
style.GradientColor1 = base.lighter(108);
style.GradientColor2 = base.darker(105);
style.GradientColor3 = base.darker(120);
style.NormalBoundaryColor = base.lighter(135);
style.SelectedBoundaryColor = QColor(255, 165, 0);
style.FontColor = QColor(236, 240, 246);
style.FontColorFaded = QColor(160, 168, 182);
style.ConnectionPointColor = QColor(200, 208, 220);
style.FilledConnectionPointColor = QColor(255, 165, 0);
style.WarningColor = QColor(230, 180, 70);
style.ErrorColor = QColor(220, 70, 70);
style.PenWidth = 1.3f;
style.HoveredPenWidth = 2.4f;
style.ConnectionPointDiameter = 10.0f;
style.Opacity = 1.0f;
return style.toJson().toVariantMap();
}
int nodeWidthFor(const Potato::NodeInfo &info) int nodeWidthFor(const Potato::NodeInfo &info)
{ {
QFont captionFont; QFont captionFont;
@ -38,9 +84,9 @@ int nodeWidthFor(const Potato::NodeInfo &info)
maxTextWidth = std::max(maxTextWidth, portMetrics.horizontalAdvance(port.name)); maxTextWidth = std::max(maxTextWidth, portMetrics.horizontalAdvance(port.name));
} }
const int widthPadding = 180; const int widthPadding = 120;
const int minWidth = 320; const int minWidth = 200;
const int maxWidth = 700; const int maxWidth = 600;
const int width = maxTextWidth + widthPadding; const int width = maxTextWidth + widthPadding;
return std::max(minWidth, std::min(maxWidth, width)); return std::max(minWidth, std::min(maxWidth, width));
} }
@ -212,9 +258,9 @@ QVariant PipeWireGraphModel::nodeData(QtNodes::NodeId nodeId, QtNodes::NodeRole
case QtNodes::NodeRole::Size: case QtNodes::NodeRole::Size:
{ {
const int maxPorts = std::max(info.inputPorts.size(), info.outputPorts.size()); const int maxPorts = std::max(info.inputPorts.size(), info.outputPorts.size());
const int baseHeight = 70; const int baseHeight = 50;
const int perPortHeight = 28; const int perPortHeight = 28;
const int height = std::max(110, baseHeight + (maxPorts * perPortHeight)); const int height = std::max(80, baseHeight + (maxPorts * perPortHeight));
const int width = nodeWidthFor(info); const int width = nodeWidthFor(info);
@ -227,7 +273,7 @@ QVariant PipeWireGraphModel::nodeData(QtNodes::NodeId nodeId, QtNodes::NodeRole
case QtNodes::NodeRole::Type: case QtNodes::NodeRole::Type:
return QString("PipeWire"); return QString("PipeWire");
case QtNodes::NodeRole::Style: case QtNodes::NodeRole::Style:
return QtNodes::StyleCollection::nodeStyle().toJson().toVariantMap(); return nodeStyleVariant(info);
default: default:
return QVariant(); return QVariant();
} }