#pragma once #include "pipewire/pipewirecontroller.h" #include #include #include #include #include #include #include #include #include #include class PipeWireGraphModel : public QtNodes::AbstractGraphModel { Q_OBJECT public: explicit PipeWireGraphModel(Potato::PipeWireController *controller, QObject *parent = nullptr); QtNodes::NodeId newNodeId() override; std::unordered_set allNodeIds() const override; std::unordered_set allConnectionIds(QtNodes::NodeId const nodeId) const override; std::unordered_set connections(QtNodes::NodeId nodeId, QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override; bool connectionExists(QtNodes::ConnectionId const connectionId) const override; QtNodes::NodeId addNode(QString const nodeType = QString()) override; bool connectionPossible(QtNodes::ConnectionId const connectionId) const override; void addConnection(QtNodes::ConnectionId const connectionId) override; bool nodeExists(QtNodes::NodeId const nodeId) const override; QVariant nodeData(QtNodes::NodeId nodeId, QtNodes::NodeRole role) const override; bool setNodeData(QtNodes::NodeId nodeId, QtNodes::NodeRole role, QVariant value) override; QVariant portData(QtNodes::NodeId nodeId, QtNodes::PortType portType, QtNodes::PortIndex portIndex, QtNodes::PortRole role) const override; bool setPortData(QtNodes::NodeId nodeId, QtNodes::PortType portType, QtNodes::PortIndex portIndex, QVariant const &value, QtNodes::PortRole role = QtNodes::PortRole::Data) override; bool deleteConnection(QtNodes::ConnectionId const connectionId) override; bool deleteNode(QtNodes::NodeId const nodeId) override; QJsonObject saveNode(QtNodes::NodeId const) const override; void loadNode(QJsonObject const &) override; QtNodes::NodeId addPipeWireNode(const Potato::NodeInfo &node); void removePipeWireNode(uint32_t nodeId); bool addPipeWireConnection(const Potato::LinkInfo &link, QtNodes::ConnectionId *connectionId); void removePipeWireConnection(uint32_t linkId); bool findConnectionForLink(uint32_t linkId, QtNodes::ConnectionId &connectionId) const; const Potato::NodeInfo *nodeInfo(QtNodes::NodeId nodeId) const; bool connectionIdForLink(const Potato::LinkInfo &link, QtNodes::ConnectionId &connectionId) const; void reset(); void loadLayout(); void saveLayout() const; void saveLayoutAs(const QString &path) const; void autoArrange(); void resetLayout(); QString defaultLayoutPath() const; void setViewState(double scale, const QPointF ¢er); bool viewState(double &scale, QPointF ¢er) const; private: QtNodes::ConnectionId connectionFromPipeWire(const Potato::LinkInfo &link, bool *ok) const; bool findPortIndex(const Potato::NodeInfo &node, uint32_t portId, QtNodes::PortType type, QtNodes::PortIndex &index) const; QString portLabel(const Potato::PortInfo &port) const; QPointF nextPosition() const; QString layoutFilePath() const; void updateLayoutForNode(QtNodes::NodeId nodeId, QPointF position); void writeLayoutToFile(const QString &path) const; void applyLayoutData(const QJsonArray &nodes); Potato::PipeWireController *m_controller = nullptr; QtNodes::NodeId m_nextNodeId = 1; std::unordered_map m_nodes; std::unordered_map m_pwToNode; std::unordered_set m_connections; std::unordered_map m_linkIdToConnection; std::unordered_map m_positions; QHash m_layoutByStableId; QPointF m_viewCenter = QPointF(0, 0); double m_viewScale = 1.0; bool m_hasViewState = false; };