diff --git a/CMakeLists.txt b/CMakeLists.txt index 497e248..f383700 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,6 @@ if(WARPPIPE_BUILD_GUI) gui/PresetManager.cpp gui/VolumeWidgets.cpp gui/AudioLevelMeter.cpp - gui/SquareConnectionPainter.cpp ) target_link_libraries(warppipe-gui PRIVATE @@ -103,7 +102,6 @@ if(WARPPIPE_BUILD_GUI) gui/PresetManager.cpp gui/VolumeWidgets.cpp gui/AudioLevelMeter.cpp - gui/SquareConnectionPainter.cpp ) target_compile_definitions(warppipe-gui-tests PRIVATE WARPPIPE_TESTING) diff --git a/gui/GraphEditorWidget.cpp b/gui/GraphEditorWidget.cpp index 8dc75df..e05eef2 100644 --- a/gui/GraphEditorWidget.cpp +++ b/gui/GraphEditorWidget.cpp @@ -1,14 +1,12 @@ #include "AudioLevelMeter.h" #include "GraphEditorWidget.h" #include "PresetManager.h" -#include "SquareConnectionPainter.h" #include "VolumeWidgets.h" #include "WarpGraphModel.h" #include #include #include -#include #include #include #include @@ -643,15 +641,6 @@ void GraphEditorWidget::showCanvasContextMenu(const QPoint &screenPos, autoArrange->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_L)); QAction *refreshGraph = menu.addAction(QStringLiteral("Refresh Graph")); 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(); QAction *saveLayoutAs = menu.addAction(QStringLiteral("Save Layout As...")); QAction *resetLayout = menu.addAction(QStringLiteral("Reset Layout")); @@ -694,10 +683,6 @@ void GraphEditorWidget::showCanvasContextMenu(const QPoint &screenPos, m_model->autoArrange(); m_view->zoomFitAll(); saveLayoutWithViewState(); - } else if (chosen == styleBezier) { - setConnectionStyle(ConnectionStyleType::kBezier); - } else if (chosen == styleSquare) { - setConnectionStyle(ConnectionStyleType::kSquare); } else if (chosen == savePresetAction) { savePreset(); } else if (chosen == loadPresetAction) { @@ -1118,7 +1103,6 @@ void GraphEditorWidget::saveLayoutWithViewState() { QList sizes = m_splitter->sizes(); vs.splitterGraph = sizes.value(0, 1200); vs.splitterSidebar = sizes.value(1, 320); - vs.connectionStyle = static_cast(m_connectionStyle); vs.valid = true; m_model->saveLayout(m_layoutPath, vs); } @@ -1131,9 +1115,6 @@ void GraphEditorWidget::restoreViewState() { if (vs.splitterGraph > 0 || vs.splitterSidebar > 0) { m_splitter->setSizes({vs.splitterGraph, vs.splitterSidebar}); } - if (vs.connectionStyle == static_cast(ConnectionStyleType::kSquare)) { - setConnectionStyle(ConnectionStyleType::kSquare); - } } else { m_view->zoomFitAll(); } @@ -1467,10 +1448,6 @@ void GraphEditorWidget::rebuildRulesList() { " border-radius: 4px; padding: 6px 12px; }" "QPushButton:hover { background: #3a3a44; }" "QPushButton:pressed { background: #44444e; }"); - const QString editBtnStyle = QStringLiteral( - "QPushButton { background: transparent; color: #5070a0; border: none;" - " font-size: 14px; font-weight: bold; padding: 2px 6px; }" - "QPushButton:hover { color: #70a0e0; }"); const QString delBtnStyle = QStringLiteral( "QPushButton { background: transparent; color: #a05050; border: none;" " font-size: 14px; font-weight: bold; padding: 2px 6px; }" @@ -1523,23 +1500,10 @@ void GraphEditorWidget::rebuildRulesList() { cardLayout->addLayout(infoLayout, 1); - auto *editBtn = new QPushButton(QString(QChar(0x270E))); - editBtn->setFixedSize(24, 24); - editBtn->setStyleSheet(editBtnStyle); - warppipe::RuleId ruleId = rule.id; - std::string ruleApp = rule.match.application_name; - std::string ruleBin = rule.match.process_binary; - std::string ruleRole = rule.match.media_role; - std::string ruleTarget = rule.target_node; - connect(editBtn, &QPushButton::clicked, this, - [this, ruleApp, ruleBin, ruleRole, ruleTarget, ruleId]() { - showAddRuleDialog(ruleApp, ruleBin, ruleRole, ruleTarget, ruleId); - }); - cardLayout->addWidget(editBtn); - auto *delBtn = new QPushButton(QString(QChar(0x2715))); delBtn->setFixedSize(24, 24); delBtn->setStyleSheet(delBtnStyle); + warppipe::RuleId ruleId = rule.id; connect(delBtn, &QPushButton::clicked, this, [this, ruleId]() { m_client->RemoveRouteRule(ruleId); rebuildRulesList(); @@ -1559,38 +1523,14 @@ void GraphEditorWidget::rebuildRulesList() { static_cast(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()); - } else { - m_scene->setConnectionPainter( - std::make_unique()); - } - - for (auto *item : m_scene->items()) { - item->update(); - } - - scheduleSaveLayout(); -} - void GraphEditorWidget::showAddRuleDialog(const std::string &prefillApp, const std::string &prefillBin, - const std::string &prefillRole, - const std::string &prefillTarget, - warppipe::RuleId editRuleId) { + const std::string &prefillRole) { if (!m_client) return; - bool editing = editRuleId.value != 0; - QDialog dlg(this); - dlg.setWindowTitle(editing ? QStringLiteral("Edit Routing Rule") - : QStringLiteral("Add Routing Rule")); + dlg.setWindowTitle(QStringLiteral("Add Routing Rule")); dlg.setStyleSheet(QStringLiteral( "QDialog { background: #1e1e22; }" "QLabel { color: #ecf0f6; }" @@ -1635,11 +1575,6 @@ void GraphEditorWidget::showAddRuleDialog(const std::string &prefillApp, } } } - if (!prefillTarget.empty()) { - int idx = targetCombo->findData(QString::fromStdString(prefillTarget)); - if (idx >= 0) - targetCombo->setCurrentIndex(idx); - } form->addRow(QStringLiteral("Target Node:"), targetCombo); auto *buttons = new QDialogButtonBox( @@ -1671,10 +1606,6 @@ void GraphEditorWidget::showAddRuleDialog(const std::string &prefillApp, return; } - if (editing) { - m_client->RemoveRouteRule(editRuleId); - } - warppipe::RouteRule rule; rule.match.application_name = appName; rule.match.process_binary = procBin; diff --git a/gui/GraphEditorWidget.h b/gui/GraphEditorWidget.h index c56998f..deec287 100644 --- a/gui/GraphEditorWidget.h +++ b/gui/GraphEditorWidget.h @@ -27,11 +27,6 @@ class QTabWidget; class QTimer; class DeleteVirtualNodeCommand; -enum class ConnectionStyleType : uint8_t { - kBezier = 0, - kSquare, -}; - class GraphEditorWidget : public QWidget { Q_OBJECT @@ -81,10 +76,7 @@ private: void rebuildRulesList(); void showAddRuleDialog(const std::string &prefillApp = {}, const std::string &prefillBin = {}, - const std::string &prefillRole = {}, - const std::string &prefillTarget = {}, - warppipe::RuleId editRuleId = {}); - void setConnectionStyle(ConnectionStyleType style); + const std::string &prefillRole = {}); struct PendingPasteLink { std::string outNodeName; @@ -127,6 +119,4 @@ private: QWidget *m_rulesContainer = nullptr; QScrollArea *m_rulesScroll = nullptr; - - ConnectionStyleType m_connectionStyle = ConnectionStyleType::kBezier; }; diff --git a/gui/SquareConnectionPainter.cpp b/gui/SquareConnectionPainter.cpp deleted file mode 100644 index 752a7d6..0000000 --- a/gui/SquareConnectionPainter.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "SquareConnectionPainter.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -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(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(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(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); -} diff --git a/gui/SquareConnectionPainter.h b/gui/SquareConnectionPainter.h deleted file mode 100644 index 8c6dc44..0000000 --- a/gui/SquareConnectionPainter.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -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; -}; diff --git a/gui/WarpGraphModel.cpp b/gui/WarpGraphModel.cpp index 80d4dcd..a62a63a 100644 --- a/gui/WarpGraphModel.cpp +++ b/gui/WarpGraphModel.cpp @@ -466,8 +466,7 @@ void WarpGraphModel::refreshFromClient() { if (savedIt != m_savedPositions.end()) { m_positions.emplace(qtId, savedIt->second); } else { - QPointF candidate = nextPosition(nodeIt->second); - m_positions.emplace(qtId, findNonOverlappingPosition(candidate, nodeIt->second)); + m_positions.emplace(qtId, nextPosition(nodeIt->second)); } } @@ -699,40 +698,6 @@ QPointF WarpGraphModel::nextPosition(const WarpNodeData &data) { return pos; } -QPointF WarpGraphModel::findNonOverlappingPosition(QPointF candidate, - const WarpNodeData &data) const { - QSizeF newSize(estimateNodeSize(data)); - constexpr int kMaxAttempts = 50; - - for (int attempt = 0; attempt < kMaxAttempts; ++attempt) { - QRectF newRect(candidate, newSize); - bool overlaps = false; - for (const auto &[existingId, existingPos] : m_positions) { - auto nodeIt = m_nodes.find(existingId); - if (nodeIt == m_nodes.end()) - continue; - QSizeF existingSize; - auto sizeIt = m_sizes.find(existingId); - if (sizeIt != m_sizes.end()) { - existingSize = QSizeF(sizeIt->second); - } else { - existingSize = QSizeF(estimateNodeSize(nodeIt->second)); - } - QRectF existingRect(existingPos, existingSize); - QRectF padded = existingRect.adjusted(-kHorizontalGap / 2, -kVerticalGap / 2, - kHorizontalGap / 2, kVerticalGap / 2); - if (newRect.intersects(padded)) { - candidate.setY(existingRect.bottom() + kVerticalGap); - overlaps = true; - break; - } - } - if (!overlaps) - break; - } - return candidate; -} - bool WarpGraphModel::isGhost(QtNodes::NodeId nodeId) const { return m_ghostNodes.find(nodeId) != m_ghostNodes.end(); } @@ -905,7 +870,6 @@ void WarpGraphModel::saveLayout(const QString &path, viewObj["splitter_graph"] = viewState.splitterGraph; viewObj["splitter_sidebar"] = viewState.splitterSidebar; } - viewObj["connection_style"] = viewState.connectionStyle; root["view"] = viewObj; } @@ -965,7 +929,6 @@ bool WarpGraphModel::loadLayout(const QString &path) { m_savedViewState.centerY = viewObj["center_y"].toDouble(); m_savedViewState.splitterGraph = viewObj["splitter_graph"].toInt(0); m_savedViewState.splitterSidebar = viewObj["splitter_sidebar"].toInt(0); - m_savedViewState.connectionStyle = viewObj["connection_style"].toInt(0); m_savedViewState.valid = true; } diff --git a/gui/WarpGraphModel.h b/gui/WarpGraphModel.h index b339057..e667eb5 100644 --- a/gui/WarpGraphModel.h +++ b/gui/WarpGraphModel.h @@ -88,7 +88,6 @@ public: double centerY; int splitterGraph; int splitterSidebar; - int connectionStyle; bool valid; }; @@ -103,7 +102,6 @@ private: static QString captionForNode(const warppipe::NodeInfo &info); static QVariant styleForNode(WarpNodeType type, bool ghost); QPointF nextPosition(const WarpNodeData &data); - QPointF findNonOverlappingPosition(QPointF candidate, const WarpNodeData &data) const; static QSize estimateNodeSize(const WarpNodeData &data); warppipe::Client *m_client = nullptr;