实现图元基础连线功能
This commit is contained in:
parent
8ba53cf1ca
commit
deec2c2d63
|
|
@ -48,6 +48,7 @@ set(H_HEADER_FILES
|
||||||
include/operationCommand.h
|
include/operationCommand.h
|
||||||
include/toolPage.h
|
include/toolPage.h
|
||||||
include/toolBox.h
|
include/toolBox.h
|
||||||
|
include/statusBar.h
|
||||||
|
|
||||||
include/util/baseSelector.h
|
include/util/baseSelector.h
|
||||||
include/util/creatingSelector.h
|
include/util/creatingSelector.h
|
||||||
|
|
@ -58,7 +59,10 @@ set(H_HEADER_FILES
|
||||||
include/util/connectingSelector.h
|
include/util/connectingSelector.h
|
||||||
include/util/selectorManager.h
|
include/util/selectorManager.h
|
||||||
|
|
||||||
|
include/graphicsDataModel/fixedPortsModel.h
|
||||||
|
|
||||||
include/graphicsItem/itemControlHandle.h
|
include/graphicsItem/itemControlHandle.h
|
||||||
|
include/graphicsItem/itemPort.h
|
||||||
include/graphicsItem/graphicsBaseItem.h
|
include/graphicsItem/graphicsBaseItem.h
|
||||||
include/graphicsItem/graphicsRectItem.h
|
include/graphicsItem/graphicsRectItem.h
|
||||||
include/graphicsItem/graphicsPolygonItem.h
|
include/graphicsItem/graphicsPolygonItem.h
|
||||||
|
|
@ -67,6 +71,8 @@ set(H_HEADER_FILES
|
||||||
include/graphicsItem/electricSvgItemBus.h
|
include/graphicsItem/electricSvgItemBus.h
|
||||||
include/graphicsItem/electricSvgItemRect.h
|
include/graphicsItem/electricSvgItemRect.h
|
||||||
include/graphicsItem/electricSvgItemTriangle.h
|
include/graphicsItem/electricSvgItemTriangle.h
|
||||||
|
include/graphicsItem/electricConnectLineItem.h
|
||||||
|
|
||||||
include/abstractGraphModel.h
|
include/abstractGraphModel.h
|
||||||
include/connectionIdUtils.h
|
include/connectionIdUtils.h
|
||||||
include/serializable.h
|
include/serializable.h
|
||||||
|
|
@ -108,6 +114,7 @@ set(CPP_SOURCE_FILES
|
||||||
source/operationCommand.cpp
|
source/operationCommand.cpp
|
||||||
source/toolPage.cpp
|
source/toolPage.cpp
|
||||||
source/toolBox.cpp
|
source/toolBox.cpp
|
||||||
|
source/statusBar.cpp
|
||||||
|
|
||||||
source/util/baseSelector.cpp
|
source/util/baseSelector.cpp
|
||||||
source/util/creatingSelector.cpp
|
source/util/creatingSelector.cpp
|
||||||
|
|
@ -118,7 +125,10 @@ set(CPP_SOURCE_FILES
|
||||||
source/util/connectingSelector.cpp
|
source/util/connectingSelector.cpp
|
||||||
source/util/selectorManager.cpp
|
source/util/selectorManager.cpp
|
||||||
|
|
||||||
|
source/graphicsDataModel/fixedPortsModel.cpp
|
||||||
|
|
||||||
source/graphicsItem/itemControlHandle.cpp
|
source/graphicsItem/itemControlHandle.cpp
|
||||||
|
source/graphicsItem/itemPort.cpp
|
||||||
source/graphicsItem/graphicsBaseItem.cpp
|
source/graphicsItem/graphicsBaseItem.cpp
|
||||||
source/graphicsItem/graphicsRectItem.cpp
|
source/graphicsItem/graphicsRectItem.cpp
|
||||||
source/graphicsItem/graphicsPolygonItem.cpp
|
source/graphicsItem/graphicsPolygonItem.cpp
|
||||||
|
|
@ -127,6 +137,8 @@ set(CPP_SOURCE_FILES
|
||||||
source/graphicsItem/electricSvgItemBus.cpp
|
source/graphicsItem/electricSvgItemBus.cpp
|
||||||
source/graphicsItem/electricSvgItemRect.cpp
|
source/graphicsItem/electricSvgItemRect.cpp
|
||||||
source/graphicsItem/electricSvgItemTriangle.cpp
|
source/graphicsItem/electricSvgItemTriangle.cpp
|
||||||
|
source/graphicsItem/electricConnectLineItem.cpp
|
||||||
|
|
||||||
source/abstractGraphModel.cpp
|
source/abstractGraphModel.cpp
|
||||||
source/dataFlowGraphModel.cpp
|
source/dataFlowGraphModel.cpp
|
||||||
source/nodeDelegateModel.cpp
|
source/nodeDelegateModel.cpp
|
||||||
|
|
@ -164,6 +176,8 @@ if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||||
${CPP_SOURCE_FILES}
|
${CPP_SOURCE_FILES}
|
||||||
${UI_FILES}
|
${UI_FILES}
|
||||||
resource/DiagramDesigner.qrc
|
resource/DiagramDesigner.qrc
|
||||||
|
include/graphicsDataModel/fixedPortsModel.h
|
||||||
|
source/graphicsDataModel/fixedPortsModel.cpp
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,13 @@ private:
|
||||||
bool zoomLimit(double&);
|
bool zoomLimit(double&);
|
||||||
double getScaleFactor();
|
double getScaleFactor();
|
||||||
void translate(const QPointF&);
|
void translate(const QPointF&);
|
||||||
|
signals:
|
||||||
|
void onScaleChanged(double d);
|
||||||
private:
|
private:
|
||||||
bool m_bMousePress;
|
bool m_bMousePress;
|
||||||
double m_dScale;
|
double m_dScale;
|
||||||
QPointF m_ptLatstMouse_view; //鼠标最后按下在view中的位置
|
QPointF m_ptLatstMouse_view; //鼠标最后按下在view中的位置
|
||||||
|
int m_nLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,7 @@ class DesignerView;
|
||||||
class DesignerScene;
|
class DesignerScene;
|
||||||
class SelectorManager;
|
class SelectorManager;
|
||||||
class GraphicsItemGroup;
|
class GraphicsItemGroup;
|
||||||
//class NodeDelegateModelRegistry;
|
class StatusBar;
|
||||||
|
|
||||||
|
|
||||||
class DrawingPanel : public QWidget
|
class DrawingPanel : public QWidget
|
||||||
{
|
{
|
||||||
|
|
@ -45,7 +44,7 @@ private:
|
||||||
DesignerView* m_pGraphicsView;
|
DesignerView* m_pGraphicsView;
|
||||||
DesignerScene* m_pGraphicsScene;
|
DesignerScene* m_pGraphicsScene;
|
||||||
SelectorManager* m_pSelectorManager;
|
SelectorManager* m_pSelectorManager;
|
||||||
|
StatusBar* m_pStatusBar;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ enum GraphicsItemType
|
||||||
//======================================
|
//======================================
|
||||||
GIT_bus = QGraphicsItem::UserType + 50,
|
GIT_bus = QGraphicsItem::UserType + 50,
|
||||||
GIT_itemRect = QGraphicsItem::UserType + 51,
|
GIT_itemRect = QGraphicsItem::UserType + 51,
|
||||||
GIT_itemTri = QGraphicsItem::UserType + 52
|
GIT_itemTri = QGraphicsItem::UserType + 52,
|
||||||
|
GIT_connectLine = QGraphicsItem::UserType + 53
|
||||||
};
|
};
|
||||||
//Q_ENUM_NS(GraphicsItemType)
|
//Q_ENUM_NS(GraphicsItemType)
|
||||||
|
|
||||||
|
|
@ -87,6 +88,12 @@ enum class PortType {
|
||||||
};
|
};
|
||||||
//Q_ENUM_NS(PortType)
|
//Q_ENUM_NS(PortType)
|
||||||
|
|
||||||
|
enum PortState
|
||||||
|
{
|
||||||
|
P_const = 0, //固定端口
|
||||||
|
p_movable, //移动端口
|
||||||
|
};
|
||||||
|
|
||||||
using PortCount = int;
|
using PortCount = int;
|
||||||
|
|
||||||
/// ports are consecutively numbered starting from zero.
|
/// ports are consecutively numbered starting from zero.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "abstractGraphModel.h"
|
||||||
|
#include "connectionIdUtils.h"
|
||||||
|
#include "nodeDelegateModelRegistry.h"
|
||||||
|
#include "serializable.h"
|
||||||
|
#include "styleCollection.h"
|
||||||
|
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
|
||||||
|
class FixedPortsModel : public AbstractGraphModel, public Serializable
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct NodeGeometryData
|
||||||
|
{
|
||||||
|
QSize size;
|
||||||
|
QPointF pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
FixedPortsModel(QSharedPointer<NodeDelegateModelRegistry> registry);
|
||||||
|
|
||||||
|
QSharedPointer<NodeDelegateModelRegistry> dataModelRegistry() { return _registry; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
QSet<NodeId> allNodeIds() const override;
|
||||||
|
|
||||||
|
QSet<ConnectionId> allConnectionIds(NodeId const nodeId) const override;
|
||||||
|
|
||||||
|
QSet<ConnectionId> connections(NodeId nodeId,
|
||||||
|
PortType portType,
|
||||||
|
PortIndex portIndex) const override;
|
||||||
|
|
||||||
|
bool connectionExists(ConnectionId const connectionId) const override;
|
||||||
|
|
||||||
|
NodeId addNode(QString const nodeType) override;
|
||||||
|
|
||||||
|
bool connectionPossible(ConnectionId const connectionId) const override;
|
||||||
|
|
||||||
|
void addConnection(ConnectionId const connectionId) override;
|
||||||
|
|
||||||
|
bool nodeExists(NodeId const nodeId) const override;
|
||||||
|
|
||||||
|
QVariant nodeData(NodeId nodeId, NodeRole role) const override;
|
||||||
|
|
||||||
|
NodeFlags nodeFlags(NodeId nodeId) const override;
|
||||||
|
|
||||||
|
bool setNodeData(NodeId nodeId, NodeRole role, QVariant value) override;
|
||||||
|
|
||||||
|
QVariant portData(NodeId nodeId,
|
||||||
|
PortType portType,
|
||||||
|
PortIndex portIndex,
|
||||||
|
PortRole role) const override;
|
||||||
|
|
||||||
|
bool setPortData(NodeId nodeId,
|
||||||
|
PortType portType,
|
||||||
|
PortIndex portIndex,
|
||||||
|
QVariant const &value,
|
||||||
|
PortRole role = PortRole::Data) override;
|
||||||
|
|
||||||
|
bool deleteConnection(ConnectionId const connectionId) override;
|
||||||
|
|
||||||
|
bool deleteNode(NodeId const nodeId) override;
|
||||||
|
|
||||||
|
QJsonObject saveNode(NodeId const) const override;
|
||||||
|
|
||||||
|
QJsonObject save() const override;
|
||||||
|
|
||||||
|
void loadNode(QJsonObject const &nodeJson) override;
|
||||||
|
|
||||||
|
void load(QJsonObject const &json) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the NodeDelegateModel for the given `nodeId` and tries to cast the
|
||||||
|
* stored pointer to the given type
|
||||||
|
*/
|
||||||
|
template<typename NodeDelegateModelType>
|
||||||
|
NodeDelegateModelType *delegateModel(NodeId const nodeId)
|
||||||
|
{
|
||||||
|
auto it = _models.find(nodeId);
|
||||||
|
if (it == _models.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
//auto model = dynamic_cast<NodeDelegateModelType *>(it->second.get());
|
||||||
|
auto model = dynamic_cast<NodeDelegateModelType *>(*it);
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void inPortDataWasSet(NodeId const, PortType const, PortIndex const);
|
||||||
|
|
||||||
|
private:
|
||||||
|
NodeId newNodeId() override { return _nextNodeId++; }
|
||||||
|
|
||||||
|
void sendConnectionCreation(ConnectionId const connectionId);
|
||||||
|
|
||||||
|
void sendConnectionDeletion(ConnectionId const connectionId);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
/**
|
||||||
|
* Fuction is called in three cases:
|
||||||
|
*
|
||||||
|
* - By underlying NodeDelegateModel when a node has new data to propagate.
|
||||||
|
* @see DataFlowGraphModel::addNode
|
||||||
|
* - When a new connection is created.
|
||||||
|
* @see DataFlowGraphModel::addConnection
|
||||||
|
* - When a node restored from JSON an needs to send data downstream.
|
||||||
|
* @see DataFlowGraphModel::loadNode
|
||||||
|
*/
|
||||||
|
void onOutPortDataUpdated(NodeId const nodeId, PortIndex const portIndex);
|
||||||
|
|
||||||
|
/// Function is called after detaching a connection.
|
||||||
|
void propagateEmptyDataTo(NodeId const nodeId, PortIndex const portIndex);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedPointer<NodeDelegateModelRegistry> _registry;
|
||||||
|
|
||||||
|
NodeId _nextNodeId;
|
||||||
|
|
||||||
|
QMap<NodeId, QSharedPointer<NodeDelegateModel>> _models;
|
||||||
|
|
||||||
|
QSet<ConnectionId> _connectivity;
|
||||||
|
|
||||||
|
mutable QMap<NodeId, NodeGeometryData> _nodeGeometryData;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtNodes/NodeDelegateModel>
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "DecimalData.hpp"
|
||||||
|
|
||||||
|
using QtNodes::NodeData;
|
||||||
|
using QtNodes::NodeDataType;
|
||||||
|
using QtNodes::NodeDelegateModel;
|
||||||
|
using QtNodes::PortIndex;
|
||||||
|
using QtNodes::PortType;
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
|
||||||
|
/// The model dictates the number of inputs and outputs for the Node.
|
||||||
|
/// In this example it has no logic.
|
||||||
|
class NumberDisplayDataModel : public NodeDelegateModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
NumberDisplayDataModel();
|
||||||
|
|
||||||
|
~NumberDisplayDataModel() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QString caption() const override { return QStringLiteral("Result"); }
|
||||||
|
|
||||||
|
bool captionVisible() const override { return false; }
|
||||||
|
|
||||||
|
QString name() const override { return QStringLiteral("Result"); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
unsigned int nPorts(PortType portType) const override;
|
||||||
|
|
||||||
|
NodeDataType dataType(PortType portType, PortIndex portIndex) const override;
|
||||||
|
|
||||||
|
std::shared_ptr<NodeData> outData(PortIndex port) override;
|
||||||
|
|
||||||
|
void setInData(std::shared_ptr<NodeData> data, PortIndex portIndex) override;
|
||||||
|
|
||||||
|
QWidget *embeddedWidget() override;
|
||||||
|
|
||||||
|
double number() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<DecimalData> _numberData;
|
||||||
|
|
||||||
|
QLabel *_label;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
#ifndef ELECTRICCONNECTLINEITEM_H
|
||||||
|
#define ELECTRICCONNECTLINEITEM_H
|
||||||
|
|
||||||
|
#include <QPainterPath>
|
||||||
|
#include "graphicsBaseItem.h"
|
||||||
|
|
||||||
|
struct Connection
|
||||||
|
{
|
||||||
|
int nSrcNodeId;
|
||||||
|
int nSrcPort;
|
||||||
|
HandleType srcType;
|
||||||
|
int nDestNodeId;
|
||||||
|
int nDestPort;
|
||||||
|
HandleType destType;
|
||||||
|
|
||||||
|
Connection()
|
||||||
|
{
|
||||||
|
|
||||||
|
nSrcNodeId = -1;
|
||||||
|
nSrcPort = -1;
|
||||||
|
srcType = T_none;
|
||||||
|
nDestNodeId = -1;
|
||||||
|
nDestPort = -1;
|
||||||
|
destType = T_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection(int nSNI,int nSP,HandleType sT,int nDNI,int nDP,HandleType dT)
|
||||||
|
{
|
||||||
|
nSrcNodeId = nSNI;
|
||||||
|
nSrcPort = nSP;
|
||||||
|
srcType = sT;
|
||||||
|
nDestNodeId = nDNI;
|
||||||
|
nDestPort = nDP;
|
||||||
|
destType = dT;
|
||||||
|
}
|
||||||
|
bool operator==(Connection& obj)
|
||||||
|
{
|
||||||
|
return ((obj.nSrcNodeId == nSrcNodeId)&&(obj.nSrcPort == nSrcPort)&&(obj.srcType == srcType)&&(obj.nDestNodeId == nDestNodeId)&&(obj.nDestPort == nDestPort)&&(obj.destType == destType));
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection& operator=(Connection& obj)
|
||||||
|
{
|
||||||
|
if(*this == obj)
|
||||||
|
return *this;
|
||||||
|
nSrcNodeId = obj.nSrcNodeId;
|
||||||
|
nSrcPort = obj.nSrcPort;
|
||||||
|
srcType = obj.srcType;
|
||||||
|
nDestNodeId = obj.nDestNodeId;
|
||||||
|
nDestPort = obj.nDestPort;
|
||||||
|
destType = obj.destType;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ElectricConnectLineItem : public GraphicsBaseItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ElectricConnectLineItem(QGraphicsItem *parent = 0);
|
||||||
|
virtual ~ElectricConnectLineItem();
|
||||||
|
|
||||||
|
void setStartPoint(const QPointF& p){m_pStart = p;}
|
||||||
|
void setEndPoint(const QPointF& p){m_pEnd = p;}
|
||||||
|
QPainterPath getPoints(void) const { return m_points; }
|
||||||
|
|
||||||
|
void calculatePath();
|
||||||
|
bool addConnection();
|
||||||
|
|
||||||
|
void updateConnection(int callerId,QPointF pos); //外部调用的更新函数,id为调用者id
|
||||||
|
void setConnection(Connection con){m_connectState = con;}
|
||||||
|
protected:
|
||||||
|
virtual QPainterPath shape();
|
||||||
|
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
|
||||||
|
private:
|
||||||
|
Connection m_connectState;
|
||||||
|
QPainterPath m_points;
|
||||||
|
QPointF m_pStart;
|
||||||
|
QPointF m_pEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -9,6 +9,8 @@ class ElectricSvgItemBus :public ElectricSvgItem
|
||||||
public:
|
public:
|
||||||
ElectricSvgItemBus(const QRect &rect, QGraphicsItem *parent = 0);
|
ElectricSvgItemBus(const QRect &rect, QGraphicsItem *parent = 0);
|
||||||
virtual ~ElectricSvgItemBus();
|
virtual ~ElectricSvgItemBus();
|
||||||
|
|
||||||
|
void addPort();
|
||||||
protected:
|
protected:
|
||||||
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
|
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define GRAPHICSBASEITEM_H
|
#define GRAPHICSBASEITEM_H
|
||||||
|
|
||||||
#include "itemControlHandle.h"
|
#include "itemControlHandle.h"
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QGraphicsItem>
|
#include <QGraphicsItem>
|
||||||
|
|
@ -20,10 +21,10 @@ enum ShapeType
|
||||||
enum ItemState
|
enum ItemState
|
||||||
{
|
{
|
||||||
S_normal = 0,
|
S_normal = 0,
|
||||||
S_lineOut,
|
S_prepareConnect,
|
||||||
s_lineIn
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//基类采用模板形式,QGraphicsItem是默认值,也可以是别的类型,比如QGraphicsItemGroup,这样不同的基类继承可以共用一些高层的行为定义
|
//基类采用模板形式,QGraphicsItem是默认值,也可以是别的类型,比如QGraphicsItemGroup,这样不同的基类继承可以共用一些高层的行为定义
|
||||||
template <typename BaseType = QGraphicsItem>
|
template <typename BaseType = QGraphicsItem>
|
||||||
class AbstractShapeType : public BaseType
|
class AbstractShapeType : public BaseType
|
||||||
|
|
@ -38,6 +39,7 @@ public:
|
||||||
m_dWidth = m_dHeight = 0;
|
m_dWidth = m_dHeight = 0;
|
||||||
m_pOperationCopy = nullptr;
|
m_pOperationCopy = nullptr;
|
||||||
m_dSyncRotationByParent = 0.0;
|
m_dSyncRotationByParent = 0.0;
|
||||||
|
m_touched = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~AbstractShapeType()
|
virtual ~AbstractShapeType()
|
||||||
|
|
@ -105,7 +107,10 @@ public:
|
||||||
{
|
{
|
||||||
QPointF pt = pHandle->mapFromScene(point);
|
QPointF pt = pHandle->mapFromScene(point);
|
||||||
if(pHandle->contains(pt))
|
if(pHandle->contains(pt))
|
||||||
return pHandle->getTag();
|
{
|
||||||
|
if(pHandle->enable())
|
||||||
|
return pHandle->getTag();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HandleTag::H_none;
|
return HandleTag::H_none;
|
||||||
|
|
@ -166,10 +171,72 @@ public:
|
||||||
ItemControlHandle* pHandle = m_vecHanle.value(key);
|
ItemControlHandle* pHandle = m_vecHanle.value(key);
|
||||||
if(pHandle)
|
if(pHandle)
|
||||||
{
|
{
|
||||||
if(bVisible)
|
if(pHandle->ifShow())
|
||||||
pHandle->show();
|
{
|
||||||
else
|
if(bVisible)
|
||||||
pHandle->hide();
|
pHandle->show();
|
||||||
|
else
|
||||||
|
pHandle->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void setHandleVisible(int tag,bool bVisible)
|
||||||
|
{
|
||||||
|
foreach (int key, m_vecHanle.keys())
|
||||||
|
{
|
||||||
|
ItemControlHandle* pHandle = m_vecHanle.value(key);
|
||||||
|
if(pHandle)
|
||||||
|
{
|
||||||
|
if(pHandle->getTag() == tag)
|
||||||
|
{
|
||||||
|
if(bVisible)
|
||||||
|
pHandle->show();
|
||||||
|
else
|
||||||
|
pHandle->hide();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void setFunctionHandleIfShow(bool bVisible) //是否参与显示判断
|
||||||
|
{
|
||||||
|
foreach (int key, m_vecHanle.keys())
|
||||||
|
{
|
||||||
|
ItemControlHandle* pHandle = m_vecHanle.value(key);
|
||||||
|
if(pHandle)
|
||||||
|
{
|
||||||
|
if(pHandle->getTag() < H_connect)
|
||||||
|
{
|
||||||
|
pHandle->setIfShow(bVisible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void setFunctionHandleEnaable(bool val)
|
||||||
|
{
|
||||||
|
foreach (int key, m_vecHanle.keys())
|
||||||
|
{
|
||||||
|
ItemControlHandle* pHandle = m_vecHanle.value(key);
|
||||||
|
if(pHandle)
|
||||||
|
{
|
||||||
|
if(pHandle->getTag() < H_connect) //设置port以外端点是否交互
|
||||||
|
pHandle->setEnable(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void setHandleEnaable(HandleTag tag,bool val)
|
||||||
|
{
|
||||||
|
foreach (int key, m_vecHanle.keys())
|
||||||
|
{
|
||||||
|
ItemControlHandle* pHandle = m_vecHanle.value(key);
|
||||||
|
if(pHandle)
|
||||||
|
{
|
||||||
|
if(pHandle->getTag() == tag) //设置端点是否交互
|
||||||
|
{
|
||||||
|
pHandle->setEnable(val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -221,93 +288,6 @@ public:
|
||||||
{
|
{
|
||||||
int nMargin = 5;
|
int nMargin = 5;
|
||||||
const QRectF& boundRect = this->boundingRect();
|
const QRectF& boundRect = this->boundingRect();
|
||||||
/*for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
|
|
||||||
{
|
|
||||||
switch ((*it)->getTag()) {
|
|
||||||
case H_leftTop:
|
|
||||||
(*it)->move(boundRect.x() - nMargin, boundRect.y() - nMargin);
|
|
||||||
break;
|
|
||||||
case H_top:
|
|
||||||
(*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() - nMargin);
|
|
||||||
break;
|
|
||||||
case H_rightTop:
|
|
||||||
(*it)->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() - nMargin);
|
|
||||||
break;
|
|
||||||
case H_right:
|
|
||||||
(*it)->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() + boundRect.height() * 0.5 + nMargin);
|
|
||||||
break;
|
|
||||||
case H_rightBottom:
|
|
||||||
(*it)->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() + boundRect.height() + nMargin);
|
|
||||||
break;
|
|
||||||
case H_bottom:
|
|
||||||
(*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() + boundRect.height()+ nMargin);
|
|
||||||
break;
|
|
||||||
case H_leftBottom:
|
|
||||||
(*it)->move(boundRect.x() - nMargin, boundRect.y() + boundRect.height() + nMargin);
|
|
||||||
break;
|
|
||||||
case H_left:
|
|
||||||
(*it)->move(boundRect.x() - nMargin, boundRect.y() + boundRect.height() * 0.5);
|
|
||||||
break;
|
|
||||||
case H_rotate_leftTop:
|
|
||||||
{
|
|
||||||
ItemControlHandle* handle = getHandle(H_leftTop);
|
|
||||||
if(handle)
|
|
||||||
{
|
|
||||||
int nSize = handle->getSize();
|
|
||||||
QPointF pt = handle->pos();
|
|
||||||
(*it)->move(pt.x() - nSize - 1, pt.y() - nSize - 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(*it)->setVisible(false);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case H_rotate_rightTop:
|
|
||||||
{
|
|
||||||
ItemControlHandle* handle = getHandle(H_rightTop);
|
|
||||||
if(handle)
|
|
||||||
{
|
|
||||||
int nSize = handle->getSize();
|
|
||||||
QPointF pt = handle->pos();
|
|
||||||
(*it)->move(pt.x() + nSize + 1, pt.y() - nSize - 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(*it)->setVisible(false);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case H_rotate_rightBottom:
|
|
||||||
{
|
|
||||||
ItemControlHandle* handle = getHandle(H_rightBottom);
|
|
||||||
if(handle)
|
|
||||||
{
|
|
||||||
int nSize = handle->getSize();
|
|
||||||
QPointF pt = handle->pos();
|
|
||||||
(*it)->move(pt.x() + nSize + 1, pt.y() + nSize + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(*it)->setVisible(false);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case H_rotate_leftBottom:
|
|
||||||
{
|
|
||||||
ItemControlHandle* handle = getHandle(H_leftBottom);
|
|
||||||
if(handle)
|
|
||||||
{
|
|
||||||
int nSize = handle->getSize();
|
|
||||||
QPointF pt = handle->pos();
|
|
||||||
(*it)->move(pt.x() - nSize - 1, pt.y() + nSize + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(*it)->setVisible(false);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
foreach (int key, m_vecHanle.keys())
|
foreach (int key, m_vecHanle.keys())
|
||||||
{
|
{
|
||||||
|
|
@ -417,7 +397,7 @@ public:
|
||||||
|
|
||||||
virtual void syncRotationDataFromParent(const double&) {}
|
virtual void syncRotationDataFromParent(const double&) {}
|
||||||
virtual double getSyncRotationDataFromParent() {return m_dSyncRotationByParent;}
|
virtual double getSyncRotationDataFromParent() {return m_dSyncRotationByParent;}
|
||||||
|
virtual void setTouched(bool b){m_touched = b;}
|
||||||
protected:
|
protected:
|
||||||
ShapeType m_type;
|
ShapeType m_type;
|
||||||
QPen m_pen;
|
QPen m_pen;
|
||||||
|
|
@ -426,6 +406,7 @@ protected:
|
||||||
double m_dHeight;
|
double m_dHeight;
|
||||||
QRectF m_boundingRect;
|
QRectF m_boundingRect;
|
||||||
QRectF m_boundingRect_selected; //选中矩形框
|
QRectF m_boundingRect_selected; //选中矩形框
|
||||||
|
bool m_touched; //被触碰状态
|
||||||
|
|
||||||
double m_dSyncRotationByParent; //父项(被加入到某一组)的旋转数据,因为加入某一组后,对该组进行旋转,自身的旋转数据不会同步更新
|
double m_dSyncRotationByParent; //父项(被加入到某一组)的旋转数据,因为加入某一组后,对该组进行旋转,自身的旋转数据不会同步更新
|
||||||
|
|
||||||
|
|
@ -436,6 +417,8 @@ protected:
|
||||||
QMap<int,ItemControlHandle*> m_vecHanle;
|
QMap<int,ItemControlHandle*> m_vecHanle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ItemPort;
|
||||||
|
|
||||||
typedef AbstractShapeType<QGraphicsItem> AbstractShape;
|
typedef AbstractShapeType<QGraphicsItem> AbstractShape;
|
||||||
|
|
||||||
class GraphicsBaseItem : public QObject, public AbstractShapeType<QGraphicsItem>
|
class GraphicsBaseItem : public QObject, public AbstractShapeType<QGraphicsItem>
|
||||||
|
|
@ -454,18 +437,34 @@ public:
|
||||||
//多边形、线段等点选创建的对象需要的函数
|
//多边形、线段等点选创建的对象需要的函数
|
||||||
virtual void addPoint(const QPointF&) {}
|
virtual void addPoint(const QPointF&) {}
|
||||||
virtual bool endDrawing() { return true; }
|
virtual bool endDrawing() { return true; }
|
||||||
|
|
||||||
|
|
||||||
|
virtual int addPort(PortState typ,QPointF vec); //新建,返回-1失败
|
||||||
|
virtual void addPort(PortState typ,int ntagId,QPointF vec); //载入 PortState为P_const时,QPointF中为(0~1,0~1)的相对位置;PortState为p_movable时,QPointF为坐标值
|
||||||
|
virtual uint itemId() const {return m_itemId;}
|
||||||
|
virtual void setItemId(uint n){m_itemId = n;}
|
||||||
virtual void setState(ItemState s){m_state = s;}
|
virtual void setState(ItemState s){m_state = s;}
|
||||||
virtual void setBeginConnectPos(QPointF p){m_beginConnectPoint = p;}
|
virtual void setBeginConnectPos(QPointF p){m_beginConnectPoint = p;}
|
||||||
virtual void setEndConnectPos(QPointF p){m_endConnectPoint = p;}
|
virtual void setEndConnectPos(QPointF p){m_endConnectPoint = p;}
|
||||||
|
virtual void setItemType(GraphicsItemType type){m_Itemtype = type;}
|
||||||
|
virtual GraphicsItemType getItemType() const {return m_Itemtype;}
|
||||||
|
virtual void setLastPort(int n){_lastPort = n;}
|
||||||
|
virtual int getLastPort() const {return _lastPort;}
|
||||||
|
virtual ItemPort* getPortPtr(int) const;
|
||||||
|
virtual QMap<QString,ItemPort*>& getPorts() {return m_mapPort;}
|
||||||
protected:
|
protected:
|
||||||
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&);
|
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&);
|
||||||
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
|
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
uint m_itemId;
|
||||||
|
GraphicsItemType m_Itemtype;
|
||||||
ItemState m_state;
|
ItemState m_state;
|
||||||
|
QMap<QString,ItemPort*> m_mapPort; //单独存放port
|
||||||
QPointF m_beginConnectPoint;
|
QPointF m_beginConnectPoint;
|
||||||
QPointF m_endConnectPoint;
|
QPointF m_endConnectPoint;
|
||||||
|
uint _portId; //port编号
|
||||||
|
int _lastPort; //最后触碰的port
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,13 @@
|
||||||
|
|
||||||
enum HandleType
|
enum HandleType
|
||||||
{
|
{
|
||||||
|
T_none = 0,
|
||||||
T_resize, //调整大小
|
T_resize, //调整大小
|
||||||
T_rotate, //旋转
|
T_rotate, //旋转
|
||||||
T_editShape, //编辑形状
|
T_editShape, //编辑形状
|
||||||
T_lineIn, //入线口
|
T_lineIn, //入线口
|
||||||
T_lineOut //出线口
|
T_lineOut, //出线口
|
||||||
|
T_lineInOut //双端线
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HandleTag
|
enum HandleTag
|
||||||
|
|
@ -31,6 +33,15 @@ enum HandleTag
|
||||||
H_connect = 50 //连接操作点从50开始,前面预留
|
H_connect = 50 //连接操作点从50开始,前面预留
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PortPos
|
||||||
|
{
|
||||||
|
P_top = 0,
|
||||||
|
P_down,
|
||||||
|
P_left,
|
||||||
|
P_right
|
||||||
|
};
|
||||||
|
|
||||||
|
const int HNDLE_SIZE = 8;
|
||||||
|
|
||||||
class ItemControlHandle : public QObject,public QGraphicsRectItem
|
class ItemControlHandle : public QObject,public QGraphicsRectItem
|
||||||
{
|
{
|
||||||
|
|
@ -50,15 +61,21 @@ public:
|
||||||
int getSize();
|
int getSize();
|
||||||
void move(double, double);
|
void move(double, double);
|
||||||
|
|
||||||
|
void setEnable(bool b){m_enable = b;}
|
||||||
|
bool enable(){return m_enable;}
|
||||||
|
|
||||||
|
void setIfShow(bool b){m_ifShow = b;}
|
||||||
|
bool ifShow(){return m_ifShow;}
|
||||||
protected:
|
protected:
|
||||||
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*) override;
|
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*) override;
|
||||||
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override;
|
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override;
|
||||||
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
|
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
HandleType m_type;
|
HandleType m_type;
|
||||||
int m_tag;
|
int m_tag;
|
||||||
|
bool m_enable;
|
||||||
|
bool m_ifShow;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef ITEMPORT_H
|
||||||
|
#define ITEMPORT_H
|
||||||
|
|
||||||
|
#include "graphicsItem/itemControlHandle.h"
|
||||||
|
|
||||||
|
class ElectricConnectLineItem;
|
||||||
|
|
||||||
|
class ItemPort : public ItemControlHandle
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ItemPort(QGraphicsItem *parent);
|
||||||
|
virtual ~ItemPort();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setPortPos(PortPos p){_pos = p;}
|
||||||
|
PortPos portPos() const {return _pos;}
|
||||||
|
void setConnect(ElectricConnectLineItem* ptr){_ptr = ptr;}
|
||||||
|
void disConnect(){_ptr = nullptr;}
|
||||||
|
bool connected() const {return _ptr == nullptr?false:true;}
|
||||||
|
ElectricConnectLineItem* getConnectPtr() const {return _ptr;}
|
||||||
|
protected:
|
||||||
|
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PortPos _pos;
|
||||||
|
ElectricConnectLineItem* _ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef STATUSBAR_H
|
||||||
|
#define STATUSBAR_H
|
||||||
|
|
||||||
|
#include <QStatusBar>
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
|
||||||
|
class StatusBar : public QStatusBar
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit StatusBar(QWidget *parent = nullptr);
|
||||||
|
~StatusBar();
|
||||||
|
public slots:
|
||||||
|
void onScaleLevelChanged(double f);
|
||||||
|
private:
|
||||||
|
QLabel *m_pScaleLevel;
|
||||||
|
};
|
||||||
|
#endif // STATUSBAR_H
|
||||||
|
|
@ -34,6 +34,10 @@ enum OperationMode
|
||||||
OM_connect, //连接
|
OM_connect, //连接
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GraphicsBaseItem;
|
||||||
|
|
||||||
|
using ItemMap = QMap<QString,QMap<QString,GraphicsBaseItem*>>;
|
||||||
|
|
||||||
class BaseSelector : public QObject
|
class BaseSelector : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -53,7 +57,11 @@ public:
|
||||||
OperationMode getOperationMode() { return ms_opMode; }
|
OperationMode getOperationMode() { return ms_opMode; }
|
||||||
|
|
||||||
void setCursor(DesignerScene*, const QCursor&);
|
void setCursor(DesignerScene*, const QCursor&);
|
||||||
|
void setSceneName(const QString& str) {m_sceneName = str;}
|
||||||
|
QString sceneName() const {return m_sceneName;}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static ItemMap m_graphicsItem; //存储所有对象 类型 <图名<id,对象>>
|
||||||
signals:
|
signals:
|
||||||
void setWorkingSelector(SelectorType);
|
void setWorkingSelector(SelectorType);
|
||||||
|
|
||||||
|
|
@ -64,8 +72,10 @@ protected:
|
||||||
static QPointF ms_ptMouseLast;
|
static QPointF ms_ptMouseLast;
|
||||||
static double ms_dAngleMouseDownToItem; //鼠标按下时其位置和item中心点形成的夹角
|
static double ms_dAngleMouseDownToItem; //鼠标按下时其位置和item中心点形成的夹角
|
||||||
static int ms_nDragHandle; //当前抓取的控制点
|
static int ms_nDragHandle; //当前抓取的控制点
|
||||||
|
static uint _Id;
|
||||||
SelectorType m_type;
|
SelectorType m_type;
|
||||||
|
|
||||||
|
QString m_sceneName;
|
||||||
private:
|
private:
|
||||||
bool m_bHoverOnHandel; //鼠标是否悬停在handel
|
bool m_bHoverOnHandel; //鼠标是否悬停在handel
|
||||||
OperationMode m_opMode;
|
OperationMode m_opMode;
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,18 @@ class ConnectingSelector : public BaseSelector
|
||||||
public:
|
public:
|
||||||
explicit ConnectingSelector(QObject *parent = 0);
|
explicit ConnectingSelector(QObject *parent = 0);
|
||||||
virtual ~ConnectingSelector();
|
virtual ~ConnectingSelector();
|
||||||
|
public:
|
||||||
|
bool targetCouldConnect(GraphicsBaseItem* p,QPointF pos);
|
||||||
|
void setTargetHighLight(bool val); //设置目标高亮
|
||||||
|
void createConnectLline(GraphicsBaseItem* connecting,GraphicsBaseItem* touched,DesignerScene* scene);
|
||||||
public:
|
public:
|
||||||
void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
|
void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
|
||||||
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
|
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
|
||||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
|
||||||
private:
|
private:
|
||||||
GraphicsBaseItem* m_pConnectingItem;
|
GraphicsBaseItem* m_pConnectingItem;
|
||||||
|
GraphicsBaseItem* m_pTouchedItem; //连线时接触的对象
|
||||||
|
bool m_bReadyConnect; //准备连接
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ public:
|
||||||
explicit MovingSelector(QObject *parent = 0);
|
explicit MovingSelector(QObject *parent = 0);
|
||||||
virtual ~MovingSelector();
|
virtual ~MovingSelector();
|
||||||
|
|
||||||
|
void updateConnectLine(QList<QGraphicsItem *>);
|
||||||
public:
|
public:
|
||||||
void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
|
void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
|
||||||
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
|
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ public:
|
||||||
BaseSelector* getWorkingSelector(); //根据操作方式获取selector
|
BaseSelector* getWorkingSelector(); //根据操作方式获取selector
|
||||||
|
|
||||||
void setDrawGraphicsItem(GraphicsItemType);
|
void setDrawGraphicsItem(GraphicsItemType);
|
||||||
|
void setName(const QString&);
|
||||||
public slots:
|
public slots:
|
||||||
void onSignal_setWorkingSelector(SelectorType);
|
void onSignal_setWorkingSelector(SelectorType);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ DesignerScene::DesignerScene(DataFlowGraphModel &graphModel, QObject *parent)
|
||||||
m_bGridVisible = true;
|
m_bGridVisible = true;
|
||||||
m_pView = nullptr;
|
m_pView = nullptr;
|
||||||
m_pDrawingPanel = dynamic_cast<DrawingPanel*>(parent);
|
m_pDrawingPanel = dynamic_cast<DrawingPanel*>(parent);
|
||||||
|
|
||||||
connect(&_graphModel,
|
connect(&_graphModel,
|
||||||
&DataFlowGraphModel::inPortDataWasSet,
|
&DataFlowGraphModel::inPortDataWasSet,
|
||||||
[this](NodeId const nodeId, PortType const, PortIndex const) { onNodeUpdated(nodeId); });
|
[this](NodeId const nodeId, PortType const, PortIndex const) { onNodeUpdated(nodeId); });
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ DesignerView::DesignerView(QWidget *parent)
|
||||||
m_bMousePress = false;
|
m_bMousePress = false;
|
||||||
m_dScale = 1.0;
|
m_dScale = 1.0;
|
||||||
initialize();
|
initialize();
|
||||||
|
m_nLevel = 10;
|
||||||
}
|
}
|
||||||
DesignerView::~DesignerView()
|
DesignerView::~DesignerView()
|
||||||
{
|
{
|
||||||
|
|
@ -80,6 +81,7 @@ void DesignerView::wheelEvent(QWheelEvent* event) //滚轮进行放大缩小
|
||||||
QPointF mousePos = event->position();
|
QPointF mousePos = event->position();
|
||||||
double angleDeltaY = event->angleDelta().y();
|
double angleDeltaY = event->angleDelta().y();
|
||||||
double zoomFactor = qPow(1.0015, angleDeltaY); //可以实现更平滑的缩放
|
double zoomFactor = qPow(1.0015, angleDeltaY); //可以实现更平滑的缩放
|
||||||
|
|
||||||
zoom(mousePos, zoomFactor);
|
zoom(mousePos, zoomFactor);
|
||||||
|
|
||||||
//注意不要调用基类的滚轮函数,否则滚轮事件会映射到滚动条操作
|
//注意不要调用基类的滚轮函数,否则滚轮事件会映射到滚动条操作
|
||||||
|
|
@ -109,6 +111,12 @@ bool DesignerView::zoomLimit(double& value)
|
||||||
if(qFabs(value - 1) < 0.01) //缩放因子近似为1
|
if(qFabs(value - 1) < 0.01) //缩放因子近似为1
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if(value > 1)
|
||||||
|
m_nLevel +=1;
|
||||||
|
else
|
||||||
|
m_nLevel -=1;
|
||||||
|
|
||||||
|
emit onScaleChanged(m_nLevel);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,6 +138,7 @@ void DesignerView::zoom(const QPointF& mousePos, double zoomFactor)
|
||||||
trans.translate(-targetScenePos.x(), -targetScenePos.y());
|
trans.translate(-targetScenePos.x(), -targetScenePos.y());
|
||||||
setTransform(trans);
|
setTransform(trans);
|
||||||
setTransformationAnchor(lastAnchor);
|
setTransformationAnchor(lastAnchor);
|
||||||
|
//emit onScaleChanged(m_nLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerView::zoomIn()
|
void DesignerView::zoomIn()
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include "dataFlowGraphModel.h"
|
#include "dataFlowGraphModel.h"
|
||||||
#include "nodeDelegateModelRegistry.h"
|
#include "nodeDelegateModelRegistry.h"
|
||||||
#include "util/selectorManager.h"
|
#include "util/selectorManager.h"
|
||||||
|
#include "statusBar.h"
|
||||||
|
|
||||||
DrawingPanel::DrawingPanel(QWidget *parent)
|
DrawingPanel::DrawingPanel(QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
|
|
@ -26,7 +26,9 @@ DrawingPanel::DrawingPanel(QWidget *parent)
|
||||||
m_pGraphicsScene->setView(m_pGraphicsView);
|
m_pGraphicsScene->setView(m_pGraphicsView);
|
||||||
ui->mainLayout->addWidget(m_pGraphicsView);
|
ui->mainLayout->addWidget(m_pGraphicsView);
|
||||||
|
|
||||||
|
m_pStatusBar = new StatusBar(this);
|
||||||
|
ui->mainLayout->addWidget(m_pStatusBar);
|
||||||
|
connect(m_pGraphicsView,&DesignerView::onScaleChanged,m_pStatusBar,&StatusBar::onScaleLevelChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawingPanel::~DrawingPanel()
|
DrawingPanel::~DrawingPanel()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
#include "NumberDisplayDataModel.hpp"
|
||||||
|
|
||||||
|
#include <QtWidgets/QLabel>
|
||||||
|
|
||||||
|
NumberDisplayDataModel::NumberDisplayDataModel()
|
||||||
|
: _label{nullptr}
|
||||||
|
{}
|
||||||
|
|
||||||
|
unsigned int NumberDisplayDataModel::nPorts(PortType portType) const
|
||||||
|
{
|
||||||
|
unsigned int result = 1;
|
||||||
|
|
||||||
|
switch (portType) {
|
||||||
|
case PortType::In:
|
||||||
|
result = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PortType::Out:
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeDataType NumberDisplayDataModel::dataType(PortType, PortIndex) const
|
||||||
|
{
|
||||||
|
return DecimalData().type();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<NodeData> NumberDisplayDataModel::outData(PortIndex)
|
||||||
|
{
|
||||||
|
std::shared_ptr<NodeData> ptr;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NumberDisplayDataModel::setInData(std::shared_ptr<NodeData> data, PortIndex portIndex)
|
||||||
|
{
|
||||||
|
_numberData = std::dynamic_pointer_cast<DecimalData>(data);
|
||||||
|
|
||||||
|
if (!_label)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_numberData) {
|
||||||
|
_label->setText(_numberData->numberAsText());
|
||||||
|
} else {
|
||||||
|
_label->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
_label->adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *NumberDisplayDataModel::embeddedWidget()
|
||||||
|
{
|
||||||
|
if (!_label) {
|
||||||
|
_label = new QLabel();
|
||||||
|
_label->setMargin(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _label;
|
||||||
|
}
|
||||||
|
|
||||||
|
double NumberDisplayDataModel::number() const
|
||||||
|
{
|
||||||
|
if (_numberData)
|
||||||
|
return _numberData->number();
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,530 @@
|
||||||
|
#include "graphicsDataModel/fixedPortsModel.h"
|
||||||
|
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
|
||||||
|
FixedPortsModel::FixedPortsModel(QSharedPointer<NodeDelegateModelRegistry> registry)
|
||||||
|
: _registry(registry)
|
||||||
|
, _nextNodeId{0}
|
||||||
|
{}
|
||||||
|
|
||||||
|
QSet<NodeId> FixedPortsModel::allNodeIds() const
|
||||||
|
{
|
||||||
|
QSet<NodeId> nodeIds;
|
||||||
|
//for_each(_models.begin(), _models.end(), [&nodeIds](auto const &p) { nodeIds.insert(p.first); });
|
||||||
|
|
||||||
|
for(auto iter = _models.begin();iter != _models.end();++iter)
|
||||||
|
{
|
||||||
|
nodeIds.insert(iter.key());
|
||||||
|
}
|
||||||
|
return nodeIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<ConnectionId> FixedPortsModel::allConnectionIds(NodeId const nodeId) const
|
||||||
|
{
|
||||||
|
QSet<ConnectionId> result;
|
||||||
|
|
||||||
|
std::copy_if(_connectivity.begin(),
|
||||||
|
_connectivity.end(),
|
||||||
|
std::inserter(result, std::end(result)),
|
||||||
|
[&nodeId](ConnectionId const &cid) {
|
||||||
|
return cid.inNodeId == nodeId || cid.outNodeId == nodeId;
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<ConnectionId> FixedPortsModel::connections(NodeId nodeId,
|
||||||
|
PortType portType,
|
||||||
|
PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
QSet<ConnectionId> result;
|
||||||
|
|
||||||
|
std::copy_if(_connectivity.begin(),
|
||||||
|
_connectivity.end(),
|
||||||
|
std::inserter(result, std::end(result)),
|
||||||
|
[&portType, &portIndex, &nodeId](ConnectionId const &cid) {
|
||||||
|
return (getNodeId(portType, cid) == nodeId
|
||||||
|
&& getPortIndex(portType, cid) == portIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FixedPortsModel::connectionExists(ConnectionId const connectionId) const
|
||||||
|
{
|
||||||
|
return (_connectivity.find(connectionId) != _connectivity.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeId FixedPortsModel::addNode(QString const nodeType)
|
||||||
|
{
|
||||||
|
QSharedPointer<NodeDelegateModel> model = _registry->create(nodeType);
|
||||||
|
|
||||||
|
if (model) {
|
||||||
|
NodeId newId = newNodeId();
|
||||||
|
|
||||||
|
connect(model.get(),
|
||||||
|
&NodeDelegateModel::dataUpdated,
|
||||||
|
[newId, this](PortIndex const portIndex) {
|
||||||
|
onOutPortDataUpdated(newId, portIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(model.get(),
|
||||||
|
&NodeDelegateModel::portsAboutToBeDeleted,
|
||||||
|
this,
|
||||||
|
[newId, this](PortType const portType, PortIndex const first, PortIndex const last) {
|
||||||
|
portsAboutToBeDeleted(newId, portType, first, last);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(model.get(),
|
||||||
|
&NodeDelegateModel::portsDeleted,
|
||||||
|
this,
|
||||||
|
&FixedPortsModel::portsDeleted);
|
||||||
|
|
||||||
|
connect(model.get(),
|
||||||
|
&NodeDelegateModel::portsAboutToBeInserted,
|
||||||
|
this,
|
||||||
|
[newId, this](PortType const portType, PortIndex const first, PortIndex const last) {
|
||||||
|
portsAboutToBeInserted(newId, portType, first, last);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(model.get(),
|
||||||
|
&NodeDelegateModel::portsInserted,
|
||||||
|
this,
|
||||||
|
&FixedPortsModel::portsInserted);
|
||||||
|
|
||||||
|
_models[newId] = model;
|
||||||
|
|
||||||
|
Q_EMIT nodeCreated(newId);
|
||||||
|
|
||||||
|
return newId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return InvalidNodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FixedPortsModel::connectionPossible(ConnectionId const connectionId) const
|
||||||
|
{
|
||||||
|
auto getDataType = [&](PortType const portType) {
|
||||||
|
return portData(getNodeId(portType, connectionId),
|
||||||
|
portType,
|
||||||
|
getPortIndex(portType, connectionId),
|
||||||
|
PortRole::DataType)
|
||||||
|
.value<NodeDataType>();
|
||||||
|
};
|
||||||
|
|
||||||
|
auto portVacant = [&](PortType const portType) {
|
||||||
|
NodeId const nodeId = getNodeId(portType, connectionId);
|
||||||
|
PortIndex const portIndex = getPortIndex(portType, connectionId);
|
||||||
|
auto const connected = connections(nodeId, portType, portIndex);
|
||||||
|
|
||||||
|
auto policy = portData(nodeId, portType, portIndex, PortRole::ConnectionPolicyRole)
|
||||||
|
.value<ConnectionPolicy>();
|
||||||
|
|
||||||
|
return connected.empty() || (policy == ConnectionPolicy::Many);
|
||||||
|
};
|
||||||
|
|
||||||
|
return getDataType(PortType::Out).id == getDataType(PortType::In).id
|
||||||
|
&& portVacant(PortType::Out) && portVacant(PortType::In);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedPortsModel::addConnection(ConnectionId const connectionId)
|
||||||
|
{
|
||||||
|
_connectivity.insert(connectionId);
|
||||||
|
|
||||||
|
sendConnectionCreation(connectionId);
|
||||||
|
|
||||||
|
QVariant const portDataToPropagate = portData(connectionId.outNodeId,
|
||||||
|
PortType::Out,
|
||||||
|
connectionId.outPortIndex,
|
||||||
|
PortRole::Data);
|
||||||
|
|
||||||
|
setPortData(connectionId.inNodeId,
|
||||||
|
PortType::In,
|
||||||
|
connectionId.inPortIndex,
|
||||||
|
portDataToPropagate,
|
||||||
|
PortRole::Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedPortsModel::sendConnectionCreation(ConnectionId const connectionId)
|
||||||
|
{
|
||||||
|
Q_EMIT connectionCreated(connectionId);
|
||||||
|
|
||||||
|
auto iti = _models.find(connectionId.inNodeId);
|
||||||
|
auto ito = _models.find(connectionId.outNodeId);
|
||||||
|
if (iti != _models.end() && ito != _models.end()) {
|
||||||
|
auto &modeli = *iti;
|
||||||
|
auto &modelo = *ito;
|
||||||
|
modeli->inputConnectionCreated(connectionId);
|
||||||
|
modelo->outputConnectionCreated(connectionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedPortsModel::sendConnectionDeletion(ConnectionId const connectionId)
|
||||||
|
{
|
||||||
|
Q_EMIT connectionDeleted(connectionId);
|
||||||
|
|
||||||
|
auto iti = _models.find(connectionId.inNodeId);
|
||||||
|
auto ito = _models.find(connectionId.outNodeId);
|
||||||
|
if (iti != _models.end() && ito != _models.end()) {
|
||||||
|
auto &modeli = *iti;
|
||||||
|
auto &modelo = *ito;
|
||||||
|
modeli->inputConnectionDeleted(connectionId);
|
||||||
|
modelo->outputConnectionDeleted(connectionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FixedPortsModel::nodeExists(NodeId const nodeId) const
|
||||||
|
{
|
||||||
|
return (_models.find(nodeId) != _models.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant FixedPortsModel::nodeData(NodeId nodeId, NodeRole role) const
|
||||||
|
{
|
||||||
|
QVariant result;
|
||||||
|
|
||||||
|
auto it = _models.find(nodeId);
|
||||||
|
if (it == _models.end())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
auto &model = *it;
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case NodeRole::Type:
|
||||||
|
result = model->name();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::Position:
|
||||||
|
result = _nodeGeometryData[nodeId].pos;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::Size:
|
||||||
|
result = _nodeGeometryData[nodeId].size;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::CaptionVisible:
|
||||||
|
result = model->captionVisible();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::Caption:
|
||||||
|
result = model->caption();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::Style: {
|
||||||
|
auto style = StyleCollection::nodeStyle();
|
||||||
|
result = style.toJson().toVariantMap();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NodeRole::InternalData: {
|
||||||
|
QJsonObject nodeJson;
|
||||||
|
|
||||||
|
nodeJson["internal-data"] = _models[nodeId]->save();
|
||||||
|
|
||||||
|
result = nodeJson.toVariantMap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NodeRole::InPortCount:
|
||||||
|
result = model->nPorts(PortType::In);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::OutPortCount:
|
||||||
|
result = model->nPorts(PortType::Out);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::Widget: {
|
||||||
|
auto w = model->embeddedWidget();
|
||||||
|
result = QVariant::fromValue(w);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeFlags FixedPortsModel::nodeFlags(NodeId nodeId) const
|
||||||
|
{
|
||||||
|
auto it = _models.find(nodeId);
|
||||||
|
|
||||||
|
if (it != _models.end() && it->data()->resizable())
|
||||||
|
return NodeFlag::Resizable;
|
||||||
|
|
||||||
|
return NodeFlag::NoFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FixedPortsModel::setNodeData(NodeId nodeId, NodeRole role, QVariant value)
|
||||||
|
{
|
||||||
|
Q_UNUSED(nodeId);
|
||||||
|
Q_UNUSED(role);
|
||||||
|
Q_UNUSED(value);
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case NodeRole::Type:
|
||||||
|
break;
|
||||||
|
case NodeRole::Position: {
|
||||||
|
_nodeGeometryData[nodeId].pos = value.value<QPointF>();
|
||||||
|
|
||||||
|
Q_EMIT nodePositionUpdated(nodeId);
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NodeRole::Size: {
|
||||||
|
_nodeGeometryData[nodeId].size = value.value<QSize>();
|
||||||
|
result = true;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NodeRole::CaptionVisible:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::Caption:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::Style:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::InternalData:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::InPortCount:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::OutPortCount:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NodeRole::Widget:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant FixedPortsModel::portData(NodeId nodeId,
|
||||||
|
PortType portType,
|
||||||
|
PortIndex portIndex,
|
||||||
|
PortRole role) const
|
||||||
|
{
|
||||||
|
QVariant result;
|
||||||
|
|
||||||
|
auto it = _models.find(nodeId);
|
||||||
|
if (it == _models.end())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
auto &model = *it;
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case PortRole::Data:
|
||||||
|
if (portType == PortType::Out)
|
||||||
|
result = QVariant::fromValue(model->outData(portIndex));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PortRole::DataType:
|
||||||
|
result = QVariant::fromValue(model->dataType(portType, portIndex));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PortRole::ConnectionPolicyRole:
|
||||||
|
result = QVariant::fromValue(model->portConnectionPolicy(portType, portIndex));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PortRole::CaptionVisible:
|
||||||
|
result = model->portCaptionVisible(portType, portIndex);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PortRole::Caption:
|
||||||
|
result = model->portCaption(portType, portIndex);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FixedPortsModel::setPortData(
|
||||||
|
NodeId nodeId, PortType portType, PortIndex portIndex, QVariant const &value, PortRole role)
|
||||||
|
{
|
||||||
|
Q_UNUSED(nodeId);
|
||||||
|
|
||||||
|
QVariant result;
|
||||||
|
|
||||||
|
auto it = _models.find(nodeId);
|
||||||
|
if (it == _models.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto &model = *it;
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case PortRole::Data:
|
||||||
|
if (portType == PortType::In) {
|
||||||
|
model->setInData(value.value<std::shared_ptr<NodeData>>(), portIndex);
|
||||||
|
|
||||||
|
// Triggers repainting on the scene.
|
||||||
|
Q_EMIT inPortDataWasSet(nodeId, portType, portIndex);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FixedPortsModel::deleteConnection(ConnectionId const connectionId)
|
||||||
|
{
|
||||||
|
bool disconnected = false;
|
||||||
|
|
||||||
|
auto it = _connectivity.find(connectionId);
|
||||||
|
|
||||||
|
if (it != _connectivity.end()) {
|
||||||
|
disconnected = true;
|
||||||
|
|
||||||
|
_connectivity.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disconnected) {
|
||||||
|
sendConnectionDeletion(connectionId);
|
||||||
|
|
||||||
|
propagateEmptyDataTo(getNodeId(PortType::In, connectionId),
|
||||||
|
getPortIndex(PortType::In, connectionId));
|
||||||
|
}
|
||||||
|
|
||||||
|
return disconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FixedPortsModel::deleteNode(NodeId const nodeId)
|
||||||
|
{
|
||||||
|
// Delete connections to this node first.
|
||||||
|
auto connectionIds = allConnectionIds(nodeId);
|
||||||
|
for (auto &cId : connectionIds) {
|
||||||
|
deleteConnection(cId);
|
||||||
|
}
|
||||||
|
|
||||||
|
_nodeGeometryData.take(nodeId);
|
||||||
|
_models.take(nodeId);
|
||||||
|
|
||||||
|
Q_EMIT nodeDeleted(nodeId);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject FixedPortsModel::saveNode(NodeId const nodeId) const
|
||||||
|
{
|
||||||
|
QJsonObject nodeJson;
|
||||||
|
|
||||||
|
nodeJson["id"] = static_cast<qint64>(nodeId);
|
||||||
|
|
||||||
|
nodeJson["internal-data"] = _models[nodeId]->save();
|
||||||
|
|
||||||
|
{
|
||||||
|
QPointF const pos = nodeData(nodeId, NodeRole::Position).value<QPointF>();
|
||||||
|
|
||||||
|
QJsonObject posJson;
|
||||||
|
posJson["x"] = pos.x();
|
||||||
|
posJson["y"] = pos.y();
|
||||||
|
nodeJson["position"] = posJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject FixedPortsModel::save() const
|
||||||
|
{
|
||||||
|
QJsonObject sceneJson;
|
||||||
|
|
||||||
|
QJsonArray nodesJsonArray;
|
||||||
|
for (auto const nodeId : allNodeIds()) {
|
||||||
|
nodesJsonArray.append(saveNode(nodeId));
|
||||||
|
}
|
||||||
|
sceneJson["nodes"] = nodesJsonArray;
|
||||||
|
|
||||||
|
QJsonArray connJsonArray;
|
||||||
|
for (auto const &cid : _connectivity) {
|
||||||
|
connJsonArray.append(toJson(cid));
|
||||||
|
}
|
||||||
|
sceneJson["connections"] = connJsonArray;
|
||||||
|
|
||||||
|
return sceneJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedPortsModel::loadNode(QJsonObject const &nodeJson)
|
||||||
|
{
|
||||||
|
// Possibility of the id clash when reading it from json and not generating a
|
||||||
|
// new value.
|
||||||
|
// 1. When restoring a scene from a file.
|
||||||
|
// Conflict is not possible because the scene must be cleared by the time of
|
||||||
|
// loading.
|
||||||
|
// 2. When undoing the deletion command. Conflict is not possible
|
||||||
|
// because all the new ids were created past the removed nodes.
|
||||||
|
NodeId restoredNodeId = nodeJson["id"].toInt();
|
||||||
|
|
||||||
|
_nextNodeId = std::max(_nextNodeId, restoredNodeId + 1);
|
||||||
|
|
||||||
|
QJsonObject const internalDataJson = nodeJson["internal-data"].toObject();
|
||||||
|
|
||||||
|
QString delegateModelName = internalDataJson["model-name"].toString();
|
||||||
|
|
||||||
|
QSharedPointer<NodeDelegateModel> model = _registry->create(delegateModelName);
|
||||||
|
|
||||||
|
if (model) {
|
||||||
|
connect(model.get(),
|
||||||
|
&NodeDelegateModel::dataUpdated,
|
||||||
|
[restoredNodeId, this](PortIndex const portIndex) {
|
||||||
|
onOutPortDataUpdated(restoredNodeId, portIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
_models[restoredNodeId] = std::move(model);
|
||||||
|
|
||||||
|
Q_EMIT nodeCreated(restoredNodeId);
|
||||||
|
|
||||||
|
QJsonObject posJson = nodeJson["position"].toObject();
|
||||||
|
QPointF const pos(posJson["x"].toDouble(), posJson["y"].toDouble());
|
||||||
|
|
||||||
|
setNodeData(restoredNodeId, NodeRole::Position, pos);
|
||||||
|
|
||||||
|
_models[restoredNodeId]->load(internalDataJson);
|
||||||
|
} else {
|
||||||
|
throw std::logic_error(std::string("No registered model with name ")
|
||||||
|
+ delegateModelName.toLocal8Bit().data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedPortsModel::load(QJsonObject const &jsonDocument)
|
||||||
|
{
|
||||||
|
QJsonArray nodesJsonArray = jsonDocument["nodes"].toArray();
|
||||||
|
|
||||||
|
for (QJsonValueRef nodeJson : nodesJsonArray) {
|
||||||
|
loadNode(nodeJson.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonArray connectionJsonArray = jsonDocument["connections"].toArray();
|
||||||
|
|
||||||
|
for (QJsonValueRef connection : connectionJsonArray) {
|
||||||
|
QJsonObject connJson = connection.toObject();
|
||||||
|
|
||||||
|
ConnectionId connId = fromJson(connJson);
|
||||||
|
|
||||||
|
// Restore the connection
|
||||||
|
addConnection(connId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedPortsModel::onOutPortDataUpdated(NodeId const nodeId, PortIndex const portIndex)
|
||||||
|
{
|
||||||
|
QSet<ConnectionId> const &connected = connections(nodeId,
|
||||||
|
PortType::Out,
|
||||||
|
portIndex);
|
||||||
|
|
||||||
|
QVariant const portDataToPropagate = portData(nodeId, PortType::Out, portIndex, PortRole::Data);
|
||||||
|
|
||||||
|
for (auto const &cn : connected) {
|
||||||
|
setPortData(cn.inNodeId, PortType::In, cn.inPortIndex, portDataToPropagate, PortRole::Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedPortsModel::propagateEmptyDataTo(NodeId const nodeId, PortIndex const portIndex)
|
||||||
|
{
|
||||||
|
QVariant emptyData{};
|
||||||
|
|
||||||
|
setPortData(nodeId, PortType::In, portIndex, emptyData, PortRole::Data);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "graphicsItem/electricConnectLineItem.h"
|
||||||
|
#include <QGraphicsScene>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
|
||||||
|
ElectricConnectLineItem::ElectricConnectLineItem(QGraphicsItem *parent)
|
||||||
|
: GraphicsBaseItem(parent)
|
||||||
|
{
|
||||||
|
m_pen = QPen(Qt::black);
|
||||||
|
m_brush = QBrush(Qt::NoBrush);
|
||||||
|
setHandleVisible(false);
|
||||||
|
setFunctionHandleIfShow(false);
|
||||||
|
setFunctionHandleEnaable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElectricConnectLineItem::~ElectricConnectLineItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainterPath ElectricConnectLineItem::shape()
|
||||||
|
{
|
||||||
|
QPainterPath path;
|
||||||
|
path.addPath(m_points);
|
||||||
|
path.closeSubpath(); //将路径闭合
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElectricConnectLineItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
|
||||||
|
{
|
||||||
|
painter->setPen(m_pen);
|
||||||
|
painter->setBrush(m_brush);
|
||||||
|
|
||||||
|
painter->drawPath(m_points);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElectricConnectLineItem::calculatePath()
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
m_points.clear();
|
||||||
|
|
||||||
|
m_points.moveTo(m_pStart);
|
||||||
|
m_points.lineTo(m_pEnd.x(),m_pStart.y());
|
||||||
|
m_points.lineTo(m_pEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElectricConnectLineItem::updateConnection(int callerId,QPointF pos)
|
||||||
|
{
|
||||||
|
qDebug()<<pos;
|
||||||
|
if(callerId == m_connectState.nSrcNodeId)
|
||||||
|
setStartPoint(pos);
|
||||||
|
else if(callerId == m_connectState.nDestNodeId)
|
||||||
|
setEndPoint(pos);
|
||||||
|
else
|
||||||
|
qDebug()<<"ConnectLine update err";
|
||||||
|
calculatePath();
|
||||||
|
}
|
||||||
|
|
@ -59,11 +59,16 @@ void ElectricSvgItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* o
|
||||||
|
|
||||||
painter->setPen(m_pen);
|
painter->setPen(m_pen);
|
||||||
painter->setBrush(m_brush);
|
painter->setBrush(m_brush);
|
||||||
if(m_state == S_lineOut)
|
if(m_state == S_prepareConnect)
|
||||||
{
|
{
|
||||||
painter->setPen(QPen(QColor(255,51,153,180)));
|
painter->setPen(QPen(QColor(255,51,153,180)));
|
||||||
painter->drawLine(m_beginConnectPoint,m_endConnectPoint);
|
painter->drawLine(m_beginConnectPoint,m_endConnectPoint);
|
||||||
}
|
}
|
||||||
|
if(m_touched)
|
||||||
|
{
|
||||||
|
painter->setPen(QPen(QColor(238,58,140,220)));
|
||||||
|
painter->drawRect(m_boundingRect);
|
||||||
|
}
|
||||||
|
|
||||||
if (option->state & QStyle::State_Selected) //是选中状态,绘制选中框
|
if (option->state & QStyle::State_Selected) //是选中状态,绘制选中框
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,11 @@ ElectricSvgItemBus::ElectricSvgItemBus(const QRect &rect, QGraphicsItem *parent)
|
||||||
: ElectricSvgItem(rect,parent)
|
: ElectricSvgItem(rect,parent)
|
||||||
{
|
{
|
||||||
loadSvg(":/images/element/svg_bus.svg");
|
loadSvg(":/images/element/svg_bus.svg");
|
||||||
|
setHandleVisible(false);
|
||||||
|
setFunctionHandleIfShow(false);
|
||||||
|
setFunctionHandleEnaable(false);
|
||||||
|
setHandleEnaable(H_right,true);
|
||||||
|
setHandleEnaable(H_left,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElectricSvgItemBus::~ElectricSvgItemBus()
|
ElectricSvgItemBus::~ElectricSvgItemBus()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include "graphicsItem/electricSvgItemRect.h"
|
#include "graphicsItem/electricSvgItemRect.h"
|
||||||
#include "graphicsItem/itemControlHandle.h"
|
#include "graphicsItem/itemPort.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QStyleOption>
|
#include <QStyleOption>
|
||||||
|
|
@ -8,19 +8,27 @@ ElectricSvgItemRect::ElectricSvgItemRect(const QRect &rect, QGraphicsItem *paren
|
||||||
: ElectricSvgItem(rect,parent)
|
: ElectricSvgItem(rect,parent)
|
||||||
{
|
{
|
||||||
loadSvg(":/images/element/svg_rect.svg");
|
loadSvg(":/images/element/svg_rect.svg");
|
||||||
|
setHandleVisible(false);
|
||||||
|
setFunctionHandleIfShow(false);
|
||||||
|
setFunctionHandleEnaable(false);
|
||||||
|
|
||||||
//入线口
|
//入线口
|
||||||
ItemControlHandle* pHandle1 = new ItemControlHandle(this);
|
ItemPort* pHandle1 = new ItemPort(this);
|
||||||
pHandle1->setType(T_lineIn);
|
pHandle1->setType(T_lineIn);
|
||||||
pHandle1->setTag(H_connect);
|
pHandle1->setTag(H_connect);
|
||||||
|
pHandle1->setPortPos(P_top);
|
||||||
m_vecHanle.insert(H_connect,pHandle1);
|
m_vecHanle.insert(H_connect,pHandle1);
|
||||||
//出线口
|
//出线口
|
||||||
ItemControlHandle* pHandle2 = new ItemControlHandle(this);
|
ItemPort* pHandle2 = new ItemPort(this);
|
||||||
pHandle2->setType(T_lineOut);
|
pHandle2->setType(T_lineOut);
|
||||||
pHandle2->setTag(H_connect+1);
|
pHandle2->setTag(H_connect+1);
|
||||||
|
pHandle2->setPortPos(P_down);
|
||||||
m_vecHanle.insert(H_connect+1,pHandle2);
|
m_vecHanle.insert(H_connect+1,pHandle2);
|
||||||
|
|
||||||
m_dRatioX = 0.5;
|
m_dRatioX = 0.5;
|
||||||
|
|
||||||
|
m_mapPort.insert(QString::number(_portId++),pHandle1);
|
||||||
|
m_mapPort.insert(QString::number(_portId++),pHandle2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElectricSvgItemRect::~ElectricSvgItemRect()
|
ElectricSvgItemRect::~ElectricSvgItemRect()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include "graphicsItem/electricSvgItemTriangle.h"
|
#include "graphicsItem/electricSvgItemTriangle.h"
|
||||||
#include "graphicsItem/itemControlHandle.h"
|
#include "graphicsItem/itemPort.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QStyleOption>
|
#include <QStyleOption>
|
||||||
|
|
@ -8,25 +8,35 @@ ElectricSvgItemTriangle::ElectricSvgItemTriangle(const QRect &rect, QGraphicsIte
|
||||||
: ElectricSvgItem(rect,parent)
|
: ElectricSvgItem(rect,parent)
|
||||||
{
|
{
|
||||||
loadSvg(":/images/element/svg_triangle.svg");
|
loadSvg(":/images/element/svg_triangle.svg");
|
||||||
|
setHandleVisible(false);
|
||||||
|
setFunctionHandleIfShow(false);
|
||||||
|
setFunctionHandleEnaable(false);
|
||||||
|
|
||||||
//入线口
|
//入线口
|
||||||
ItemControlHandle* pHandle1 = new ItemControlHandle(this);
|
ItemPort* pHandle1 = new ItemPort(this);
|
||||||
pHandle1->setType(T_lineIn);
|
pHandle1->setType(T_lineOut);
|
||||||
pHandle1->setTag(H_connect);
|
pHandle1->setTag(H_connect);
|
||||||
|
pHandle1->setPortPos(P_top);
|
||||||
m_vecHanle.insert(H_connect,pHandle1);
|
m_vecHanle.insert(H_connect,pHandle1);
|
||||||
//出线口
|
//出线口
|
||||||
ItemControlHandle* pHandle2 = new ItemControlHandle(this);
|
ItemPort* pHandle2 = new ItemPort(this);
|
||||||
pHandle2->setType(T_lineOut);
|
pHandle2->setType(T_lineIn);
|
||||||
pHandle2->setTag(H_connect+1);
|
pHandle2->setTag(H_connect+1);
|
||||||
|
pHandle2->setPortPos(P_down);
|
||||||
m_vecHanle.insert(H_connect+1,pHandle2);
|
m_vecHanle.insert(H_connect+1,pHandle2);
|
||||||
|
|
||||||
ItemControlHandle* pHandle3 = new ItemControlHandle(this);
|
ItemPort* pHandle3 = new ItemPort(this);
|
||||||
pHandle3->setType(T_lineOut);
|
pHandle3->setType(T_lineIn);
|
||||||
pHandle3->setTag(H_connect+2);
|
pHandle3->setTag(H_connect+2);
|
||||||
|
pHandle3->setPortPos(P_down);
|
||||||
m_vecHanle.insert(H_connect+2,pHandle3);
|
m_vecHanle.insert(H_connect+2,pHandle3);
|
||||||
|
|
||||||
m_dTopRatioX = 0.5;
|
m_dTopRatioX = 0.5;
|
||||||
m_dBottomRatioX = 0.333;
|
m_dBottomRatioX = 0.333;
|
||||||
|
|
||||||
|
m_mapPort.insert(QString::number(_portId++),pHandle1);
|
||||||
|
m_mapPort.insert(QString::number(_portId++),pHandle2);
|
||||||
|
m_mapPort.insert(QString::number(_portId++),pHandle3);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElectricSvgItemTriangle::~ElectricSvgItemTriangle()
|
ElectricSvgItemTriangle::~ElectricSvgItemTriangle()
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "graphicsItem/graphicsBaseItem.h"
|
#include "graphicsItem/graphicsBaseItem.h"
|
||||||
|
#include "graphicsItem/itemPort.h"
|
||||||
#include <QGraphicsScene>
|
#include <QGraphicsScene>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -6,6 +7,8 @@ GraphicsBaseItem::GraphicsBaseItem(QGraphicsItem *parent)
|
||||||
: AbstractShapeType<QGraphicsItem>(parent)
|
: AbstractShapeType<QGraphicsItem>(parent)
|
||||||
{
|
{
|
||||||
m_type = T_item;
|
m_type = T_item;
|
||||||
|
_portId = 1;
|
||||||
|
_lastPort = -1;
|
||||||
//初始化缩放操作用的handle
|
//初始化缩放操作用的handle
|
||||||
//m_vecHanle.reserve(H_left);
|
//m_vecHanle.reserve(H_left);
|
||||||
for(int i = H_leftTop; i <= H_left; i++)
|
for(int i = H_leftTop; i <= H_left; i++)
|
||||||
|
|
@ -100,6 +103,7 @@ QVariant GraphicsBaseItem::itemChange(QGraphicsItem::GraphicsItemChange change,
|
||||||
QGraphicsItemGroup *group = dynamic_cast<QGraphicsItemGroup *>(parentItem());
|
QGraphicsItemGroup *group = dynamic_cast<QGraphicsItemGroup *>(parentItem());
|
||||||
if(!group)
|
if(!group)
|
||||||
setHandleVisible(value.toBool());
|
setHandleVisible(value.toBool());
|
||||||
|
//setFunctionHandleVisible(false);
|
||||||
else //在某一组群中,由组群展示是否选中,自身不做展示
|
else //在某一组群中,由组群展示是否选中,自身不做展示
|
||||||
{
|
{
|
||||||
setSelected(false);
|
setSelected(false);
|
||||||
|
|
@ -114,3 +118,48 @@ void GraphicsBaseItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
|
||||||
Q_UNUSED(event);
|
Q_UNUSED(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GraphicsBaseItem::addPort(PortState typ,QPointF vec)
|
||||||
|
{
|
||||||
|
int ntagId = -1;
|
||||||
|
for(ntagId = H_connect;ntagId < 999;++ntagId) //添加到未占用位置
|
||||||
|
{
|
||||||
|
if(!m_vecHanle.contains(ntagId))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(typ == p_movable)
|
||||||
|
{
|
||||||
|
ItemPort* pPort = new ItemPort(this);
|
||||||
|
pPort->setType(T_lineInOut);
|
||||||
|
pPort->setTag(ntagId);
|
||||||
|
m_vecHanle.insert(ntagId,pPort);
|
||||||
|
pPort->setPos(vec);
|
||||||
|
|
||||||
|
m_mapPort.insert(QString::number(_portId++),pPort);
|
||||||
|
}
|
||||||
|
return ntagId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicsBaseItem::addPort(PortState typ,int ntagId,QPointF vec)
|
||||||
|
{
|
||||||
|
if(typ == p_movable)
|
||||||
|
{
|
||||||
|
ItemPort* pPort = new ItemPort(this);
|
||||||
|
pPort->setType(T_lineInOut);
|
||||||
|
pPort->setTag(ntagId);
|
||||||
|
m_vecHanle.insert(ntagId,pPort);
|
||||||
|
pPort->setPos(vec);
|
||||||
|
|
||||||
|
m_mapPort.insert(QString::number(_portId++),pPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemPort* GraphicsBaseItem::getPortPtr(int n) const
|
||||||
|
{
|
||||||
|
for(auto iter:m_mapPort)
|
||||||
|
{
|
||||||
|
int tag = iter->getTag();
|
||||||
|
if(tag == n)
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
#include "graphicsItem/itemControlHandle.h"
|
#include "graphicsItem/itemControlHandle.h"
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
#define HNDLE_SIZE 8
|
|
||||||
|
|
||||||
ItemControlHandle::ItemControlHandle(QGraphicsItem *parent)
|
ItemControlHandle::ItemControlHandle(QGraphicsItem *parent)
|
||||||
: QGraphicsRectItem(-HNDLE_SIZE / 2,
|
: QGraphicsRectItem(-HNDLE_SIZE / 2,
|
||||||
-HNDLE_SIZE / 2,
|
-HNDLE_SIZE / 2,
|
||||||
|
|
@ -11,6 +9,8 @@ ItemControlHandle::ItemControlHandle(QGraphicsItem *parent)
|
||||||
{
|
{
|
||||||
m_type = T_resize;
|
m_type = T_resize;
|
||||||
m_tag = H_none;
|
m_tag = H_none;
|
||||||
|
m_enable = true;
|
||||||
|
m_ifShow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemControlHandle::~ItemControlHandle()
|
ItemControlHandle::~ItemControlHandle()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
#include <QPainter>
|
||||||
|
#include "graphicsItem/itemPort.h"
|
||||||
|
|
||||||
|
ItemPort::ItemPort(QGraphicsItem *parent)
|
||||||
|
: ItemControlHandle(parent)
|
||||||
|
{
|
||||||
|
_pos = P_top;
|
||||||
|
_ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemPort::~ItemPort()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemPort::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
|
||||||
|
{
|
||||||
|
Q_UNUSED(option)
|
||||||
|
Q_UNUSED(widget)
|
||||||
|
|
||||||
|
painter->setPen(Qt::SolidLine);
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
|
||||||
|
QPolygonF Triangle;
|
||||||
|
QRectF rec = rect();
|
||||||
|
qreal left = rec.left();
|
||||||
|
qreal right = rec.right();
|
||||||
|
qreal width = rec.width();
|
||||||
|
qreal height = rec.height();
|
||||||
|
qreal bottom = rec.bottom();
|
||||||
|
painter->setBrush(Qt::black);
|
||||||
|
if((_pos == P_top && m_type == T_lineIn) || (_pos == P_down && m_type == T_lineOut) ) //从上入或者从下出都是向下
|
||||||
|
{
|
||||||
|
Triangle.append(QPointF(left,0));
|
||||||
|
Triangle.append(QPointF(right,0));
|
||||||
|
Triangle.append(QPointF(left+width*0.5,bottom));
|
||||||
|
painter->drawPolygon(Triangle);
|
||||||
|
}
|
||||||
|
else if((_pos == P_top && m_type == T_lineOut) || (_pos == P_down && m_type == T_lineIn) ) //从上出或者从下入都是向上
|
||||||
|
{
|
||||||
|
Triangle.append(QPointF(left,bottom));
|
||||||
|
Triangle.append(QPointF(right,bottom));
|
||||||
|
Triangle.append(QPointF(left+width*0.5,0));
|
||||||
|
painter->drawPolygon(Triangle);
|
||||||
|
}
|
||||||
|
else if((_pos == P_left && m_type == T_lineIn) || (_pos == P_right && m_type == T_lineOut) ) //从左入或者从右出都是向右
|
||||||
|
{
|
||||||
|
Triangle.append(QPointF(0,0));
|
||||||
|
Triangle.append(QPointF(0,bottom));
|
||||||
|
Triangle.append(QPointF(right,height*0.5));
|
||||||
|
painter->drawPolygon(Triangle);
|
||||||
|
}
|
||||||
|
else if((_pos == P_left && m_type == T_lineOut) || (_pos == P_right && m_type == T_lineIn) ) //从左出或者从右入都是向左
|
||||||
|
{
|
||||||
|
Triangle.append(QPointF(right,0));
|
||||||
|
Triangle.append(QPointF(right,bottom));
|
||||||
|
Triangle.append(QPointF(0,height*0.5));
|
||||||
|
painter->drawPolygon(Triangle);
|
||||||
|
}
|
||||||
|
else if(m_type == T_lineInOut)
|
||||||
|
{
|
||||||
|
painter->drawEllipse(rect().center(), HNDLE_SIZE / 4, HNDLE_SIZE / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if(m_type==T_lineIn)
|
||||||
|
{
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(Qt::green);
|
||||||
|
painter->drawEllipse(rect().center(), HNDLE_SIZE / 2, HNDLE_SIZE / 2);
|
||||||
|
}
|
||||||
|
else if(m_type==T_lineOut)
|
||||||
|
{
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(Qt::red);
|
||||||
|
painter->drawEllipse(rect().center(), HNDLE_SIZE / 2, HNDLE_SIZE / 2);
|
||||||
|
}*/
|
||||||
|
//ItemControlHandle::paint(painter,option,widget);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <QLabel>
|
||||||
|
#include "statusBar.h"
|
||||||
|
|
||||||
|
StatusBar::StatusBar(QWidget *parent)
|
||||||
|
: QStatusBar(parent)
|
||||||
|
,m_pScaleLevel(nullptr)
|
||||||
|
{
|
||||||
|
m_pScaleLevel = new QLabel("当前级数:10",this);
|
||||||
|
m_pScaleLevel->setMinimumWidth(250);
|
||||||
|
addWidget(m_pScaleLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusBar::~StatusBar()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusBar::onScaleLevelChanged(double f)
|
||||||
|
{
|
||||||
|
m_pScaleLevel->setText(QString::fromWCharArray(L"当前级数:")+QString::number(f));
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,8 @@ QPointF BaseSelector::ms_ptMouseDown(0.0,0.0);
|
||||||
QPointF BaseSelector::ms_ptMouseLast(0.0,0.0);
|
QPointF BaseSelector::ms_ptMouseLast(0.0,0.0);
|
||||||
double BaseSelector::ms_dAngleMouseDownToItem = 0.0;
|
double BaseSelector::ms_dAngleMouseDownToItem = 0.0;
|
||||||
int BaseSelector::ms_nDragHandle = 0;
|
int BaseSelector::ms_nDragHandle = 0;
|
||||||
|
uint BaseSelector::_Id = 0;
|
||||||
|
ItemMap BaseSelector::m_graphicsItem;
|
||||||
|
|
||||||
BaseSelector::BaseSelector(QObject *parent)
|
BaseSelector::BaseSelector(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
|
@ -70,7 +72,8 @@ void BaseSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScen
|
||||||
else if(ms_nDragHandle >= H_connect ) //连接控制点
|
else if(ms_nDragHandle >= H_connect ) //连接控制点
|
||||||
{
|
{
|
||||||
m_opMode = OM_connect;
|
m_opMode = OM_connect;
|
||||||
setCursor(scene, Qt::ClosedHandCursor);
|
//setCursor(scene, Qt::ClosedHandCursor);
|
||||||
|
setCursor(scene, Qt::ArrowCursor);
|
||||||
emit setWorkingSelector(ST_connecting);
|
emit setWorkingSelector(ST_connecting);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,18 @@
|
||||||
#include "util/connectingSelector.h"
|
#include "util/connectingSelector.h"
|
||||||
|
#include "graphicsItem/itemControlHandle.h"
|
||||||
|
#include "graphicsItem/itemPort.h"
|
||||||
|
#include "graphicsItem/electricConnectLineItem.h"
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
#include <graphicsItem/graphicsBaseItem.h>
|
#include <graphicsItem/graphicsBaseItem.h>
|
||||||
|
|
||||||
ConnectingSelector::ConnectingSelector(QObject *parent)
|
ConnectingSelector::ConnectingSelector(QObject *parent)
|
||||||
: BaseSelector(parent),m_pConnectingItem(nullptr)
|
: BaseSelector(parent)
|
||||||
|
,m_pConnectingItem(nullptr)
|
||||||
|
,m_pTouchedItem(nullptr)
|
||||||
{
|
{
|
||||||
m_type = ST_connecting;
|
m_type = ST_connecting;
|
||||||
|
m_bReadyConnect = false;
|
||||||
}
|
}
|
||||||
ConnectingSelector::~ConnectingSelector()
|
ConnectingSelector::~ConnectingSelector()
|
||||||
{
|
{
|
||||||
|
|
@ -19,6 +25,112 @@ void ConnectingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Design
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConnectingSelector::targetCouldConnect(GraphicsBaseItem* p,QPointF pos)
|
||||||
|
{
|
||||||
|
GraphicsItemType iType = p->getItemType();
|
||||||
|
if(iType == GIT_bus)
|
||||||
|
{
|
||||||
|
setTargetHighLight(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int nHandle = p->collidesWithHandle(pos);
|
||||||
|
if(nHandle >= H_connect ) //连接控制点
|
||||||
|
{
|
||||||
|
setTargetHighLight(false);
|
||||||
|
p->setLastPort(nHandle);
|
||||||
|
ItemPort* pt = p->getPortPtr(nHandle);
|
||||||
|
if(pt)
|
||||||
|
{
|
||||||
|
HandleType targetDir = pt->getType();
|
||||||
|
bool bCon = pt->connected();
|
||||||
|
|
||||||
|
if(m_pConnectingItem)
|
||||||
|
{
|
||||||
|
ItemPort* ptSrc = m_pConnectingItem->getPortPtr(ms_nDragHandle);
|
||||||
|
HandleType sourceDir = ptSrc->getType();
|
||||||
|
|
||||||
|
if((targetDir != sourceDir) && !bCon)
|
||||||
|
{
|
||||||
|
setTargetHighLight(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //超出了触碰范围
|
||||||
|
{
|
||||||
|
setTargetHighLight(false);
|
||||||
|
p->setLastPort(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectingSelector::setTargetHighLight(bool val)
|
||||||
|
{
|
||||||
|
if(m_pTouchedItem)
|
||||||
|
{
|
||||||
|
GraphicsItemType iType = m_pTouchedItem->getItemType();
|
||||||
|
if(iType == GIT_bus)
|
||||||
|
{
|
||||||
|
m_pTouchedItem->setTouched(val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int n = m_pTouchedItem->getLastPort();
|
||||||
|
if(n != -1)
|
||||||
|
m_pTouchedItem->setHandleVisible(n,val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectingSelector::createConnectLline(GraphicsBaseItem* connectingItem,GraphicsBaseItem* touchedItem,DesignerScene* scene)
|
||||||
|
{
|
||||||
|
ElectricConnectLineItem* pItem = new ElectricConnectLineItem();
|
||||||
|
pItem->setItemId(++_Id);
|
||||||
|
pItem->setItemType(GIT_connectLine);
|
||||||
|
scene->addItem(pItem);
|
||||||
|
|
||||||
|
ItemPort* ptSrc = connectingItem->getPortPtr(ms_nDragHandle);
|
||||||
|
int srcId = connectingItem->itemId();
|
||||||
|
int srcPort = ptSrc->getTag();
|
||||||
|
HandleType srcType = ptSrc->getType();
|
||||||
|
pItem->setStartPoint(ptSrc->scenePos());
|
||||||
|
ptSrc->setConnect(pItem);
|
||||||
|
|
||||||
|
ItemPort* ptDest = nullptr;
|
||||||
|
if(touchedItem->getItemType() == GIT_bus) //母线动态创建port
|
||||||
|
{
|
||||||
|
int nId = touchedItem->addPort(p_movable,touchedItem->mapFromScene(ms_ptMouseLast));
|
||||||
|
if(nId != -1)
|
||||||
|
{
|
||||||
|
ptDest = touchedItem->getPortPtr(nId);
|
||||||
|
pItem->setEndPoint(ptDest->scenePos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int nLastPort = touchedItem->getLastPort();
|
||||||
|
ptDest = touchedItem->getPortPtr(nLastPort);
|
||||||
|
pItem->setEndPoint(ptDest->scenePos());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ptDest != nullptr)
|
||||||
|
{
|
||||||
|
int destId = touchedItem->itemId();
|
||||||
|
int destPort = ptDest->getTag();
|
||||||
|
HandleType destType = ptDest->getType();
|
||||||
|
|
||||||
|
pItem->calculatePath();
|
||||||
|
pItem->setConnection(Connection(srcId,srcPort,srcType,destId,destPort,destType));
|
||||||
|
ptDest->setConnect(pItem);
|
||||||
|
|
||||||
|
m_graphicsItem[sceneName()].insert(QString::number(pItem->itemId()),pItem); //插入连接线到总表
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConnectingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
|
void ConnectingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
|
||||||
{
|
{
|
||||||
ms_ptMouseLast = event->scenePos();
|
ms_ptMouseLast = event->scenePos();
|
||||||
|
|
@ -32,7 +144,7 @@ void ConnectingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, Designe
|
||||||
{
|
{
|
||||||
if(ms_nDragHandle != H_none)
|
if(ms_nDragHandle != H_none)
|
||||||
{
|
{
|
||||||
item->setState(S_lineOut);
|
item->setState(S_prepareConnect);
|
||||||
QPointF start = item->mapFromScene(ms_ptMouseDown);
|
QPointF start = item->mapFromScene(ms_ptMouseDown);
|
||||||
QPointF end = item->mapFromScene(ms_ptMouseLast);
|
QPointF end = item->mapFromScene(ms_ptMouseLast);
|
||||||
item->setBeginConnectPos(start);
|
item->setBeginConnectPos(start);
|
||||||
|
|
@ -48,6 +160,33 @@ void ConnectingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, Designe
|
||||||
{
|
{
|
||||||
QPointF end = m_pConnectingItem->mapFromScene(ms_ptMouseLast);
|
QPointF end = m_pConnectingItem->mapFromScene(ms_ptMouseLast);
|
||||||
m_pConnectingItem->setEndConnectPos(end);
|
m_pConnectingItem->setEndConnectPos(end);
|
||||||
|
|
||||||
|
QList<QGraphicsItem *> items = scene->items(ms_ptMouseLast);
|
||||||
|
if (items.count() == 1)
|
||||||
|
{
|
||||||
|
GraphicsBaseItem* item = dynamic_cast<GraphicsBaseItem*>(items.first());
|
||||||
|
if(item)
|
||||||
|
{
|
||||||
|
int n1 = item->itemId();
|
||||||
|
int n2 = m_pConnectingItem->itemId();
|
||||||
|
if(n1 != n2) //判断两个对象是否相同
|
||||||
|
{
|
||||||
|
m_pTouchedItem = item;
|
||||||
|
m_bReadyConnect = targetCouldConnect(item,ms_ptMouseLast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(items.isEmpty())
|
||||||
|
{
|
||||||
|
//todo取消选中
|
||||||
|
m_bReadyConnect = false;
|
||||||
|
setTargetHighLight(false);
|
||||||
|
if(m_pTouchedItem)
|
||||||
|
{
|
||||||
|
m_pTouchedItem->setLastPort(-1);
|
||||||
|
m_pTouchedItem = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,8 +194,24 @@ void ConnectingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, Designe
|
||||||
|
|
||||||
void ConnectingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
|
void ConnectingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
|
||||||
{
|
{
|
||||||
|
if(m_bReadyConnect)
|
||||||
|
{
|
||||||
|
if(m_pConnectingItem && m_pTouchedItem)
|
||||||
|
{
|
||||||
|
createConnectLline(m_pConnectingItem,m_pTouchedItem,scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(m_pConnectingItem)
|
if(m_pConnectingItem)
|
||||||
|
{
|
||||||
m_pConnectingItem->setState(S_normal);
|
m_pConnectingItem->setState(S_normal);
|
||||||
|
}
|
||||||
|
if(m_pTouchedItem)
|
||||||
|
{
|
||||||
|
setTargetHighLight(false);
|
||||||
|
m_pTouchedItem->setLastPort(-1);
|
||||||
|
m_pTouchedItem = nullptr;
|
||||||
|
}
|
||||||
m_pConnectingItem = nullptr;
|
m_pConnectingItem = nullptr;
|
||||||
ms_nDragHandle = H_none;
|
ms_nDragHandle = H_none;
|
||||||
setCursor(scene, Qt::ArrowCursor);
|
setCursor(scene, Qt::ArrowCursor);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ CreatingSelector::CreatingSelector(QObject *parent)
|
||||||
m_creatingMethod = CM_drag;
|
m_creatingMethod = CM_drag;
|
||||||
m_pCreatingItem = nullptr;
|
m_pCreatingItem = nullptr;
|
||||||
m_scalBasePoint = QPointF();
|
m_scalBasePoint = QPointF();
|
||||||
|
_Id = 0;
|
||||||
}
|
}
|
||||||
CreatingSelector::~CreatingSelector()
|
CreatingSelector::~CreatingSelector()
|
||||||
{
|
{
|
||||||
|
|
@ -58,7 +59,8 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
|
||||||
{
|
{
|
||||||
m_creatingMethod = CM_click;
|
m_creatingMethod = CM_click;
|
||||||
m_pCreatingItem = new ElectricSvgItemBus(QRect(-100, -3, 200, 6));
|
m_pCreatingItem = new ElectricSvgItemBus(QRect(-100, -3, 200, 6));
|
||||||
|
m_pCreatingItem->setItemId(++_Id);
|
||||||
|
m_pCreatingItem->setItemType(GIT_bus);
|
||||||
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
|
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
|
||||||
emit setWorkingSelector(ST_base);
|
emit setWorkingSelector(ST_base);
|
||||||
}
|
}
|
||||||
|
|
@ -66,8 +68,9 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
|
||||||
case GIT_itemRect:
|
case GIT_itemRect:
|
||||||
{
|
{
|
||||||
m_creatingMethod = CM_click;
|
m_creatingMethod = CM_click;
|
||||||
m_pCreatingItem = new ElectricSvgItemRect(QRect(-30, -30, 60, 60));
|
m_pCreatingItem = new ElectricSvgItemRect(QRect(-20, -20, 40, 40));
|
||||||
|
m_pCreatingItem->setItemId(++_Id);
|
||||||
|
m_pCreatingItem->setItemType(GIT_itemRect);
|
||||||
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
|
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
|
||||||
emit setWorkingSelector(ST_base);
|
emit setWorkingSelector(ST_base);
|
||||||
}
|
}
|
||||||
|
|
@ -75,8 +78,9 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
|
||||||
case GIT_itemTri:
|
case GIT_itemTri:
|
||||||
{
|
{
|
||||||
m_creatingMethod = CM_click;
|
m_creatingMethod = CM_click;
|
||||||
m_pCreatingItem = new ElectricSvgItemTriangle(QRect(-30, -30, 60, 60));
|
m_pCreatingItem = new ElectricSvgItemTriangle(QRect(-20, -20, 40, 40));
|
||||||
|
m_pCreatingItem->setItemId(++_Id);
|
||||||
|
m_pCreatingItem->setItemType(GIT_itemTri);
|
||||||
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
|
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
|
||||||
emit setWorkingSelector(ST_base);
|
emit setWorkingSelector(ST_base);
|
||||||
}
|
}
|
||||||
|
|
@ -106,6 +110,7 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
|
||||||
//创建时添加了第一个点,紧接着再次添加第二点,然后从第二个点开始进行移动绘制
|
//创建时添加了第一个点,紧接着再次添加第二点,然后从第二个点开始进行移动绘制
|
||||||
m_pCreatingItem->addPoint(ms_ptMouseDown);
|
m_pCreatingItem->addPoint(ms_ptMouseDown);
|
||||||
ms_nDragHandle = m_pCreatingItem->handleCount();
|
ms_nDragHandle = m_pCreatingItem->handleCount();
|
||||||
|
m_graphicsItem[sceneName()].insert(QString::number(m_pCreatingItem->itemId()),m_pCreatingItem); //插入数据到总表
|
||||||
m_pCreatingItem = nullptr; //先舍弃多次点击创建对象241124 by
|
m_pCreatingItem = nullptr; //先舍弃多次点击创建对象241124 by
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
#include "util/movingSelector.h"
|
#include "util/movingSelector.h"
|
||||||
|
#include "graphicsItem/itemPort.h"
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
#include <graphicsItem/graphicsBaseItem.h>
|
#include <graphicsItem/graphicsBaseItem.h>
|
||||||
|
#include "graphicsItem/electricConnectLineItem.h"
|
||||||
|
|
||||||
MovingSelector::MovingSelector(QObject *parent)
|
MovingSelector::MovingSelector(QObject *parent)
|
||||||
: BaseSelector(parent)
|
: BaseSelector(parent)
|
||||||
|
|
@ -15,7 +17,10 @@ MovingSelector::~MovingSelector()
|
||||||
|
|
||||||
void MovingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
|
void MovingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
|
||||||
{
|
{
|
||||||
|
ms_ptMouseLast = event->scenePos();
|
||||||
|
|
||||||
|
QList<QGraphicsItem *> items = scene->selectedItems();
|
||||||
|
updateConnectLine(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MovingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
|
void MovingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
|
||||||
|
|
@ -40,9 +45,33 @@ void MovingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, Designer
|
||||||
if(item)
|
if(item)
|
||||||
item->removeOperationCopy();
|
item->removeOperationCopy();
|
||||||
}
|
}
|
||||||
|
updateConnectLine(items);
|
||||||
|
|
||||||
setCursor(scene, Qt::ArrowCursor);
|
setCursor(scene, Qt::ArrowCursor);
|
||||||
scene->callParentEvent(event);
|
scene->callParentEvent(event);
|
||||||
emit setWorkingSelector(ST_base);
|
emit setWorkingSelector(ST_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MovingSelector::updateConnectLine(QList<QGraphicsItem *> lst)
|
||||||
|
{
|
||||||
|
for(auto iter:lst) //更新连接线
|
||||||
|
{
|
||||||
|
auto item = dynamic_cast<GraphicsBaseItem*>(iter);
|
||||||
|
if(item)
|
||||||
|
{
|
||||||
|
if(item->getItemType() != GIT_connectLine)
|
||||||
|
{
|
||||||
|
int nId = item->itemId();
|
||||||
|
for(auto pPort:item->getPorts())
|
||||||
|
{
|
||||||
|
if(pPort->connected())
|
||||||
|
{
|
||||||
|
auto pConnect = pPort->getConnectPtr();
|
||||||
|
pConnect->updateConnection(nId,pPort->scenePos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,14 @@ void SelectorManager::setDrawGraphicsItem(GraphicsItemType item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SelectorManager::setName(const QString& str)
|
||||||
|
{
|
||||||
|
for(auto iter:m_vecSelectors)
|
||||||
|
{
|
||||||
|
iter->setSceneName(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SelectorManager::onSignal_setWorkingSelector(SelectorType s)
|
void SelectorManager::onSignal_setWorkingSelector(SelectorType s)
|
||||||
{
|
{
|
||||||
setWorkingSelector(s);
|
setWorkingSelector(s);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue