实现图元基础连线功能

This commit is contained in:
baiYue 2024-12-07 17:24:36 +08:00
parent 8ba53cf1ca
commit deec2c2d63
35 changed files with 1545 additions and 130 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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

View File

@ -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:

View File

@ -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,9 +107,12 @@ public:
{ {
QPointF pt = pHandle->mapFromScene(point); QPointF pt = pHandle->mapFromScene(point);
if(pHandle->contains(pt)) if(pHandle->contains(pt))
{
if(pHandle->enable())
return pHandle->getTag(); return pHandle->getTag();
} }
} }
}
return HandleTag::H_none; return HandleTag::H_none;
} }
@ -165,6 +170,8 @@ public:
{ {
ItemControlHandle* pHandle = m_vecHanle.value(key); ItemControlHandle* pHandle = m_vecHanle.value(key);
if(pHandle) if(pHandle)
{
if(pHandle->ifShow())
{ {
if(bVisible) if(bVisible)
pHandle->show(); pHandle->show();
@ -173,6 +180,66 @@ public:
} }
} }
} }
}
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;
}
}
}
}
virtual QPointF getSymmetricPointPos(int nHandle) //获取对称点的坐标位置,缩放的时候需要以对称点为锚点 virtual QPointF getSymmetricPointPos(int nHandle) //获取对称点的坐标位置,缩放的时候需要以对称点为锚点
{ {
QPointF pt; QPointF pt;
@ -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~10~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

View File

@ -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

View File

@ -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

20
include/statusBar.h Normal file
View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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*);

View File

@ -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);

View File

@ -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); });

View File

@ -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()

View File

@ -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()

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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) //是选中状态,绘制选中框
{ {

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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;
}

View File

@ -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()

View File

@ -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);
}

21
source/statusBar.cpp Normal file
View File

@ -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));
}

View File

@ -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

View File

@ -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);

View File

@ -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
} }
} }

View File

@ -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());
}
}
}
}
}
}

View File

@ -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);