Skip to content
Permalink
Browse files
Allow paint effects to be applied to an annotation layer
  • Loading branch information
nyalldawson committed Sep 10, 2021
1 parent 94051eb commit 5e150f92621ce881ef12c3c65033312b5412a5df
@@ -12,6 +12,7 @@




class QgsAnnotationLayer : QgsMapLayer
{
%Docstring(signature="appended")
@@ -156,6 +157,26 @@ Returns ``True`` if the operation was successfully applied.
virtual QString htmlMetadata() const;


QgsPaintEffect *paintEffect() const;
%Docstring
Returns the current paint effect for the layer.

.. seealso:: :py:func:`setPaintEffect`

.. versionadded:: 3.22
%End

void setPaintEffect( QgsPaintEffect *effect /Transfer/ );
%Docstring
Sets the current paint ``effect`` for the layer.

Ownership is transferred to the renderer.

.. seealso:: :py:func:`paintEffect`

.. versionadded:: 3.22
%End

};


@@ -22,11 +22,11 @@
#include "qgsgui.h"
#include "qgsnative.h"
#include "qgsapplication.h"
#include "qgsmetadatawidget.h"
#include "qgsmaplayerloadstyledialog.h"
#include "qgsmaplayerconfigwidgetfactory.h"
#include "qgsmaplayerconfigwidget.h"
#include "qgsdatumtransformdialog.h"
#include "qgspainteffect.h"
#include <QFileDialog>
#include <QMenu>
#include <QMessageBox>
@@ -83,6 +83,8 @@ QgsAnnotationLayerProperties::QgsAnnotationLayerProperties( QgsAnnotationLayer *
restoreOptionsBaseUi( title );
}

QgsAnnotationLayerProperties::~QgsAnnotationLayerProperties() = default;

void QgsAnnotationLayerProperties::addPropertiesPageFactory( const QgsMapLayerConfigWidgetFactory *factory )
{
if ( !factory->supportsLayer( mLayer ) || !factory->supportLayerPropertiesDialog() )
@@ -115,6 +117,9 @@ void QgsAnnotationLayerProperties::apply()
mLayer->setBlendMode( mBlendModeComboBox->blendMode() );
mLayer->setOpacity( mOpacityWidget->opacity() );

if ( mPaintEffect )
mLayer->setPaintEffect( mPaintEffect->clone() );

for ( QgsMapLayerConfigWidget *w : mConfigWidgets )
w->apply();

@@ -162,6 +167,12 @@ void QgsAnnotationLayerProperties::syncToLayer()
mBlendModeComboBox->setBlendMode( mLayer->blendMode() );
mOpacityWidget->setOpacity( mLayer->opacity() );

if ( mLayer->paintEffect() )
{
mPaintEffect.reset( mLayer->paintEffect()->clone() );
mEffectWidget->setPaintEffect( mPaintEffect.get() );
}

for ( QgsMapLayerConfigWidget *w : mConfigWidgets )
w->syncToLayer( mLayer );
}
@@ -38,6 +38,7 @@ class QgsAnnotationLayerProperties : public QgsOptionsDialogBase, private Ui::Qg
Q_OBJECT
public:
QgsAnnotationLayerProperties( QgsAnnotationLayer *layer, QgsMapCanvas *canvas, QgsMessageBar *messageBar, QWidget *parent = nullptr, Qt::WindowFlags = QgsGuiUtils::ModalDialogFlags );
~QgsAnnotationLayerProperties() override;

void addPropertiesPageFactory( const QgsMapLayerConfigWidgetFactory *factory );

@@ -73,6 +74,8 @@ class QgsAnnotationLayerProperties : public QgsOptionsDialogBase, private Ui::Qg
*/
QgsMapLayerStyle mOldStyle;

std::unique_ptr< QgsPaintEffect > mPaintEffect;

QList<QgsMapLayerConfigWidget *> mConfigWidgets;

};
@@ -24,6 +24,9 @@
#include "qgsmaplayerfactory.h"
#include "qgsfeedback.h"
#include "qgsannotationitemeditoperation.h"
#include "qgspainteffect.h"
#include "qgseffectstack.h"
#include "qgspainteffectregistry.h"
#include <QUuid>
#include "RTree.h"

@@ -105,6 +108,9 @@ QgsAnnotationLayer::QgsAnnotationLayer( const QString &name, const LayerOptions
mShouldValidateCrs = false;
mValid = true;
mDataProvider = new QgsAnnotationLayerDataProvider( QgsDataProvider::ProviderOptions(), QgsDataProvider::ReadFlags() );

mPaintEffect.reset( QgsPaintEffectRegistry::defaultStack() );
mPaintEffect->setEnabled( false );
}

QgsAnnotationLayer::~QgsAnnotationLayer()
@@ -289,6 +295,9 @@ QgsAnnotationLayer *QgsAnnotationLayer::clone() const
layer->mSpatialIndex->insert( it.key(), ( *it )->boundingBox() );
}

if ( mPaintEffect )
layer->setPaintEffect( mPaintEffect->clone() );

return layer.release();
}

@@ -409,6 +418,11 @@ bool QgsAnnotationLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QStr
const QDomText blendModeText = doc.createTextNode( QString::number( QgsPainting::getBlendModeEnum( blendMode() ) ) );
blendModeElem.appendChild( blendModeText );
node.appendChild( blendModeElem );

QDomElement paintEffectElem = doc.createElement( QStringLiteral( "paintEffect" ) );
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect.get() ) )
mPaintEffect->saveProperties( doc, paintEffectElem );
node.appendChild( paintEffectElem );
}

return true;
@@ -435,6 +449,17 @@ bool QgsAnnotationLayer::readSymbology( const QDomNode &node, QString &, QgsRead
const QDomElement e = blendModeNode.toElement();
setBlendMode( QgsPainting::getCompositionMode( static_cast< QgsPainting::BlendMode >( e.text().toInt() ) ) );
}

//restore layer effect
const QDomNode paintEffectNode = node.namedItem( QStringLiteral( "paintEffect" ) );
if ( !paintEffectNode.isNull() )
{
const QDomElement effectElem = paintEffectNode.firstChildElement( QStringLiteral( "effect" ) );
if ( !effectElem.isNull() )
{
setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
}
}
}

return true;
@@ -512,6 +537,16 @@ QString QgsAnnotationLayer::htmlMetadata() const
return metadata;
}

QgsPaintEffect *QgsAnnotationLayer::paintEffect() const
{
return mPaintEffect.get();
}

void QgsAnnotationLayer::setPaintEffect( QgsPaintEffect *effect )
{
mPaintEffect.reset( effect );
}


//
// QgsAnnotationLayerDataProvider
@@ -25,6 +25,8 @@

class QgsAnnotationItem;
class QgsAbstractAnnotationItemEditOperation;
class QgsPaintEffect;


///@cond PRIVATE
class QgsAnnotationLayerSpatialIndex;
@@ -172,6 +174,23 @@ class CORE_EXPORT QgsAnnotationLayer : public QgsMapLayer
const QgsDataProvider *dataProvider() const override SIP_SKIP;
QString htmlMetadata() const override;

/**
* Returns the current paint effect for the layer.
* \see setPaintEffect()
* \since QGIS 3.22
*/
QgsPaintEffect *paintEffect() const;

/**
* Sets the current paint \a effect for the layer.
*
* Ownership is transferred to the renderer.
*
* \see paintEffect()
* \since QGIS 3.22
*/
void setPaintEffect( QgsPaintEffect *effect SIP_TRANSFER );

private:

QStringList queryIndex( const QgsRectangle &bounds, QgsFeedback *feedback = nullptr ) const;
@@ -184,6 +203,8 @@ class CORE_EXPORT QgsAnnotationLayer : public QgsMapLayer

QgsDataProvider *mDataProvider = nullptr;

std::unique_ptr< QgsPaintEffect > mPaintEffect;

