调整结构、实现锚点缩放

This commit is contained in:
duanshengchao 2024-08-13 15:30:36 +08:00
parent 17bf78bd8a
commit 2c4a2ad19b
15 changed files with 488 additions and 271 deletions

View File

@ -42,6 +42,8 @@ set(H_HEADER_FILES
include/util/baseSelector.h
include/util/creatingSelector.h
include/util/movingSelector.h
include/util/scalingSelector.h
include/util/selectorManager.h
include/graphicsItem/itemControlHandle.h
@ -58,6 +60,8 @@ set(CPP_SOURCE_FILES
source/util/baseSelector.cpp
source/util/creatingSelector.cpp
source/util/movingSelector.cpp
source/util/scalingSelector.cpp
source/util/selectorManager.cpp
source/graphicsItem/itemControlHandle.cpp

View File

@ -21,6 +21,7 @@ protected:
void mousePressEvent(QGraphicsSceneMouseEvent*) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*) override;
private:
bool m_bGridVisible;

View File

@ -8,13 +8,32 @@
#include <QGraphicsSceneMouseEvent>
#include <QPen>
class GraphicsBaseItem : public QObject, public QGraphicsItem
//基类采用模板形式QGraphicsItem是默认值,也可以是别的类型比如QGraphicsItemGroup这样不同的基类继承可以共用一些高层的行为定义
template <typename BaseType = QGraphicsItem>
class AbstractShapeType : public BaseType
{
Q_OBJECT
public:
GraphicsBaseItem(QGraphicsItem *parent);
virtual ~GraphicsBaseItem();
explicit AbstractShapeType(QGraphicsItem *parent = 0)
: BaseType(parent)
{
m_pen = QPen(Qt::NoPen);
m_brush = QBrush(QColor(rand() % 32 * 8, rand() % 32 * 8, rand() % 32 * 8));
m_dWidth = m_dHeight = 0;
m_pMovingCopy = nullptr;
}
virtual ~AbstractShapeType()
{
for (size_t i = 0; i < m_vecHanle.size(); i++)
{
ItemControlHandle* pHandle = m_vecHanle[i];
if (pHandle)
{
delete pHandle;
pHandle = nullptr;
}
}
}
public:
QPen pen() { return m_pen; }
@ -28,27 +47,130 @@ public:
void setBrushColor(const QColor &color) { m_brush.setColor(color); }
double width() { return m_dWidth; }
void setWidth(double);
void setWidth(double width)
{
m_dWidth = width;
updateCoordinate();
}
double height() { return m_dHeight; }
void setHeight(double);
void setHeight(double height)
{
m_dHeight = height;
updateCoordinate();
}
int collidesWithHandle(const QPointF&);
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();
}
return HandleTag::H_none;
}
virtual QRectF boundingRect() const { return m_boundingRect; }
//移动副本相关
virtual void createMovingCopy() {};
virtual void removeMovingCopy() {};
virtual void moveMovingCopy(const QPointF&) {};
virtual QPainterPath shape() {}
virtual void updateHandles();
virtual void resize(int,double, double, const QPointF&) {}
virtual void updateCoordinate() {}
virtual void move(const QPointF& point) { Q_UNUSED(point); }
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&);
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
virtual void updateCoordinate() {}
//handle相关
virtual void setHandleVisible(bool);
virtual QPointF getSymmetricPointPos(int); //获取对称点的坐标位置,缩放的时候需要以对称点为锚点
virtual void setHandleVisible(bool bVisible)
{
for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
if(bVisible)
(*it)->show();
else
(*it)->hide();
}
}
virtual QPointF getSymmetricPointPos(int nHandle) //获取对称点的坐标位置,缩放的时候需要以对称点为锚点
{
QPointF pt;
//编号从1开始因此下标需要-1
switch (nHandle)
{
case H_leftTop:
pt = m_vecHanle.at(H_rightBottom - 1)->pos();
break;
case H_top:
pt = m_vecHanle.at(H_bottom - 1)->pos();
break;
case H_rightTop:
pt = m_vecHanle.at(H_leftBottom - 1)->pos();
break;
case H_right:
pt = m_vecHanle.at(H_left - 1)->pos();
break;
case H_rightBottom:
pt = m_vecHanle.at(H_leftTop - 1)->pos();
break;
case H_bottom:
pt = m_vecHanle.at(H_top - 1)->pos();
break;
case H_leftBottom:
pt = m_vecHanle.at(H_rightTop - 1)->pos();
break;
case H_left:
pt = m_vecHanle.at(H_right - 1)->pos();
break;
default:
break;
}
return pt;
}
virtual void updateHandles()
{
const QRectF& boundRect = this->boundingRect();
for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
switch ((*it)->getTag()) {
case H_leftTop:
(*it)->move(boundRect.x(), boundRect.y());
break;
case H_top:
(*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y());
break;
case H_rightTop:
(*it)->move(boundRect.x() + boundRect.width(), boundRect.y());
break;
case H_right:
(*it)->move(boundRect.x() + boundRect.width(), boundRect.y() + boundRect.height() * 0.5);
break;
case H_rightBottom:
(*it)->move(boundRect.x() + boundRect.width(), boundRect.y() + boundRect.height());
break;
case H_bottom:
(*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() + boundRect.height());
break;
case H_leftBottom:
(*it)->move(boundRect.x(), boundRect.y() + boundRect.height());
break;
case H_left:
(*it)->move(boundRect.x(), boundRect.y() + boundRect.height() * 0.5);
break;
default:
break;
}
}
}
protected:
virtual QRectF boundingRect() const { return m_boundingRect; }
virtual QPainterPath shape()
{
QPainterPath path;
return path;
}
protected:
QPen m_pen;
@ -57,7 +179,27 @@ protected:
double m_dHeight;
QRectF m_boundingRect;
QGraphicsPathItem* m_pMovingCopy; //图元移动时的副本
QPointF m_movingIniPos; //移动副本开始移动初始点
QVector<ItemControlHandle*> m_vecHanle;
};
class GraphicsBaseItem : public QObject, public AbstractShapeType<QGraphicsItem>
{
Q_OBJECT
public:
GraphicsBaseItem(QGraphicsItem *parent);
virtual ~GraphicsBaseItem();
virtual void createMovingCopy();
virtual void removeMovingCopy();
virtual void moveMovingCopy(const QPointF&);
protected:
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&);
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
};
#endif

View File

@ -1,7 +1,7 @@
/**
*\file baseSelector.h
*
*\brief selector是用来实现图元具体操作的行为
*\brief selector是用来实现图元进行具体操作的类
*
*\author dsc
*/
@ -16,6 +16,7 @@ enum SelectorType
{
ST_base = 0, //基本
ST_cerating, //创建
ST_moving, //移动
ST_editing, //顶点编辑
ST_scaling, //缩放
ST_rotating, //旋转
@ -43,6 +44,7 @@ public:
virtual void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
SelectorType getSelectorType() { return m_type; }
//void setOperationMode(OperationMode m) { m_opMode = m; }
@ -64,9 +66,7 @@ protected:
private:
bool m_bHoverOnHandel; //鼠标是否悬停在handel
QPointF m_movingItemIniPos; //图元移动时的初始点
QGraphicsPathItem* m_pMovingItemCopy; //图元移动时的副本
OperationMode m_opMode;
};
#endif

View File

@ -0,0 +1,29 @@
/**
*\file movingSelector.h
*
*\brief selector
*
*\author dsc
*/
#ifndef MOVINGSELECTOR_H
#define MOVINGSELECTOR_H
#include "baseSelector.h"
class MovingSelector : public BaseSelector
{
Q_OBJECT
public:
explicit MovingSelector(QObject *parent = 0);
virtual ~MovingSelector();
public:
void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
};
#endif

View File

@ -0,0 +1,28 @@
/**
*\file scalingSelector.h
*
*\brief selector
*\author dsc
*/
#ifndef SCALINGSELECTOR_H
#define SCALINGSELECTOR_H
#include "baseSelector.h"
class ScalingSelector : public BaseSelector
{
Q_OBJECT
public:
explicit ScalingSelector(QObject *parent = 0);
virtual ~ScalingSelector();
public:
void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
};
#endif

View File

@ -1,29 +0,0 @@
/**
*\file selectionSelector.h
*
*\brief selectorselector
*
*\author dsc
*/
#ifndef SELECTIONSELECTOR_H
#define SELECTIONSELECTOR_H
#include "baseSelector.h"
class SelectionSelector : public BaseSelector
{
Q_OBJECT
public:
explicit SelectionSelector(QObject *parent = 0);
virtual ~SelectionSelector();
public:
void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
};
#endif

View File

