DiagramDesigner/diagramCavas/source/util/connectingSelector.cpp

247 lines
7.9 KiB
C++
Raw Normal View History

2024-12-03 20:07:25 +08:00
#include "util/connectingSelector.h"
2024-12-07 17:24:36 +08:00
#include "graphicsItem/itemControlHandle.h"
#include "graphicsItem/itemPort.h"
#include "graphicsItem/electricConnectLineItem.h"
2025-04-30 16:29:17 +08:00
#include "topologyManager.h"
2024-12-03 20:07:25 +08:00
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <graphicsItem/graphicsBaseItem.h>
2025-07-11 18:13:54 +08:00
#include "baseProperty.h"
2025-05-09 19:36:32 +08:00
#include <QMessageBox>
2024-12-03 20:07:25 +08:00
2025-02-06 16:36:50 +08:00
ConnectingSelector::ConnectingSelector(FixedPortsModel* model,QObject *parent)
: BaseSelector(model,parent)
2024-12-07 17:24:36 +08:00
,m_pConnectingItem(nullptr)
,m_pTouchedItem(nullptr)
2024-12-03 20:07:25 +08:00
{
m_type = ST_connecting;
2024-12-07 17:24:36 +08:00
m_bReadyConnect = false;
2024-12-03 20:07:25 +08:00
}
ConnectingSelector::~ConnectingSelector()
{
}
2025-06-20 18:09:41 +08:00
void ConnectingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene,DiagramMode sceneMode)
2024-12-03 20:07:25 +08:00
{
ms_ptMouseLast = event->scenePos();
}
bool ConnectingSelector::targetCouldConnect(GraphicsProjectModelItem* p,QPointF pos)
2024-12-07 17:24:36 +08:00
{
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(GraphicsProjectModelItem* connectingItem,GraphicsProjectModelItem* touchedItem,DesignerScene* scene)
2024-12-07 17:24:36 +08:00
{
2025-05-09 19:36:32 +08:00
if (!_model->isItemValid(connectingItem) || !_model->isItemValid(touchedItem)) {
QMessageBox::information(NULL, QString("提示"), QString::fromWCharArray(L"请先完成设备命名"));
return;
}
2025-04-30 16:29:17 +08:00
QUuid uid = QUuid::createUuid();
2024-12-07 17:24:36 +08:00
ElectricConnectLineItem* pItem = new ElectricConnectLineItem();
2025-04-30 16:29:17 +08:00
pItem->setItemId(uid);
pItem->setItemType(GIT_link);
2024-12-07 17:24:36 +08:00
scene->addItem(pItem);
ItemPort* ptSrc = connectingItem->getPortPtr(ms_nDragHandle);
2025-05-09 19:36:32 +08:00
2024-12-07 17:24:36 +08:00
pItem->setStartPoint(ptSrc->scenePos());
ptSrc->setConnect(pItem);
2025-04-30 16:29:17 +08:00
QString srcPortId = ptSrc->getId(); //port自身id
2024-12-07 17:24:36 +08:00
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());
}
2025-04-30 16:29:17 +08:00
2025-05-16 19:20:46 +08:00
_model->createTopoTerminalsByItem(touchedItem); //创建port时创建对应的terminal
2024-12-07 17:24:36 +08:00
}
else
{
int nLastPort = touchedItem->getLastPort();
ptDest = touchedItem->getPortPtr(nLastPort);
pItem->setEndPoint(ptDest->scenePos());
}
if(ptDest != nullptr)
{
2025-04-30 16:29:17 +08:00
QString destPortId = ptDest->getId(); //port自身id
2025-05-16 19:20:46 +08:00
if(TopologyManager::instance().validateConnection(srcPortId,destPortId)){
PowerConnection* pCon = TopologyManager::instance().createConnection(uid.toString(),srcPortId,destPortId,connectingItem->itemId().toString(),touchedItem->itemId().toString()); //创建拓扑连接(逻辑)
if(pCon)
pCon->setState(DataState::changed);
}
2024-12-07 17:24:36 +08:00
2025-07-11 18:13:54 +08:00
pItem->getProperty()->setConnection(Connection(connectingItem->itemId(),QUuid(srcPortId),ptSrc->getType(),ptSrc->portPos(),touchedItem->itemId(),QUuid(destPortId),ptDest->getType(),ptDest->portPos()));
2025-02-06 16:36:50 +08:00
_model->addNodeItem(pItem->itemId(),pItem);
auto srcParent = ptSrc->getParentPtr();
auto destParent = ptDest->getParentPtr();
srcParent->setItemChanged(true);
destParent->setItemChanged(true);
2024-12-07 17:24:36 +08:00
}
}
2025-06-20 18:09:41 +08:00
void ConnectingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene,DiagramMode sceneMode)
2024-12-03 20:07:25 +08:00
{
ms_ptMouseLast = event->scenePos();
if(m_pConnectingItem == nullptr)
{
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1)
{
GraphicsProjectModelItem* item = qgraphicsitem_cast<GraphicsProjectModelItem*>(items.first());
2024-12-03 20:07:25 +08:00
if(item)
{
2025-04-30 16:29:17 +08:00
if(ms_nDragHandle >= H_connect) //操作的是port端点
2024-12-03 20:07:25 +08:00
{
ItemPort* pt = item->getPortPtr(ms_nDragHandle);
if(pt)
{
if(pt->connected()) //只判断未连接的port
return;
item->setState(S_prepareConnect);
QPointF start = item->mapFromScene(ms_ptMouseDown);
QPointF end = item->mapFromScene(ms_ptMouseLast);
item->setBeginConnectPos(start);
item->setEndConnectPos(end);
m_pConnectingItem = item;
}
2024-12-03 20:07:25 +08:00
}
}
}
}
else
{
if(m_pConnectingItem)
{
QPointF end = m_pConnectingItem->mapFromScene(ms_ptMouseLast);
m_pConnectingItem->setEndConnectPos(end);
2024-12-07 17:24:36 +08:00
QList<QGraphicsItem *> items = scene->items(ms_ptMouseLast);
if (items.count() == 1)
{
GraphicsProjectModelItem* item = dynamic_cast<GraphicsProjectModelItem*>(items.first());
2024-12-07 17:24:36 +08:00
if(item)
{
2025-02-06 16:36:50 +08:00
QUuid n1 = item->itemId();
QUuid n2 = m_pConnectingItem->itemId();
2024-12-07 17:24:36 +08:00
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;
}
}
2024-12-03 20:07:25 +08:00
}
}
}
2025-06-20 18:09:41 +08:00
void ConnectingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene,DiagramMode sceneMode)
2024-12-03 20:07:25 +08:00
{
2024-12-07 17:24:36 +08:00
if(m_bReadyConnect)
{
if(m_pConnectingItem && m_pTouchedItem)
{
createConnectLline(m_pConnectingItem,m_pTouchedItem,scene);
2025-04-30 16:29:17 +08:00
auto obj = dynamic_cast<QGraphicsItem*>(m_pConnectingItem);
QList<QGraphicsItem*> lst;
lst.append(obj);
updateConnectLineByTopology(lst);
2024-12-07 17:24:36 +08:00
}
}
2024-12-03 20:07:25 +08:00
if(m_pConnectingItem)
2024-12-07 17:24:36 +08:00
{
2024-12-03 20:07:25 +08:00
m_pConnectingItem->setState(S_normal);
2024-12-07 17:24:36 +08:00
}
if(m_pTouchedItem)
{
setTargetHighLight(false);
m_pTouchedItem->setLastPort(-1);
m_pTouchedItem = nullptr;
}
2024-12-03 20:07:25 +08:00
m_pConnectingItem = nullptr;
ms_nDragHandle = H_none;
setCursor(scene, Qt::ArrowCursor);
scene->callParentEvent(event);
emit setWorkingSelector(ST_base);
}