Compare commits

..

No commits in common. "5bb41373b21aa20975e4aa6c8a9700148e8abc8f" and "0dbd10b5e3c413141cec268c46f1d8a73ad3f02b" have entirely different histories.

6 changed files with 28 additions and 1602 deletions

View file

@ -39,7 +39,6 @@
#include <QMessageBox>
#include <QMimeData>
#include <QPixmap>
#include <QPointer>
#include <QPushButton>
#include <QScrollArea>
#include <QSplitter>
@ -615,19 +614,9 @@ GraphEditorWidget::GraphEditorWidget(warppipe::Client *client,
&GraphEditorWidget::onRefreshTimer);
if (m_client) {
QPointer<QTimer> changeTimer = m_changeTimer;
m_client->SetChangeCallback([changeTimer] {
auto *app = QCoreApplication::instance();
if (!app) {
return;
}
QMetaObject::invokeMethod(app,
[changeTimer]() {
if (changeTimer) {
changeTimer->start();
}
},
m_client->SetChangeCallback([this] {
QMetaObject::invokeMethod(m_changeTimer,
qOverload<>(&QTimer::start),
Qt::QueuedConnection);
});
}
@ -647,11 +636,6 @@ GraphEditorWidget::GraphEditorWidget(warppipe::Client *client,
void GraphEditorWidget::onRefreshTimer() {
m_model->refreshFromClient();
if (m_scene &&
m_scene->itemIndexMethod() != QGraphicsScene::BspTreeIndex) {
m_scene->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
}
if (!m_graphReady && m_model->allNodeIds().size() > 0) {
m_graphReady = true;
Q_EMIT graphReady();
@ -664,13 +648,6 @@ void GraphEditorWidget::scheduleSaveLayout() {
}
GraphEditorWidget::~GraphEditorWidget() {
if (m_scene) {
disconnect(m_scene, nullptr, this, nullptr);
}
if (m_model) {
disconnect(m_model, nullptr, this, nullptr);
}
if (m_client) {
m_client->SetChangeCallback(nullptr);
}
@ -693,45 +670,6 @@ int GraphEditorWidget::linkCount() const {
return count / 2;
}
QAction *GraphEditorWidget::execMenuAction(QMenu &menu,
const QPoint &screenPos) {
return menu.exec(screenPos);
}
QString GraphEditorWidget::promptTextInput(const QString &title,
const QString &label,
bool *ok) {
return QInputDialog::getText(this,
title,
label,
QLineEdit::Normal,
QString(),
ok);
}
QString GraphEditorWidget::chooseSaveFilePath(const QString &title,
const QString &initialDir,
const QString &filter) {
return QFileDialog::getSaveFileName(this,
title,
initialDir,
filter);
}
QString GraphEditorWidget::chooseOpenFilePath(const QString &title,
const QString &initialDir,
const QString &filter) {
return QFileDialog::getOpenFileName(this,
title,
initialDir,
filter);
}
void GraphEditorWidget::showWarningDialog(const QString &title,
const QString &message) {
QMessageBox::warning(this, title, message);
}
void GraphEditorWidget::setDebugScreenshotDir(const QString &dir) {
m_debugScreenshotDir = dir;
QDir d(dir);
@ -874,7 +812,7 @@ void GraphEditorWidget::showCanvasContextMenu(const QPoint &screenPos,
QAction *savePresetAction = menu.addAction(QStringLiteral("Save Preset..."));
QAction *loadPresetAction = menu.addAction(QStringLiteral("Load Preset..."));
QAction *chosen = execMenuAction(menu, screenPos);
QAction *chosen = menu.exec(screenPos);
if (chosen == createSink) {
createVirtualNode(true, scenePos);
} else if (chosen == createSource) {
@ -966,7 +904,7 @@ void GraphEditorWidget::showNodeContextMenu(const QPoint &screenPos,
QStringLiteral(
"application/warppipe-virtual-graph"))));
QAction *chosen = execMenuAction(menu, screenPos);
QAction *chosen = menu.exec(screenPos);
if (!chosen) {
return;
}
@ -993,9 +931,9 @@ void GraphEditorWidget::createVirtualNode(bool isSink,
const QPointF &scenePos) {
if (isSink) {
bool ok = false;
QString name = promptTextInput(QStringLiteral("Create Virtual Sink"),
QStringLiteral("Node name:"),
&ok);
QString name = QInputDialog::getText(
this, QStringLiteral("Create Virtual Sink"),
QStringLiteral("Node name:"), QLineEdit::Normal, QString(), &ok);
if (!ok || name.trimmed().isEmpty())
return;
@ -1003,8 +941,8 @@ void GraphEditorWidget::createVirtualNode(bool isSink,
m_model->setPendingPosition(nodeName, scenePos);
auto result = m_client->CreateVirtualSink(nodeName);
if (!result.status.ok()) {
showWarningDialog(QStringLiteral("Error"),
QString::fromStdString(result.status.message));
QMessageBox::warning(this, QStringLiteral("Error"),
QString::fromStdString(result.status.message));
return;
}
m_model->refreshFromClient();
@ -1078,8 +1016,8 @@ void GraphEditorWidget::createVirtualNode(bool isSink,
QString name = nameEdit->text().trimmed();
if (name.isEmpty()) {
showWarningDialog(QStringLiteral("Error"),
QStringLiteral("Name cannot be empty."));
QMessageBox::warning(this, QStringLiteral("Error"),
QStringLiteral("Name cannot be empty."));
return;
}
@ -1094,8 +1032,8 @@ void GraphEditorWidget::createVirtualNode(bool isSink,
auto result = m_client->CreateVirtualSource(nodeName, opts);
if (!result.status.ok()) {
showWarningDialog(QStringLiteral("Error"),
QString::fromStdString(result.status.message));
QMessageBox::warning(this, QStringLiteral("Error"),
QString::fromStdString(result.status.message));
return;
}
m_model->refreshFromClient();
@ -1459,9 +1397,9 @@ void GraphEditorWidget::savePreset() {
if (!dir.exists())
dir.mkpath(".");
QString path = chooseSaveFilePath(QStringLiteral("Save Preset"),
m_presetDir,
QStringLiteral("JSON files (*.json)"));
QString path = QFileDialog::getSaveFileName(
this, QStringLiteral("Save Preset"), m_presetDir,
QStringLiteral("JSON files (*.json)"));
if (path.isEmpty())
return;
if (!path.endsWith(QStringLiteral(".json"), Qt::CaseInsensitive))
@ -1472,15 +1410,15 @@ void GraphEditorWidget::savePreset() {
mw->statusBar()->showMessage(
QStringLiteral("Preset saved: ") + QFileInfo(path).fileName(), 4000);
} else {
showWarningDialog(QStringLiteral("Error"),
QStringLiteral("Failed to save preset."));
QMessageBox::warning(this, QStringLiteral("Error"),
QStringLiteral("Failed to save preset."));
}
}
void GraphEditorWidget::loadPreset() {
QString path = chooseOpenFilePath(QStringLiteral("Load Preset"),
m_presetDir,
QStringLiteral("JSON files (*.json)"));
QString path = QFileDialog::getOpenFileName(
this, QStringLiteral("Load Preset"), m_presetDir,
QStringLiteral("JSON files (*.json)"));
if (path.isEmpty())
return;
@ -1489,8 +1427,8 @@ void GraphEditorWidget::loadPreset() {
mw->statusBar()->showMessage(
QStringLiteral("Preset loaded: ") + QFileInfo(path).fileName(), 4000);
} else {
showWarningDialog(QStringLiteral("Error"),
QStringLiteral("Failed to load preset."));
QMessageBox::warning(this, QStringLiteral("Error"),
QStringLiteral("Failed to load preset."));
}
}

View file

@ -27,8 +27,6 @@ class QSplitter;
class QTabWidget;
class QSlider;
class QTimer;
class QAction;
class QMenu;
class DeleteVirtualNodeCommand;
enum class ConnectionStyleType : uint8_t {
@ -61,20 +59,6 @@ private slots:
void onContextMenuRequested(const QPoint &pos);
void scheduleSaveLayout();
protected:
virtual QAction *execMenuAction(QMenu &menu, const QPoint &screenPos);
virtual QString promptTextInput(const QString &title,
const QString &label,
bool *ok);
virtual QString chooseSaveFilePath(const QString &title,
const QString &initialDir,
const QString &filter);
virtual QString chooseOpenFilePath(const QString &title,
const QString &initialDir,
const QString &filter);
virtual void showWarningDialog(const QString &title,
const QString &message);
private:
void showCanvasContextMenu(const QPoint &screenPos, const QPointF &scenePos);
void showNodeContextMenu(const QPoint &screenPos, uint32_t pwNodeId,

View file

@ -352,11 +352,12 @@ void WarpGraphModel::refreshFromClient() {
return;
}
Q_EMIT beginBatchUpdate();
m_refreshing = true;
bool sceneChanged = false;
auto nodesResult = m_client->ListNodes();
if (!nodesResult.ok()) {
m_refreshing = false;
Q_EMIT endBatchUpdate();
return;
}
@ -511,10 +512,6 @@ void WarpGraphModel::refreshFromClient() {
m_volumeStates[qtId] = {};
}
if (!sceneChanged) {
sceneChanged = true;
Q_EMIT beginBatchUpdate();
}
Q_EMIT nodeCreated(qtId);
}
@ -529,10 +526,6 @@ void WarpGraphModel::refreshFromClient() {
if (it == m_pwToQt.end()) {
continue;
}
if (!sceneChanged) {
sceneChanged = true;
Q_EMIT beginBatchUpdate();
}
QtNodes::NodeId qtId = it->second;
auto nodeIt = m_nodes.find(qtId);
if (nodeIt == m_nodes.end()) {
@ -588,10 +581,6 @@ void WarpGraphModel::refreshFromClient() {
QtNodes::ConnectionId connId{outNodeIt->second, outPortIdx,
inNodeIt->second, inPortIdx};
if (m_connections.find(connId) == m_connections.end()) {
if (!sceneChanged) {
sceneChanged = true;
Q_EMIT beginBatchUpdate();
}
m_connections.insert(connId);
m_linkIdToConn.emplace(link.id.value, connId);
Q_EMIT connectionCreated(connId);
@ -620,10 +609,6 @@ void WarpGraphModel::refreshFromClient() {
{
auto connIt = m_connections.find(connId);
if (connIt != m_connections.end()) {
if (!sceneChanged) {
sceneChanged = true;
Q_EMIT beginBatchUpdate();
}
m_connections.erase(connIt);
Q_EMIT connectionDeleted(connId);
}
@ -711,9 +696,7 @@ void WarpGraphModel::refreshFromClient() {
}
m_refreshing = false;
if (sceneChanged) {
Q_EMIT endBatchUpdate();
}
Q_EMIT endBatchUpdate();
}
const WarpNodeData *

View file

@ -18,7 +18,7 @@ public:
explicit ZoomGraphicsView(QtNodes::BasicGraphicsScene *scene,
QWidget *parent = nullptr)
: QtNodes::GraphicsView(scene, parent) {
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
setCacheMode(QGraphicsView::CacheNone);
}

File diff suppressed because it is too large Load diff

View file

@ -626,60 +626,6 @@ TEST_CASE("set default sink without metadata returns unavailable") {
REQUIRE_FALSE(status.ok());
}
TEST_CASE("set default source without metadata returns unavailable") {
auto result = warppipe::Client::Create(DefaultOptions());
if (!result.ok()) {
SUCCEED("PipeWire unavailable");
return;
}
auto status = result.value->SetDefaultSource("");
REQUIRE_FALSE(status.ok());
}
TEST_CASE("GetVirtualNodeInfo returns details for created virtual sink") {
auto result = warppipe::Client::Create(DefaultOptions());
if (!result.ok()) {
SUCCEED("PipeWire unavailable");
return;
}
warppipe::VirtualNodeOptions options;
options.display_name = "warppipe-test-info";
options.group = "warppipe-test";
options.format.rate = 48000;
options.format.channels = 2;
auto sink = result.value->CreateVirtualSink("warppipe-info-sink", options);
if (!sink.ok()) {
if (sink.status.code == warppipe::StatusCode::kUnavailable) {
SUCCEED("PipeWire unavailable");
return;
}
REQUIRE(sink.ok());
}
auto info = result.value->GetVirtualNodeInfo(sink.value.node);
REQUIRE(info.ok());
REQUIRE(info.value.node.value == sink.value.node.value);
REQUIRE(info.value.name == sink.value.name);
REQUIRE_FALSE(info.value.is_source);
REQUIRE(result.value->RemoveNode(sink.value.node).ok());
}
TEST_CASE("GetVirtualNodeInfo missing node returns not found") {
auto result = warppipe::Client::Create(DefaultOptions());
if (!result.ok()) {
SUCCEED("PipeWire unavailable");
return;
}
auto info = result.value->GetVirtualNodeInfo(warppipe::NodeId{999999});
REQUIRE_FALSE(info.ok());
REQUIRE(info.status.code == warppipe::StatusCode::kNotFound);
}
TEST_CASE("NodeInfo captures application properties") {
auto result = warppipe::Client::Create(DefaultOptions());
if (!result.ok()) {