DiagramDesigner/diagramCavas/include/graphicsItem/graphicsBaseItem.h

594 lines
20 KiB
C
Raw Normal View History

2024-12-03 20:07:25 +08:00
#ifndef GRAPHICSBASEITEM_H
#define GRAPHICSBASEITEM_H
#include "itemControlHandle.h"
2024-12-07 17:24:36 +08:00
#include "global.h"
2024-12-03 20:07:25 +08:00
#include <QObject>
#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QPen>
#include <QGraphicsSvgItem>
2025-02-06 16:36:50 +08:00
#include <QUuid>
#include <QJsonObject>
//#include "graphicsItem/itemPort.h"
2024-12-03 20:07:25 +08:00
enum ShapeType
{
T_undefined,
T_item,
T_group
};
enum ItemState
{
S_normal = 0,
2024-12-07 17:24:36 +08:00
S_prepareConnect,
2024-12-03 20:07:25 +08:00
};
2024-12-07 17:24:36 +08:00
2024-12-03 20:07:25 +08:00
//基类采用模板形式QGraphicsItem是默认值,也可以是别的类型比如QGraphicsItemGroup这样不同的基类继承可以共用一些高层的行为定义
template <typename BaseType = QGraphicsItem>
class AbstractShapeType : public BaseType
{
public:
explicit AbstractShapeType(QGraphicsItem *parent = 0)
: BaseType(parent)
{
m_type = T_undefined;
m_pen = QPen(Qt::NoPen);
m_brush = QBrush(QColor(rand() % 32 * 8, rand() % 32 * 8, rand() % 32 * 8));
m_dWidth = m_dHeight = 0;
m_pOperationCopy = nullptr;
m_dSyncRotationByParent = 0.0;
2024-12-07 17:24:36 +08:00
m_touched = false;
2024-12-03 20:07:25 +08:00
}
virtual ~AbstractShapeType()
{
/*for (size_t i = 0; i < m_vecHanle.size(); i++)
{
ItemControlHandle* pHandle = m_vecHanle[i];
if (pHandle)
{
delete pHandle;
pHandle = nullptr;
}
}*/
foreach (int key, m_vecHanle.keys())
{
ItemControlHandle* pHandle = m_vecHanle.value(key);
if (pHandle)
{
delete pHandle;
pHandle = nullptr;
}
}
}
public:
virtual ShapeType getType() {return m_type;}
QPen pen() { return m_pen; }
void setPen(const QPen &pen) { m_pen = pen; }
QColor penColor() { return m_pen.color(); }
void setPenColor(const QColor &color) { m_pen.setColor(color); }
QBrush brush() { return m_brush; }
void setBrush(const QBrush &brush) { m_brush = brush; }
QColor brushColor() { return m_brush.color(); }
void setBrushColor(const QColor &color) { m_brush.setColor(color); }
double width() { return m_dWidth; }
void setWidth(double width)
{
m_dWidth = width;
updateCoordinate();
}
double height() { return m_dHeight; }
void setHeight(double height)
{
m_dHeight = height;
updateCoordinate();
}
int collidesWithHandle(const QPointF& point)
{
/*for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
QPointF pt = (*it)->mapFromScene(point);
if((*it)->contains(pt))
return (*it)->getTag();
}*/
foreach (int key, m_vecHanle.keys())
{
ItemControlHandle* pHandle = m_vecHanle.value(key);
if (pHandle)
{
QPointF pt = pHandle->mapFromScene(point);
if(pHandle->contains(pt))
2024-12-07 17:24:36 +08:00
{
if(pHandle->enable())
return pHandle->getTag();
}
2024-12-03 20:07:25 +08:00
}
}
return HandleTag::H_none;
}
//操作副本相关
virtual void createOperationCopy() {}
virtual void removeOperationCopy() {}
virtual void moveOperationCopy(const QPointF&) {}
virtual void rotateOperationCopy(const double&) {}
virtual void resize(int,double, double, const QPointF&) {}
virtual void move(const QPointF&) {}
virtual void editShape(int, const QPointF&) {}
virtual void updateCoordinate() {}
//handle相关
virtual int handleCount() { return m_vecHanle.count(); }
virtual ItemControlHandle* getHandle(int nHandle)
{
ItemControlHandle* handle = nullptr;
/*for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
if((*it)->getTag() == nHandle)
{
handle = (*it);
return handle;
}
}*/
foreach (int key, m_vecHanle.keys())
{
ItemControlHandle* pHandle = m_vecHanle.value(key);
if (pHandle)
{
if(pHandle->getTag() == nHandle)
{
handle = pHandle;
return handle;
}
}
}
return handle;
}
virtual void setHandleVisible(bool bVisible)
{
/*for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
if(bVisible)
(*it)->show();
else
(*it)->hide();
}*/
foreach (int key, m_vecHanle.keys())
{
ItemControlHandle* pHandle = m_vecHanle.value(key);
if(pHandle)
{
2024-12-07 17:24:36 +08:00
if(pHandle->ifShow())
{
if(bVisible)
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 setHandleIfShow(int tag,bool bVisible) //是否参与显示判断
{
foreach (int key, m_vecHanle.keys())
{
ItemControlHandle* pHandle = m_vecHanle.value(key);
if(pHandle)
{
if(pHandle->getTag() == tag)
{
pHandle->setIfShow(bVisible);
break;
}
}
}
}
2024-12-07 17:24:36 +08:00
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;
}
2024-12-03 20:07:25 +08:00
}
}
}
virtual QPointF getSymmetricPointPos(int nHandle) //获取对称点的坐标位置,缩放的时候需要以对称点为锚点
{
QPointF pt;
//handle的位置相对boundingRect会有一个向外的错位因此直接采用bounddingRect的相应位置会更精准
switch (nHandle)
{
case H_leftTop:
//pt = m_vecHanle.at(H_rightBottom - 1)->pos();
pt = m_boundingRect.bottomRight();
break;
case H_top:
//pt = m_vecHanle.at(H_bottom - 1)->pos();
pt = QPointF(m_boundingRect.width() * 0.5, m_boundingRect.bottom());
break;
case H_rightTop:
//pt = m_vecHanle.at(H_leftBottom - 1)->pos();
pt = m_boundingRect.bottomLeft();
break;
case H_right:
//pt = m_vecHanle.at(H_left - 1)->pos();
pt = QPointF(m_boundingRect.left(), m_boundingRect.height() * 0.5);
break;
case H_rightBottom:
//pt = m_vecHanle.at(H_leftTop - 1)->pos();
pt = m_boundingRect.topLeft();
break;
case H_bottom:
//pt = m_vecHanle.at(H_top - 1)->pos();
pt = QPointF(m_boundingRect.width() * 0.5, m_boundingRect.top());
break;
case H_leftBottom:
//pt = m_vecHanle.at(H_rightTop - 1)->pos();
pt = m_boundingRect.topRight();
break;
case H_left:
//pt = m_vecHanle.at(H_right - 1)->pos();
pt = QPointF(m_boundingRect.right(), m_boundingRect.height() * 0.5);
break;
default:
break;
}
return pt;
}
virtual void updateHandles()
{
int nMargin = 5;
const QRectF& boundRect = this->boundingRect();
foreach (int key, m_vecHanle.keys())
{
ItemControlHandle* pHandle = m_vecHanle.value(key);
if(pHandle)
{
switch (pHandle->getTag()) {
case H_leftTop:
pHandle->move(boundRect.x() - nMargin, boundRect.y() - nMargin);
break;
case H_top:
pHandle->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() - nMargin);
break;
case H_rightTop:
pHandle->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() - nMargin);
break;
case H_right:
pHandle->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() + boundRect.height() * 0.5 + nMargin);
break;
case H_rightBottom:
pHandle->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() + boundRect.height() + nMargin);
break;
case H_bottom:
pHandle->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() + boundRect.height()+ nMargin);
break;
case H_leftBottom:
pHandle->move(boundRect.x() - nMargin, boundRect.y() + boundRect.height() + nMargin);
break;
case H_left:
pHandle->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();
pHandle->move(pt.x() - nSize - 1, pt.y() - nSize - 1);
}
else
pHandle->setVisible(false);
break;
}
case H_rotate_rightTop:
{
ItemControlHandle* handle = getHandle(H_rightTop);
if(handle)
{
int nSize = handle->getSize();
QPointF pt = handle->pos();
pHandle->move(pt.x() + nSize + 1, pt.y() - nSize - 1);
}
else
pHandle->setVisible(false);
break;
}
case H_rotate_rightBottom:
{
ItemControlHandle* handle = getHandle(H_rightBottom);
if(handle)
{
int nSize = handle->getSize();
QPointF pt = handle->pos();
pHandle->move(pt.x() + nSize + 1, pt.y() + nSize + 1);
}
else
pHandle->setVisible(false);
break;
}
case H_rotate_leftBottom:
{
ItemControlHandle* handle = getHandle(H_leftBottom);
if(handle)
{
int nSize = handle->getSize();
QPointF pt = handle->pos();
pHandle->move(pt.x() - nSize - 1, pt.y() + nSize + 1);
}
else
pHandle->setVisible(false);
break;
}
default:
break;
}
}
}
double dWidth = boundRect.width();
double dHeight = boundRect.height();
double dDiagonal = sqrt((dWidth* 0.5)*(dWidth * 0.5)+(dHeight*0.5)*(dHeight*0.5));
double dParam = dWidth > dHeight ? (dDiagonal-dWidth*0.5):(dDiagonal-dHeight*0.5);
m_boundingRect_selected = boundRect.adjusted(-dParam-nMargin, -dParam-nMargin, dParam+nMargin, dParam+nMargin);
}
virtual QRectF boundingRect() const { return m_boundingRect; }
virtual QPainterPath shape()
{
QPainterPath path;
return path;
}
virtual void syncRotationDataFromParent(const double&) {}
virtual double getSyncRotationDataFromParent() {return m_dSyncRotationByParent;}
2024-12-07 17:24:36 +08:00
virtual void setTouched(bool b){m_touched = b;}
virtual void setLastPoint(QPointF p) {m_lastPoint = p;}
2024-12-03 20:07:25 +08:00
protected:
ShapeType m_type;
QPen m_pen;
QBrush m_brush;
double m_dWidth;
double m_dHeight;
QRectF m_boundingRect;
QRectF m_boundingRect_selected; //选中矩形框
2024-12-07 17:24:36 +08:00
bool m_touched; //被触碰状态
2024-12-03 20:07:25 +08:00
double m_dSyncRotationByParent; //父项(被加入到某一组)的旋转数据,因为加入某一组后,对该组进行旋转,自身的旋转数据不会同步更新
QGraphicsPathItem* m_pOperationCopy; //图元移动和旋转时的操作副本
QPointF m_movingIniPos; //移动副本开始移动初始
QPointF m_lastPoint; //鼠标上次点击位置
2024-12-03 20:07:25 +08:00
QMap<int,ItemControlHandle*> m_vecHanle;
};
2024-12-07 17:24:36 +08:00
class ItemPort;
2025-02-06 16:36:50 +08:00
class BaseProperty;
2024-12-07 17:24:36 +08:00
2024-12-03 20:07:25 +08:00
typedef AbstractShapeType<QGraphicsItem> AbstractShape;
class GraphicsBaseItem : public QObject, public AbstractShapeType<QGraphicsItem>
{
Q_OBJECT
public:
GraphicsBaseItem(QGraphicsItem *parent);
virtual ~GraphicsBaseItem();
virtual void createOperationCopy();
virtual void removeOperationCopy();
virtual void moveOperationCopy(const QPointF&);
virtual void rotateOperationCopy(const double&);
virtual void syncRotationDataFromParent(const double&);
//多边形、线段等点选创建的对象需要的函数
virtual void addPoint(const QPointF&) {}
virtual bool endDrawing() { return true; }
2024-12-07 17:24:36 +08:00
2025-02-06 16:36:50 +08:00
virtual void setLabelTag(const QString& name); //设置名字牌
virtual QString getLabelTag() const;
virtual void setLabelCurrent(const QString& str); //设置电流标签
virtual QString getLabelCurrent() const;
virtual void setLabelVoltage(const QString& str); //设置电压标签
virtual QString getLabelVoltage() const;
2024-12-07 17:24:36 +08:00
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为坐标值
2025-02-06 16:36:50 +08:00
virtual QUuid itemId() const {return m_itemId;}
virtual void setItemId(QUuid n){m_itemId = n;}
2024-12-03 20:07:25 +08:00
virtual void setState(ItemState s){m_state = s;}
virtual void setBeginConnectPos(QPointF p){m_beginConnectPoint = p;}
virtual void setEndConnectPos(QPointF p){m_endConnectPoint = p;}
2024-12-07 17:24:36 +08:00
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 ItemControlHandle* getHandlePtr(int) const;
2024-12-07 17:24:36 +08:00
virtual QMap<QString,ItemPort*>& getPorts() {return m_mapPort;}
2025-02-06 16:36:50 +08:00
virtual void setProperty(BaseProperty* p);
virtual BaseProperty* getProperty() {return _property;}
virtual void unbindProperty(); //断开图元与数据的绑定
virtual void updateByProperty(); //使用data对象更新自己
virtual void updateConnectData(); //更新连接关系数据
virtual void setItemChanged(bool b){_itemChanged = b;}
virtual bool itemChanged() const {return _itemChanged;}
2025-03-28 18:08:21 +08:00
virtual void setModelName(QString sName){_modelName = sName;}
virtual QString getModelName() const {return _modelName;}
2024-12-03 20:07:25 +08:00
protected:
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&);
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
2025-02-06 16:36:50 +08:00
signals:
void ifExist(QUuid id,const QString&,int type,GraphicsBaseItem*);
public slots:
void onEditNameFinish(const QString&);
void onUpdateData(); //data发送的更新通知
2024-12-03 20:07:25 +08:00
protected:
2025-02-06 16:36:50 +08:00
QUuid m_itemId;
2024-12-07 17:24:36 +08:00
GraphicsItemType m_Itemtype;
2024-12-03 20:07:25 +08:00
ItemState m_state;
2024-12-07 17:24:36 +08:00
QMap<QString,ItemPort*> m_mapPort; //单独存放port
2024-12-03 20:07:25 +08:00
QPointF m_beginConnectPoint;
QPointF m_endConnectPoint;
2024-12-07 17:24:36 +08:00
uint _portId; //port编号
int _lastPort; //最后触碰的port
2025-02-06 16:36:50 +08:00
BaseProperty* _property;
bool _itemChanged; //图元变化标志,判断是否需要保存
2025-03-28 18:08:21 +08:00
QString _modelName; //当前图元使用的模型名用来在model中检索属性信息
2025-02-06 16:36:50 +08:00
};
class BaseProperty:public QObject //属性类,存放电路元件属性
{
Q_OBJECT
public:
BaseProperty(QObject* parent);
virtual ~BaseProperty();
void setUuid(QUuid id) {uUid = id;}
QUuid uuid() const {return uUid;}
2025-03-28 18:08:21 +08:00
void setModelName(QString sName) {sModelName = sName;}
QString modelName() const {return sModelName;}
2025-02-06 16:36:50 +08:00
void setType(int n) {nType = n;}
int type() const {return nType;}
void setPage(int n){nPageId = n;}
int page() const {return nPageId;}
void setTag(QString s){sTag = s;}
QString tag() const {return sTag;}
void setName(QString s){sName = s;}
QString name() const {return sName;}
void setPath(QString s){sPath = s;}
QString path() const {return sPath;}
void setDescription(QString s) {sDescription = s;}
QString description() const {return sDescription;}
void setInService(bool b) {bInService = b;}
bool inService() {return bInService;}
void setState(int n) {nState = n;}
int state() const {return nState;}
void setConnectedBus(QJsonObject j) {jConnectedBus = j;}
QJsonObject connectedBus() const {return jConnectedBus;}
void setLabel(QJsonObject j){jLabel = j;}
QJsonObject label() const {return jLabel;}
void setContext(QJsonObject j){jContext = j;}
QJsonObject context() const {return jContext;}
void setGrid(const QString& s) {sGrid = s;}
QString grid() const {return sGrid;}
void setZone(const QString& s) {sZone = s;}
QString zone() const {return sZone;}
void setStation(const QString& s) {sStation = s;}
QString station() const {return sStation;}
void setPrepareDelete(bool b) {_prepareDelete = b;}
bool prepareDelete() const {return _prepareDelete;}
void setDataChanged(bool b) {_dataChanged = b;} //数据变换标签
bool dataChanged() const {return _dataChanged;}
void notifyUpdate(){emit updateData();}
signals:
void updateData(); //通知数据拥有者更新
protected:
QUuid uUid;
2025-03-28 18:08:21 +08:00
QString sModelName; //模型名
2025-02-06 16:36:50 +08:00
int nType; //设备类型
int nPageId; //暂定为创建本数据的图Id(待定)
QString sTag;
QString sName;
QString sPath;
QString sDescription;
QString sGrid;
QString sZone;
QString sStation;
bool bInService;
int nState;
QJsonObject jConnectedBus;
QJsonObject jLabel;
QJsonObject jContext; //存放port信息
bool _dataChanged; //数据状态,为真则写入库
bool _prepareDelete; //状态,为真准备删除
2024-12-03 20:07:25 +08:00
};
2025-03-28 18:08:21 +08:00
typedef QMap<QString,QVariant> VariableMap; //属性名,值
class VariableProperty:public BaseProperty //收到的变量数据
{
Q_OBJECT
public:
VariableProperty(QObject* parent);
~VariableProperty();
2025-04-09 16:20:34 +08:00
modelDataInfo getPropertyValue() const;
2025-03-28 18:08:21 +08:00
};
2024-12-03 20:07:25 +08:00
#endif