friend class QgsAnnotationLayerRenderer;

};
@@ -18,6 +18,7 @@
#include "qgsannotationlayer.h"
#include "qgsfeedback.h"
#include "qgsrenderedannotationitemdetails.h"
#include "qgspainteffect.h"
#include <optional>

QgsAnnotationLayerRenderer::QgsAnnotationLayerRenderer( QgsAnnotationLayer *layer, QgsRenderContext &context )
@@ -50,6 +51,11 @@ QgsAnnotationLayerRenderer::QgsAnnotationLayerRenderer( QgsAnnotationLayer *laye
const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &a,
const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &b )
{ return a.second->zIndex() < b.second->zIndex(); } );

if ( layer->paintEffect() && layer->paintEffect()->enabled() )
{
mPaintEffect.reset( layer->paintEffect()->clone() );
}
}

QgsAnnotationLayerRenderer::~QgsAnnotationLayerRenderer() = default;
@@ -63,6 +69,11 @@ bool QgsAnnotationLayerRenderer::render()
{
QgsRenderContext &context = *renderContext();

if ( mPaintEffect )
{
mPaintEffect->begin( context );
}

bool canceled = false;
for ( const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &item : std::as_const( mItems ) )
{
@@ -87,6 +98,12 @@ bool QgsAnnotationLayerRenderer::render()
appendRenderedItemDetails( details.release() );
}
}

if ( mPaintEffect )
{
mPaintEffect->end( context );
}

return !canceled;
}

@@ -28,6 +28,7 @@
#include <memory>

class QgsAnnotationLayer;
class QgsPaintEffect;

/**
* \ingroup core
@@ -53,6 +54,7 @@ class CORE_EXPORT QgsAnnotationLayerRenderer : public QgsMapLayerRenderer
std::vector < std::pair< QString, std::unique_ptr< QgsAnnotationItem > > > mItems;
std::unique_ptr< QgsFeedback > mFeedback;
double mLayerOpacity = 1.0;
std::unique_ptr< QgsPaintEffect > mPaintEffect;

};

@@ -384,34 +384,47 @@
<property name="rightMargin">
<number>3</number>
</property>
<item row="1" column="2" colspan="2">
<widget class="QgsBlendModeComboBox" name="mBlendModeComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>4</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QgsOpacityWidget" name="mOpacityWidget" native="true">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblBlend">
<property name="text">
<string>Blending mode</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblTransparency">
<property name="text">
<string>Opacity</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblBlend">
<property name="text">
<string>Blending mode</string>
<item row="2" column="0" colspan="4">
<widget class="QgsEffectStackCompactWidget" name="mEffectWidget" native="true">
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QgsBlendModeComboBox" name="mBlendModeComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>4</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
@@ -519,6 +532,12 @@
<extends>QComboBox</extends>
<header>qgsblendmodecombobox.h</header>
</customwidget>
<customwidget>
<class>QgsEffectStackCompactWidget</class>
<extends>QWidget</extends>
<header>qgseffectstackpropertieswidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsOpacityWidget</class>
<extends>QWidget</extends>
@@ -529,6 +548,16 @@
<tabstops>
<tabstop>mSearchLineEdit</tabstop>
<tabstop>mOptionsListWidget</tabstop>
<tabstop>mInformationTextBrowser</tabstop>
<tabstop>mLayerOrigNameLineEdit</tabstop>
<tabstop>mCrsGroupBox</tabstop>
<tabstop>mCrsSelector</tabstop>
<tabstop>scrollArea_19</tabstop>
<tabstop>mScaleVisibilityGroupBox</tabstop>
<tabstop>mScaleRangeWidget</tabstop>
<tabstop>mOpacityWidget</tabstop>
<tabstop>mBlendModeComboBox</tabstop>
<tabstop>mEffectWidget</tabstop>
</tabstops>
<resources>
<include location="../../../images/images.qrc"/>

0 comments on commit 5e150f9

Please sign in to comment.