1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
#pragma once
#include "DataModelRegistry.hpp"
#include "Export.hpp"
#include "QUuidStdHash.hpp"
#include "TypeConverter.hpp"
#include "memory.hpp"
#include <QtCore/QUuid>
#include <QtWidgets/QGraphicsScene>
#include <functional>
#include <tuple>
#include <unordered_map>
namespace QtNodes
{
class NodeDataModel;
class FlowItemInterface;
class Node;
class NodeGraphicsObject;
class Connection;
class ConnectionGraphicsObject;
class NodeStyle;
/// Scene holds connections and nodes.
class NODE_EDITOR_PUBLIC FlowScene : public QGraphicsScene
{
Q_OBJECT
public:
FlowScene(std::shared_ptr<DataModelRegistry> registry, QObject *parent = Q_NULLPTR);
FlowScene(QObject *parent = Q_NULLPTR);
~FlowScene();
public:
std::shared_ptr<Connection> createConnection(PortType connectedPort, Node &node, PortIndex portIndex);
std::shared_ptr<Connection> createConnection(Node &nodeIn, PortIndex portIndexIn, Node &nodeOut, PortIndex portIndexOut,
TypeConverter const &converter = TypeConverter{});
std::shared_ptr<Connection> restoreConnection(QJsonObject const &connectionJson);
void deleteConnection(const Connection &connection);
Node &createNode(std::unique_ptr<NodeDataModel> &&dataModel);
Node &restoreNode(QJsonObject const &nodeJson);
void removeNode(Node &node);
DataModelRegistry ®istry() const;
void setRegistry(std::shared_ptr<DataModelRegistry> registry);
void iterateOverNodes(std::function<void(Node *)> const &visitor);
void iterateOverNodeData(std::function<void(NodeDataModel *)> const &visitor);
void iterateOverNodeDataDependentOrder(std::function<void(NodeDataModel *)> const &visitor);
QPointF getNodePosition(Node const &node) const;
void setNodePosition(Node &node, QPointF const &pos) const;
QSizeF getNodeSize(Node const &node) const;
public:
inline std::unique_ptr<Node> const &node(const QUuid &id) const
{
return nodes().at(id);
}
inline std::shared_ptr<Connection> const &connection(const QUuid &id) const
{
return connections().at(id);
}
std::unordered_map<QUuid, std::unique_ptr<Node>> const &nodes() const;
std::unordered_map<QUuid, std::shared_ptr<Connection>> const &connections() const;
std::vector<Node *> allNodes() const;
std::vector<Node *> selectedNodes() const;
public:
void clearScene();
void save() const;
void load();
QByteArray saveToMemory() const;
void loadFromMemory(const QByteArray &data);
Q_SIGNALS:
/**
* @brief Node has been created but not on the scene yet.
* @see nodePlaced()
*/
void nodeCreated(Node &n);
/**
* @brief Node has been added to the scene.
* @details Connect to this signal if need a correct position of node.
* @see nodeCreated()
*/
void nodePlaced(Node &n);
void nodeDeleted(Node &n);
void connectionCreated(Connection const &c);
void connectionDeleted(Connection const &c);
void nodeMoved(Node &n, const QPointF &newLocation);
void nodeDoubleClicked(Node &n);
void nodeClicked(Node &n);
void connectionHovered(Connection &c, QPoint screenPos);
void nodeHovered(Node &n, QPoint screenPos);
void connectionHoverLeft(Connection &c);
void nodeHoverLeft(Node &n);
void nodeContextMenu(Node &n, const QPointF &pos);
private:
using SharedConnection = std::shared_ptr<Connection>;
using UniqueNode = std::unique_ptr<Node>;
std::unordered_map<QUuid, SharedConnection> _connections;
std::unordered_map<QUuid, UniqueNode> _nodes;
std::shared_ptr<DataModelRegistry> _registry;
private Q_SLOTS:
void setupConnectionSignals(Connection const &c);
void sendConnectionCreatedToNodes(Connection const &c);
void sendConnectionDeletedToNodes(Connection const &c);
void sceneContextMenuEvent(Node &node, const QPointF &pos);
};
Node *locateNodeAt(QPointF scenePoint, FlowScene &scene, QTransform const &viewTransform);
} // namespace QtNodes
|