Skip to content

Commit

Permalink
Minor refactor of QgsPointMarkerItem
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Dec 10, 2019
1 parent 6ee4907 commit e0fb896
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 55 deletions.
2 changes: 1 addition & 1 deletion src/app/qgsmaptooloffsetpointsymbol.cpp
Expand Up @@ -176,7 +176,7 @@ void QgsMapToolOffsetPointSymbol::createPreviewItem( QgsMarkerSymbol *markerSymb

mOffsetItem = new QgsPointMarkerItem( mCanvas );
mOffsetItem->setOpacity( 0.7 );
mOffsetItem->setSymbol( markerSymbol->clone() );
mOffsetItem->setSymbol( std::unique_ptr< QgsSymbol >( markerSymbol->clone() ) );
}

QMap<int, QVariant> QgsMapToolOffsetPointSymbol::calculateNewOffsetAttributes( const QgsPointXY &startPoint, const QgsPointXY &endPoint ) const
Expand Down
69 changes: 48 additions & 21 deletions src/app/qgspointmarkeritem.cpp
Expand Up @@ -22,14 +22,19 @@
#include <QPainter>
#include <cmath>

QgsPointMarkerItem::QgsPointMarkerItem( QgsMapCanvas *canvas )

//
// QgsMapCanvasSymbolItem
//

QgsMapCanvasSymbolItem::QgsMapCanvasSymbolItem( QgsMapCanvas *canvas )
: QgsMapCanvasItem( canvas )
, mOpacityEffect( new QgsDrawSourceEffect() )
{
setCacheMode( QGraphicsItem::ItemCoordinateCache );
}

QgsRenderContext QgsPointMarkerItem::renderContext( QPainter *painter )
QgsRenderContext QgsMapCanvasSymbolItem::renderContext( QPainter *painter )
{
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
Expand All @@ -56,7 +61,7 @@ QgsRenderContext QgsPointMarkerItem::renderContext( QPainter *painter )
return rc;
}

void QgsPointMarkerItem::paint( QPainter *painter )
void QgsMapCanvasSymbolItem::paint( QPainter *painter )
{
if ( !painter )
{
Expand All @@ -73,56 +78,78 @@ void QgsPointMarkerItem::paint( QPainter *painter )
mOpacityEffect->begin( rc );
}

mMarkerSymbol->startRender( rc, mFeature.fields() );
mMarkerSymbol->renderPoint( mLocation - pos(), &mFeature, rc );
mMarkerSymbol->stopRender( rc );
mSymbol->startRender( rc, mFeature.fields() );
renderSymbol( rc, mFeature );
mSymbol->stopRender( rc );

if ( useEffect )
{
mOpacityEffect->end( rc );
}
}

void QgsPointMarkerItem::setPointLocation( const QgsPointXY &p )
void QgsMapCanvasSymbolItem::setSymbol( std::unique_ptr< QgsSymbol > symbol )
{
mLocation = toCanvasCoordinates( p );
mSymbol = std::move( symbol );
}

void QgsPointMarkerItem::setSymbol( QgsMarkerSymbol *symbol )
const QgsSymbol *QgsMapCanvasSymbolItem::symbol() const
{
mMarkerSymbol.reset( symbol );
return mSymbol.get();
}

QgsMarkerSymbol *QgsPointMarkerItem::symbol()
void QgsMapCanvasSymbolItem::setFeature( const QgsFeature &feature )
{
return mMarkerSymbol.get();
mFeature = feature;
}
void QgsMapCanvasSymbolItem::setOpacity( double opacity )
{
mOpacityEffect->setOpacity( opacity );
}

void QgsPointMarkerItem::setFeature( const QgsFeature &feature )
double QgsMapCanvasSymbolItem::opacity() const
{
mFeature = feature;
return mOpacityEffect->opacity();
}


//
// QgsPointMarkerItem
//

QgsPointMarkerItem::QgsPointMarkerItem( QgsMapCanvas *canvas )
: QgsMapCanvasSymbolItem( canvas )
{
}


void QgsPointMarkerItem::setPointLocation( const QgsPointXY &p )
{
mLocation = toCanvasCoordinates( p );
}

void QgsPointMarkerItem::updateSize()
{
QgsRenderContext rc = renderContext( nullptr );
mMarkerSymbol->startRender( rc, mFeature.fields() );
QRectF bounds = mMarkerSymbol->bounds( mLocation, rc, mFeature );
mMarkerSymbol->stopRender( rc );
markerSymbol()->startRender( rc, mFeature.fields() );
QRectF bounds = markerSymbol()->bounds( mLocation, rc, mFeature );
markerSymbol()->stopRender( rc );
QgsRectangle r( mMapCanvas->mapSettings().mapToPixel().toMapCoordinates( static_cast<int>( bounds.x() ),
static_cast<int>( bounds.y() ) ),
mMapCanvas->mapSettings().mapToPixel().toMapCoordinates( static_cast<int>( bounds.x() + bounds.width() * 2 ),
static_cast<int>( bounds.y() + bounds.height() * 2 ) ) );
setRect( r );
}

void QgsPointMarkerItem::setOpacity( double opacity )
void QgsPointMarkerItem::renderSymbol( QgsRenderContext &context, const QgsFeature &feature )
{
mOpacityEffect->setOpacity( opacity );
markerSymbol()->renderPoint( mLocation - pos(), &feature, context );
}

double QgsPointMarkerItem::opacity() const
QgsMarkerSymbol *QgsPointMarkerItem::markerSymbol()
{
return mOpacityEffect->opacity();
QgsMarkerSymbol *marker = dynamic_cast< QgsMarkerSymbol * >( mSymbol.get() );
Q_ASSERT( marker );
return marker;
}

86 changes: 53 additions & 33 deletions src/app/qgspointmarkeritem.h
Expand Up @@ -27,86 +27,106 @@

class QgsMarkerSymbol;


/**
* \ingroup app
* \class QgsPointMarkerItem
* \brief An item that shows a point marker symbol centered on a map location.
* \class QgsMapCanvasSymbolItem
* \brief Base class for map canvas items which are rendered using a QgsSymbol.
*/

class APP_EXPORT QgsPointMarkerItem: public QgsMapCanvasItem
class APP_EXPORT QgsMapCanvasSymbolItem: public QgsMapCanvasItem
{
public:

QgsPointMarkerItem( QgsMapCanvas *canvas = nullptr );
QgsMapCanvasSymbolItem( QgsMapCanvas *canvas = nullptr );

void paint( QPainter *painter ) override;

/**
* Sets the center point of the marker symbol (in map coordinates)
* \param p center point
*/
void setPointLocation( const QgsPointXY &p );

/**
* Sets the marker symbol to use for rendering the point. Note - you may need to call
* updateSize() after setting the symbol.
* \param symbol marker symbol. Ownership is transferred to item.
* Sets the symbol to use for rendering the item.
* \see symbol()
* \see updateSize()
*/
void setSymbol( QgsMarkerSymbol *symbol );
void setSymbol( std::unique_ptr< QgsSymbol > symbol );

/**
* Returns the marker symbol used for rendering the point.
* Returns the symbol used for rendering the item.
* \see setSymbol()
*/
QgsMarkerSymbol *symbol();
const QgsSymbol *symbol() const;

/**
* Sets the feature used for rendering the marker symbol. The feature's attributes
* Sets the feature used for rendering the symbol. The feature's attributes
* may affect the rendered symbol if data defined overrides are in place.
* \param feature feature for symbol
* \see feature()
* \see updateSize()
*/
void setFeature( const QgsFeature &feature );

/**
* Returns the feature used for rendering the marker symbol.
* Returns the feature used for rendering the symbol.
* \see setFeature()
*/
QgsFeature feature() const { return mFeature; }

/**
* Must be called after setting the symbol or feature and when the symbol's size may
* have changed.
*/
void updateSize();

/**
* Sets the \a opacity for the marker.
* Sets the \a opacity for the item.
* \param opacity double between 0 and 1 inclusive, where 0 is fully transparent
* and 1 is fully opaque
* \see opacity()
*/
void setOpacity( double opacity );

/**
* Returns the opacity for the marker.
* Returns the opacity for the item.
* \returns opacity value between 0 and 1 inclusive, where 0 is fully transparent
* and 1 is fully opaque
* \see setOpacity()
*/
double opacity() const;

private:
protected:

virtual void renderSymbol( QgsRenderContext &context, const QgsFeature &feature ) = 0;

QgsRenderContext renderContext( QPainter *painter );
std::unique_ptr< QgsSymbol > mSymbol;
QgsFeature mFeature;
std::unique_ptr< QgsMarkerSymbol > mMarkerSymbol;
QPointF mLocation;

private:

std::unique_ptr< QgsDrawSourceEffect > mOpacityEffect;

QgsRenderContext renderContext( QPainter *painter );
};

/**
* \ingroup app
* \class QgsPointMarkerItem
* \brief An item that shows a point marker symbol centered on a map location.
*/
class APP_EXPORT QgsPointMarkerItem: public QgsMapCanvasSymbolItem
{
public:

QgsPointMarkerItem( QgsMapCanvas *canvas = nullptr );

/**
* Sets the center point of the marker symbol (in map coordinates)
* \param p center point
*/
void setPointLocation( const QgsPointXY &p );

/**
* Must be called after setting the symbol or feature and when the symbol's size may
* have changed.
*/
void updateSize();

void renderSymbol( QgsRenderContext &context, const QgsFeature &feature ) override;

private:

QPointF mLocation;

QgsMarkerSymbol *markerSymbol();
};

#endif // QGSPOINTMARKERITEM_H

0 comments on commit e0fb896

Please sign in to comment.