Add video node visualization
This commit is contained in:
parent
d314ad7dd9
commit
8a8b039dcc
4 changed files with 56 additions and 7 deletions
|
|
@ -1252,6 +1252,8 @@ void GraphEditorWidget::rebuildMixerStrips() {
|
|||
const WarpNodeData *data = m_model->warpNodeData(nodeId);
|
||||
if (!data)
|
||||
continue;
|
||||
if (!nodeHasVolume(WarpGraphModel::classifyNode(data->info)))
|
||||
continue;
|
||||
|
||||
auto *strip = new QWidget();
|
||||
strip->setStyleSheet(QStringLiteral(
|
||||
|
|
|
|||
|
|
@ -230,6 +230,9 @@ QVariant WarpGraphModel::portData(QtNodes::NodeId nodeId,
|
|||
const auto &data = it->second;
|
||||
|
||||
if (role == QtNodes::PortRole::DataType) {
|
||||
WarpNodeType ntype = classifyNode(data.info);
|
||||
if (ntype == WarpNodeType::kVideoSource || ntype == WarpNodeType::kVideoSink)
|
||||
return QString("video");
|
||||
return QString("audio");
|
||||
}
|
||||
|
||||
|
|
@ -479,9 +482,11 @@ void WarpGraphModel::refreshFromClient() {
|
|||
}
|
||||
}
|
||||
|
||||
auto *volumeWidget = new NodeVolumeWidget();
|
||||
m_volumeWidgets[qtId] = volumeWidget;
|
||||
m_volumeStates[qtId] = {};
|
||||
if (nodeHasVolume(nodeType)) {
|
||||
auto *volumeWidget = new NodeVolumeWidget();
|
||||
m_volumeWidgets[qtId] = volumeWidget;
|
||||
m_volumeStates[qtId] = {};
|
||||
}
|
||||
|
||||
Q_EMIT nodeCreated(qtId);
|
||||
}
|
||||
|
|
@ -801,6 +806,12 @@ WarpGraphModel::classifyNode(const warppipe::NodeInfo &info) {
|
|||
if (mc == "Stream/Output/Audio" || mc == "Stream/Input/Audio") {
|
||||
return WarpNodeType::kApplication;
|
||||
}
|
||||
if (mc == "Video/Source") {
|
||||
return WarpNodeType::kVideoSource;
|
||||
}
|
||||
if (mc == "Video/Sink") {
|
||||
return WarpNodeType::kVideoSink;
|
||||
}
|
||||
|
||||
return WarpNodeType::kUnknown;
|
||||
}
|
||||
|
|
@ -1071,9 +1082,11 @@ bool WarpGraphModel::loadLayout(const QString &path) {
|
|||
? m_positions.at(qtId)
|
||||
: QPointF(0, 0);
|
||||
|
||||
auto *volumeWidget = new NodeVolumeWidget();
|
||||
m_volumeWidgets[qtId] = volumeWidget;
|
||||
m_volumeStates[qtId] = {};
|
||||
if (nodeHasVolume(classifyNode(info))) {
|
||||
auto *volumeWidget = new NodeVolumeWidget();
|
||||
m_volumeWidgets[qtId] = volumeWidget;
|
||||
m_volumeStates[qtId] = {};
|
||||
}
|
||||
|
||||
Q_EMIT nodeCreated(qtId);
|
||||
}
|
||||
|
|
@ -1105,6 +1118,7 @@ void WarpGraphModel::autoArrange() {
|
|||
Column sources;
|
||||
Column apps;
|
||||
Column sinks;
|
||||
Column video;
|
||||
|
||||
for (const auto &[qtId, data] : m_nodes) {
|
||||
WarpNodeType type = classifyNode(data.info);
|
||||
|
|
@ -1121,6 +1135,11 @@ void WarpGraphModel::autoArrange() {
|
|||
apps.ids.push_back(qtId);
|
||||
apps.maxWidth = std::max(apps.maxWidth, w);
|
||||
break;
|
||||
case WarpNodeType::kVideoSource:
|
||||
case WarpNodeType::kVideoSink:
|
||||
video.ids.push_back(qtId);
|
||||
video.maxWidth = std::max(video.maxWidth, w);
|
||||
break;
|
||||
default:
|
||||
sinks.ids.push_back(qtId);
|
||||
sinks.maxWidth = std::max(sinks.maxWidth, w);
|
||||
|
|
@ -1146,6 +1165,10 @@ void WarpGraphModel::autoArrange() {
|
|||
layoutColumn(apps, x);
|
||||
x += apps.maxWidth + kHorizontalGap * 3;
|
||||
layoutColumn(sinks, x);
|
||||
if (!video.ids.empty()) {
|
||||
x += sinks.maxWidth + kHorizontalGap * 3;
|
||||
layoutColumn(video, x);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant WarpGraphModel::styleForNode(WarpNodeType type, bool ghost) {
|
||||
|
|
@ -1168,6 +1191,12 @@ QVariant WarpGraphModel::styleForNode(WarpNodeType type, bool ghost) {
|
|||
case WarpNodeType::kApplication:
|
||||
base = QColor(138, 104, 72);
|
||||
break;
|
||||
case WarpNodeType::kVideoSource:
|
||||
base = QColor(120, 80, 130);
|
||||
break;
|
||||
case WarpNodeType::kVideoSink:
|
||||
base = QColor(100, 70, 140);
|
||||
break;
|
||||
default:
|
||||
base = QColor(86, 94, 108);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -20,8 +20,21 @@ enum class WarpNodeType : uint8_t {
|
|||
kVirtualSink,
|
||||
kVirtualSource,
|
||||
kApplication,
|
||||
kVideoSource,
|
||||
kVideoSink,
|
||||
};
|
||||
|
||||
inline bool nodeHasVolume(WarpNodeType type) {
|
||||
switch (type) {
|
||||
case WarpNodeType::kVideoSource:
|
||||
case WarpNodeType::kVideoSink:
|
||||
case WarpNodeType::kUnknown:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
struct WarpNodeData {
|
||||
warppipe::NodeInfo info;
|
||||
std::vector<warppipe::PortInfo> inputPorts;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/catch_approx.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace {
|
||||
|
||||
warppipe::ConnectionOptions TestOptions() {
|
||||
|
|
@ -1093,7 +1095,8 @@ TEST_CASE("setNodeVolumeState syncs inline widget") {
|
|||
ns.mute = true;
|
||||
model.setNodeVolumeState(qtId, ns);
|
||||
|
||||
REQUIRE(vol->volume() == 70);
|
||||
// Cubic scaling: slider = cbrt(0.7) * 100 ≈ 89
|
||||
REQUIRE(vol->volume() == static_cast<int>(std::round(std::cbrt(0.7f) * 100.0f)));
|
||||
REQUIRE(vol->isMuted());
|
||||
}
|
||||
|
||||
|
|
@ -1139,6 +1142,8 @@ TEST_CASE("preset saves and loads volume state") {
|
|||
}
|
||||
REQUIRE(found);
|
||||
|
||||
tc.client->Test_SetNodeVolume(warppipe::NodeId{100650}, 1.0f, false);
|
||||
|
||||
WarpGraphModel model2(tc.client.get());
|
||||
model2.refreshFromClient();
|
||||
auto qtId2 = model2.qtNodeIdForPw(100650);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue