From a625c3561628e6f96db590c53765a1649c8778be Mon Sep 17 00:00:00 2001 From: BojanKverh Date: Sat, 23 Jul 2016 15:26:15 +0200 Subject: [PATCH] Added comments to most important new classes --HG-- branch : feature --- src/libs/vlayout/vlayoutdetail.cpp | 54 ++++++-- src/libs/vlayout/vlayoutdetail.h | 3 +- src/libs/vlayout/vtextmanager.cpp | 79 ++++++++++++ src/libs/vlayout/vtextmanager.h | 14 ++- src/libs/vpatterndb/vpatterninfogeometry.h | 21 +++- src/libs/vpatterndb/vpatternpiecedata.h | 26 ++-- src/libs/vtools/tools/vtextgraphicsitem.cpp | 130 +++++++++++++++++++- src/libs/vtools/tools/vtextgraphicsitem.h | 5 + src/libs/vtools/tools/vtooldetail.cpp | 8 +- 9 files changed, 303 insertions(+), 37 deletions(-) diff --git a/src/libs/vlayout/vlayoutdetail.cpp b/src/libs/vlayout/vlayoutdetail.cpp index bcd904037..aae990633 100644 --- a/src/libs/vlayout/vlayoutdetail.cpp +++ b/src/libs/vlayout/vlayoutdetail.cpp @@ -492,12 +492,21 @@ void VLayoutDetail::CreateTextItems() // first add detail texts if (d->detailLabel.count() > 0) { + // get the mapped label vertices QVector points = Map(Mirror(d->detailLabel)); + // append the first point to obtain the closed rectangle points.push_back(points.at(0)); + // calculate the angle of rotation qreal dAng = qAtan2(points.at(1).y() - points.at(0).y(), points.at(1).x() - points.at(0).x()); + // calculate the label width qreal dW = GetDistance(points.at(0), points.at(1)); qreal dY = 0; qreal dX; + // set up the rotation around top-left corner matrix + QMatrix mat; + mat.translate(points.at(0).x(), points.at(0).y()); + mat.rotate(qRadiansToDegrees(dAng)); + for (int i = 0; i < d->m_tmDetail.GetCount(); ++i) { const TextLine& tl = d->m_tmDetail.GetLine(i); @@ -506,11 +515,9 @@ void VLayoutDetail::CreateTextItems() fnt.setWeight(tl.m_eFontWeight); fnt.setStyle(tl.m_eStyle); dY += tl.m_iHeight; - QMatrix mat; - mat.translate(points.at(0).x(), points.at(0).y()); - mat.rotate(qRadiansToDegrees(dAng)); QFontMetrics fm(fnt); + // find the correct horizontal offset, depending on the alignment flag if ((tl.m_eAlign & Qt::AlignLeft) > 0) { dX = 0; @@ -523,6 +530,7 @@ void VLayoutDetail::CreateTextItems() { dX = dW - fm.width(tl.m_qsText); } + // create text path and add it to the list QPainterPath path; path.addText(dX, dY - (fm.height() - fm.ascent())/2, fnt, tl.m_qsText); d->m_liPP << mat.map(path); @@ -532,12 +540,17 @@ void VLayoutDetail::CreateTextItems() // and then add pattern texts if (d->patternInfo.count() > 0) { + // similar approach like for the detail label QVector points = Map(Mirror(d->patternInfo)); points.push_back(points.at(0)); qreal dAng = qAtan2(points.at(1).y() - points.at(0).y(), points.at(1).x() - points.at(0).x()); qreal dW = GetDistance(points.at(0), points.at(1)); qreal dY = 0; qreal dX; + QMatrix mat; + mat.translate(points.at(0).x(), points.at(0).y()); + mat.rotate(qRadiansToDegrees(dAng)); + for (int i = 0; i < d->m_tmPattern.GetCount(); ++i) { const TextLine& tl = d->m_tmPattern.GetLine(i); @@ -546,9 +559,6 @@ void VLayoutDetail::CreateTextItems() fnt.setWeight(tl.m_eFontWeight); fnt.setStyle(tl.m_eStyle); dY += tl.m_iHeight; - QMatrix mat; - mat.translate(points.at(0).x(), points.at(0).y()); - mat.rotate(qRadiansToDegrees(dAng)); QFontMetrics fm(fnt); if ((tl.m_eAlign & Qt::AlignLeft) > 0) @@ -578,6 +588,11 @@ int VLayoutDetail::GetTextItemsCount() const } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VLayoutDetail::GetTextItem Creates and returns the i-th text item + * @param i index of the requested item + * @return pointer to the newly created item. The caller is responsible to delete it. + */ QGraphicsItem* VLayoutDetail::GetTextItem(int i) const { QGraphicsPathItem* item = new QGraphicsPathItem(); @@ -600,12 +615,18 @@ QGraphicsItem* VLayoutDetail::GetTextItem(int i) const qreal dRot = qRadiansToDegrees(qAtan2(points.at(1).y() - points.at(0).y(), points.at(1).x() - points.at(0).x())); // we need to move the center back to the origin, rotate it to align it with x axis, - // then mirror it to obtain the proper text direction, rotate it and translate it back to original position + // then mirror it to obtain the proper text direction, rotate it and translate it back to original position. + // The operations must be added in reverse order QTransform t; + // move the label back to its original position t.translate(ptCenter.x(), ptCenter.y()); + // rotate the label back to original angle t.rotate(dRot); + // mirror the label horizontally t.scale(-1, 1); + // rotate the label to normal position t.rotate(-dRot); + // move the label center into origin t.translate(-ptCenter.x(), -ptCenter.y()); path = t.map(path); } @@ -653,6 +674,13 @@ void VLayoutDetail::SetMirror(bool value) } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VLayoutDetail::RotatePoint rotates a point around the center for given angle + * @param ptCenter center around which the point is rotated + * @param pt point, which is rotated around the center + * @param dAng angle of rotation + * @return position of point pt after rotating it around the center for dAng radians + */ QPointF VLayoutDetail::RotatePoint(const QPointF &ptCenter, const QPointF& pt, qreal dAng) const { QPointF ptDest; @@ -664,6 +692,12 @@ QPointF VLayoutDetail::RotatePoint(const QPointF &ptCenter, const QPointF& pt, q } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VLayoutDetail::Mirror if the detail layout is rotated, this method will flip the + * label points over vertical axis, which goes through the center of the label + * @param list of 4 label vertices + * @return list of flipped points + */ QVector VLayoutDetail::Mirror(const QVector &points) const { // should only call this method with rectangular shapes @@ -683,6 +717,12 @@ QVector VLayoutDetail::Mirror(const QVector &points) const } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VLayoutDetail::GetDistance calculates the Euclidian distance between the points + * @param pt1 first point + * @param pt2 second point + * @return Euclidian distance between the two points + */ qreal VLayoutDetail::GetDistance(const QPointF &pt1, const QPointF &pt2) const { qreal dX = pt1.x() - pt2.x(); diff --git a/src/libs/vlayout/vlayoutdetail.h b/src/libs/vlayout/vlayoutdetail.h index e90e1b0c4..56cb5aff0 100644 --- a/src/libs/vlayout/vlayoutdetail.h +++ b/src/libs/vlayout/vlayoutdetail.h @@ -32,7 +32,8 @@ #include "vabstractdetail.h" #include "../vpatterndb/vpatternpiecedata.h" #include "../vpatterndb/vpatterninfogeometry.h" -#include "vtextmanager.h" +#include "../ifc/xml/vabstractpattern.h" + #include #include diff --git a/src/libs/vlayout/vtextmanager.cpp b/src/libs/vlayout/vtextmanager.cpp index 0cadb02e4..9a996b16c 100644 --- a/src/libs/vlayout/vtextmanager.cpp +++ b/src/libs/vlayout/vtextmanager.cpp @@ -4,75 +4,128 @@ #include "vtextmanager.h" //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief TextLine::TextLine default constructor + */ TextLine::TextLine() :m_qsText(), m_iFontSize(MIN_FONT_SIZE), m_eFontWeight(QFont::Normal), m_eStyle(QFont::StyleNormal), m_eAlign(Qt::AlignCenter), m_iHeight(0) {} //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::VTextManager constructor + */ VTextManager::VTextManager() :m_font(), m_liLines(), m_liOutput() {} //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::~VTextManager destructor + */ VTextManager::~VTextManager() {} //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::GetSpacing returns the vertical spacing between the lines + * @return + */ int VTextManager::GetSpacing() const { return 2; } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::SetFont set the text base font + * @param font text base font + */ void VTextManager::SetFont(const QFont& font) { m_font = font; } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::GetFont returns the text base font + * @return text base font + */ const QFont& VTextManager::GetFont() const { return m_font; } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::SetFontSize sets the font size + * @param iFS font size in pixels + */ void VTextManager::SetFontSize(int iFS) { m_font.setPixelSize(iFS); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::AddLine add new text line to the list + * @param tl text line object to be added + */ void VTextManager::AddLine(const TextLine& tl) { m_liLines << tl; } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::Clear deletes the list of texts + */ void VTextManager::Clear() { m_liLines.clear(); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::GetCount returns the number of output text lines + * @return number of output text lines + */ int VTextManager::GetCount() const { return m_liOutput.count(); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::GetSourceLineCount returns the number of input text lines + * @return number of text lines that were added to the list by calling AddLine + */ int VTextManager::GetSourceLineCount() const { return m_liLines.count(); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::GetLine returns the i-th output text line + * @param i index of the output text line + * @return i-th output text line + */ const TextLine& VTextManager::GetLine(int i) const { return m_liOutput[i]; } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::IsBigEnough Checks if rectangle of size (fW, fH) is big enough to hold the text with base font + * size iFontSize + * @param fW rectangle width + * @param fH rectangle height + * @param iFontSize base font size + * @return true, if rectangle of size (fW, fH) + */ bool VTextManager::IsBigEnough(qreal fW, qreal fH, int iFontSize) { m_liOutput.clear(); @@ -97,6 +150,12 @@ bool VTextManager::IsBigEnough(qreal fW, qreal fH, int iFontSize) } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::FitFontSize sets the font size just big enough, so that the text fits into rectangle of + * size (fW, fH) + * @param fW rectangle width + * @param fH rectangle height + */ void VTextManager::FitFontSize(qreal fW, qreal fH) { int iFontSize = GetFont().pixelSize(); @@ -112,6 +171,11 @@ void VTextManager::FitFontSize(qreal fW, qreal fH) } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::Update updates the text lines with detail data + * @param qsName detail name + * @param data reference to the detail data + */ void VTextManager::Update(const QString& qsName, const VPatternPieceData& data) { Clear(); @@ -155,6 +219,10 @@ void VTextManager::Update(const QString& qsName, const VPatternPieceData& data) } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::Update updates the text lines with pattern info + * @param pDoc pointer to the abstract pattern object + */ void VTextManager::Update(const VAbstractPattern *pDoc) { Clear(); @@ -225,9 +293,17 @@ void VTextManager::Update(const VAbstractPattern *pDoc) } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::SplitString splits the string into several lines, which all fit into width fW + * @param qs string to split + * @param fW required width of every output string + * @param fm font metrics of the font used + * @return list of strings, each of which is not wider than fW using the font metrics fm + */ QStringList VTextManager::SplitString(const QString &qs, qreal fW, const QFontMetrics &fm) { QRegularExpression reg("\\s+"); + // split the string into words QStringList qslWords = qs.split(reg); QStringList qslLines; QString qsCurrent; @@ -237,9 +313,12 @@ QStringList VTextManager::SplitString(const QString &qs, qreal fW, const QFontMe { qsCurrent += QLatin1Literal(" "); } + // check if another word can be added into current line if (fm.width(qsCurrent + qslWords[i]) > fW) { + // if not, add the current line into the list of text lines qslLines << qsCurrent; + // and set the current line to contain the current word qsCurrent = qslWords[i]; } else diff --git a/src/libs/vlayout/vtextmanager.h b/src/libs/vlayout/vtextmanager.h index e3bc52f47..1fa5a48de 100644 --- a/src/libs/vlayout/vtextmanager.h +++ b/src/libs/vlayout/vtextmanager.h @@ -11,6 +11,9 @@ #define MIN_FONT_SIZE 12 #define MAX_FONT_SIZE 128 +/** + * @brief The TextLine struct holds the information about one text line + */ struct TextLine { QString m_qsText; @@ -23,13 +26,17 @@ struct TextLine TextLine(); }; +/** + * @brief The VTextManager class this class is used to determine whether a collection of + * text lines can fit into specified bounding box and with what font size + */ class VTextManager { public: VTextManager(); ~VTextManager(); - int GetSpacing() const; + virtual int GetSpacing() const; void SetFont(const QFont& font); const QFont& GetFont() const; void SetFontSize(int iFS); @@ -40,12 +47,7 @@ public: const TextLine& GetLine(int i) const; bool IsBigEnough(qreal fW, qreal fH, int iFontSize); void FitFontSize(qreal fW, qreal fH); - /** @brief Update(const QString& qsName, const VPatternPieceData& data) - * Updates the manager with detail name and detail data - */ void Update(const QString& qsName, const VPatternPieceData& data); - /** @brief Update(const VAbstractPattern* pDoc) updates the manager with pattern data - */ void Update(const VAbstractPattern* pDoc); protected: diff --git a/src/libs/vpatterndb/vpatterninfogeometry.h b/src/libs/vpatterndb/vpatterninfogeometry.h index 0f9ff5cfd..6bb562fa1 100644 --- a/src/libs/vpatterndb/vpatterninfogeometry.h +++ b/src/libs/vpatterndb/vpatterninfogeometry.h @@ -33,6 +33,9 @@ #include +/** + * @brief The VPatternInfoGeometry class holds the information about pattern info label geometry + */ class VPatternInfoGeometry { public: @@ -54,20 +57,28 @@ public: void SetVisible(bool bVal); private: + /** + * @brief m_ptPos position of label's top left corner + */ QPointF m_ptPos; - /** @brief Label width + /** + * @brief m_dLabelWidth label width */ qreal m_dLabelWidth; - /** @brief Label height + /** + * @brief m_dLabelHeight label height */ qreal m_dLabelHeight; - /** @brief Label font size + /** + * @brief m_iFontSize label text base font size */ int m_iFontSize; - /** @brief Label rotation + /** + * @brief m_dRotation Label rotation */ qreal m_dRotation; - /** @brief Visibility flag + /** + * @brief m_bVisible visibility flag */ bool m_bVisible; diff --git a/src/libs/vpatterndb/vpatternpiecedata.h b/src/libs/vpatterndb/vpatternpiecedata.h index 65051a09d..0852b5724 100644 --- a/src/libs/vpatterndb/vpatternpiecedata.h +++ b/src/libs/vpatterndb/vpatternpiecedata.h @@ -51,7 +51,7 @@ enum class PlacementType : char }; /** - * @brief This structure holds a material, cut number and placement 3-tuple + * @brief The MaterialCutPlacement struct used to hold a material, cut number and placement 3-tuple */ struct MaterialCutPlacement { @@ -103,28 +103,36 @@ public: void SetVisible(bool bVal); private: - /** @brief Pattern piece letter (should be no more than 3 letters) + /** + * @brief m_qsLetter Detail letter (should be no more than 3 characters) */ QString m_qsLetter; - /** @brief List of material, cut number and placement 3-tuples + /** + * @brief m_conMCP List of material, cut, placement tuples */ MCPContainer m_conMCP; - /** @brief Location of the label + /** + * @brief m_ptPos position of label's top left corner */ QPointF m_ptPos; - /** @brief Label width + /** + * @brief m_dLabelWidth label width */ qreal m_dLabelWidth; - /** @brief Label height + /** + * @brief m_dLabelHeight label height */ qreal m_dLabelHeight; - /** @brief Label font size + /** + * @brief m_iFontSize label font size */ int m_iFontSize; - /** @brief Label rotation + /** + * @brief m_dRotation label rotation */ qreal m_dRotation; - /** @brief Visibility flag + /** + * @brief m_bVisible visibility flag */ bool m_bVisible; diff --git a/src/libs/vtools/tools/vtextgraphicsitem.cpp b/src/libs/vtools/tools/vtextgraphicsitem.cpp index 06d7af6b6..06d1649fc 100644 --- a/src/libs/vtools/tools/vtextgraphicsitem.cpp +++ b/src/libs/vtools/tools/vtextgraphicsitem.cpp @@ -47,6 +47,10 @@ #define TOP_Z 2 //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::VTextGraphicsItem constructor + * @param pParent pointer to the parent item + */ VTextGraphicsItem::VTextGraphicsItem(QGraphicsItem* pParent) :QGraphicsObject(pParent), m_eMode(VTextGraphicsItem::mNormal), m_bReleased(false), m_ptStartPos(), m_ptStart(), m_ptRotCenter(), m_szStart(), m_dRotation(0), m_dAngle(0), @@ -58,21 +62,34 @@ VTextGraphicsItem::VTextGraphicsItem(QGraphicsItem* pParent) } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::~VTextGraphicsItem destructor + */ VTextGraphicsItem::~VTextGraphicsItem() {} //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::SetFont sets the item font + * @param fnt font to be used in item + */ void VTextGraphicsItem::SetFont(const QFont& fnt) { m_tm.SetFont(fnt); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::paint redraws the item content + * @param painter pointer to the QPainter in use + * @param option pointer to the object containing the actual label rectangle + * @param widget not used + */ void VTextGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(widget); painter->fillRect(option->rect, QColor(251, 251, 175)); - painter->setRenderHints(QPainter::Antialiasing); + painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); // draw text lines int iY = 0; @@ -91,26 +108,30 @@ void VTextGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem iY += iH + m_tm.GetSpacing(); } - + // now draw the features specific to non-normal modes if (m_eMode != mNormal) { + // outline the rectangle painter->setPen(QPen(Qt::black, 2, Qt::DashLine)); painter->drawRect(boundingRect().adjusted(1, 1, -1, -1)); if (m_eMode != mRotate) { + // draw the resize square painter->setPen(Qt::black); painter->setBrush(Qt::black); painter->drawRect(m_rectResize); if (m_eMode == mResize) { + // draw the resize diagonal lines painter->drawLine(0, 0, qRound(m_rectBoundingBox.width()), qRound(m_rectBoundingBox.height())); painter->drawLine(0, qRound(m_rectBoundingBox.height()), qRound(m_rectBoundingBox.width()), 0); } } else { + // in rotate mode, draw the circle in the middle painter->setPen(Qt::black); painter->setBrush(Qt::black); painter->drawEllipse( @@ -120,6 +141,7 @@ void VTextGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem ); painter->setPen(QPen(Qt::black, 3)); painter->setBrush(Qt::NoBrush); + // and then draw the arc in each of the corners int iTop = ROTATE_RECT - ROTATE_ARC; int iLeft = ROTATE_RECT - ROTATE_ARC; int iRight = qRound(m_rectBoundingBox.width()) - ROTATE_RECT; @@ -133,6 +155,9 @@ void VTextGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::Reset resets the item, putting the mode and z coordinate to normal and redraws it + */ void VTextGraphicsItem::Reset() { m_eMode = mNormal; @@ -142,6 +167,11 @@ void VTextGraphicsItem::Reset() } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::AddLine adds a line of text to the label list. If necessary, it also resizes the + * label bounding box until it is big enough to contain all the text + * @param tl line of text to add + */ void VTextGraphicsItem::AddLine(const TextLine& tl) { m_tm.AddLine(tl); @@ -156,12 +186,21 @@ void VTextGraphicsItem::AddLine(const TextLine& tl) } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::Clear deletes all the label texts + */ void VTextGraphicsItem::Clear() { m_tm.Clear(); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::SetSize Tries to set the label size to (fW, fH). If any of those is too small, the label + * size does not change. + * @param fW label width + * @param fH label height + */ void VTextGraphicsItem::SetSize(qreal fW, qreal fH) { // don't allow resize under specific size @@ -181,6 +220,9 @@ void VTextGraphicsItem::SetSize(qreal fW, qreal fH) } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::Update sets the correct font size and redraws the label + */ void VTextGraphicsItem::Update() { UpdateFont(); @@ -188,6 +230,16 @@ void VTextGraphicsItem::Update() } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::IsContained checks if the bounding box around rotated rectBB is contained in + * the parent. If that is not the case, it calculates the amount of movement needed to put it inside the parent + * and write it into dX, dY + * @param rectBB bounding box in question + * @param dRot bounding box rotation in degrees + * @param dX horizontal translation needed to put the box inside parent item + * @param dY vertical translation needed to put the box inside parent item + * @return true, if rectBB is contained in parent item and false otherwise + */ bool VTextGraphicsItem::IsContained(QRectF rectBB, qreal dRot, qreal &dX, qreal &dY) const { QRectF rectParent = parentItem()->boundingRect(); @@ -221,42 +273,68 @@ bool VTextGraphicsItem::IsContained(QRectF rectBB, qreal dRot, qreal &dX, qreal } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::UpdateData Updates the detail label + * @param qsName name of detail + * @param data reference to VPatternPieceData + */ void VTextGraphicsItem::UpdateData(const QString &qsName, const VPatternPieceData &data) { m_tm.Update(qsName, data); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::UpdateData Updates the pattern label + * @param pDoc pointer to the pattern object + */ void VTextGraphicsItem::UpdateData(const VAbstractPattern* pDoc) { m_tm.Update(pDoc); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::GetFontSize returns the currently used text base font size + * @return current text base font size + */ int VTextGraphicsItem::GetFontSize() const { return m_tm.GetFont().pixelSize(); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::boundingRect returns the label bounding box + * @return label bounding box + */ QRectF VTextGraphicsItem::boundingRect() const { return m_rectBoundingBox; } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::mousePressEvent handles left button mouse press events + * @param pME pointer to QGraphicsSceneMouseEvent object + */ void VTextGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *pME) { if (pME->button() == Qt::LeftButton) { + // record the parameters of the mouse press. Specially record the position + // of the press as the origin for the following operations m_ptStartPos = pos(); m_ptStart = pME->scenePos(); m_szStart = m_rectBoundingBox.size(); m_ptRotCenter = mapToScene(m_rectBoundingBox.center()); m_dAngle = GetAngle(pME->scenePos()); m_dRotation = rotation(); + // in rotation mode, do not do any changes here, because user might want to + // rotate the label more. if (m_eMode != mRotate) { + // if user pressed the button inside the resize square, switch to resize mode if (m_rectResize.contains(pME->pos()) == true) { m_eMode = mResize; @@ -264,16 +342,22 @@ void VTextGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *pME) } else { + // if user pressed the button outside the resize square, switch to move mode m_eMode = mMove; SetOverrideCursor(cursorArrowCloseHand, 1, 1); } } + // raise the label and redraw it setZValue(TOP_Z + 1); UpdateBox(); } } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::mouseMoveEvent handles mouse move events + * @param pME pointer to QGraphicsSceneMouseEvent object + */ void VTextGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) { qreal dX; @@ -282,10 +366,12 @@ void VTextGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) QPointF ptDiff = pME->scenePos() - m_ptStart; if (m_eMode == mMove) { + // in move mode move the label along the mouse move from the origin QPointF pt = m_ptStartPos + ptDiff; rectBB.setTopLeft(pt); rectBB.setWidth(m_rectBoundingBox.width()); rectBB.setHeight(m_rectBoundingBox.height()); + // before moving label to a new position, check if it will still be inside the parent item if (IsContained(rectBB, rotation(), dX, dY) == false) { pt.setX(pt.x() + dX); @@ -296,10 +382,12 @@ void VTextGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) } else if (m_eMode == mResize) { + // in resize mode, resize the label along the mouse move from the origin QPointF pt = m_ptStartPos; rectBB.setTopLeft(pt); QSizeF sz(m_szStart.width() + ptDiff.x(), m_szStart.height() + ptDiff.y()); rectBB.setSize(sz); + // before resizing the label to a new size, check if it will still be inside the parent item if (IsContained(rectBB, rotation(), dX, dY) == true) { SetSize(sz.width(), sz.height()); @@ -309,15 +397,19 @@ void VTextGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) } else if (m_eMode == mRotate) { + // if the angle from the original position is small (0.5 degrees), just remeber the new angle + // new angle will be the starting angle for rotation if (fabs(m_dAngle) < 0.01) { m_dAngle = GetAngle(pME->scenePos()); return; } - double dAng = qRadiansToDegrees(GetAngle(pME->scenePos()) - m_dAngle); + // calculate the angle difference from the starting angle + double dAng = qRadiansToDegrees(GetAngle(pME->scenePos()) - m_dAngle); rectBB.setTopLeft(m_ptStartPos); rectBB.setWidth(m_rectBoundingBox.width()); rectBB.setHeight(m_rectBoundingBox.height()); + // check if the rotated label will be inside the parent item and then rotate it if (IsContained(rectBB, m_dRotation + dAng, dX, dY) == true) { setRotation(m_dRotation + dAng); @@ -327,10 +419,15 @@ void VTextGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::mouseReleaseEvent handles left button mouse release events + * @param pME pointer to QGraphicsSceneMouseEvent object + */ void VTextGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) { if (pME->button() == Qt::LeftButton) { + // restore the cursor if (m_eMode == mMove) { RestoreOverrideCursor(cursorArrowCloseHand); @@ -340,10 +437,12 @@ void VTextGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) RestoreOverrideCursor(Qt::SizeFDiagCursor); } double dDist = fabs(pME->scenePos().x() - m_ptStart.x()) + fabs(pME->scenePos().y() - m_ptStart.y()); + // determine if this was just press/release (bShort == true) or user did some operation between press and release bool bShort = (dDist < 2); if (m_eMode == mMove || m_eMode == mResize) - { // when released in mMove or mResize mode + { // if user just pressed and released the button, we must switch the mode to rotate + // but if user did some operation (move/resize), emit the proper signal and update the label if (bShort == true) { if (m_bReleased == true) @@ -364,7 +463,7 @@ void VTextGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) } } else - { // when released in mRotate mode + { // in rotate mode, if user did just press/release, switch to move mode if (bShort == true) { m_eMode = mMove; @@ -372,6 +471,7 @@ void VTextGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) } else { + // if user rotated the item, emit proper signal and update the label emit SignalRotated(rotation()); UpdateBox(); } @@ -381,12 +481,19 @@ void VTextGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::UpdateBox redraws the label content + */ void VTextGraphicsItem::UpdateBox() { update(m_rectBoundingBox); } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::UpdateFont sets the text font size, so that the entire text will + * just fit into the label bounding box + */ void VTextGraphicsItem::UpdateFont() { int iFS = m_tm.GetFont().pixelSize(); @@ -406,6 +513,12 @@ void VTextGraphicsItem::UpdateFont() } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::GetAngle calculates the angle between the line, which goes from + * rotation center to pt and x axis + * @param pt point of interest + * @return the angle between line from rotation center and point of interest and x axis + */ double VTextGraphicsItem::GetAngle(QPointF pt) const { double dX = pt.x() - m_ptRotCenter.x(); @@ -422,6 +535,13 @@ double VTextGraphicsItem::GetAngle(QPointF pt) const } //--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::GetBoundingRect calculates the bounding box + * around rectBB rectangle, rotated around its center by dRot degrees + * @param rectBB rectangle of interest + * @param dRot rectangle rotation + * @return bounding box around rectBB rotated by dRot + */ QRectF VTextGraphicsItem::GetBoundingRect(QRectF rectBB, qreal dRot) const { QPointF apt[4] = { rectBB.topLeft(), rectBB.topRight(), rectBB.bottomLeft(), rectBB.bottomRight() }; diff --git a/src/libs/vtools/tools/vtextgraphicsitem.h b/src/libs/vtools/tools/vtextgraphicsitem.h index 14a585d9a..0b1275894 100644 --- a/src/libs/vtools/tools/vtextgraphicsitem.h +++ b/src/libs/vtools/tools/vtextgraphicsitem.h @@ -35,6 +35,11 @@ #include "../vlayout/vtextmanager.h" +/** + * @brief The VTextGraphicsItem class. This class implements text graphics item, + * which can be dragged around, resized and rotated within the parent item. The text font + * size will be automatically updated, so that the entire text will fit into the item. + */ class VTextGraphicsItem : public QGraphicsObject { Q_OBJECT diff --git a/src/libs/vtools/tools/vtooldetail.cpp b/src/libs/vtools/tools/vtooldetail.cpp index c73425416..bfbe238df 100644 --- a/src/libs/vtools/tools/vtooldetail.cpp +++ b/src/libs/vtools/tools/vtooldetail.cpp @@ -351,7 +351,7 @@ void VToolDetail::AddToFile() QDomElement domData = doc->createElement(VAbstractPattern::TagData); const VPatternPieceData& data = detail.GetPatternPieceData(); doc->SetAttribute(domData, VAbstractPattern::AttrLetter, data.GetLetter()); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? 1:0); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); doc->SetAttribute(domData, AttrMx, data.GetPos().x()); doc->SetAttribute(domData, AttrMy, data.GetPos().y()); doc->SetAttribute(domData, AttrWidth, data.GetLabelWidth()); @@ -373,7 +373,7 @@ void VToolDetail::AddToFile() domData = doc->createElement(VAbstractPattern::TagPatternInfo); const VPatternInfoGeometry& geom = detail.GetPatternInfo(); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, geom.IsVisible() == true? 1:0); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, geom.IsVisible() == true? trueStr : falseStr); doc->SetAttribute(domData, AttrMx, geom.GetPos().x()); doc->SetAttribute(domData, AttrMy, geom.GetPos().y()); doc->SetAttribute(domData, AttrWidth, geom.GetLabelWidth()); @@ -410,7 +410,7 @@ void VToolDetail::RefreshDataInFile() QDomElement domData = doc->createElement(VAbstractPattern::TagData); const VPatternPieceData& data = det.GetPatternPieceData(); doc->SetAttribute(domData, VAbstractPattern::AttrLetter, data.GetLetter()); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? 1:0); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); doc->SetAttribute(domData, AttrMx, data.GetPos().x()); doc->SetAttribute(domData, AttrMy, data.GetPos().y()); doc->SetAttribute(domData, AttrWidth, data.GetLabelWidth()); @@ -432,7 +432,7 @@ void VToolDetail::RefreshDataInFile() domData = doc->createElement(VAbstractPattern::TagPatternInfo); const VPatternInfoGeometry& geom = det.GetPatternInfo(); - doc->SetAttribute(domData, VAbstractPattern::AttrVisible, geom.IsVisible() == true? 1:0); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, geom.IsVisible() == true? trueStr : falseStr); doc->SetAttribute(domData, AttrMx, geom.GetPos().x()); doc->SetAttribute(domData, AttrMy, geom.GetPos().y()); doc->SetAttribute(domData, AttrWidth, geom.GetLabelWidth());