Index: src/core/qgsvectorlayer.cpp =================================================================== --- src/core/qgsvectorlayer.cpp (revision 13302) +++ src/core/qgsvectorlayer.cpp (working copy) @@ -706,15 +706,6 @@ mRendererV2->startRender( rendererContext, this ); - QgsSingleSymbolRendererV2* selRenderer = NULL; - if ( !mSelectedFeatureIds.isEmpty() ) - { - selRenderer = new QgsSingleSymbolRendererV2( QgsSymbolV2::defaultSymbol( geometryType() ) ); - selRenderer->symbol()->setColor( QgsRenderer::selectionColor() ); - selRenderer->setVertexMarkerAppearance( currentVertexMarkerType(), currentVertexMarkerSize() ); - selRenderer->startRender( rendererContext, this ); - } - #ifndef Q_WS_MAC int totalFeatures = pendingFeatureCount(); int featureCount = 0; @@ -748,10 +739,7 @@ bool drawMarker = ( mEditable && ( !vertexMarkerOnlyForSelection || sel ) ); // render feature - if ( sel ) - selRenderer->renderFeature( fet, rendererContext, -1, drawMarker ); - else - mRendererV2->renderFeature( fet, rendererContext, -1, drawMarker ); + mRendererV2->renderFeature( fet, rendererContext, -1, sel, drawMarker ); // labeling - register feature if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL ) @@ -772,8 +760,6 @@ ++featureCount; #endif //Q_WS_MAC } - - stopRendererV2( rendererContext, selRenderer ); } void QgsVectorLayer::drawRendererV2Levels( QgsRenderContext& rendererContext, bool labeling ) @@ -886,10 +872,7 @@ try { - if ( sel ) - selRenderer->renderFeature( *fit, rendererContext, -1, drawMarker ); - else - mRendererV2->renderFeature( *fit, rendererContext, layer, drawMarker ); + mRendererV2->renderFeature( *fit, rendererContext, layer, sel, drawMarker ); } catch ( const QgsCsException &cse ) { Index: src/core/symbology-ng/qgsfillsymbollayerv2.cpp =================================================================== --- src/core/symbology-ng/qgsfillsymbollayerv2.cpp (revision 13302) +++ src/core/symbology-ng/qgsfillsymbollayerv2.cpp (working copy) @@ -47,6 +47,10 @@ { mColor.setAlphaF( context.alpha() ); mBrush = QBrush( mColor, mBrushStyle ); + QColor selColor = selectionColor(); + // selColor.setAlphaF( context.alpha() ); + mSelBrush = QBrush( selColor ); + if( selectFillStyle ) mSelBrush.setStyle( mBrushStyle ); mBorderColor.setAlphaF( context.alpha() ); mPen = QPen( mBorderColor ); mPen.setStyle( mBorderStyle ); @@ -65,7 +69,7 @@ return; } - p->setBrush( mBrush ); + p->setBrush( context.selected() ? mSelBrush : mBrush ); p->setPen( mPen ); _renderPolygon( p, points, rings ); @@ -209,18 +213,25 @@ { return; } + p->setPen( QPen( Qt::NoPen ) ); + if( context.selected()) + { + QColor selColor = selectionColor(); + if( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() ); + p->setBrush( QBrush(selColor)); + _renderPolygon(p,points,rings); + } p->setBrush( mBrush ); - p->setPen( QPen( Qt::NoPen ) ); _renderPolygon( p, points, rings ); if ( mOutline ) { - mOutline->renderPolyline( points, context.renderContext() ); + mOutline->renderPolyline( points, context.renderContext(), -1, selectFillBorder && context.selected() ); if ( rings ) { QList::const_iterator ringIt = rings->constBegin(); for ( ; ringIt != rings->constEnd(); ++ringIt ) { - mOutline->renderPolyline( *ringIt, context.renderContext() ); + mOutline->renderPolyline( *ringIt, context.renderContext(), -1, selectFillBorder && context.selected() ); } } } Index: src/core/symbology-ng/qgsfillsymbollayerv2.h =================================================================== --- src/core/symbology-ng/qgsfillsymbollayerv2.h (revision 13302) +++ src/core/symbology-ng/qgsfillsymbollayerv2.h (working copy) @@ -54,6 +54,7 @@ protected: QBrush mBrush; + QBrush mSelBrush; Qt::BrushStyle mBrushStyle; QColor mBorderColor; Qt::PenStyle mBorderStyle; Index: src/core/symbology-ng/qgslinesymbollayerv2.cpp =================================================================== --- src/core/symbology-ng/qgslinesymbollayerv2.cpp (revision 13302) +++ src/core/symbology-ng/qgslinesymbollayerv2.cpp (working copy) @@ -83,6 +83,11 @@ } mPen.setJoinStyle( mPenJoinStyle ); mPen.setCapStyle( mPenCapStyle ); + + mSelPen = mPen; + QColor selColor = selectionColor(); + if( ! selectionIsOpaque ) selColor.setAlphaF(context.alpha()); + mSelPen.setColor(selColor); } void QgsSimpleLineSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context ) @@ -97,7 +102,7 @@ return; } - p->setPen( mPen ); + p->setPen( context.selected() ? mSelPen : mPen ); if ( mOffset == 0 ) { p->drawPolyline( points ); @@ -309,7 +314,7 @@ // draw first marker if ( first ) { - mMarker->renderPoint( lastPt, rc ); + mMarker->renderPoint( lastPt, rc, -1, context.selected() ); first = false; } @@ -319,7 +324,7 @@ // "c" is 1 for regular point or in interval (0,1] for begin of line segment lastPt += c * diff; lengthLeft -= painterUnitInterval; - mMarker->renderPoint( lastPt, rc ); + mMarker->renderPoint( lastPt, rc, -1, context.selected() ); c = 1; // reset c (if wasn't 1 already) } @@ -401,6 +406,9 @@ QColor penColor = mColor; penColor.setAlphaF( context.alpha() ); mPen.setColor( penColor ); + QColor selColor = selectionColor(); + if( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() ); + mSelPen.setColor(selColor); } void QgsLineDecorationSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context ) @@ -442,7 +450,7 @@ QPointF p2_1 = p2 - QPointF( size * cos( angle1 ), size * sin( angle1 ) ); QPointF p2_2 = p2 - QPointF( size * cos( angle2 ), size * sin( angle2 ) ); - p->setPen( mPen ); + p->setPen( context.selected() ? mSelPen : mPen ); p->drawLine( p2, p2_1 ); p->drawLine( p2, p2_2 ); } Index: src/core/symbology-ng/qgslinesymbollayerv2.h =================================================================== --- src/core/symbology-ng/qgslinesymbollayerv2.h (revision 13302) +++ src/core/symbology-ng/qgslinesymbollayerv2.h (working copy) @@ -64,6 +64,7 @@ Qt::PenJoinStyle mPenJoinStyle; Qt::PenCapStyle mPenCapStyle; QPen mPen; + QPen mSelPen; double mOffset; //use a custom dash dot pattern instead of the predefined ones bool mUseCustomDashPattern; @@ -159,6 +160,7 @@ protected: QPen mPen; + QPen mSelPen; }; Index: src/core/symbology-ng/qgsmarkersymbollayerv2.cpp =================================================================== --- src/core/symbology-ng/qgsmarkersymbollayerv2.cpp (revision 13302) +++ src/core/symbology-ng/qgsmarkersymbollayerv2.cpp (working copy) @@ -68,6 +68,10 @@ mBrush = QBrush( mColor ); mPen = QPen( mBorderColor ); mPen.setWidthF( context.outputLineWidth( mPen.widthF() ) ); + QColor selColor = selectionColor(); + mSelBrush = QBrush( selColor ); + mSelPen = QPen( selColor == mColor ? selColor : mBorderColor ); + mSelPen.setWidthF(mPen.widthF()); mPolygon.clear(); @@ -148,6 +152,9 @@ else { // some markers can't be drawn as a polygon (circle, cross) + // For these set the selected border color to the selected color + + if( mName != "circle" ) mSelPen.setColor(selColor); } // rotate if needed @@ -176,10 +183,40 @@ drawMarker( &p, context ); p.end(); + // Construct the selected version of the Cache + + mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied ); + mSelCache.fill( 0 ); + + p.begin( &mSelCache ); + p.setRenderHint( QPainter::Antialiasing ); + p.setBrush( mSelBrush ); + p.setPen( mSelPen ); + p.translate( QPointF( center, center ) ); + drawMarker( &p, context ); + p.end(); + + // Check that the selected version is different. If not, then re-render, + // filling the background with the selection colour and using the normal + // colours for the symbol .. could be ugly! + + if( mSelCache == mCache ) + { + p.begin( &mSelCache ); + p.setRenderHint( QPainter::Antialiasing ); + p.fillRect(0,0,imageSize,imageSize,selColor); + p.setBrush( mBrush ); + p.setPen( mPen ); + p.translate( QPointF( center, center ) ); + drawMarker( &p, context ); + p.end(); + } + //opacity if ( context.alpha() < 1.0 ) { QgsSymbolLayerV2Utils::multiplyImageOpacity( &mCache, context.alpha() ); + if( ! selectionIsOpaque ) QgsSymbolLayerV2Utils::multiplyImageOpacity( &mSelCache, context.alpha() ); } } @@ -203,11 +240,12 @@ //p->translate(point); //drawMarker(p); - //mCache.save("/home/marco/tmp/marker.png", "PNG"); - double s = mCache.width() / context.renderContext().rasterScaleFactor(); + //mCache.save("/home/marco/tmp/marker.png","PNG"); + QImage &img = context.selected() ? mSelCache : mCache; + double s = img.width() / context.renderContext().rasterScaleFactor(); p->drawImage( QRectF( point.x() - s / 2.0 + context.outputLineWidth( mOffset.x() ), point.y() - s / 2.0 + context.outputLineWidth( mOffset.y() ), - s, s ), mCache ); + s, s ), img ); //p->restore(); } @@ -328,6 +366,13 @@ QSvgRenderer renderer( mPath ); QPainter painter( &mPicture ); renderer.render( &painter, rect ); + double selPictureSize = pictureSize*1.2; + QPainter selPainter( &mSelPicture ); + selPainter.setRenderHint( QPainter::Antialiasing ); + selPainter.setBrush(QBrush(selectionColor())); + selPainter.setPen( Qt::NoPen ); + selPainter.drawEllipse(QPointF(0,0),pictureSize*0.6,pictureSize*0.6); + renderer.render(&selPainter,rect); } void QgsSvgMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context ) @@ -350,7 +395,8 @@ if ( mAngle != 0 ) p->rotate( mAngle ); - p->drawPicture( 0, 0, mPicture ); + QPicture &pct = context.selected() ? mSelPicture : mPicture; + p->drawPicture( 0, 0, pct ); if ( mAngle != 0 ) p->rotate( -mAngle ); @@ -529,7 +575,7 @@ void QgsFontMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ) { QPainter* p = context.renderContext().painter(); - QColor penColor = mColor; + QColor penColor = context.selected() ? selectionColor() : mColor; penColor.setAlphaF( context.alpha() ); p->setPen( penColor ); p->setFont( mFont ); Index: src/core/symbology-ng/qgsmarkersymbollayerv2.h =================================================================== --- src/core/symbology-ng/qgsmarkersymbollayerv2.h (revision 13302) +++ src/core/symbology-ng/qgsmarkersymbollayerv2.h (working copy) @@ -59,6 +59,9 @@ QPolygonF mPolygon; QString mName; QImage mCache; + QPen mSelPen; + QBrush mSelBrush; + QImage mSelCache; }; ////////// @@ -110,6 +113,7 @@ QString mPath; QPicture mPicture; + QPicture mSelPicture; }; Index: src/core/symbology-ng/qgsrendererv2.cpp =================================================================== --- src/core/symbology-ng/qgsrendererv2.cpp (revision 13302) +++ src/core/symbology-ng/qgsrendererv2.cpp (working copy) @@ -151,7 +151,7 @@ } -void QgsFeatureRendererV2::renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer, bool drawVertexMarker ) +void QgsFeatureRendererV2::renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer, bool selected, bool drawVertexMarker ) { QgsSymbolV2* symbol = symbolForFeature( feature ); if ( symbol == NULL ) @@ -172,7 +172,7 @@ } QPointF pt; _getPoint( pt, context, geom->asWkb() ); - (( QgsMarkerSymbolV2* )symbol )->renderPoint( pt, context, layer ); + (( QgsMarkerSymbolV2* )symbol )->renderPoint( pt, context, layer, selected ); //if ( drawVertexMarker ) // renderVertexMarker( pt, context ); @@ -189,7 +189,7 @@ } QPolygonF pts; _getLineString( pts, context, geom->asWkb() ); - (( QgsLineSymbolV2* )symbol )->renderPolyline( pts, context, layer ); + (( QgsLineSymbolV2* )symbol )->renderPolyline( pts, context, layer, selected ); if ( drawVertexMarker ) renderVertexMarkerPolyline( pts, context ); @@ -207,7 +207,7 @@ QPolygonF pts; QList holes; _getPolygon( pts, holes, context, geom->asWkb() ); - (( QgsFillSymbolV2* )symbol )->renderPolygon( pts, ( holes.count() ? &holes : NULL ), context, layer ); + (( QgsFillSymbolV2* )symbol )->renderPolygon( pts, ( holes.count() ? &holes : NULL ), context, layer, selected ); if ( drawVertexMarker ) renderVertexMarkerPolygon( pts, ( holes.count() ? &holes : NULL ), context ); @@ -231,7 +231,7 @@ for ( unsigned int i = 0; i < num; ++i ) { ptr = _getPoint( pt, context, ptr ); - (( QgsMarkerSymbolV2* )symbol )->renderPoint( pt, context, layer ); + (( QgsMarkerSymbolV2* )symbol )->renderPoint( pt, context, layer, selected ); //if ( drawVertexMarker ) // renderVertexMarker( pt, context ); @@ -256,7 +256,7 @@ for ( unsigned int i = 0; i < num; ++i ) { ptr = _getLineString( pts, context, ptr ); - (( QgsLineSymbolV2* )symbol )->renderPolyline( pts, context, layer ); + (( QgsLineSymbolV2* )symbol )->renderPolyline( pts, context, layer, selected ); if ( drawVertexMarker ) renderVertexMarkerPolyline( pts, context ); @@ -282,7 +282,7 @@ for ( unsigned int i = 0; i < num; ++i ) { ptr = _getPolygon( pts, holes, context, ptr ); - (( QgsFillSymbolV2* )symbol )->renderPolygon( pts, ( holes.count() ? &holes : NULL ), context, layer ); + (( QgsFillSymbolV2* )symbol )->renderPolygon( pts, ( holes.count() ? &holes : NULL ), context ); if ( drawVertexMarker ) renderVertexMarkerPolygon( pts, ( holes.count() ? &holes : NULL ), context ); Index: src/core/symbology-ng/qgsrendererv2.h =================================================================== --- src/core/symbology-ng/qgsrendererv2.h (revision 13302) +++ src/core/symbology-ng/qgsrendererv2.h (working copy) @@ -73,7 +73,7 @@ virtual QgsFeatureRendererV2* clone() = 0; - virtual void renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool drawVertexMarker = false ); + virtual void renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false ); //! for debugging virtual QString dump(); Index: src/core/symbology-ng/qgssymbollayerv2.cpp =================================================================== --- src/core/symbology-ng/qgssymbollayerv2.cpp (revision 13302) +++ src/core/symbology-ng/qgssymbollayerv2.cpp (working copy) @@ -1,6 +1,7 @@ #include "qgssymbollayerv2.h" +#include "qgsrenderer.h" #include "qgsrendercontext.h" #include @@ -10,6 +11,11 @@ +QColor QgsSymbolLayerV2::selectionColor() +{ + return QgsRenderer::selectionColor(); +} + QgsMarkerSymbolLayerV2::QgsMarkerSymbolLayerV2( bool locked ) : QgsSymbolLayerV2( QgsSymbolV2::Marker, locked ) { Index: src/core/symbology-ng/qgssymbollayerv2.h =================================================================== --- src/core/symbology-ng/qgssymbollayerv2.h (revision 13302) +++ src/core/symbology-ng/qgssymbollayerv2.h (working copy) @@ -18,7 +18,6 @@ class QgsSymbolV2; - class CORE_EXPORT QgsSymbolLayerV2 { public: @@ -53,6 +52,10 @@ void setRenderingPass( int renderingPass ) { mRenderingPass = renderingPass; } int renderingPass() const { return mRenderingPass; } + // Colour used for selections + + static QColor selectionColor(); + protected: QgsSymbolLayerV2( QgsSymbolV2::SymbolType type, bool locked = false ) : mType( type ), mLocked( locked ), mRenderingPass( 0 ) {} @@ -61,6 +64,12 @@ bool mLocked; QColor mColor; int mRenderingPass; + + // Configuration of selected symbology implementation + static const bool selectionIsOpaque = true; // Selection ignores symbol alpha + static const bool selectFillBorder = false; // Fill symbol layer also selects border symbology + static const bool selectFillStyle = false; // Fill symbol uses symbol layer style.. + }; ////////////////////// Index: src/core/symbology-ng/qgssymbolv2.cpp =================================================================== --- src/core/symbology-ng/qgssymbolv2.cpp (revision 13302) +++ src/core/symbology-ng/qgssymbolv2.cpp (working copy) @@ -244,8 +244,8 @@ //////////////////// -QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha ) - : mRenderContext( c ), mOutputUnit( u ), mAlpha( alpha ) +QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha, bool selected ) + : mRenderContext( c ), mOutputUnit( u ), mAlpha( alpha ), mSelected( selected ) { } @@ -338,9 +338,9 @@ return maxSize; } -void QgsMarkerSymbolV2::renderPoint( const QPointF& point, QgsRenderContext& context, int layer ) +void QgsMarkerSymbolV2::renderPoint( const QPointF& point, QgsRenderContext& context, int layer, bool selected ) { - QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha ); + QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected ); if ( layer != -1 ) { if ( layer >= 0 && layer < mLayers.count() ) @@ -407,9 +407,9 @@ return maxWidth; } -void QgsLineSymbolV2::renderPolyline( const QPolygonF& points, QgsRenderContext& context, int layer ) +void QgsLineSymbolV2::renderPolyline( const QPolygonF& points, QgsRenderContext& context, int layer, bool selected ) { - QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha ); + QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected ); if ( layer != -1 ) { if ( layer >= 0 && layer < mLayers.count() ) @@ -443,9 +443,9 @@ mLayers.append( new QgsSimpleFillSymbolLayerV2() ); } -void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList* rings, QgsRenderContext& context, int layer ) +void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList* rings, QgsRenderContext& context, int layer, bool selected ) { - QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha ); + QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected ); if ( layer != -1 ) { if ( layer >= 0 && layer < mLayers.count() ) Index: src/core/symbology-ng/qgssymbolv2.h =================================================================== --- src/core/symbology-ng/qgssymbolv2.h (revision 13302) +++ src/core/symbology-ng/qgssymbolv2.h (working copy) @@ -103,7 +103,7 @@ class CORE_EXPORT QgsSymbolV2RenderContext { public: - QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0 ); + QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0, bool selected = false ); ~QgsSymbolV2RenderContext(); QgsRenderContext& renderContext() { return mRenderContext; } @@ -115,6 +115,9 @@ qreal alpha() const { return mAlpha; } void setAlpha( qreal alpha ) { mAlpha = alpha; } + bool selected() const { return mSelected; } + void setSelected( bool selected ) { mSelected = selected; } + double outputLineWidth( double width ) const; double outputPixelSize( double size ) const; @@ -125,6 +128,7 @@ QgsRenderContext& mRenderContext; QgsSymbolV2::OutputUnit mOutputUnit; qreal mAlpha; + bool mSelected; }; @@ -144,7 +148,7 @@ void setSize( double size ); double size(); - void renderPoint( const QPointF& point, QgsRenderContext& context, int layer = -1 ); + void renderPoint( const QPointF& point, QgsRenderContext& context, int layer = -1, bool selected = false ); virtual QgsSymbolV2* clone() const; }; @@ -159,7 +163,7 @@ void setWidth( double width ); double width(); - void renderPolyline( const QPolygonF& points, QgsRenderContext& context, int layer = -1 ); + void renderPolyline( const QPolygonF& points, QgsRenderContext& context, int layer = -1, bool selected = false ); virtual QgsSymbolV2* clone() const; }; @@ -171,7 +175,7 @@ public: QgsFillSymbolV2( QgsSymbolLayerV2List layers = QgsSymbolLayerV2List() ); - void renderPolygon( const QPolygonF& points, QList* rings, QgsRenderContext& context, int layer = -1 ); + void renderPolygon( const QPolygonF& points, QList* rings, QgsRenderContext& context, int layer = -1, bool selected = false ); virtual QgsSymbolV2* clone() const; };