Added comments to most important new classes

--HG--
branch : feature
This commit is contained in:
BojanKverh 2016-07-23 15:26:15 +02:00
parent b19f45e90a
commit a625c35616
9 changed files with 303 additions and 37 deletions

View file

@ -492,12 +492,21 @@ void VLayoutDetail::CreateTextItems()
// first add detail texts
if (d->detailLabel.count() > 0)
{
// get the mapped label vertices
QVector<QPointF> 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<QPointF> 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<QPointF> VLayoutDetail::Mirror(const QVector<QPointF> &points) const
{
// should only call this method with rectangular shapes
@ -683,6 +717,12 @@ QVector<QPointF> VLayoutDetail::Mirror(const QVector<QPointF> &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();

View file

@ -32,7 +32,8 @@
#include "vabstractdetail.h"
#include "../vpatterndb/vpatternpiecedata.h"
#include "../vpatterndb/vpatterninfogeometry.h"
#include "vtextmanager.h"
#include "../ifc/xml/vabstractpattern.h"
#include <QMatrix>
#include <QPointF>

View file

@ -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

View file

@ -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:

View file

@ -33,6 +33,9 @@
#include <QPointF>
/**
* @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;

View file

@ -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;

View file

@ -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() };

View file

@ -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

View file

@ -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());