@ -72,6 +72,17 @@ void DesignerScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* mouseEvent)
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
void DesignerScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* mouseEvent)
{
if(SelectorManager::getInstance())
{
SelectorManager::getInstance()->getWorkingSelector()->mouseDoubleClickEvent(mouseEvent, this);
update();
}
else
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
void DesignerScene::setGridVisible(bool bVisible)
{
m_bGridVisible = bVisible;

View File

@ -1,7 +1,8 @@
#include "graphicsItem/graphicsBaseItem.h"
#include <QGraphicsScene>
GraphicsBaseItem::GraphicsBaseItem(QGraphicsItem *parent)
:QGraphicsItem(parent)
: AbstractShapeType<QGraphicsItem>(parent)
{
//初始化缩放操作用的handle
m_vecHanle.reserve(H_left);
@ -21,40 +22,48 @@ GraphicsBaseItem::GraphicsBaseItem(QGraphicsItem *parent)
GraphicsBaseItem::~GraphicsBaseItem()
{
for (size_t i = 0; i < m_vecHanle.size(); i++)
}
void GraphicsBaseItem::createMovingCopy()
{
m_pMovingCopy = new QGraphicsPathItem(this->shape());
m_pMovingCopy->setPen(Qt::DashLine);
m_pMovingCopy->setPos(this->pos());
m_pMovingCopy->setTransformOriginPoint(this->transformOriginPoint());
m_pMovingCopy->setTransform(this->transform());
m_pMovingCopy->setRotation(this->rotation());
m_pMovingCopy->setScale(this->scale());
m_pMovingCopy->setZValue(this->zValue());
QGraphicsScene* scene = this->scene();
if(scene && m_pMovingCopy)
{
ItemControlHandle* pHandle = m_vecHanle[i];
if (pHandle)
{
delete pHandle;
pHandle = nullptr;
}
scene->addItem(m_pMovingCopy);
m_movingIniPos = this->pos();
}
}
void GraphicsBaseItem::setWidth(double width)
void GraphicsBaseItem::removeMovingCopy()
{
m_dWidth = width;
updateCoordinate();
}
void GraphicsBaseItem::setHeight(double height)
{
m_dHeight = height;
updateCoordinate();
}
int GraphicsBaseItem::collidesWithHandle(const QPointF& point)
{
for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
QGraphicsScene* scene = this->scene();
if(scene && m_pMovingCopy)
{
QPointF pt = (*it)->mapFromScene(point);
if((*it)->contains(pt))
return (*it)->getTag();
this->setPos(m_pMovingCopy->pos()); //本体先移动到副本的位置
scene->removeItem(m_pMovingCopy);
delete m_pMovingCopy;
m_pMovingCopy = nullptr;
}
return HandleTag::H_none;
}
void GraphicsBaseItem::moveMovingCopy(const QPointF& distance)
{
if(m_pMovingCopy)
m_pMovingCopy->setPos(m_movingIniPos + distance);
}
QVariant GraphicsBaseItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
{
if (change == QGraphicsItem::ItemSelectedHasChanged)
@ -76,86 +85,4 @@ void GraphicsBaseItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
Q_UNUSED(event);
}
void GraphicsBaseItem::setHandleVisible(bool visible)
{
for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
if(visible)
(*it)->show();
else
(*it)->hide();
}
}
QPointF GraphicsBaseItem::getSymmetricPointPos(int nHandle)
{
QPointF pt;
//编号从1开始因此下标需要-1
switch (nHandle)
{
case H_leftTop:
pt = m_vecHanle.at(H_rightBottom - 1)->pos();
break;
case H_top:
pt = m_vecHanle.at(H_bottom - 1)->pos();
break;
case H_rightTop:
pt = m_vecHanle.at(H_leftBottom - 1)->pos();
break;
case H_right:
pt = m_vecHanle.at(H_left - 1)->pos();
break;
case H_rightBottom:
pt = m_vecHanle.at(H_leftTop - 1)->pos();
break;
case H_bottom:
pt = m_vecHanle.at(H_top - 1)->pos();
break;
case H_leftBottom:
pt = m_vecHanle.at(H_rightTop - 1)->pos();
break;
case H_left:
pt = m_vecHanle.at(H_right - 1)->pos();
break;
default:
break;
}
return pt;
}
void GraphicsBaseItem::updateHandles()
{
const QRectF& boundRect = this->boundingRect();
for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
switch ((*it)->getTag()) {
case H_leftTop:
(*it)->move(boundRect.x(), boundRect.y());
break;
case H_top:
(*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y());
break;
case H_rightTop:
(*it)->move(boundRect.x() + boundRect.width(), boundRect.y());
break;
case H_right:
(*it)->move(boundRect.x() + boundRect.width(), boundRect.y() + boundRect.height() * 0.5);
break;
case H_rightBottom:
(*it)->move(boundRect.x() + boundRect.width(), boundRect.y() + boundRect.height());
break;
case H_bottom:
(*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() + boundRect.height());
break;
case H_leftBottom:
(*it)->move(boundRect.x(), boundRect.y() + boundRect.height());
break;
case H_left:
(*it)->move(boundRect.x(), boundRect.y() + boundRect.height() * 0.5);
break;
default:
break;
}
}
}

View File

@ -2,8 +2,8 @@
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <graphicsItem/graphicsBaseItem.h>
#include <QDebug>
OperationMode BaseSelector::ms_opMode = OM_none;
QPointF BaseSelector::ms_ptMouseDown(0.0,0.0);
QPointF BaseSelector::ms_ptMouseLast(0.0,0.0);
int BaseSelector::ms_nDragHandle = 0;
@ -12,8 +12,8 @@ BaseSelector::BaseSelector(QObject *parent)
: QObject(parent)
{
m_type = ST_base;
m_opMode = OM_none;
m_bHoverOnHandel = false;
m_pMovingItemCopy = nullptr;
}
BaseSelector::~BaseSelector()
{
@ -31,50 +31,50 @@ void BaseSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScen
if(!m_bHoverOnHandel)
scene->callParentEvent(event); //此处是通过触发QGraphicsScene的事件函数来取消所有被选中item的选中状态
ms_opMode = OM_none;
GraphicsBaseItem* item = nullptr;
m_opMode = OM_none;
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1) //只有一个选中
{
item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item)
{
//需要增加当前是否点击在控制点的判断函数
ms_nDragHandle = item->collidesWithHandle(event->scenePos());
if(ms_nDragHandle != H_none && ms_nDragHandle <= H_left) //在缩放控制点上
ms_opMode = OM_scale;
{
m_opMode = OM_scale;
emit setWorkingSelector(ST_scaling);
}
else if(ms_nDragHandle > H_left) //编辑控制点上
{
ms_opMode = OM_edit;
m_opMode = OM_edit;
//setCursor(scene, Qt::ClosedHandCursor);
}
else
{
ms_opMode = OM_move;
m_opMode = OM_move;
emit setWorkingSelector(ST_moving);
setCursor(scene, Qt::ClosedHandCursor);
//创建移动时显示的item副本
m_pMovingItemCopy = new QGraphicsPathItem(item->shape());
m_pMovingItemCopy->setPen(Qt::DashLine);
m_pMovingItemCopy->setPos(item->pos());
m_pMovingItemCopy->setTransformOriginPoint(item->transformOriginPoint());
m_pMovingItemCopy->setTransform(item->transform());
m_pMovingItemCopy->setRotation(item->rotation());
m_pMovingItemCopy->setScale(item->scale());
m_pMovingItemCopy->setZValue(item->zValue());
scene->addItem(m_pMovingItemCopy);
m_movingItemIniPos = item->pos();
}
}
}
else if (items.count() > 1) //选中多个
{
ms_opMode = OM_move;
m_opMode = OM_move;
emit setWorkingSelector(ST_moving);
setCursor(scene, Qt::ClosedHandCursor);
}
if(ms_opMode == OM_none)
if(m_opMode == OM_move)
{
for(int n = 0; n < items.size(); n++)
{
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.at(n));
item->createMovingCopy();
}
}
else if(m_opMode == OM_none)
{
QGraphicsView *view = scene->getView();
if(view)
@ -87,92 +87,83 @@ void BaseSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene
{
ms_ptMouseLast = event->scenePos();
GraphicsBaseItem* item = nullptr;
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1)
{
item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item)
{
if(ms_nDragHandle != H_none && ms_opMode == OM_scale)
if(ms_nDragHandle == H_none)
{
QPointF basePoint = item->getSymmetricPointPos(ms_nDragHandle);
if(basePoint.x() == 0)
basePoint.setX(1);
if(basePoint.y() == 0)
basePoint.setY(1);
//设置光标样式
int nHandle = item->collidesWithHandle(event->scenePos());
if(nHandle == H_none)
{
setCursor(scene, Qt::ArrowCursor);
m_bHoverOnHandel = false;
}
else
{
switch (nHandle)
{
case H_leftTop:
setCursor(scene, Qt::SizeFDiagCursor);
break;
case H_top:
setCursor(scene, Qt::SizeVerCursor);
break;
case H_rightTop:
setCursor(scene, Qt::SizeBDiagCursor);
break;
case H_right:
setCursor(scene, Qt::SizeHorCursor);
break;
case H_rightBottom:
setCursor(scene, Qt::SizeFDiagCursor);
break;
case H_bottom:
setCursor(scene, Qt::SizeVerCursor);
break;
case H_leftBottom:
setCursor(scene, Qt::SizeBDiagCursor);
break;
case H_left:
setCursor(scene, Qt::SizeHorCursor);
break;
default:
break;
}
//计算缩放倍数
QPointF iniDelta = item->mapFromScene(ms_ptMouseDown) - basePoint;
QPointF lastDelta = item->mapFromScene(ms_ptMouseLast) - basePoint;
double sx = lastDelta.x() / iniDelta.x();
double sy = lastDelta.y() / iniDelta.y();
item->resize(ms_nDragHandle, sx, sy, basePoint);
}
else if(ms_nDragHandle > H_left && ms_opMode == OM_edit) //编辑形状
{
}
else if(ms_opMode == OM_move)
{
if(m_pMovingItemCopy)
m_pMovingItemCopy->setPos(m_movingItemIniPos + (ms_ptMouseLast - ms_ptMouseDown));
m_bHoverOnHandel = true;
}
}
}
}
if (ms_opMode != OM_scale && items.count() > 1) //例如多选移动等采用默认行为
{
scene->callParentEvent(event);
}
}
void BaseSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
if (event->scenePos() == ms_ptMouseDown)
ms_opMode = OM_none;
setCursor(scene, Qt::ArrowCursor);
GraphicsBaseItem* item = nullptr;
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1)
{
item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item && (ms_opMode == OM_scale || ms_opMode == OM_edit) && ms_ptMouseLast != ms_ptMouseDown)
{
item->updateCoordinate();
}
else if(item && ms_opMode == OM_move && ms_ptMouseLast != ms_ptMouseDown)
{
item->setPos(m_movingItemIniPos + (ms_ptMouseLast - ms_ptMouseDown));
}
}
if(ms_opMode == OM_none)
if(m_opMode == OM_none)
{
QGraphicsView *view = scene->getView();
if(view)
view->setDragMode(QGraphicsView::NoDrag);
}
if(m_pMovingItemCopy)
{
scene->removeItem(m_pMovingItemCopy);
delete m_pMovingItemCopy;
m_pMovingItemCopy = nullptr;
}
ms_opMode = OM_none;
m_opMode = OM_none;
m_bHoverOnHandel = false;
ms_nDragHandle = H_none;
scene->callParentEvent(event);
}
void BaseSelector::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
Q_UNUSED(event)
Q_UNUSED(scene)
}
void BaseSelector::setCursor(DesignerScene *scene, const QCursor &cursor)
{

View File

@ -39,20 +39,35 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
scene->addItem(m_pCreatingItem);
m_pCreatingItem->setSelected(true);
ms_opMode = OM_scale;
ms_nDragHandle = H_rightBottom;
}
void CreatingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
setCursor(scene, Qt::CrossCursor);
BaseSelector::mouseMoveEvent(event, scene);
ms_ptMouseLast = event->scenePos();
if (m_pCreatingItem)
{
QPointF basePoint = m_pCreatingItem->getSymmetricPointPos(ms_nDragHandle);
if(basePoint.x() == 0)
basePoint.setX(1);
if(basePoint.y() == 0)
basePoint.setY(1);
//计算缩放倍数
QPointF iniDelta = m_pCreatingItem->mapFromScene(ms_ptMouseDown) - basePoint;
QPointF lastDelta = m_pCreatingItem->mapFromScene(ms_ptMouseLast) - basePoint;
double sx = lastDelta.x() / iniDelta.x();
double sy = lastDelta.y() / iniDelta.y();
m_pCreatingItem->resize(ms_nDragHandle, sx, sy, basePoint);
}
}
void CreatingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
BaseSelector::mouseReleaseEvent(event, scene);
if (event->scenePos() == (ms_ptMouseDown - QPoint(2, 2))) //最小拖动范围
{
if(m_pCreatingItem)
@ -60,9 +75,15 @@ void CreatingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, Design
m_pCreatingItem->setSelected(false);
scene->removeItem(m_pCreatingItem);
delete m_pCreatingItem;
m_pCreatingItem = nullptr;
}
}
else if (m_pCreatingItem && ms_ptMouseLast != ms_ptMouseDown)
{
m_pCreatingItem->updateCoordinate();
}
ms_nDragHandle = H_none;
m_pCreatingItem = nullptr;
setCursor(scene, Qt::ArrowCursor);
emit setWorkingSelector(ST_base);
}

