Fix regression. Heavy method boundingRect() slows down the Details mode.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2017-08-01 12:57:19 +03:00
parent 6ca77f6721
commit 651d22e488
6 changed files with 56 additions and 66 deletions

View File

@ -86,31 +86,7 @@ QPainterPath VAbstractSpline::shape() const
SceneScale(scene())))); SceneScale(scene()))));
} }
path.setFillRule(Qt::WindingFill); path.setFillRule(Qt::WindingFill);
return ItemShapeFromPath(path, pen());
// We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
// if we pass a value of 0.0 to QPainterPathStroker::setWidth()
const qreal penWidthZero = qreal(0.00000001);
if (path == QPainterPath() || pen() == Qt::NoPen)
{
return path;
}
QPainterPathStroker ps;
ps.setCapStyle(pen().capStyle());
if (pen().widthF() <= 0.0)
{
ps.setWidth(penWidthZero);
}
else
{
ps.setWidth(pen().widthF());
}
ps.setJoinStyle(pen().joinStyle());
ps.setMiterLimit(pen().miterLimit());
QPainterPath p = ps.createStroke(path);
p.addPath(path);
return p;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -807,18 +807,14 @@ void VToolSeamAllowance::paint(QPainter *painter, const QStyleOptionGraphicsItem
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VToolSeamAllowance::boundingRect() const QRectF VToolSeamAllowance::boundingRect() const
{ {
VPiece detail; if (m_mainPathRect.isNull())
try
{ {
detail = VAbstractTool::data.GetPiece(id); return QGraphicsPathItem::boundingRect();
} }
catch(const VExceptionBadId &) else
{ {
return QRectF(); return m_mainPathRect;
} }
return detail.MainPathPath(this->getData()).boundingRect();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1114,6 +1110,8 @@ VToolSeamAllowance::VToolSeamAllowance(VAbstractPattern *doc, VContainer *data,
const QString &drawName, QGraphicsItem *parent) const QString &drawName, QGraphicsItem *parent)
: VInteractiveTool(doc, data, id), : VInteractiveTool(doc, data, id),
QGraphicsPathItem(parent), QGraphicsPathItem(parent),
m_mainPath(),
m_mainPathRect(),
m_sceneDetails(scene), m_sceneDetails(scene),
m_drawName(drawName), m_drawName(drawName),
m_seamAllowance(new VNoBrushScalePathItem(this)), m_seamAllowance(new VNoBrushScalePathItem(this)),
@ -1191,16 +1189,21 @@ void VToolSeamAllowance::RefreshGeometry()
this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false); this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false);
const VPiece detail = VAbstractTool::data.GetPiece(id); const VPiece detail = VAbstractTool::data.GetPiece(id);
QPainterPath path; QPainterPath path = detail.MainPathPath(this->getData());
if (not detail.IsHideMainPath() || not detail.IsSeamAllowance() || detail.IsSeamAllowanceBuiltIn()) if (not detail.IsHideMainPath() || not detail.IsSeamAllowance() || detail.IsSeamAllowanceBuiltIn())
{ {
m_mainPath = QPainterPath();
m_mainPathRect = QRectF();
m_seamAllowance->setBrush(QBrush(Qt::Dense7Pattern)); m_seamAllowance->setBrush(QBrush(Qt::Dense7Pattern));
path = detail.MainPathPath(this->getData());
} }
else else
{ {
m_seamAllowance->setBrush(QBrush(Qt::NoBrush)); // Disable if the main path was hidden m_seamAllowance->setBrush(QBrush(Qt::NoBrush)); // Disable if the main path was hidden
// need for returning a bounding rect when main path is not visible
m_mainPath = path;
m_mainPathRect = m_mainPath.controlPointRect();
path = QPainterPath();
} }
this->setPath(path); this->setPath(path);

View File

