Skip to content

Commit

Permalink
Ensure map frame and background also follow clip path
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 28, 2020
1 parent c5b3443 commit a533268
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 25 deletions.
15 changes: 15 additions & 0 deletions python/core/auto_generated/layout/qgslayoutitem.sip.in
Expand Up @@ -1147,16 +1147,31 @@ Draws the item's contents using the specified item render ``context``.

Note that the context's painter has been scaled so that painter units are pixels.
Use the QgsRenderContext methods to convert from millimeters or other units to the painter's units.
%End

virtual QPainterPath framePath() const;
%Docstring
Returns the path to use when drawing the item's frame or background.

.. seealso:: :py:func:`drawFrame`

.. seealso:: :py:func:`drawBackground`

.. versionadded:: 3.16
%End

virtual void drawFrame( QgsRenderContext &context );
%Docstring
Draws the frame around the item.

.. seealso:: :py:func:`framePath`
%End

virtual void drawBackground( QgsRenderContext &context );
%Docstring
Draws the background for the item.

.. seealso:: :py:func:`framePath`
%End

virtual void setFixedSize( const QgsLayoutSize &size );
Expand Down
17 changes: 17 additions & 0 deletions python/core/auto_generated/layout/qgslayoutitemmap.sip.in
Expand Up @@ -157,6 +157,21 @@ Sets whether the map content should be clipped to the associated item.
QgsGeometry clippedMapExtent() const;
%Docstring
Returns the geometry to use for clipping the parent map, in the map item's CRS.

.. seealso:: :py:func:`clipPathInMapItemCoordinates`
%End

QgsGeometry clipPathInMapItemCoordinates() const;
%Docstring
Returns the clipping path geometry, in the map item's coordinate space.

.. warning::

The return path is not in geographic coordinates, rather the map
layout item's QGraphicsItem coordinate space. Use :py:func:`~QgsLayoutItemMapItemClipPathSettings.clippedMapExtent` to retrieve
the clip path in the map's CRS.

.. seealso:: :py:func:`clippedMapExtent`
%End

QgsMapClippingRegion toMapClippingRegion() const;
Expand Down Expand Up @@ -880,6 +895,8 @@ Returns the map's item based clip path settings.

virtual bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context );

virtual QPainterPath framePath() const;


bool isDrawing() const;
%Docstring
Expand Down
11 changes: 9 additions & 2 deletions src/core/layout/qgslayoutitem.cpp
Expand Up @@ -1210,6 +1210,13 @@ void QgsLayoutItem::drawDebugRect( QPainter *painter )
painter->drawRect( rect() );
}

QPainterPath QgsLayoutItem::framePath() const
{
QPainterPath path;
path.addRect( QRectF( 0, 0, rect().width(), rect().height() ) );
return path;
}

void QgsLayoutItem::drawFrame( QgsRenderContext &context )
{
if ( !mFrame || !context.painter() )
Expand All @@ -1223,7 +1230,7 @@ void QgsLayoutItem::drawFrame( QgsRenderContext &context )
p->setBrush( Qt::NoBrush );
context.setPainterFlagsUsingContext( p );

p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
p->drawPath( framePath() );
}

void QgsLayoutItem::drawBackground( QgsRenderContext &context )
Expand All @@ -1238,7 +1245,7 @@ void QgsLayoutItem::drawBackground( QgsRenderContext &context )
p->setPen( Qt::NoPen );
context.setPainterFlagsUsingContext( p );

p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
p->drawPath( framePath() );
}

void QgsLayoutItem::setFixedSize( const QgsLayoutSize &size )
Expand Down
13 changes: 13 additions & 0 deletions src/core/layout/qgslayoutitem.h
Expand Up @@ -1081,13 +1081,26 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
*/
virtual void draw( QgsLayoutItemRenderContext &context ) = 0;

/**
* Returns the path to use when drawing the item's frame or background.
*
* \see drawFrame()
* \see drawBackground()
* \since QGIS 3.16
*/
virtual QPainterPath framePath() const;

/**
* Draws the frame around the item.
*
* \see framePath()
*/
virtual void drawFrame( QgsRenderContext &context );

/**
* Draws the background for the item.
*
* \see framePath()
*/
virtual void drawBackground( QgsRenderContext &context );

Expand Down
22 changes: 22 additions & 0 deletions src/core/layout/qgslayoutitemmap.cpp
Expand Up @@ -859,6 +859,17 @@ bool QgsLayoutItemMap::readPropertiesFromElement( const QDomElement &itemElem, c
return true;
}

QPainterPath QgsLayoutItemMap::framePath() const
{
if ( mItemClippingSettings->isActive() )
{
const QgsGeometry g = mItemClippingSettings->clipPathInMapItemCoordinates();
if ( !g.isNull() )
return g.constGet()->asQPainterPath();
}
return QgsLayoutItem::framePath();
}

void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem *style, QWidget * )
{
if ( !mLayout || !painter || !painter->device() || !mUpdatesEnabled )
Expand Down Expand Up @@ -2867,6 +2878,17 @@ QgsGeometry QgsLayoutItemMapItemClipPathSettings::clippedMapExtent() const
return QgsGeometry();
}

QgsGeometry QgsLayoutItemMapItemClipPathSettings::clipPathInMapItemCoordinates() const
{
if ( isActive() )
{
QgsGeometry clipGeom( mClipPathSource->clipPath() );
clipGeom.transform( mMap->sceneTransform().inverted() );
return clipGeom;
}
return QgsGeometry();
}

QgsMapClippingRegion QgsLayoutItemMapItemClipPathSettings::toMapClippingRegion() const
{
QgsMapClippingRegion region( clippedMapExtent() );
Expand Down
14 changes: 14 additions & 0 deletions src/core/layout/qgslayoutitemmap.h
Expand Up @@ -182,9 +182,22 @@ class CORE_EXPORT QgsLayoutItemMapItemClipPathSettings : public QObject

/**
* Returns the geometry to use for clipping the parent map, in the map item's CRS.
*
* \see clipPathInMapItemCoordinates()
*/
QgsGeometry clippedMapExtent() const;

/**
* Returns the clipping path geometry, in the map item's coordinate space.
*
* \warning The return path is not in geographic coordinates, rather the map
* layout item's QGraphicsItem coordinate space. Use clippedMapExtent() to retrieve
* the clip path in the map's CRS.
*
* \see clippedMapExtent()
*/
QgsGeometry clipPathInMapItemCoordinates() const;

/**
* Returns the clip path as a map clipping region.
*/
Expand Down Expand Up @@ -824,6 +837,7 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem, public QgsTemporalRan
void draw( QgsLayoutItemRenderContext &context ) override;
bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override;
bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context ) override;
QPainterPath framePath() const override;

//! True if a draw is already in progress
bool isDrawing() const {return mDrawing;}
Expand Down

0 comments on commit a533268

Please sign in to comment.