#include "util/connectingSelector.h" #include "graphicsItem/itemControlHandle.h" #include "graphicsItem/itemPort.h" #include "graphicsItem/electricConnectLineItem.h" #include "topologyManager.h" #include #include #include ConnectingSelector::ConnectingSelector(FixedPortsModel* model,QObject *parent) : BaseSelector(model,parent) ,m_pConnectingItem(nullptr) ,m_pTouchedItem(nullptr) { m_type = ST_connecting; m_bReadyConnect = false; } ConnectingSelector::~ConnectingSelector() { } void ConnectingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene) { ms_ptMouseLast = event->scenePos(); } 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) { QUuid uid = QUuid::createUuid(); ElectricConnectLineItem* pItem = new ElectricConnectLineItem(); pItem->setItemId(uid); pItem->setItemType(GIT_link); scene->addItem(pItem); ItemPort* ptSrc = connectingItem->getPortPtr(ms_nDragHandle); //QUuid srcId = connectingItem->itemId(); //int srcPort = ptSrc->getTag(); //HandleType srcType = ptSrc->getType(); //PortPos srcPos = ptSrc->portPos(); pItem->setStartPoint(ptSrc->scenePos()); ptSrc->setConnect(pItem); QString srcPortId = ptSrc->getId(); //port自身id 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()); } createTopoTerminals(touchedItem); //创建port时创建对应的terminal } else { int nLastPort = touchedItem->getLastPort(); ptDest = touchedItem->getPortPtr(nLastPort); pItem->setEndPoint(ptDest->scenePos()); } if(ptDest != nullptr) { //QUuid destId = touchedItem->itemId(); //int destPort = ptDest->getTag(); //HandleType destType = ptDest->getType(); //PortPos destPos = ptDest->portPos(); QString destPortId = ptDest->getId(); //port自身id //pItem->calculatePath(); //pItem->setConnection(Connection(srcId,srcPort,srcType,srcPos,destId,destPort,destType,destPos)); //ptDest->setConnect(pItem); if(TopologyManager::instance().validateConnection(srcPortId,destPortId)) TopologyManager::instance().createConnection(uid.toString(),srcPortId,destPortId); //创建拓扑连接(逻辑) _model->addNodeItem(pItem->itemId(),pItem); auto srcParent = ptSrc->getParentPtr(); auto destParent = ptDest->getParentPtr(); srcParent->setItemChanged(true); destParent->setItemChanged(true); } } void ConnectingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene) { ms_ptMouseLast = event->scenePos(); if(m_pConnectingItem == nullptr) { QList items = scene->selectedItems(); if (items.count() == 1) { GraphicsBaseItem* item = qgraphicsitem_cast(items.first()); if(item) { if(ms_nDragHandle >= H_connect) //操作的是port端点 { 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; } } } } } else { if(m_pConnectingItem) { QPointF end = m_pConnectingItem->mapFromScene(ms_ptMouseLast); m_pConnectingItem->setEndConnectPos(end); QList items = scene->items(ms_ptMouseLast); if (items.count() == 1) { GraphicsBaseItem* item = dynamic_cast(items.first()); if(item) { QUuid n1 = item->itemId(); QUuid 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; } } } } } void ConnectingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene) { if(m_bReadyConnect) { if(m_pConnectingItem && m_pTouchedItem) { createConnectLline(m_pConnectingItem,m_pTouchedItem,scene); auto obj = dynamic_cast(m_pConnectingItem); QList lst; lst.append(obj); updateConnectLineByTopology(lst); } } if(m_pConnectingItem) { m_pConnectingItem->setState(S_normal); } if(m_pTouchedItem) { setTargetHighLight(false); m_pTouchedItem->setLastPort(-1); m_pTouchedItem = nullptr; } m_pConnectingItem = nullptr; ms_nDragHandle = H_none; setCursor(scene, Qt::ArrowCursor); scene->callParentEvent(event); emit setWorkingSelector(ST_base); }