This commit is contained in:
Joey Yakimowich-Payne 2026-01-27 16:41:51 -07:00
commit 87e5aca9d8
11 changed files with 459 additions and 33 deletions

View file

@ -1,19 +1,56 @@
#include "PipeWireGraphModel.h"
#include "PipeWireGraphModel.h"
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QObject>
#include <QtCore/QStandardPaths>
#include <QtGui/QFont>
#include <QtGui/QFontMetrics>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QtNodes/StyleCollection>
#include <algorithm>
#include <unordered_set>
#include <vector>
namespace {
int nodeWidthFor(const Potato::NodeInfo &info)
{
QFont captionFont;
captionFont.setBold(true);
QFontMetrics captionMetrics(captionFont);
int maxTextWidth = captionMetrics.horizontalAdvance(info.name);
QFont portFont;
QFontMetrics portMetrics(portFont);
for (const auto &port : info.inputPorts) {
maxTextWidth = std::max(maxTextWidth, portMetrics.horizontalAdvance(port.name));
}
for (const auto &port : info.outputPorts) {
maxTextWidth = std::max(maxTextWidth, portMetrics.horizontalAdvance(port.name));
}
const int widthPadding = 140;
const int minWidth = 300;
const int maxWidth = 520;
const int width = maxTextWidth + widthPadding;
return std::max(minWidth, std::min(maxWidth, width));
}
QString elideLabel(const QString &text, int width, const QFont &font)
{
QFontMetrics metrics(font);
const int available = std::max(60, width);
return metrics.elidedText(text, Qt::ElideRight, available);
}
}
PipeWireGraphModel::PipeWireGraphModel(Potato::PipeWireController *controller, QObject *parent)
: QtNodes::AbstractGraphModel()
, m_controller(controller)
@ -154,7 +191,12 @@ QVariant PipeWireGraphModel::nodeData(QtNodes::NodeId nodeId, QtNodes::NodeRole
switch (role) {
case QtNodes::NodeRole::Caption:
return info.name;
{
QFont captionFont;
captionFont.setBold(true);
const int width = nodeWidthFor(info) - 40;
return elideLabel(info.name, width, captionFont);
}
case QtNodes::NodeRole::CaptionVisible:
return true;
case QtNodes::NodeRole::Position: {
@ -165,13 +207,24 @@ QVariant PipeWireGraphModel::nodeData(QtNodes::NodeId nodeId, QtNodes::NodeRole
return QPointF(0, 0);
}
case QtNodes::NodeRole::Size:
return QSize(180, 80);
{
const int maxPorts = std::max(info.inputPorts.size(), info.outputPorts.size());
const int baseHeight = 70;
const int perPortHeight = 28;
const int height = std::max(110, baseHeight + (maxPorts * perPortHeight));
const int width = nodeWidthFor(info);
return QSize(width, height);
}
case QtNodes::NodeRole::InPortCount:
return static_cast<unsigned int>(info.inputPorts.size());
case QtNodes::NodeRole::OutPortCount:
return static_cast<unsigned int>(info.outputPorts.size());
case QtNodes::NodeRole::Type:
return QString("PipeWire");
case QtNodes::NodeRole::Style:
return QtNodes::StyleCollection::nodeStyle().toJson().toVariantMap();
default:
return QVariant();
}
@ -217,11 +270,15 @@ QVariant PipeWireGraphModel::portData(QtNodes::NodeId nodeId,
if (role == QtNodes::PortRole::Caption) {
if (portType == QtNodes::PortType::In) {
if (portIndex < static_cast<QtNodes::PortIndex>(info.inputPorts.size())) {
return portLabel(info.inputPorts.at(portIndex));
QFont font;
const int width = nodeWidthFor(info) - 80;
return elideLabel(info.inputPorts.at(portIndex).name, width, font);
}
} else if (portType == QtNodes::PortType::Out) {
if (portIndex < static_cast<QtNodes::PortIndex>(info.outputPorts.size())) {
return portLabel(info.outputPorts.at(portIndex));
QFont font;
const int width = nodeWidthFor(info) - 80;
return elideLabel(info.outputPorts.at(portIndex).name, width, font);
}
}
}
@ -361,6 +418,19 @@ bool PipeWireGraphModel::findConnectionForLink(uint32_t linkId, QtNodes::Connect
return true;
}
bool PipeWireGraphModel::updatePipeWireNode(const Potato::NodeInfo &node)
{
auto it = m_pwToNode.find(node.id);
if (it == m_pwToNode.end()) {
return false;
}
const QtNodes::NodeId nodeId = it->second;
m_nodes[nodeId] = node;
Q_EMIT nodeUpdated(nodeId);
return true;
}
const Potato::NodeInfo *PipeWireGraphModel::nodeInfo(QtNodes::NodeId nodeId) const
{
auto it = m_nodes.find(nodeId);
@ -650,3 +720,4 @@ bool PipeWireGraphModel::viewState(double &scale, QPointF &center) const
center = m_viewCenter;
return true;
}
#include <QtNodes/StyleCollection>