View File

@ -0,0 +1,47 @@
#include "util/MovingSelector.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <graphicsItem/graphicsBaseItem.h>
MovingSelector::MovingSelector(QObject *parent)
: BaseSelector(parent)
{
m_type = ST_moving;
}
MovingSelector::~MovingSelector()
{
}
void MovingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
}
void MovingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
ms_ptMouseLast = event->scenePos();
QList<QGraphicsItem *> items = scene->selectedItems();
for(int n = 0; n < items.size(); n++)
{
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.at(n));
if(item)
item->moveMovingCopy(ms_ptMouseLast - ms_ptMouseDown);
}
}
void MovingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
QList<QGraphicsItem *> items = scene->selectedItems();
for(int n = 0; n < items.size(); n++)
{
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.at(n));
if(item)
item->removeMovingCopy();
}
setCursor(scene, Qt::ArrowCursor);
scene->callParentEvent(event);
emit setWorkingSelector(ST_base);
}

View File

@ -0,0 +1,65 @@
#include "util/ScalingSelector.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <graphicsItem/graphicsBaseItem.h>
ScalingSelector::ScalingSelector(QObject *parent)
: BaseSelector(parent)
{
m_type = ST_scaling;
}
ScalingSelector::~ScalingSelector()
{
}
void ScalingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
BaseSelector::mousePressEvent(event,scene);
}
void ScalingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
ms_ptMouseLast = event->scenePos();
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1)
{
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item)
{
if(ms_nDragHandle != H_none)
{
QPointF basePoint = item->getSymmetricPointPos(ms_nDragHandle);
if(basePoint.x() == 0)
basePoint.setX(1);
if(basePoint.y() == 0)
basePoint.setY(1);
//计算缩放倍数
QPointF iniDelta = item->mapFromScene(ms_ptMouseDown) - basePoint;
QPointF lastDelta = item->mapFromScene(ms_ptMouseLast) - basePoint;
double sx = lastDelta.x() / iniDelta.x();
double sy = lastDelta.y() / iniDelta.y();
item->resize(ms_nDragHandle, sx, sy, basePoint);
}
}
}
}
void ScalingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1)
{
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item && ms_ptMouseLast != ms_ptMouseDown)
{
item->updateCoordinate();
}
}
ms_nDragHandle = H_none;
setCursor(scene, Qt::ArrowCursor);
emit setWorkingSelector(ST_base);
}

