diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a696db..f864a11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/include/designerScene.h b/include/designerScene.h index c138e36..8be2167 100644 --- a/include/designerScene.h +++ b/include/designerScene.h @@ -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; diff --git a/include/graphicsItem/graphicsBaseItem.h b/include/graphicsItem/graphicsBaseItem.h index 282e46f..5537978 100644 --- a/include/graphicsItem/graphicsBaseItem.h +++ b/include/graphicsItem/graphicsBaseItem.h @@ -8,13 +8,32 @@ #include #include -class GraphicsBaseItem : public QObject, public QGraphicsItem +//基类采用模板形式,QGraphicsItem是默认值,也可以是别的类型,比如QGraphicsItemGroup,这样不同的基类继承可以共用一些高层的行为定义 +template +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 m_vecHanle; }; +class GraphicsBaseItem : public QObject, public AbstractShapeType +{ + 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 diff --git a/include/util/baseSelector.h b/include/util/baseSelector.h index 63dee64..9caea68 100644 --- a/include/util/baseSelector.h +++ b/include/util/baseSelector.h @@ -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 diff --git a/include/util/movingSelector.h b/include/util/movingSelector.h new file mode 100644 index 0000000..93aefe8 --- /dev/null +++ b/include/util/movingSelector.h @@ -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 diff --git a/include/util/scalingSelector.h b/include/util/scalingSelector.h new file mode 100644 index 0000000..8ffdd11 --- /dev/null +++ b/include/util/scalingSelector.h @@ -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 diff --git a/include/util/selectionSelector.h b/include/util/selectionSelector.h deleted file mode 100644 index 1dc0c93..0000000 --- a/include/util/selectionSelector.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - *\file selectionSelector.h - * - *\brief 用来实现图元选择的selector,比如点选、框选和取消选择等,也是默认的selector - * - *\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 diff --git a/source/designerScene.cpp b/source/designerScene.cpp index a5a4df6..c5f427f 100644 --- a/source/designerScene.cpp +++ b/source/designerScene.cpp @@ -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; diff --git a/source/graphicsItem/graphicsBaseItem.cpp b/source/graphicsItem/graphicsBaseItem.cpp index 5514d46..be6fbba 100644 --- a/source/graphicsItem/graphicsBaseItem.cpp +++ b/source/graphicsItem/graphicsBaseItem.cpp @@ -1,7 +1,8 @@ #include "graphicsItem/graphicsBaseItem.h" +#include GraphicsBaseItem::GraphicsBaseItem(QGraphicsItem *parent) - :QGraphicsItem(parent) + : AbstractShapeType(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; - } - } -} diff --git a/source/util/baseSelector.cpp b/source/util/baseSelector.cpp index 31b4449..5681eed 100644 --- a/source/util/baseSelector.cpp +++ b/source/util/baseSelector.cpp @@ -2,8 +2,8 @@ #include #include #include +#include -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 items = scene->selectedItems(); if (items.count() == 1) //只有一个选中 { - item = qgraphicsitem_cast(items.first()); + GraphicsBaseItem* item = qgraphicsitem_cast(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(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 items = scene->selectedItems(); if (items.count() == 1) { - item = qgraphicsitem_cast(items.first()); + GraphicsBaseItem* item = qgraphicsitem_cast(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 items = scene->selectedItems(); - if (items.count() == 1) - { - item = qgraphicsitem_cast(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) { diff --git a/source/util/creatingSelector.cpp b/source/util/creatingSelector.cpp index 57d5b49..5ffcaa8 100644 --- a/source/util/creatingSelector.cpp +++ b/source/util/creatingSelector.cpp @@ -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); } diff --git a/source/util/movingSelector.cpp b/source/util/movingSelector.cpp new file mode 100644 index 0000000..f6b8e2d --- /dev/null +++ b/source/util/movingSelector.cpp @@ -0,0 +1,47 @@ +#include "util/MovingSelector.h" +#include +#include +#include + +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 items = scene->selectedItems(); + for(int n = 0; n < items.size(); n++) + { + GraphicsBaseItem* item = qgraphicsitem_cast(items.at(n)); + if(item) + item->moveMovingCopy(ms_ptMouseLast - ms_ptMouseDown); + } +} + +void MovingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene) +{ + QList items = scene->selectedItems(); + for(int n = 0; n < items.size(); n++) + { + GraphicsBaseItem* item = qgraphicsitem_cast(items.at(n)); + if(item) + item->removeMovingCopy(); + } + + setCursor(scene, Qt::ArrowCursor); + scene->callParentEvent(event); + emit setWorkingSelector(ST_base); +} diff --git a/source/util/scalingSelector.cpp b/source/util/scalingSelector.cpp new file mode 100644 index 0000000..3a49f60 --- /dev/null +++ b/source/util/scalingSelector.cpp @@ -0,0 +1,65 @@ +#include "util/ScalingSelector.h" +#include +#include +#include + +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 items = scene->selectedItems(); + if (items.count() == 1) + { + GraphicsBaseItem* item = qgraphicsitem_cast(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 items = scene->selectedItems(); + if (items.count() == 1) + { + GraphicsBaseItem* item = qgraphicsitem_cast(items.first()); + if(item && ms_ptMouseLast != ms_ptMouseDown) + { + item->updateCoordinate(); + } + } + + ms_nDragHandle = H_none; + setCursor(scene, Qt::ArrowCursor); + emit setWorkingSelector(ST_base); +} diff --git a/source/util/selectionSelector.cpp b/source/util/selectionSelector.cpp deleted file mode 100644 index 9de6166..0000000 --- a/source/util/selectionSelector.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "util/selectionSelector.h" -#include -#include - -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) -{ - -} diff --git a/source/util/selectorManager.cpp b/source/util/selectorManager.cpp index d40ca74..19fea4a 100644 --- a/source/util/selectorManager.cpp +++ b/source/util/selectorManager.cpp @@ -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; }