From 4374c6e475620b7a90effdf726db03c48438d22d Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 29 Sep 2017 10:58:45 +1000 Subject: [PATCH] Fix incorrect draw stacking when drawing rubber bands with secondary lines enabled --- python/gui/qgsrubberband.sip | 2 +- src/gui/qgsrubberband.cpp | 52 ++++++++++++++++++++++-------------- src/gui/qgsrubberband.h | 2 +- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/python/gui/qgsrubberband.sip b/python/gui/qgsrubberband.sip index 43e0cc33c26..aa498b13d55 100644 --- a/python/gui/qgsrubberband.sip +++ b/python/gui/qgsrubberband.sip @@ -275,7 +275,7 @@ for tracking the mouse while drawing polylines or polygons. \param p The QPainter object %End - void drawShape( QPainter *p, QVector &pts ); + void drawShape( QPainter *p, const QVector &pts ); %Docstring Draws shape of the rubber band. \param p The QPainter object diff --git a/src/gui/qgsrubberband.cpp b/src/gui/qgsrubberband.cpp index 3917d724737..43040b4cfb7 100644 --- a/src/gui/qgsrubberband.cpp +++ b/src/gui/qgsrubberband.cpp @@ -405,35 +405,47 @@ void QgsRubberBand::setToCanvasRectangle( QRect rect ) void QgsRubberBand::paint( QPainter *p ) { - if ( !mPoints.isEmpty() ) + if ( mPoints.isEmpty() ) + return; + + QVector< QVector > shapes; + for ( const QList &line : qgsAsConst( mPoints ) ) { - Q_FOREACH ( const QList &line, mPoints ) + QVector pts; + for ( const QgsPointXY &pt : line ) { - QVector pts; - Q_FOREACH ( const QgsPointXY &pt, line ) - { - const QPointF cur = toCanvasCoordinates( QgsPointXY( pt.x() + mTranslationOffsetX, pt.y() + mTranslationOffsetY ) ) - pos(); - if ( pts.empty() || std::abs( pts.back().x() - cur.x() ) > 1 || std::abs( pts.back().y() - cur.y() ) > 1 ) - pts.append( cur ); - } - - if ( mSecondaryPen.color().isValid() ) - { - mSecondaryPen.setWidth( mPen.width() + 2 ); - - p->setBrush( Qt::NoBrush ); - p->setPen( mSecondaryPen ); - drawShape( p, pts ); - } + const QPointF cur = toCanvasCoordinates( QgsPointXY( pt.x() + mTranslationOffsetX, pt.y() + mTranslationOffsetY ) ) - pos(); + if ( pts.empty() || std::abs( pts.back().x() - cur.x() ) > 1 || std::abs( pts.back().y() - cur.y() ) > 1 ) + pts.append( cur ); + } + shapes << pts; + } + int iterations = mSecondaryPen.color().isValid() ? 2 : 1; + for ( int i = 0; i < iterations; ++i ) + { + if ( i == 0 && iterations > 1 ) + { + // first iteration with multi-pen painting, so use secondary pen + mSecondaryPen.setWidth( mPen.width() + 2 ); + p->setBrush( Qt::NoBrush ); + p->setPen( mSecondaryPen ); + } + else + { + // "top" layer, use primary pen/brush p->setBrush( mBrush ); p->setPen( mPen ); - drawShape( p, pts ); + } + + for ( const QVector &shape : qgsAsConst( shapes ) ) + { + drawShape( p, shape ); } } } -void QgsRubberBand::drawShape( QPainter *p, QVector &pts ) +void QgsRubberBand::drawShape( QPainter *p, const QVector &pts ) { switch ( mGeometryType ) { diff --git a/src/gui/qgsrubberband.h b/src/gui/qgsrubberband.h index 555f28fb56a..383954e7921 100644 --- a/src/gui/qgsrubberband.h +++ b/src/gui/qgsrubberband.h @@ -310,7 +310,7 @@ class GUI_EXPORT QgsRubberBand: public QgsMapCanvasItem * \param p The QPainter object * \param pts A list of points used to draw the shape */ - void drawShape( QPainter *p, QVector &pts ); + void drawShape( QPainter *p, const QVector &pts ); //! Recalculates needed rectangle void updateRect();