From dc36337663b1c170aec0b3c300b9e8befcbd6f0b Mon Sep 17 00:00:00 2001 From: BojanKverh Date: Tue, 11 Oct 2016 00:27:14 +0200 Subject: [PATCH] Implemented interactive resizing for grainline item --HG-- branch : feature --- src/libs/vtools/tools/vgrainlineitem.cpp | 100 ++++++++++++++++++++--- src/libs/vtools/tools/vgrainlineitem.h | 8 +- src/libs/vtools/tools/vtooldetail.cpp | 15 ++++ src/libs/vtools/tools/vtooldetail.h | 1 + 4 files changed, 111 insertions(+), 13 deletions(-) diff --git a/src/libs/vtools/tools/vgrainlineitem.cpp b/src/libs/vtools/tools/vgrainlineitem.cpp index d0dbc0a83..665017b74 100644 --- a/src/libs/vtools/tools/vgrainlineitem.cpp +++ b/src/libs/vtools/tools/vgrainlineitem.cpp @@ -41,6 +41,7 @@ #define ARROW_ANGLE 0.35 #define ARROW_LENGTH 15 #define RECT_WIDTH 30 +#define RESIZE_RECT_SIZE 10 #define ACTIVE_Z 10 #define INACTIVE_Z 5 @@ -51,7 +52,7 @@ */ VGrainlineItem::VGrainlineItem(QGraphicsItem* pParent) :QGraphicsObject(pParent), m_eMode(VGrainlineItem::mNormal), m_dRotation(0), m_dLength(0), m_rectBoundingBox(), - m_polyBound(), m_ptStartPos(), m_ptStartMove(), m_dScale(1) + m_polyBound(), m_ptStartPos(), m_ptStartMove(), m_dScale(1), m_polyResize() { m_rectBoundingBox.setTopLeft(QPointF(0, 0)); setAcceptHoverEvents(true); @@ -120,6 +121,17 @@ void VGrainlineItem::paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption pP->setBrush(Qt::NoBrush); // bounding polygon pP->drawPolygon(m_polyBound); + + pP->setBrush(clr); + pP->drawPolygon(m_polyResize); + + pP->setBrush(Qt::NoBrush); + if (m_eMode == mResize) + { + pP->drawLine(m_polyBound.at(0), m_polyBound.at(2)); + pP->drawLine(m_polyBound.at(1), m_polyBound.at(3)); + } + } pP->restore(); } @@ -250,6 +262,7 @@ bool VGrainlineItem::IsContained(const QPointF& pt, qreal &dX, qreal &dY) const void VGrainlineItem::SetScale(qreal dScale) { m_dScale = dScale; + UpdateRectangle(); UpdateBox(); } @@ -262,13 +275,23 @@ void VGrainlineItem::mousePressEvent(QGraphicsSceneMouseEvent* pME) { if (pME->button() == Qt::LeftButton) { - m_eMode = mMove; - setZValue(ACTIVE_Z); m_ptStartPos = pos(); m_ptStartMove = pME->scenePos(); - UpdateBox(); - SetOverrideCursor(cursorArrowCloseHand, 1, 1); + m_dStartLength = m_dLength; + + if (m_polyResize.containsPoint(pME->pos(), Qt::OddEvenFill) == true) + { + m_eMode = mResize; + SetOverrideCursor(Qt::SizeFDiagCursor); + } + else + { + m_eMode = mMove; + SetOverrideCursor(cursorArrowCloseHand, 1, 1); + } } + setZValue(ACTIVE_Z); + UpdateBox(); } //--------------------------------------------------------------------------------------------------------------------- @@ -278,9 +301,9 @@ void VGrainlineItem::mousePressEvent(QGraphicsSceneMouseEvent* pME) */ void VGrainlineItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) { + QPointF ptDiff = pME->scenePos() - m_ptStartMove; if (m_eMode == mMove) { - QPointF ptDiff = pME->scenePos() - m_ptStartMove; QPointF pt = m_ptStartPos + ptDiff; qreal dX; qreal dY; @@ -290,6 +313,22 @@ void VGrainlineItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) pt.setY(pt.y() + dY); } setPos(pt); + UpdateBox(); + } + else if (m_eMode == mResize) + { + qreal dLen = qSqrt(ptDiff.x()*ptDiff.x() + ptDiff.y()*ptDiff.y()); + qreal dAng = qAtan2(ptDiff.y(), ptDiff.x()); + dLen = dLen*qCos(dAng - m_dRotation); + qreal dPrevLen = m_dLength; + // try with new length + m_dLength = m_dStartLength + dLen; + qreal dX; + qreal dY; + if (IsContained(m_ptStartPos, dX, dY) == false) + { + m_dLength = dPrevLen; + } UpdateRectangle(); UpdateBox(); } @@ -307,14 +346,35 @@ void VGrainlineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) { if (m_eMode == mMove) { - qreal dD = fabs(pME->scenePos().x() - m_ptStartMove.x()) + fabs(pME->scenePos().y() - m_ptStartMove.y()); - bool bShort = (dD < 2); - if (bShort == false) + RestoreOverrideCursor(cursorArrowCloseHand); + } + else if (m_eMode == mResize) + { + RestoreOverrideCursor(Qt::SizeFDiagCursor); + } + + qreal dD = fabs(pME->scenePos().x() - m_ptStartMove.x()) + fabs(pME->scenePos().y() - m_ptStartMove.y()); + bool bShort = (dD < 2); + + if (m_eMode == mMove || m_eMode == mResize) + { + if (bShort == true) { - emit SignalMoved(pos()); + // TODO: switch to rotate mode + } + else + { + if (m_eMode == mMove) + { + emit SignalMoved(pos()); + } + else + { + emit SignalResized(m_dLength); + } + UpdateBox(); } } - RestoreOverrideCursor(cursorArrowCloseHand); } } @@ -356,5 +416,23 @@ void VGrainlineItem::UpdateRectangle() m_polyBound << ptA; m_rectBoundingBox = m_polyBound.boundingRect(); setTransformOriginPoint(m_rectBoundingBox.center()); + + m_polyResize.clear(); + ptA = m_polyBound.at(2); + m_polyResize << ptA; + double dSize = m_dScale * RESIZE_RECT_SIZE; + + ptA.setX(ptA.x() + dSize*cos(m_dRotation + M_PI/2)); + ptA.setY(ptA.y() + dSize*sin(m_dRotation + M_PI/2)); + m_polyResize << ptA; + + ptA.setX(ptA.x() - dSize*cos(m_dRotation)); + ptA.setY(ptA.y() - dSize*sin(m_dRotation)); + m_polyResize << ptA; + + ptA.setX(ptA.x() + dSize*cos(m_dRotation - M_PI/2)); + ptA.setY(ptA.y() + dSize*sin(m_dRotation - M_PI/2)); + m_polyResize << ptA; + prepareGeometryChange(); } diff --git a/src/libs/vtools/tools/vgrainlineitem.h b/src/libs/vtools/tools/vgrainlineitem.h index 9475a46c9..008fdb4a6 100644 --- a/src/libs/vtools/tools/vgrainlineitem.h +++ b/src/libs/vtools/tools/vgrainlineitem.h @@ -44,7 +44,8 @@ class VGrainlineItem : public QGraphicsObject enum Mode { mNormal, - mMove + mMove, + mResize }; public: @@ -69,16 +70,19 @@ protected: signals: void SignalMoved(const QPointF& ptPos); + void SignalResized(qreal dLength); private: Mode m_eMode; qreal m_dRotation; qreal m_dLength; QRectF m_rectBoundingBox; - QPolygonF m_polyBound; + QPolygonF m_polyBound; QPointF m_ptStartPos; QPointF m_ptStartMove; qreal m_dScale; + QPolygonF m_polyResize; + qreal m_dStartLength; }; #endif // VGRAINLINEITEM_H diff --git a/src/libs/vtools/tools/vtooldetail.cpp b/src/libs/vtools/tools/vtooldetail.cpp index 8c0c03ac6..562bba867 100644 --- a/src/libs/vtools/tools/vtooldetail.cpp +++ b/src/libs/vtools/tools/vtooldetail.cpp @@ -205,6 +205,7 @@ VToolDetail::VToolDetail(VAbstractPattern *doc, VContainer *data, const quint32 connect(patternInfo, &VTextGraphicsItem::SignalRotated, this, &VToolDetail::SaveRotationPattern); connect(grainLine, &VGrainlineItem::SignalMoved, this, &VToolDetail::SaveMoveGrainline); + connect(grainLine, &VGrainlineItem::SignalResized, this, &VToolDetail::SaveResizeGrainline); connect(doc, &VAbstractPattern::patternChanged, this, &VToolDetail::UpdatePatternInfo); connect(doc, &VAbstractPattern::CheckLayout, this, &VToolDetail::UpdateLabel); @@ -1067,6 +1068,20 @@ void VToolDetail::SaveMoveGrainline(const QPointF& ptPos) qApp->getUndoStack()->push(moveCommand); } +//--------------------------------------------------------------------------------------------------------------------- +void VToolDetail::SaveResizeGrainline(qreal dLength) +{ + VDetail oldDet = VAbstractTool::data.GetDetail(id); + VDetail newDet = oldDet; + + dLength = FromPixel(dLength, *VDataTool::data.GetPatternUnit()); + newDet.GetGrainlineGeometry().SetLength(qApp->LocaleToString(dLength)); + SaveDetailOptions* moveCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); + moveCommand->setText(tr("resize grainline")); + connect(moveCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(moveCommand); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief AddNode add node to the file. diff --git a/src/libs/vtools/tools/vtooldetail.h b/src/libs/vtools/tools/vtooldetail.h index 0f2991406..c6291235c 100644 --- a/src/libs/vtools/tools/vtooldetail.h +++ b/src/libs/vtools/tools/vtooldetail.h @@ -128,6 +128,7 @@ protected slots: virtual void SaveResizePattern(qreal dLabelW, int iFontSize); virtual void SaveRotationPattern(qreal dRot); virtual void SaveMoveGrainline(const QPointF& ptPos); + virtual void SaveResizeGrainline(qreal dLength); private: Q_DISABLE_COPY(VToolDetail)