Compare commits
No commits in common. "621d67ebab29c3e048407cf7f0846f80ea08337f" and "916965488c9d3d2fd2b6da2584e1795fbc908e85" have entirely different histories.
621d67ebab
...
916965488c
4 changed files with 149 additions and 789 deletions
|
|
@ -802,13 +802,13 @@ void GraphEditorWidget::onContextMenuRequested(const QPoint &pos) {
|
|||
QPointF scenePos = m_view->mapToScene(pos);
|
||||
m_lastContextMenuScenePos = scenePos;
|
||||
|
||||
bool hitNode = false;
|
||||
uint32_t hitPwNodeId = 0;
|
||||
QtNodes::NodeId hitQtNodeId = 0;
|
||||
for (auto nodeId : m_model->allNodeIds()) {
|
||||
const WarpNodeData *data = m_model->warpNodeData(nodeId);
|
||||
if (!data)
|
||||
if (!data) {
|
||||
continue;
|
||||
}
|
||||
QPointF nodePos =
|
||||
m_model->nodeData(nodeId, QtNodes::NodeRole::Position).toPointF();
|
||||
QSize nodeSize =
|
||||
|
|
@ -817,13 +817,12 @@ void GraphEditorWidget::onContextMenuRequested(const QPoint &pos) {
|
|||
if (nodeRect.contains(scenePos)) {
|
||||
hitPwNodeId = data->info.id.value;
|
||||
hitQtNodeId = nodeId;
|
||||
hitNode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QPoint screenPos = m_view->mapToGlobal(pos);
|
||||
if (hitNode) {
|
||||
if (hitPwNodeId != 0) {
|
||||
showNodeContextMenu(screenPos, hitPwNodeId, hitQtNodeId);
|
||||
} else {
|
||||
showCanvasContextMenu(screenPos, scenePos);
|
||||
|
|
@ -1674,29 +1673,13 @@ void GraphEditorWidget::updateMeters() {
|
|||
const WarpNodeData *data = m_model->warpNodeData(nodeId);
|
||||
if (!data || !row.meter)
|
||||
continue;
|
||||
|
||||
const AppGroupData *group = m_model->appGroupData(nodeId);
|
||||
if (group) {
|
||||
float maxLevel = 0.0f;
|
||||
for (uint32_t memberPwId : group->memberPwIds) {
|
||||
auto peak = m_client->NodeMeterPeak(warppipe::NodeId{memberPwId});
|
||||
if (peak.ok())
|
||||
maxLevel = std::max(maxLevel,
|
||||
std::max(peak.value.peak_left, peak.value.peak_right));
|
||||
}
|
||||
row.meter->setLevel(maxLevel);
|
||||
m_model->setNodePeakLevel(nodeId, maxLevel);
|
||||
if (maxLevel > 0.001f)
|
||||
auto peak = m_client->NodeMeterPeak(data->info.id);
|
||||
if (peak.ok()) {
|
||||
float level = std::max(peak.value.peak_left, peak.value.peak_right);
|
||||
row.meter->setLevel(level);
|
||||
m_model->setNodePeakLevel(nodeId, level);
|
||||
if (level > 0.001f)
|
||||
anyActive = true;
|
||||
} else {
|
||||
auto peak = m_client->NodeMeterPeak(data->info.id);
|
||||
if (peak.ok()) {
|
||||
float level = std::max(peak.value.peak_left, peak.value.peak_right);
|
||||
row.meter->setLevel(level);
|
||||
m_model->setNodePeakLevel(nodeId, level);
|
||||
if (level > 0.001f)
|
||||
anyActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1737,16 +1720,8 @@ void GraphEditorWidget::rebuildNodeMeters() {
|
|||
if (!data)
|
||||
continue;
|
||||
|
||||
const AppGroupData *group = m_model->appGroupData(nodeId);
|
||||
if (group) {
|
||||
for (uint32_t memberPwId : group->memberPwIds) {
|
||||
new_pw_ids[memberPwId] = true;
|
||||
m_client->EnsureNodeMeter(warppipe::NodeId{memberPwId});
|
||||
}
|
||||
} else {
|
||||
new_pw_ids[data->info.id.value] = true;
|
||||
m_client->EnsureNodeMeter(data->info.id);
|
||||
}
|
||||
new_pw_ids[data->info.id.value] = true;
|
||||
m_client->EnsureNodeMeter(data->info.id);
|
||||
|
||||
auto *row = new QWidget();
|
||||
auto *rowLayout = new QHBoxLayout(row);
|
||||
|
|
@ -2324,21 +2299,8 @@ void GraphEditorWidget::updateNodeDetailsPanel(QtNodes::NodeId nodeId) {
|
|||
QString::fromStdString(info.media_role));
|
||||
}
|
||||
|
||||
const AppGroupData *groupData = m_model->appGroupData(nodeId);
|
||||
if (groupData) {
|
||||
addField(QStringLiteral("STREAMS"),
|
||||
QString::number(groupData->memberPwIds.size()));
|
||||
QString memberIds;
|
||||
for (uint32_t pwId : groupData->memberPwIds) {
|
||||
if (!memberIds.isEmpty())
|
||||
memberIds += QStringLiteral(", ");
|
||||
memberIds += QString::number(pwId);
|
||||
}
|
||||
addField(QStringLiteral("MEMBER NODE IDS"), memberIds);
|
||||
} else {
|
||||
addField(QStringLiteral("NODE ID"),
|
||||
QString::number(info.id.value));
|
||||
}
|
||||
addField(QStringLiteral("NODE ID"),
|
||||
QString::number(info.id.value));
|
||||
|
||||
if (!data->inputPorts.empty()) {
|
||||
layout->addSpacing(8);
|
||||
|
|
|
|||
|
|
@ -66,17 +66,7 @@ QPainterPath SquareConnectionPainter::orthogonalPath(
|
|||
constexpr double kNodePad = 15.0;
|
||||
|
||||
auto const cId = cgo.connectionId();
|
||||
|
||||
double spread = static_cast<double>(cId.outPortIndex) * kSpacing;
|
||||
auto *sceneForChannel = cgo.nodeScene();
|
||||
if (sceneForChannel) {
|
||||
auto *mdl = dynamic_cast<WarpGraphModel *>(&sceneForChannel->graphModel());
|
||||
if (mdl) {
|
||||
auto ch = mdl->connectionChannel(cId);
|
||||
spread = (static_cast<double>(ch.index) - (ch.count - 1) / 2.0)
|
||||
* kSpacing;
|
||||
}
|
||||
}
|
||||
double const spread = static_cast<double>(cId.outPortIndex) * kSpacing;
|
||||
|
||||
double const dy = in.y() - out.y();
|
||||
|
||||
|
|
@ -124,52 +114,51 @@ QPainterPath SquareConnectionPainter::orthogonalPath(
|
|||
// out -------+ seg 1 + corner 1
|
||||
//
|
||||
|
||||
double railOffset = 0.0;
|
||||
if (sceneForChannel) {
|
||||
auto *mdl2 = dynamic_cast<WarpGraphModel *>(&sceneForChannel->graphModel());
|
||||
if (mdl2) {
|
||||
auto ch = mdl2->connectionChannel(cId);
|
||||
railOffset = static_cast<double>(ch.index) * kSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
double rightX = out.x() + kMinStub + railOffset;
|
||||
double leftX = in.x() - kMinStub - railOffset;
|
||||
double midY = (out.y() + in.y()) / 2.0 + spread;
|
||||
double rightX = out.x() + kMinStub + spread;
|
||||
double leftX = in.x() - kMinStub - spread;
|
||||
double midY = (out.y() + in.y()) / 2.0;
|
||||
|
||||
// Use actual node geometry when available so the path routes cleanly
|
||||
// around both nodes instead of cutting through them.
|
||||
auto *scene = cgo.nodeScene();
|
||||
if (scene) {
|
||||
auto *outNGO = scene->nodeGraphicsObject(cId.outNodeId);
|
||||
auto *inNGO = scene->nodeGraphicsObject(cId.inNodeId);
|
||||
if (outNGO && inNGO) {
|
||||
// Map node scene bounds into the CGO's local coordinate space
|
||||
// (endPoint() values live there too).
|
||||
QRectF const outRect =
|
||||
cgo.mapRectFromScene(outNGO->sceneBoundingRect());
|
||||
QRectF const inRect =
|
||||
cgo.mapRectFromScene(inNGO->sceneBoundingRect());
|
||||
|
||||
// Push vertical rails outside both nodes.
|
||||
double const rightEdge = std::max(outRect.right(), inRect.right());
|
||||
rightX = std::max(rightX, rightEdge + kNodePad + railOffset);
|
||||
rightX = std::max(rightX, rightEdge + kNodePad + spread);
|
||||
|
||||
double const leftEdge = std::min(outRect.left(), inRect.left());
|
||||
leftX = std::min(leftX, leftEdge - kNodePad - railOffset);
|
||||
leftX = std::min(leftX, leftEdge - kNodePad - spread);
|
||||
|
||||
// Place the horizontal crossover in the gap between nodes when
|
||||
// they don't overlap vertically; otherwise route above or below.
|
||||
double const topInner =
|
||||
std::min(outRect.bottom(), inRect.bottom());
|
||||
double const botInner =
|
||||
std::max(outRect.top(), inRect.top());
|
||||
|
||||
if (botInner > topInner + 2.0 * kNodePad) {
|
||||
// Vertical gap exists — clamp midY into the gap.
|
||||
midY = std::clamp(midY, topInner + kNodePad,
|
||||
botInner - kNodePad);
|
||||
} else {
|
||||
// Nodes overlap vertically — pick the shorter detour.
|
||||
double const above =
|
||||
std::min(outRect.top(), inRect.top()) - kNodePad;
|
||||
double const below =
|
||||
std::max(outRect.bottom(), inRect.bottom()) + kNodePad;
|
||||
double baseMidY = (out.y() + in.y()) / 2.0;
|
||||
midY = (std::abs(baseMidY - above) < std::abs(baseMidY - below))
|
||||
? above + spread
|
||||
: below + spread;
|
||||
midY = (std::abs(midY - above) < std::abs(midY - below))
|
||||
? above
|
||||
: below;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -43,15 +43,6 @@ struct WarpNodeData {
|
|||
std::vector<warppipe::PortInfo> outputPorts;
|
||||
};
|
||||
|
||||
/// Data for an app-group node (multiple PipeWire streams collapsed into one visual node).
|
||||
struct AppGroupData {
|
||||
std::string groupKey;
|
||||
std::vector<uint32_t> memberPwIds; ///< PipeWire node IDs in this group.
|
||||
/// canonical port index → list of actual member PortIds for fan-out.
|
||||
std::unordered_map<unsigned int, std::vector<warppipe::PortId>> outputPortMap;
|
||||
std::unordered_map<unsigned int, std::vector<warppipe::PortId>> inputPortMap;
|
||||
};
|
||||
|
||||
class WarpGraphModel : public QtNodes::AbstractGraphModel {
|
||||
Q_OBJECT
|
||||
|
||||
|
|
@ -96,9 +87,6 @@ public:
|
|||
|
||||
uint32_t findPwNodeIdByName(const std::string &name) const;
|
||||
|
||||
bool isGroupNode(QtNodes::NodeId nodeId) const;
|
||||
const AppGroupData *appGroupData(QtNodes::NodeId nodeId) const;
|
||||
|
||||
struct NodeVolumeState {
|
||||
float volume = 1.0f;
|
||||
bool mute = false;
|
||||
|
|
@ -110,12 +98,6 @@ public:
|
|||
void setNodePeakLevel(QtNodes::NodeId nodeId, float level);
|
||||
float nodePeakLevel(QtNodes::NodeId nodeId) const;
|
||||
|
||||
struct ConnectionChannel {
|
||||
int index = 0;
|
||||
int count = 1;
|
||||
};
|
||||
ConnectionChannel connectionChannel(QtNodes::ConnectionId cId) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void beginBatchUpdate();
|
||||
void endBatchUpdate();
|
||||
|
|
@ -191,20 +173,4 @@ private:
|
|||
std::unordered_map<QtNodes::NodeId, QPointer<QWidget>> m_volumeWidgets;
|
||||
mutable std::unordered_map<QtNodes::NodeId, QVariant> m_styleCache;
|
||||
std::unordered_map<QtNodes::NodeId, float> m_peakLevels;
|
||||
std::unordered_map<QtNodes::ConnectionId, ConnectionChannel> m_connectionChannels;
|
||||
|
||||
std::unordered_map<QtNodes::NodeId, AppGroupData> m_appGroups;
|
||||
std::unordered_map<std::string, QtNodes::NodeId> m_groupKeyToQt;
|
||||
std::unordered_map<uint32_t, QtNodes::NodeId> m_pwToGroupQt;
|
||||
|
||||
struct GroupPortRef {
|
||||
QtNodes::NodeId groupQtId;
|
||||
QtNodes::PortIndex portIndex;
|
||||
bool isInput;
|
||||
};
|
||||
std::unordered_map<uint32_t, GroupPortRef> m_portToGroupPort;
|
||||
|
||||
void rebuildGroupPortMap(QtNodes::NodeId groupQtId);
|
||||
|
||||
void recomputeConnectionChannels();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue