DiagramDesigner/diagramCavas/source/util/baseSelector.cpp

499 lines
22 KiB
C++
Raw Normal View History

2024-12-03 20:07:25 +08:00
#include "util/baseSelector.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <QDebug>
2025-05-09 19:36:32 +08:00
#include <QMimeData>
2025-05-16 19:20:46 +08:00
#include <QMessageBox>
#include "graphicsItem/graphicsBaseItem.h"
#include "graphicsItem/handleText.h"
2025-04-30 16:29:17 +08:00
#include "powerEntity.h"
#include "topologyManager.h"
#include "graphicsItem/itemPort.h"
#include "graphicsItem/electricConnectLineItem.h"
#include "topologyManager.h"
2024-12-03 20:07:25 +08:00
QPointF BaseSelector::ms_ptMouseDown(0.0,0.0);
QPointF BaseSelector::ms_ptMouseLast(0.0,0.0);
double BaseSelector::ms_dAngleMouseDownToItem = 0.0;
int BaseSelector::ms_nDragHandle = 0;
2025-02-06 16:36:50 +08:00
BaseSelector::BaseSelector(FixedPortsModel* model,QObject *parent)
: _model(model)
,QObject(parent)
2024-12-03 20:07:25 +08:00
{
m_type = ST_base;
m_opMode = OM_none;
m_bHoverOnHandel = false;
}
BaseSelector::~BaseSelector()
{
}
void BaseSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
if (event->button() != Qt::LeftButton)
return;
2025-02-06 16:36:50 +08:00
_model->activateModel(); //激活当前窗口
2024-12-03 20:07:25 +08:00
ms_ptMouseDown = event->scenePos();
ms_ptMouseLast = event->scenePos();
if(!m_bHoverOnHandel)
scene->callParentEvent(event); //此处是通过触发QGraphicsScene的事件函数来取消所有被选中item的选中状态
m_opMode = OM_none;
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)
{
GraphicsItemType tpe = item->getItemType();
if(tpe == GIT_link) //对象是连接线
2024-12-03 20:07:25 +08:00
{
m_opMode = OM_linkMove;
2024-12-07 17:24:36 +08:00
setCursor(scene, Qt::ArrowCursor);
emit setWorkingSelector(ST_linkMoving);
2024-12-03 20:07:25 +08:00
}
else
{
//需要增加当前是否点击在控制点的判断函数
ms_nDragHandle = item->collidesWithHandle(event->scenePos());
if(ms_nDragHandle != H_none && ms_nDragHandle <= H_left) //在缩放控制点上
{
m_opMode = OM_scale;
emit setWorkingSelector(ST_scaling);
}
else if(ms_nDragHandle >= H_rotate_leftTop && ms_nDragHandle <= H_rotate_leftBottom) //在旋转控制点上
{
m_opMode = OM_rotate;
//计算夹角
QPointF originPoint = item->mapToScene(item->boundingRect().center());
double dLengthY = ms_ptMouseLast.y() - originPoint.y();
double dLengthX = ms_ptMouseLast.x() - originPoint.x();
ms_dAngleMouseDownToItem = atan2(dLengthY, dLengthX) * 180 / M_PI;
// if(atan2(dLengthY, dLengthX) < 0)
// ms_dAngleMouseDownToItem += 360.0;
//创建副本
item->createOperationCopy();
emit setWorkingSelector(ST_rotation);
}
else if(ms_nDragHandle > H_rotate_leftBottom && ms_nDragHandle < H_textCaption) //编辑控制点上
{
m_opMode = OM_edit;
setCursor(scene, Qt::ClosedHandCursor);
emit setWorkingSelector(ST_editing);
}
else if(ms_nDragHandle >= H_connect ) //连接控制点
{
m_opMode = OM_connect;
//setCursor(scene, Qt::ClosedHandCursor);
setCursor(scene, Qt::ArrowCursor);
emit setWorkingSelector(ST_connecting);
}
else
{
m_opMode = OM_move;
setCursor(scene, Qt::ClosedHandCursor);
emit setWorkingSelector(ST_moving);
}
2024-12-03 20:07:25 +08:00
}
}
}
else if (items.count() > 1) //选中多个
{
m_opMode = OM_move;
emit setWorkingSelector(ST_moving);
setCursor(scene, Qt::ClosedHandCursor);
}
else if(items.count() == 0) //单独移动子类
{
QList<QGraphicsItem *> items = scene->items(ms_ptMouseLast);
if (items.count() == 1)
{
ItemControlHandle* pHandle = qgraphicsitem_cast<ItemControlHandle*>(items.first());
if(pHandle)
{
//GraphicsProjectModelItem* item = pHandle->getParentPtr();
ms_nDragHandle = pHandle->getTag();
//ms_nDragHandle = item->collidesWithHandle(event->scenePos());
if(ms_nDragHandle >= H_textCaption && ms_nDragHandle < H_connect) //移动文本
{
m_opMode = OM_subMove;
setCursor(scene, Qt::ClosedHandCursor);
emit setWorkingSelector(ST_subMoving);
}
}
}
}
2024-12-03 20:07:25 +08:00
if(m_opMode == OM_move) //可以多个选中同时移动
{
for(int n = 0; n < items.size(); n++)
{
//创建副本
GraphicsProjectModelItem* item = qgraphicsitem_cast<GraphicsProjectModelItem*>(items.at(n));
GraphicsItemType tpe = item->getItemType();
if(tpe == GIT_link)
continue;
2024-12-03 20:07:25 +08:00
item->createOperationCopy();
}
}
else if(m_opMode == OM_none)
{
QGraphicsView *view = scene->getView();
if(view)
view->setDragMode(QGraphicsView::RubberBandDrag);
}
}
void BaseSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
ms_ptMouseLast = event->scenePos();
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1)
{
AbstractShape* item = qgraphicsitem_cast<AbstractShape*>(items.first());
if(item)
{
if(ms_nDragHandle == H_none)
{
//设置光标样式
int nHandle = item->collidesWithHandle(event->scenePos());
if(nHandle == H_none)
{
setCursor(scene, Qt::ArrowCursor);
m_bHoverOnHandel = false;
}
else if(nHandle >= H_edit)
{
setCursor(scene, Qt::OpenHandCursor);
m_bHoverOnHandel = true;
}
else
{
//划分为四组区间范围,分别水平组、垂直组、一三象限倾斜组、二四象限倾斜组,每组由两个对称区间构成
double dRotation = item->rotation();
dRotation += item->getSyncRotationDataFromParent();
//让角度保持在正负180的区间也就是上下两个半圈这样易于象限判断
if (dRotation > 180)
dRotation -= 360;
if (dRotation < -180)
dRotation += 360;
//qDebug() << "selfRotation:" << item->rotation() << " syncRotation:" << item->getSyncRotationDataFromParent() << " fininalRotatio:" << dRotation;
double dTileAngle = 15.0;
switch (nHandle)
{
case H_leftTop:
{
if((dRotation > -145+dTileAngle && dRotation < -45-dTileAngle) || (dRotation > 45+dTileAngle && dRotation < 145-dTileAngle)) //垂直区间
setCursor(scene, Qt::SizeBDiagCursor);
else if((dRotation >= -45-dTileAngle && dRotation <= -45+dTileAngle) || (dRotation >= 145-dTileAngle && dRotation <= 145+dTileAngle)) //一三象限倾斜
setCursor(scene, Qt::SizeHorCursor);
else if((dRotation >= -145-dTileAngle && dRotation <= -145+dTileAngle) || (dRotation >= 45-dTileAngle && dRotation <= 45+dTileAngle)) //二四象限倾斜
setCursor(scene, Qt::SizeVerCursor);
else //水平区间
setCursor(scene, Qt::SizeFDiagCursor);
break;
}
case H_top:
{
if((dRotation > -145+dTileAngle && dRotation < -45-dTileAngle) || (dRotation > 45+dTileAngle && dRotation < 145-dTileAngle)) //垂直区间
setCursor(scene, Qt::SizeHorCursor);
else if((dRotation >= -45-dTileAngle && dRotation <= -45+dTileAngle) || (dRotation >= 145-dTileAngle && dRotation <= 145+dTileAngle)) //一三象限倾斜
setCursor(scene, Qt::SizeFDiagCursor);
else if((dRotation >= -145-dTileAngle && dRotation <= -145+dTileAngle) || (dRotation >= 45-dTileAngle && dRotation <= 45+dTileAngle)) //二四象限倾斜
setCursor(scene, Qt::SizeBDiagCursor);
else
setCursor(scene, Qt::SizeVerCursor);
break;
}
case H_rightTop:
{
if((dRotation > -145+dTileAngle && dRotation < -45-dTileAngle) || (dRotation > 45+dTileAngle && dRotation < 145-dTileAngle)) //垂直区间
setCursor(scene, Qt::SizeFDiagCursor);
else if((dRotation >= -45-dTileAngle && dRotation <= -45+dTileAngle) || (dRotation >= 145-dTileAngle && dRotation <= 145+dTileAngle)) //一三象限倾斜
setCursor(scene, Qt::SizeVerCursor);
else if((dRotation >= -145-dTileAngle && dRotation <= -145+dTileAngle) || (dRotation >= 45-dTileAngle && dRotation <= 45+dTileAngle)) //二四象限倾斜
setCursor(scene, Qt::SizeHorCursor);
else
setCursor(scene, Qt::SizeBDiagCursor);
break;
}
case H_right:
{
if((dRotation > -145+dTileAngle && dRotation < -45-dTileAngle) || (dRotation > 45+dTileAngle && dRotation < 145-dTileAngle)) //垂直区间
setCursor(scene, Qt::SizeVerCursor);
else if((dRotation >= -45-dTileAngle && dRotation <= -45+dTileAngle) || (dRotation >= 145-dTileAngle && dRotation <= 145+dTileAngle)) //一三象限倾斜
setCursor(scene, Qt::SizeBDiagCursor);
else if((dRotation >= -145-dTileAngle && dRotation <= -145+dTileAngle) || (dRotation >= 45-dTileAngle && dRotation <= 45+dTileAngle)) //二四象限倾斜
setCursor(scene, Qt::SizeFDiagCursor);
else
setCursor(scene, Qt::SizeHorCursor);
break;
}
case H_rightBottom:
{
if((dRotation > -145+dTileAngle && dRotation < -45-dTileAngle) || (dRotation > 45+dTileAngle && dRotation < 145-dTileAngle)) //垂直区间
setCursor(scene, Qt::SizeBDiagCursor);
else if((dRotation >= -45-dTileAngle && dRotation <= -45+dTileAngle) || (dRotation >= 145-dTileAngle && dRotation <= 145+dTileAngle)) //一三象限倾斜
setCursor(scene, Qt::SizeHorCursor);
else if((dRotation >= -145-dTileAngle && dRotation <= -145+dTileAngle) || (dRotation >= 45-dTileAngle && dRotation <= 45+dTileAngle)) //二四象限倾斜
setCursor(scene, Qt::SizeVerCursor);
else //水平区间
setCursor(scene, Qt::SizeFDiagCursor);
break;
}
case H_bottom:
{
if((dRotation > -145+dTileAngle && dRotation < -45-dTileAngle) || (dRotation > 45+dTileAngle && dRotation < 145-dTileAngle)) //垂直区间
setCursor(scene, Qt::SizeHorCursor);
else if((dRotation >= -45-dTileAngle && dRotation <= -45+dTileAngle) || (dRotation >= 145-dTileAngle && dRotation <= 145+dTileAngle)) //一三象限倾斜
setCursor(scene, Qt::SizeFDiagCursor);
else if((dRotation >= -145-dTileAngle && dRotation <= -145+dTileAngle) || (dRotation >= 45-dTileAngle && dRotation <= 45+dTileAngle)) //二四象限倾斜
setCursor(scene, Qt::SizeBDiagCursor);
else
setCursor(scene, Qt::SizeVerCursor);
break;
}
case H_leftBottom:
{
if((dRotation > -145+dTileAngle && dRotation < -45-dTileAngle) || (dRotation > 45+dTileAngle && dRotation < 145-dTileAngle)) //垂直区间
setCursor(scene, Qt::SizeFDiagCursor);
else if((dRotation >= -45-dTileAngle && dRotation <= -45+dTileAngle) || (dRotation >= 145-dTileAngle && dRotation <= 145+dTileAngle)) //一三象限倾斜
setCursor(scene, Qt::SizeVerCursor);
else if((dRotation >= -145-dTileAngle && dRotation <= -145+dTileAngle) || (dRotation >= 45-dTileAngle && dRotation <= 45+dTileAngle)) //二四象限倾斜
setCursor(scene, Qt::SizeHorCursor);
else //水平区间
setCursor(scene, Qt::SizeBDiagCursor);
break;
}
case H_left:
{
if((dRotation > -145+dTileAngle && dRotation < -45-dTileAngle) || (dRotation > 45+dTileAngle && dRotation < 145-dTileAngle)) //垂直区间
setCursor(scene, Qt::SizeVerCursor);
else if((dRotation >= -45-dTileAngle && dRotation <= -45+dTileAngle) || (dRotation >= 145-dTileAngle && dRotation <= 145+dTileAngle)) //一三象限倾斜
setCursor(scene, Qt::SizeBDiagCursor);
else if((dRotation >= -145-dTileAngle && dRotation <= -145+dTileAngle) || (dRotation >= 45-dTileAngle && dRotation <= 45+dTileAngle)) //二四象限倾斜
setCursor(scene, Qt::SizeFDiagCursor);
else
setCursor(scene, Qt::SizeHorCursor);
break;
}
case H_rotate_leftTop:
{
int nSize = 24;
QCursor rotateCursor = QCursor(QPixmap(":/images/icon_rotate.png")/*.scaled(nSize, nSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)*/);
setCursor(scene, rotateCursor);
break;
}
case H_rotate_rightTop:
{
int nSize = 24;
QCursor rotateCursor = QCursor(QPixmap(":/images/icon_rotate.png")/*.scaled(nSize, nSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)*/);
setCursor(scene, rotateCursor);
break;
}
case H_rotate_rightBottom:
{
int nSize = 24;
QCursor rotateCursor = QCursor(QPixmap(":/images/icon_rotate.png")/*.scaled(nSize, nSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)*/);
setCursor(scene, rotateCursor);
break;
}
case H_rotate_leftBottom:
{
int nSize = 24;
QCursor rotateCursor = QCursor(QPixmap(":/images/icon_rotate.png")/*.scaled(nSize, nSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)*/);
setCursor(scene, rotateCursor);
break;
}
default:
break;
}
m_bHoverOnHandel = true;
}
}
}
}
}
void BaseSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
setCursor(scene, Qt::ArrowCursor);
if(m_opMode == OM_none)
{
QGraphicsView *view = scene->getView();
if(view)
view->setDragMode(QGraphicsView::NoDrag);
}
m_opMode = OM_none;
m_bHoverOnHandel = false;
ms_nDragHandle = H_none;
scene->callParentEvent(event);
}
void BaseSelector::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
QList<QGraphicsItem *> items = scene->selectedItems();
if(items.count() == 0)
{
QList<QGraphicsItem *> items = scene->items(ms_ptMouseLast);
if (items.count() == 1)
{
ItemControlHandle* pHandle = qgraphicsitem_cast<ItemControlHandle*>(items.first());
if(pHandle)
{
ms_nDragHandle = pHandle->getTag();
//ms_nDragHandle = item->collidesWithHandle(event->scenePos());
2025-02-06 16:36:50 +08:00
if(ms_nDragHandle >= H_textCaption && ms_nDragHandle < H_connect) //是文字节点
{
HandleText* pText = qgraphicsitem_cast<HandleText*>(pHandle);
if(pText)
{
//m_opMode = OM_subMove;
//emit setWorkingSelector(ST_subMoving);
pText->creatEditor();
}
}
}
}
}
2025-02-06 16:36:50 +08:00
else if(items.count() == 1) //不是文字节点
{
GraphicsProjectModelItem* item = qgraphicsitem_cast<GraphicsProjectModelItem*>(items.first());
2025-02-06 16:36:50 +08:00
if(item)
{
GraphicsItemType tpe = item->getItemType();
if(tpe != GIT_link)
{
QString modelName = item->getModelName(); //todo:additem时填写模型类型
QUuid uuid = item->itemId();
2025-04-09 16:20:34 +08:00
_model->showModelDlg(modelName,uuid,item);
2025-02-06 16:36:50 +08:00
}
}
}
2024-12-03 20:07:25 +08:00
}
2025-05-09 19:36:32 +08:00
void BaseSelector::dragEnterEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*)
2024-12-03 20:07:25 +08:00
{
2025-05-09 19:36:32 +08:00
if (event->mimeData()->hasText()) {
event->acceptProposedAction();
}
2024-12-03 20:07:25 +08:00
}
2025-05-09 19:36:32 +08:00
void BaseSelector::dragMoveEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*)
2025-04-30 16:29:17 +08:00
{
2025-05-09 19:36:32 +08:00
if (event->mimeData()->hasText()) {
event->acceptProposedAction();
}
}
2025-04-30 16:29:17 +08:00
2025-05-09 19:36:32 +08:00
void BaseSelector::dropEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*)
{
if (event->mimeData()->hasText()) {
QString text = event->mimeData()->text();
2025-05-16 19:20:46 +08:00
QString uuid = QString::fromLocal8Bit(event->mimeData()->data("application/id"));
2025-05-09 19:36:32 +08:00
// 根据拖拽的数据创建相应的图形项并添加到场景中
QGraphicsTextItem *textItem = new QGraphicsTextItem(text);
textItem->setPos(event->scenePos());
//addItem(textItem);
event->acceptProposedAction();
2025-05-16 19:20:46 +08:00
//根据data数据新增拖拽的item
QMap<QUuid,GraphicsProjectModelItem*> items = _model->allItems();
2025-05-16 19:20:46 +08:00
if(items.contains(QUuid(uuid))){
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"此对象在当前页已存在"));
return;
}
else{
_model->addNodeItem(QUuid(uuid),event->scenePos());
}
2025-04-30 16:29:17 +08:00
}
}
2025-06-06 18:57:37 +08:00
void BaseSelector::contextMenuEvent(QGraphicsSceneContextMenuEvent *event,DesignerScene* scene)
{
QList<QGraphicsItem*> listItem = scene->selectedItems();
if(listItem.isEmpty())
return;
else if(listItem.count() == 1)
{
QMenu menu;
QAction *removeAction = menu.addAction(QString::fromWCharArray(L"删除"));
//connect(removeAction,&QAction::triggered,this,&DesignerScene::onDeleteClicked);
connect(removeAction,&QAction::triggered,[&,scene](){
QList<QGraphicsItem*> listItem = scene->selectedItems();
if(listItem.isEmpty())
return;
else if(listItem.count() == 1)
{
GraphicsProjectModelItem* item = qgraphicsitem_cast<GraphicsProjectModelItem*>(listItem.first());
2025-06-06 18:57:37 +08:00
if(item)
{
GraphicsItemType tpe = item->getItemType();
if(tpe > QGraphicsItem::UserType && tpe < QGraphicsItem::UserType+1000)
{
if(_model)
_model->deleteNodeItem(item);
}
}
}
});
menu.exec(QCursor::pos());
}
}
2025-05-09 19:36:32 +08:00
void BaseSelector::setCursor(DesignerScene *scene, const QCursor &cursor)
{
QGraphicsView *view = scene->getView();
if (view)
view->setCursor(cursor);
}
2025-04-30 16:29:17 +08:00
void BaseSelector::updateConnectLineByTopology(QList<QGraphicsItem *> lst)
{
for(auto iter:lst) //更新连接线
{
auto item = dynamic_cast<GraphicsProjectModelItem*>(iter);
2025-04-30 16:29:17 +08:00
if(item)
{
if(item->getItemType() != GIT_link) //获取非电缆对象
{
QUuid nId = item->itemId();
auto lstConnect = TopologyManager::instance().getConnectionsFor(nId.toString());
for(auto &pConnect:lstConnect)
{
if(pConnect)
{
QString fromTerminalId = pConnect->fromTerminalId(); //connect自身包含头尾巴顺序
QString toTerminalId = pConnect->toTerminalId();
QPointF fromPos = _model->getTerminalPos(fromTerminalId);
QPointF toPos = _model->getTerminalPos(toTerminalId);
ElectricConnectLineItem* connectItem = _model->getLineItemById(fromTerminalId);
if(connectItem)
{
connectItem->setStartPoint(fromPos);
connectItem->setEndPoint(toPos);
//qDebug()<<nId<<"start:"<<fromPos.x()<<","<<fromPos.y()<<"end:"<<toPos.x()<<","<<toPos.y();
connectItem->calculatePath();
}
}
}
}
}
}
}
2025-06-06 18:57:37 +08:00