@ -91,12 +91,12 @@ public:
virtual int type() const Q_DECL_OVERRIDE {return Type;} virtual int type() const Q_DECL_OVERRIDE {return Type;}
enum { Type = UserType + static_cast<int>(Tool::Piece)}; enum { Type = UserType + static_cast<int>(Tool::Piece)};
virtual QString getTagName() const Q_DECL_OVERRIDE; virtual QString getTagName() const Q_DECL_OVERRIDE;
virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE; virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE;
virtual void GroupVisibility(quint32 object, bool visible) Q_DECL_OVERRIDE; virtual void GroupVisibility(quint32 object, bool visible) Q_DECL_OVERRIDE;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget) Q_DECL_OVERRIDE; QWidget *widget) Q_DECL_OVERRIDE;
virtual QRectF boundingRect() const Q_DECL_OVERRIDE; virtual QRectF boundingRect() const Q_DECL_OVERRIDE;
public slots: public slots:
virtual void FullUpdateFromFile () Q_DECL_OVERRIDE; virtual void FullUpdateFromFile () Q_DECL_OVERRIDE;
void EnableToolMove(bool move); void EnableToolMove(bool move);
@ -139,6 +139,9 @@ protected:
private: private:
Q_DISABLE_COPY(VToolSeamAllowance) Q_DISABLE_COPY(VToolSeamAllowance)
QPainterPath m_mainPath; // Must be first to prevent crash
QRectF m_mainPathRect;
/** @brief sceneDetails pointer to the scene. */ /** @brief sceneDetails pointer to the scene. */
VMainGraphicsScene *m_sceneDetails; VMainGraphicsScene *m_sceneDetails;
QString m_drawName; QString m_drawName;

View File

@ -104,3 +104,31 @@ qreal ScaleWidth(qreal width, qreal scale)
} }
return width; return width;
} }
//---------------------------------------------------------------------------------------------------------------------
QPainterPath ItemShapeFromPath(const QPainterPath &path, const QPen &pen)
{
// We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
// if we pass a value of 0.0 to QPainterPathStroker::setWidth()
const qreal penWidthZero = qreal(0.00000001);
if (path == QPainterPath() || pen == Qt::NoPen)
{
return path;
}
QPainterPathStroker ps;
ps.setCapStyle(pen.capStyle());
if (pen.widthF() <= 0.0)
{
ps.setWidth(penWidthZero);
}
else
{
ps.setWidth(pen.widthF());
}
ps.setJoinStyle(pen.joinStyle());
ps.setMiterLimit(pen.miterLimit());
QPainterPath p = ps.createStroke(path);
p.addPath(path);
return p;
}

View File

@ -41,6 +41,8 @@ class QGraphicsEllipseItem;
class QGraphicsLineItem; class QGraphicsLineItem;
class QColor; class QColor;
class QRectF; class QRectF;
class QPainterPath;
class QPen;
qreal SceneScale(QGraphicsScene *scene); qreal SceneScale(QGraphicsScene *scene);
@ -51,4 +53,6 @@ qreal ScaledRadius(qreal scale);
void ScaleCircleSize(QGraphicsEllipseItem *item, qreal scale); void ScaleCircleSize(QGraphicsEllipseItem *item, qreal scale);
qreal ScaleWidth(qreal width, qreal scale); qreal ScaleWidth(qreal width, qreal scale);
QPainterPath ItemShapeFromPath(const QPainterPath &path, const QPen &pen);
#endif // GLOBAL_H #endif // GLOBAL_H

View File

@ -66,31 +66,7 @@ QPainterPath VCurvePathItem::shape() const
itemPath.addPath(arrowsPath); itemPath.addPath(arrowsPath);
} }
itemPath.setFillRule(Qt::WindingFill); itemPath.setFillRule(Qt::WindingFill);
return ItemShapeFromPath(itemPath, pen());
// We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
// if we pass a value of 0.0 to QPainterPathStroker::setWidth()
const qreal penWidthZero = qreal(0.00000001);
if (itemPath == QPainterPath() || pen() == Qt::NoPen)
{
return itemPath;
}
QPainterPathStroker ps;
ps.setCapStyle(pen().capStyle());
if (pen().widthF() <= 0.0)
{
ps.setWidth(penWidthZero);
}
else
{
ps.setWidth(pen().widthF());
}
ps.setJoinStyle(pen().joinStyle());
ps.setMiterLimit(pen().miterLimit());
QPainterPath p = ps.createStroke(itemPath);
p.addPath(itemPath);
return p;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------