#pragma once #include #include #include #include #include #include namespace QtNodes { class BasicGraphicsScene; class GraphicsView; } // namespace QtNodes class WarpGraphModel; class QLabel; class QTimer; class DeleteVirtualNodeCommand; class GraphEditorWidget : public QWidget { Q_OBJECT friend class DeleteVirtualNodeCommand; public: explicit GraphEditorWidget(warppipe::Client *client, QWidget *parent = nullptr); int nodeCount() const; int linkCount() const; void setDebugScreenshotDir(const QString &dir); Q_SIGNALS: void graphReady(); private slots: void onRefreshTimer(); void onContextMenuRequested(const QPoint &pos); void scheduleSaveLayout(); private: void showCanvasContextMenu(const QPoint &screenPos, const QPointF &scenePos); void showNodeContextMenu(const QPoint &screenPos, uint32_t pwNodeId); 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(); 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; QtNodes::GraphicsView *m_view = nullptr; QTimer *m_refreshTimer = nullptr; QTimer *m_saveTimer = nullptr; QString m_layoutPath; QString m_debugScreenshotDir; bool m_graphReady = false; QJsonObject m_clipboardJson; std::vector m_pendingPasteLinks; };