View File

@ -1,28 +0,0 @@
#include "util/selectionSelector.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
SelectionSelector::SelectionSelector(QObject *parent)
: BaseSelector(parent)
{
m_opMode = OM_selection;
}
SelectionSelector::~SelectionSelector()
{
}
void SelectionSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
BaseSelector::mousePressEvent(event,scene);
}
void SelectionSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
}
void SelectionSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
}

View File

@ -1,5 +1,7 @@
#include "util/selectorManager.h"
#include "util/creatingSelector.h"
#include "util/movingSelector.h"
#include "util/scalingSelector.h"
SelectorManager* SelectorManager::m_pInstance = nullptr;
@ -15,6 +17,12 @@ SelectorManager::SelectorManager(QObject *parent)
CreatingSelector* creatingSelector = new CreatingSelector(this);
connect(creatingSelector, SIGNAL(setWorkingSelector(SelectorType)), this, SLOT(onSignal_setWorkingSelector(SelectorType)));
m_vecSelectors.push_back(creatingSelector);
MovingSelector* movingSelector = new MovingSelector(this);
connect(movingSelector, SIGNAL(setWorkingSelector(SelectorType)), this, SLOT(onSignal_setWorkingSelector(SelectorType)));
m_vecSelectors.push_back(movingSelector);
ScalingSelector* scalingSelector = new ScalingSelector(this);
connect(scalingSelector, SIGNAL(setWorkingSelector(SelectorType)), this, SLOT(onSignal_setWorkingSelector(SelectorType)));
m_vecSelectors.push_back(scalingSelector);
m_curSelector = ST_base;
}