Add custom routing
This commit is contained in:
parent
7d4804a7f8
commit
978c8c10e3
7 changed files with 182 additions and 0 deletions
|
|
@ -85,6 +85,7 @@ if(WARPPIPE_BUILD_GUI)
|
||||||
gui/PresetManager.cpp
|
gui/PresetManager.cpp
|
||||||
gui/VolumeWidgets.cpp
|
gui/VolumeWidgets.cpp
|
||||||
gui/AudioLevelMeter.cpp
|
gui/AudioLevelMeter.cpp
|
||||||
|
gui/SquareConnectionPainter.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(warppipe-gui PRIVATE
|
target_link_libraries(warppipe-gui PRIVATE
|
||||||
|
|
@ -102,6 +103,7 @@ if(WARPPIPE_BUILD_GUI)
|
||||||
gui/PresetManager.cpp
|
gui/PresetManager.cpp
|
||||||
gui/VolumeWidgets.cpp
|
gui/VolumeWidgets.cpp
|
||||||
gui/AudioLevelMeter.cpp
|
gui/AudioLevelMeter.cpp
|
||||||
|
gui/SquareConnectionPainter.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(warppipe-gui-tests PRIVATE WARPPIPE_TESTING)
|
target_compile_definitions(warppipe-gui-tests PRIVATE WARPPIPE_TESTING)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
#include "AudioLevelMeter.h"
|
#include "AudioLevelMeter.h"
|
||||||
#include "GraphEditorWidget.h"
|
#include "GraphEditorWidget.h"
|
||||||
#include "PresetManager.h"
|
#include "PresetManager.h"
|
||||||
|
#include "SquareConnectionPainter.h"
|
||||||
#include "VolumeWidgets.h"
|
#include "VolumeWidgets.h"
|
||||||
#include "WarpGraphModel.h"
|
#include "WarpGraphModel.h"
|
||||||
|
|
||||||
#include <QtNodes/BasicGraphicsScene>
|
#include <QtNodes/BasicGraphicsScene>
|
||||||
#include <QtNodes/ConnectionStyle>
|
#include <QtNodes/ConnectionStyle>
|
||||||
#include <QtNodes/GraphicsView>
|
#include <QtNodes/GraphicsView>
|
||||||
|
#include <QtNodes/internal/DefaultConnectionPainter.hpp>
|
||||||
#include <QtNodes/internal/NodeGraphicsObject.hpp>
|
#include <QtNodes/internal/NodeGraphicsObject.hpp>
|
||||||
#include <QtNodes/internal/ConnectionGraphicsObject.hpp>
|
#include <QtNodes/internal/ConnectionGraphicsObject.hpp>
|
||||||
#include <QtNodes/internal/UndoCommands.hpp>
|
#include <QtNodes/internal/UndoCommands.hpp>
|
||||||
|
|
@ -641,6 +643,15 @@ void GraphEditorWidget::showCanvasContextMenu(const QPoint &screenPos,
|
||||||
autoArrange->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_L));
|
autoArrange->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_L));
|
||||||
QAction *refreshGraph = menu.addAction(QStringLiteral("Refresh Graph"));
|
QAction *refreshGraph = menu.addAction(QStringLiteral("Refresh Graph"));
|
||||||
refreshGraph->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R));
|
refreshGraph->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R));
|
||||||
|
menu.addSeparator();
|
||||||
|
auto *connStyleMenu = menu.addMenu(QStringLiteral("Connection Style"));
|
||||||
|
auto *styleBezier = connStyleMenu->addAction(QStringLiteral("Bezier Curves"));
|
||||||
|
styleBezier->setCheckable(true);
|
||||||
|
styleBezier->setChecked(m_connectionStyle == ConnectionStyleType::kBezier);
|
||||||
|
auto *styleSquare = connStyleMenu->addAction(QStringLiteral("Square Routing"));
|
||||||
|
styleSquare->setCheckable(true);
|
||||||
|
styleSquare->setChecked(m_connectionStyle == ConnectionStyleType::kSquare);
|
||||||
|
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
QAction *saveLayoutAs = menu.addAction(QStringLiteral("Save Layout As..."));
|
QAction *saveLayoutAs = menu.addAction(QStringLiteral("Save Layout As..."));
|
||||||
QAction *resetLayout = menu.addAction(QStringLiteral("Reset Layout"));
|
QAction *resetLayout = menu.addAction(QStringLiteral("Reset Layout"));
|
||||||
|
|
@ -683,6 +694,10 @@ void GraphEditorWidget::showCanvasContextMenu(const QPoint &screenPos,
|
||||||
m_model->autoArrange();
|
m_model->autoArrange();
|
||||||
m_view->zoomFitAll();
|
m_view->zoomFitAll();
|
||||||
saveLayoutWithViewState();
|
saveLayoutWithViewState();
|
||||||
|
} else if (chosen == styleBezier) {
|
||||||
|
setConnectionStyle(ConnectionStyleType::kBezier);
|
||||||
|
} else if (chosen == styleSquare) {
|
||||||
|
setConnectionStyle(ConnectionStyleType::kSquare);
|
||||||
} else if (chosen == savePresetAction) {
|
} else if (chosen == savePresetAction) {
|
||||||
savePreset();
|
savePreset();
|
||||||
} else if (chosen == loadPresetAction) {
|
} else if (chosen == loadPresetAction) {
|
||||||
|
|
@ -1103,6 +1118,7 @@ void GraphEditorWidget::saveLayoutWithViewState() {
|
||||||
QList<int> sizes = m_splitter->sizes();
|
QList<int> sizes = m_splitter->sizes();
|
||||||
vs.splitterGraph = sizes.value(0, 1200);
|
vs.splitterGraph = sizes.value(0, 1200);
|
||||||
vs.splitterSidebar = sizes.value(1, 320);
|
vs.splitterSidebar = sizes.value(1, 320);
|
||||||
|
vs.connectionStyle = static_cast<int>(m_connectionStyle);
|
||||||
vs.valid = true;
|
vs.valid = true;
|
||||||
m_model->saveLayout(m_layoutPath, vs);
|
m_model->saveLayout(m_layoutPath, vs);
|
||||||
}
|
}
|
||||||
|
|
@ -1115,6 +1131,9 @@ void GraphEditorWidget::restoreViewState() {
|
||||||
if (vs.splitterGraph > 0 || vs.splitterSidebar > 0) {
|
if (vs.splitterGraph > 0 || vs.splitterSidebar > 0) {
|
||||||
m_splitter->setSizes({vs.splitterGraph, vs.splitterSidebar});
|
m_splitter->setSizes({vs.splitterGraph, vs.splitterSidebar});
|
||||||
}
|
}
|
||||||
|
if (vs.connectionStyle == static_cast<int>(ConnectionStyleType::kSquare)) {
|
||||||
|
setConnectionStyle(ConnectionStyleType::kSquare);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
m_view->zoomFitAll();
|
m_view->zoomFitAll();
|
||||||
}
|
}
|
||||||
|
|
@ -1540,6 +1559,25 @@ void GraphEditorWidget::rebuildRulesList() {
|
||||||
static_cast<QVBoxLayout *>(layout)->addStretch();
|
static_cast<QVBoxLayout *>(layout)->addStretch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphEditorWidget::setConnectionStyle(ConnectionStyleType style) {
|
||||||
|
if (style == m_connectionStyle)
|
||||||
|
return;
|
||||||
|
m_connectionStyle = style;
|
||||||
|
|
||||||
|
if (style == ConnectionStyleType::kSquare) {
|
||||||
|
m_scene->setConnectionPainter(std::make_unique<SquareConnectionPainter>());
|
||||||
|
} else {
|
||||||
|
m_scene->setConnectionPainter(
|
||||||
|
std::make_unique<QtNodes::DefaultConnectionPainter>());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto *item : m_scene->items()) {
|
||||||
|
item->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleSaveLayout();
|
||||||
|
}
|
||||||
|
|
||||||
void GraphEditorWidget::showAddRuleDialog(const std::string &prefillApp,
|
void GraphEditorWidget::showAddRuleDialog(const std::string &prefillApp,
|
||||||
const std::string &prefillBin,
|
const std::string &prefillBin,
|
||||||
const std::string &prefillRole,
|
const std::string &prefillRole,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,11 @@ class QTabWidget;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
class DeleteVirtualNodeCommand;
|
class DeleteVirtualNodeCommand;
|
||||||
|
|
||||||
|
enum class ConnectionStyleType : uint8_t {
|
||||||
|
kBezier = 0,
|
||||||
|
kSquare,
|
||||||
|
};
|
||||||
|
|
||||||
class GraphEditorWidget : public QWidget {
|
class GraphEditorWidget : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
@ -79,6 +84,7 @@ private:
|
||||||
const std::string &prefillRole = {},
|
const std::string &prefillRole = {},
|
||||||
const std::string &prefillTarget = {},
|
const std::string &prefillTarget = {},
|
||||||
warppipe::RuleId editRuleId = {});
|
warppipe::RuleId editRuleId = {});
|
||||||
|
void setConnectionStyle(ConnectionStyleType style);
|
||||||
|
|
||||||
struct PendingPasteLink {
|
struct PendingPasteLink {
|
||||||
std::string outNodeName;
|
std::string outNodeName;
|
||||||
|
|
@ -121,4 +127,6 @@ private:
|
||||||
|
|
||||||
QWidget *m_rulesContainer = nullptr;
|
QWidget *m_rulesContainer = nullptr;
|
||||||
QScrollArea *m_rulesScroll = nullptr;
|
QScrollArea *m_rulesScroll = nullptr;
|
||||||
|
|
||||||
|
ConnectionStyleType m_connectionStyle = ConnectionStyleType::kBezier;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
116
gui/SquareConnectionPainter.cpp
Normal file
116
gui/SquareConnectionPainter.cpp
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
#include "SquareConnectionPainter.h"
|
||||||
|
|
||||||
|
#include <QtNodes/internal/ConnectionGraphicsObject.hpp>
|
||||||
|
#include <QtNodes/internal/ConnectionState.hpp>
|
||||||
|
#include <QtNodes/internal/Definitions.hpp>
|
||||||
|
#include <QtNodes/StyleCollection>
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPainterPath>
|
||||||
|
#include <QPainterPathStroker>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
QPainterPath SquareConnectionPainter::orthogonalPath(
|
||||||
|
QtNodes::ConnectionGraphicsObject const &cgo) const {
|
||||||
|
QPointF out = cgo.endPoint(QtNodes::PortType::Out);
|
||||||
|
QPointF in = cgo.endPoint(QtNodes::PortType::In);
|
||||||
|
|
||||||
|
constexpr double kRadius = 5.0;
|
||||||
|
constexpr double kSpacing = 8.0;
|
||||||
|
constexpr double kMinStub = 20.0;
|
||||||
|
|
||||||
|
auto cId = cgo.connectionId();
|
||||||
|
double spread = static_cast<double>(cId.outPortIndex) * kSpacing;
|
||||||
|
|
||||||
|
double dy = in.y() - out.y();
|
||||||
|
|
||||||
|
if (std::abs(dy) < 0.5 && in.x() > out.x()) {
|
||||||
|
QPainterPath path(out);
|
||||||
|
path.lineTo(in);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
double midX = (out.x() + in.x()) / 2.0 + spread;
|
||||||
|
midX = std::max(midX, out.x() + kMinStub);
|
||||||
|
if (in.x() > out.x())
|
||||||
|
midX = std::min(midX, in.x() - kMinStub);
|
||||||
|
|
||||||
|
double r = std::min({kRadius, std::abs(dy) / 2.0,
|
||||||
|
std::abs(midX - out.x()),
|
||||||
|
std::abs(in.x() - midX)});
|
||||||
|
r = std::max(r, 0.0);
|
||||||
|
|
||||||
|
double sy = (dy > 0) ? 1.0 : -1.0;
|
||||||
|
double hDir = (in.x() >= midX) ? 1.0 : -1.0;
|
||||||
|
|
||||||
|
QPainterPath path(out);
|
||||||
|
|
||||||
|
if (r > 0.5) {
|
||||||
|
path.lineTo(midX - r, out.y());
|
||||||
|
path.quadTo(QPointF(midX, out.y()), QPointF(midX, out.y() + sy * r));
|
||||||
|
path.lineTo(midX, in.y() - sy * r);
|
||||||
|
path.quadTo(QPointF(midX, in.y()), QPointF(midX + hDir * r, in.y()));
|
||||||
|
} else {
|
||||||
|
path.lineTo(midX, out.y());
|
||||||
|
path.lineTo(midX, in.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
path.lineTo(in);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SquareConnectionPainter::paint(
|
||||||
|
QPainter *painter,
|
||||||
|
QtNodes::ConnectionGraphicsObject const &cgo) const {
|
||||||
|
auto const &style = QtNodes::StyleCollection::connectionStyle();
|
||||||
|
|
||||||
|
bool const hovered = cgo.connectionState().hovered();
|
||||||
|
bool const selected = cgo.isSelected();
|
||||||
|
bool const sketch = cgo.connectionState().requiresPort();
|
||||||
|
|
||||||
|
auto path = orthogonalPath(cgo);
|
||||||
|
|
||||||
|
if (hovered || selected) {
|
||||||
|
QPen pen;
|
||||||
|
pen.setWidth(static_cast<int>(2 * style.lineWidth()));
|
||||||
|
pen.setColor(selected ? style.selectedHaloColor() : style.hoveredColor());
|
||||||
|
painter->setPen(pen);
|
||||||
|
painter->setBrush(Qt::NoBrush);
|
||||||
|
painter->drawPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sketch) {
|
||||||
|
QPen pen;
|
||||||
|
pen.setWidth(static_cast<int>(style.constructionLineWidth()));
|
||||||
|
pen.setColor(style.constructionColor());
|
||||||
|
pen.setStyle(Qt::DashLine);
|
||||||
|
painter->setPen(pen);
|
||||||
|
painter->setBrush(Qt::NoBrush);
|
||||||
|
painter->drawPath(path);
|
||||||
|
} else {
|
||||||
|
QPen pen;
|
||||||
|
pen.setWidth(style.lineWidth());
|
||||||
|
pen.setColor(selected ? style.selectedColor() : style.normalColor());
|
||||||
|
painter->setPen(pen);
|
||||||
|
painter->setBrush(Qt::NoBrush);
|
||||||
|
painter->drawPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
double const pointRadius = style.pointDiameter() / 2.0;
|
||||||
|
painter->setPen(style.constructionColor());
|
||||||
|
painter->setBrush(style.constructionColor());
|
||||||
|
painter->drawEllipse(cgo.out(), pointRadius, pointRadius);
|
||||||
|
painter->drawEllipse(cgo.in(), pointRadius, pointRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainterPath SquareConnectionPainter::getPainterStroke(
|
||||||
|
QtNodes::ConnectionGraphicsObject const &cgo) const {
|
||||||
|
auto path = orthogonalPath(cgo);
|
||||||
|
|
||||||
|
QPainterPathStroker stroker;
|
||||||
|
stroker.setWidth(10.0);
|
||||||
|
|
||||||
|
return stroker.createStroke(path);
|
||||||
|
}
|
||||||
15
gui/SquareConnectionPainter.h
Normal file
15
gui/SquareConnectionPainter.h
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtNodes/internal/AbstractConnectionPainter.hpp>
|
||||||
|
|
||||||
|
class SquareConnectionPainter : public QtNodes::AbstractConnectionPainter {
|
||||||
|
public:
|
||||||
|
void paint(QPainter *painter,
|
||||||
|
QtNodes::ConnectionGraphicsObject const &cgo) const override;
|
||||||
|
QPainterPath
|
||||||
|
getPainterStroke(QtNodes::ConnectionGraphicsObject const &cgo) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPainterPath
|
||||||
|
orthogonalPath(QtNodes::ConnectionGraphicsObject const &cgo) const;
|
||||||
|
};
|
||||||
|
|
@ -905,6 +905,7 @@ void WarpGraphModel::saveLayout(const QString &path,
|
||||||
viewObj["splitter_graph"] = viewState.splitterGraph;
|
viewObj["splitter_graph"] = viewState.splitterGraph;
|
||||||
viewObj["splitter_sidebar"] = viewState.splitterSidebar;
|
viewObj["splitter_sidebar"] = viewState.splitterSidebar;
|
||||||
}
|
}
|
||||||
|
viewObj["connection_style"] = viewState.connectionStyle;
|
||||||
root["view"] = viewObj;
|
root["view"] = viewObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -964,6 +965,7 @@ bool WarpGraphModel::loadLayout(const QString &path) {
|
||||||
m_savedViewState.centerY = viewObj["center_y"].toDouble();
|
m_savedViewState.centerY = viewObj["center_y"].toDouble();
|
||||||
m_savedViewState.splitterGraph = viewObj["splitter_graph"].toInt(0);
|
m_savedViewState.splitterGraph = viewObj["splitter_graph"].toInt(0);
|
||||||
m_savedViewState.splitterSidebar = viewObj["splitter_sidebar"].toInt(0);
|
m_savedViewState.splitterSidebar = viewObj["splitter_sidebar"].toInt(0);
|
||||||
|
m_savedViewState.connectionStyle = viewObj["connection_style"].toInt(0);
|
||||||
m_savedViewState.valid = true;
|
m_savedViewState.valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ public:
|
||||||
double centerY;
|
double centerY;
|
||||||
int splitterGraph;
|
int splitterGraph;
|
||||||
int splitterSidebar;
|
int splitterSidebar;
|
||||||
|
int connectionStyle;
|
||||||
bool valid;
|
bool valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue