DiagramDesigner/diagramCavas/source/util/baseSelector.cpp

457 lines
20 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "util/baseSelector.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <QDebug>
#include "graphicsItem/graphicsBaseItem.h"
#include "graphicsItem/handleText.h"
#include "powerEntity.h"
#include "topologyManager.h"
#include "graphicsItem/itemPort.h"
#include "graphicsItem/electricConnectLineItem.h"
#include "topologyManager.h"
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;
BaseSelector::BaseSelector(FixedPortsModel* model,QObject *parent)
: _model(model)
,QObject(parent)
{
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;
_model->activateModel(); //激活当前窗口
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) //只有一个选中
{
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item)
{
GraphicsItemType tpe = item->getItemType();
if(tpe == GIT_link) //对象是连接线
{
m_opMode = OM_linkMove;
setCursor(scene, Qt::ArrowCursor);
emit setWorkingSelector(ST_linkMoving);
}
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);
}
}
}
}
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)
{
//GraphicsBaseItem* 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);
}
}
}
}
if(m_opMode == OM_move) //可以多个选中同时移动
{
for(int n = 0; n < items.size(); n++)
{
//创建副本
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.at(n));
GraphicsItemType tpe = item->getItemType();
if(tpe == GIT_link)
continue;
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());
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();
}
}
}
}
}
else if(items.count() == 1) //不是文字节点
{
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item)
{
GraphicsItemType tpe = item->getItemType();
if(tpe != GIT_link)
{
QString modelName = item->getModelName(); //todo:additem时填写模型类型
QUuid uuid = item->itemId();
_model->showModelDlg(modelName,uuid,item);
}
}
}
}
void BaseSelector::setCursor(DesignerScene *scene, const QCursor &cursor)
{
QGraphicsView *view = scene->getView();
if (view)
view->setCursor(cursor);
}
void BaseSelector::createTopoTerminals(GraphicsBaseItem* pItem)
{
PowerEntity* pEntity = pItem->entity();
if(pEntity)
{
QMap<QString,ItemPort*> mapPorts = pItem->getPorts(); //创建对应
for(auto &port:mapPorts)
{
TerminalType terType;
HandleType tpe = port->getType();
switch (tpe) {
case T_lineIn:
terType = TerminalType::PowerInput;
break;
case T_lineOut:
terType = TerminalType::PowerOutput;
break;
case T_lineInOut:
terType = TerminalType::PowerConnect;
break;
default:
break;
}
TopologyManager::instance().createTerminal(pEntity->id(),terType,"",port->pos(),port->getId());
}
}
}
void BaseSelector::updateConnectLineByTopology(QList<QGraphicsItem *> lst)
{
for(auto iter:lst) //更新连接线
{
auto item = dynamic_cast<GraphicsBaseItem*>(iter);
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();
}
}
}
}
}
}
}