From 8e0dc15e25166490def902b0f18b437a57dab451 Mon Sep 17 00:00:00 2001 From: BojanKverh Date: Sun, 11 Sep 2016 12:18:09 +0200 Subject: [PATCH] Moving the grainline works now, but still has a few issues --HG-- branch : feature --- src/libs/vtools/tools/vgrainlineitem.cpp | 213 +++++++++++++++++--- src/libs/vtools/tools/vgrainlineitem.h | 17 +- src/libs/vtools/tools/vtextgraphicsitem.cpp | 9 +- src/libs/vtools/tools/vtooldetail.cpp | 21 ++ src/libs/vtools/tools/vtooldetail.h | 1 + 5 files changed, 231 insertions(+), 30 deletions(-) diff --git a/src/libs/vtools/tools/vgrainlineitem.cpp b/src/libs/vtools/tools/vgrainlineitem.cpp index e21fdffcb..8cc61c8d6 100644 --- a/src/libs/vtools/tools/vgrainlineitem.cpp +++ b/src/libs/vtools/tools/vgrainlineitem.cpp @@ -30,39 +30,59 @@ #include #include +#include +#include #include "vgrainlineitem.h" #define ARROW_ANGLE 0.5 #define ARROW_LENGTH 0.05 #define RECT_WIDTH 30 +#define ACTIVE_Z 10 +#define INACTIVE_Z 5 //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::VGrainlineItem constructor + * @param pParent pointer to the parent item + */ VGrainlineItem::VGrainlineItem(QGraphicsItem* pParent) - :QGraphicsObject(pParent), m_eMode(mNormal), m_ptPos(QPointF(0, 0)), m_dRotation(0), m_dLength(0), - m_rectBoundingBox() + :QGraphicsObject(pParent), m_eMode(mNormal), m_dRotation(0), m_dLength(0), m_rectBoundingBox(), + m_polyBound(), m_ptStartPos(), m_ptStartMove() { - m_rectBoundingBox.setTopLeft(QPointF(0, 0)); - m_rectBoundingBox.setSize(QSizeF(200, 200)); + setAcceptHoverEvents(true); + Reset(); + UpdateRectangle(); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::~VGrainlineItem destructor + */ VGrainlineItem::~VGrainlineItem() {} //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::paint paints the item content + * @param pP pointer to the painter object + * @param pOption not used + * @param pWidget not used + */ void VGrainlineItem::paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption, QWidget* pWidget) { Q_UNUSED(pOption); Q_UNUSED(pWidget); + pP->save(); QColor clr = Qt::black; pP->setPen(QPen(clr, 3)); - QPointF pt1 = m_ptPos; - QPointF pt2 = pt1; + QPointF pt1 = pos(); + QPointF pt2; + + pt2.setX(pt1.x() + m_dLength * cos(m_dRotation)); + pt2.setY(pt1.y() + m_dLength * sin(m_dRotation)); pP->setRenderHints(QPainter::Antialiasing); - pt2.setX(pt2.x() + m_dLength * cos(m_dRotation)); - pt2.setY(pt2.y() + m_dLength * sin(m_dRotation)); pP->drawLine(pt1, pt2); QPolygonF poly; @@ -91,35 +111,178 @@ void VGrainlineItem::paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption { pP->setPen(QPen(clr, 2, Qt::DashLine)); pP->setBrush(Qt::NoBrush); - poly.clear(); - ptA.setX(pt1.x() + RECT_WIDTH*cos(m_dRotation + M_PI/2)); - ptA.setY(pt1.y() + RECT_WIDTH*sin(m_dRotation + M_PI/2)); - poly << ptA; - ptA.setX(pt1.x() + RECT_WIDTH*cos(m_dRotation - M_PI/2)); - ptA.setY(pt1.y() + RECT_WIDTH*sin(m_dRotation - M_PI/2)); - poly << ptA; - ptA.setX(pt2.x() + RECT_WIDTH*cos(m_dRotation - M_PI/2)); - ptA.setY(pt2.y() + RECT_WIDTH*sin(m_dRotation - M_PI/2)); - poly << ptA; - ptA.setX(pt2.x() + RECT_WIDTH*cos(m_dRotation + M_PI/2)); - ptA.setY(pt2.y() + RECT_WIDTH*sin(m_dRotation + M_PI/2)); - poly << ptA; - pP->drawPolygon(poly); + pP->drawPolygon(m_polyBound); } + pP->restore(); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::UpdateGeometry updates the item with grainline parameters + * @param ptPos position of one grainline's end + * @param dRotation rotation of the grainline in [degrees] + * @param dLength length of the grainline in user's units + */ void VGrainlineItem::UpdateGeometry(const QPointF& ptPos, qreal dRotation, qreal dLength) { - m_ptPos = ptPos; m_dRotation = qDegreesToRadians(dRotation); m_dLength = dLength; - m_eMode = mMove; - update(m_rectBoundingBox); + + setPos(ptPos); + UpdateRectangle(); + UpdateBox(); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::boundingRect returns the bounding rect around the grainline + * @return bounding rect + */ QRectF VGrainlineItem::boundingRect() const { return m_rectBoundingBox; } + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::Reset resets the item parameters. + */ +void VGrainlineItem::Reset() +{ + m_eMode = mNormal; + setZValue(INACTIVE_Z); + UpdateBox(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::IsIdle returns the idle flag. + * @return true, if item mode is normal and false otherwise. + */ +bool VGrainlineItem::IsIdle() const +{ + return m_eMode == mNormal; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::IsContained checks, if both ends of the grainline, starting at pt, are contained in + * parent widget. + * @param pt starting point of the grainline. + * @return true, if both ends of the grainline, starting at pt, are contained in the parent widget and + * false otherwise. + */ +bool VGrainlineItem::IsContained(const QPointF& pt) const +{ + QRectF rectParent = parentItem()->boundingRect(); + if (rectParent.contains(pt) == false) + { + qDebug() << "First point out" << pt << rectParent; + return false; + } + QPointF ptA; + ptA.setX(pt.x() + m_dLength * cos(m_dRotation)); + ptA.setY(pt.y() + m_dLength * sin(m_dRotation)); + if (rectParent.contains(ptA) == false) + { + qDebug() << "Second point out" << ptA << rectParent; + } + return (rectParent.contains(ptA)); +} +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::mousePressEvent handles left button mouse press events + * @param pME pointer to QGraphicsSceneMouseEvent object + */ +void VGrainlineItem::mousePressEvent(QGraphicsSceneMouseEvent* pME) +{ + if (pME->button() == Qt::LeftButton) + { + m_eMode = mMove; + setZValue(ACTIVE_Z); + m_ptStartPos = pos(); + m_ptStartMove = pME->scenePos(); + UpdateBox(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::mouseMoveEvent handles mouse move events, making sure that the item is moved properly + * @param pME pointer to QGraphicsSceneMouseEvent object + */ +void VGrainlineItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) +{ + if (m_eMode == mMove) + { + QPointF ptDiff = pME->scenePos() - m_ptStartMove; + QPointF pt = m_ptStartPos + ptDiff/2; + if (IsContained(pt) == true) + { + setPos(pt); + UpdateRectangle(); + UpdateBox(); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::mouseReleaseEvent handles mouse release events and emits the proper signal if the item was + * moved + * @param pME pointer to QGraphicsSceneMouseEvent object + */ +void VGrainlineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) +{ + if (pME->button() == Qt::LeftButton) + { + 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) + { + emit SignalMoved(pos()); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::UpdateBox updates the item + */ +void VGrainlineItem::UpdateBox() +{ + update(m_rectBoundingBox); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VGrainlineItem::UpdateRectangle updates the polygon for the box around active item + * and the bounding rectangle + */ +void VGrainlineItem::UpdateRectangle() +{ + m_polyBound.clear(); + QPointF pt1 = pos(); + QPointF pt2; + + pt2.setX(pt1.x() + m_dLength * cos(m_dRotation)); + pt2.setY(pt1.y() + m_dLength * sin(m_dRotation)); + + QPointF ptA; + ptA.setX(pt1.x() + RECT_WIDTH*cos(m_dRotation + M_PI/2)); + ptA.setY(pt1.y() + RECT_WIDTH*sin(m_dRotation + M_PI/2)); + m_polyBound << ptA; + ptA.setX(pt1.x() + RECT_WIDTH*cos(m_dRotation - M_PI/2)); + ptA.setY(pt1.y() + RECT_WIDTH*sin(m_dRotation - M_PI/2)); + m_polyBound << ptA; + ptA.setX(pt2.x() + RECT_WIDTH*cos(m_dRotation - M_PI/2)); + ptA.setY(pt2.y() + RECT_WIDTH*sin(m_dRotation - M_PI/2)); + m_polyBound << ptA; + ptA.setX(pt2.x() + RECT_WIDTH*cos(m_dRotation + M_PI/2)); + ptA.setY(pt2.y() + RECT_WIDTH*sin(m_dRotation + M_PI/2)); + m_polyBound << ptA; + m_rectBoundingBox = m_polyBound.boundingRect(); +} diff --git a/src/libs/vtools/tools/vgrainlineitem.h b/src/libs/vtools/tools/vgrainlineitem.h index 0f090d2a1..0ffa0c653 100644 --- a/src/libs/vtools/tools/vgrainlineitem.h +++ b/src/libs/vtools/tools/vgrainlineitem.h @@ -55,13 +55,28 @@ public: void UpdateGeometry(const QPointF& ptPos, qreal dRotation, qreal dLength); QRectF boundingRect() const; + void Reset(); + bool IsIdle() const; + bool IsContained(const QPointF &pt) const; + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent* pME); + void mouseMoveEvent(QGraphicsSceneMouseEvent* pME); + void mouseReleaseEvent(QGraphicsSceneMouseEvent* pME); + void UpdateBox(); + void UpdateRectangle(); + +signals: + void SignalMoved(const QPointF& ptPos); private: Mode m_eMode; - QPointF m_ptPos; qreal m_dRotation; qreal m_dLength; QRectF m_rectBoundingBox; + QPolygonF m_polyBound; + QPointF m_ptStartPos; + QPointF m_ptStartMove; }; #endif // VGRAINLINEITEM_H diff --git a/src/libs/vtools/tools/vtextgraphicsitem.cpp b/src/libs/vtools/tools/vtextgraphicsitem.cpp index 01b2c8775..bb73820c2 100644 --- a/src/libs/vtools/tools/vtextgraphicsitem.cpp +++ b/src/libs/vtools/tools/vtextgraphicsitem.cpp @@ -55,7 +55,8 @@ class VPatternPieceData; #define ROTATE_ARC 50 #define MIN_W 120 #define MIN_H 60 -#define TOP_Z 2 +#define INACTIVE_Z 2 +#define ACTIVE_Z 10 //--------------------------------------------------------------------------------------------------------------------- /** @@ -69,7 +70,7 @@ VTextGraphicsItem::VTextGraphicsItem(QGraphicsItem* pParent) { m_rectBoundingBox.setTopLeft(QPointF(0, 0)); SetSize(MIN_W, m_iMinH); - setZValue(TOP_Z); + setZValue(INACTIVE_Z); setAcceptHoverEvents(true); } @@ -173,7 +174,7 @@ void VTextGraphicsItem::Reset() m_eMode = mNormal; m_bReleased = false; Update(); - setZValue(TOP_Z); + setZValue(INACTIVE_Z); } //--------------------------------------------------------------------------------------------------------------------- @@ -399,7 +400,7 @@ void VTextGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *pME) SetOverrideCursor(cursorArrowCloseHand, 1, 1); } // raise the label and redraw it - setZValue(TOP_Z + 1); + setZValue(ACTIVE_Z); UpdateBox(); } } diff --git a/src/libs/vtools/tools/vtooldetail.cpp b/src/libs/vtools/tools/vtooldetail.cpp index 3f95a1ffc..8aae46e99 100644 --- a/src/libs/vtools/tools/vtooldetail.cpp +++ b/src/libs/vtools/tools/vtooldetail.cpp @@ -204,6 +204,8 @@ VToolDetail::VToolDetail(VAbstractPattern *doc, VContainer *data, const quint32 connect(patternInfo, &VTextGraphicsItem::SignalResized, this, &VToolDetail::SaveResizePattern); connect(patternInfo, &VTextGraphicsItem::SignalRotated, this, &VToolDetail::SaveRotationPattern); + connect(grainLine, &VGrainlineItem::SignalMoved, this, &VToolDetail::SaveMoveGrainline); + connect(doc, &VAbstractPattern::patternChanged, this, &VToolDetail::UpdatePatternInfo); connect(doc, &VAbstractPattern::CheckLayout, this, &VToolDetail::UpdateLabel); connect(doc, &VAbstractPattern::CheckLayout, this, &VToolDetail::UpdatePatternInfo); @@ -1038,6 +1040,20 @@ void VToolDetail::SaveRotationPattern(qreal dRot) } +//--------------------------------------------------------------------------------------------------------------------- +void VToolDetail::SaveMoveGrainline(const QPointF& ptPos) +{ + VDetail oldDet = VAbstractTool::data.GetDetail(id); + VDetail newDet = oldDet; + newDet.GetGrainlineGeometry().SetPos(ptPos); + qDebug() << "******* new grainline pos" << ptPos; + + SaveDetailOptions* moveCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); + moveCommand->setText(tr("move grainline")); + connect(moveCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(moveCommand); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief AddNode add node to the file. @@ -1198,6 +1214,11 @@ void VToolDetail::ResetChildren(QGraphicsItem *pItem) { patternInfo->Reset(); } + VGrainlineItem* pGLI = dynamic_cast(pItem); + if (pGLI != grainLine) + { + grainLine->Reset(); + } } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/tools/vtooldetail.h b/src/libs/vtools/tools/vtooldetail.h index e189f1589..0f2991406 100644 --- a/src/libs/vtools/tools/vtooldetail.h +++ b/src/libs/vtools/tools/vtooldetail.h @@ -127,6 +127,7 @@ protected slots: virtual void SaveMovePattern(const QPointF& ptPos); virtual void SaveResizePattern(qreal dLabelW, int iFontSize); virtual void SaveRotationPattern(qreal dRot); + virtual void SaveMoveGrainline(const QPointF& ptPos); private: Q_DISABLE_COPY(VToolDetail)