warp-pipe/gui/GraphEditorWidget.h
2026-02-06 11:07:01 -07:00

164 lines
4.8 KiB
C++

#pragma once
#include <warppipe/warppipe.hpp>
#include <QJsonObject>
#include <QPointF>
#include <QString>
#include <QWidget>
#include <string>
#include <unordered_map>
#include <vector>
namespace QtNodes {
using NodeId = unsigned int;
class BasicGraphicsScene;
} // namespace QtNodes
class ZoomGraphicsView;
class AudioLevelMeter;
class WarpGraphModel;
class NodeVolumeWidget;
class QLabel;
class QScrollArea;
class QSplitter;
class QTabWidget;
class QSlider;
class QTimer;
class QAction;
class QMenu;
class DeleteVirtualNodeCommand;
enum class ConnectionStyleType : uint8_t {
kBezier = 0,
kSquare,
};
class GraphEditorWidget : public QWidget {
Q_OBJECT
friend class DeleteVirtualNodeCommand;
public:
explicit GraphEditorWidget(warppipe::Client *client,
QWidget *parent = nullptr);
~GraphEditorWidget() override;
int nodeCount() const;
int linkCount() const;
void setDebugScreenshotDir(const QString &dir);
bool eventFilter(QObject *obj, QEvent *event) override;
Q_SIGNALS:
void graphReady();
private slots:
void onRefreshTimer();
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,
QtNodes::NodeId qtNodeId);
void createVirtualNode(bool isSink, const QPointF &scenePos);
void captureDebugScreenshot(const QString &event);
void deleteSelection();
void copySelection();
void pasteSelection(const QPointF &offset);
void duplicateSelection();
void removeDefaultActions();
void tryResolvePendingLinks();
void saveLayoutWithViewState();
void restoreViewState();
void savePreset();
void loadPreset();
void wireVolumeWidget(QtNodes::NodeId nodeId);
void rebuildMixerStrips();
void updateMeters();
void rebuildNodeMeters();
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);
void onSelectionChanged();
void updateNodeDetailsPanel(QtNodes::NodeId nodeId);
void clearNodeDetailsPanel();
struct PendingPasteLink {
std::string outNodeName;
std::string outPortName;
std::string inNodeName;
std::string inPortName;
};
warppipe::Client *m_client = nullptr;
WarpGraphModel *m_model = nullptr;
QtNodes::BasicGraphicsScene *m_scene = nullptr;
ZoomGraphicsView *m_view = nullptr;
QSplitter *m_splitter = nullptr;
QTabWidget *m_sidebar = nullptr;
QTimer *m_refreshTimer = nullptr;
QTimer *m_changeTimer = nullptr;
QTimer *m_saveTimer = nullptr;
QString m_layoutPath;
QString m_presetDir;
QString m_debugScreenshotDir;
bool m_graphReady = false;
QJsonObject m_clipboardJson;
std::vector<PendingPasteLink> m_pendingPasteLinks;
QPointF m_lastContextMenuScenePos;
QWidget *m_mixerContainer = nullptr;
QScrollArea *m_mixerScroll = nullptr;
std::unordered_map<QtNodes::NodeId, QWidget *> m_mixerStrips;
QTimer *m_meterTimer = nullptr;
AudioLevelMeter *m_masterMeterL = nullptr;
AudioLevelMeter *m_masterMeterR = nullptr;
QWidget *m_nodeMeterContainer = nullptr;
QScrollArea *m_nodeMeterScroll = nullptr;
struct NodeMeterRow {
QWidget *widget = nullptr;
AudioLevelMeter *meter = nullptr;
QLabel *label = nullptr;
};
std::unordered_map<QtNodes::NodeId, NodeMeterRow> m_nodeMeters;
QWidget *m_rulesContainer = nullptr;
QScrollArea *m_rulesScroll = nullptr;
ConnectionStyleType m_connectionStyle = ConnectionStyleType::kBezier;
QSlider *m_zoomSensSlider = nullptr;
QLabel *m_zoomSensValue = nullptr;
QSlider *m_zoomMinSlider = nullptr;
QLabel *m_zoomMinValue = nullptr;
QSlider *m_zoomMaxSlider = nullptr;
QLabel *m_zoomMaxValue = nullptr;
QWidget *m_nodeDetailsContainer = nullptr;
QScrollArea *m_nodeDetailsScroll = nullptr;
QtNodes::NodeId m_selectedNodeId = 0;
};