From b7064db6220e0b9f3a7215fb9e380e9068c8c577 Mon Sep 17 00:00:00 2001 From: nyalldawson Date: Sun, 31 Mar 2013 22:16:56 +1100 Subject: [PATCH 1/3] [FEATURE] Blend modes for composer items --- src/app/composer/qgscomposeritemwidget.cpp | 11 +++++ src/app/composer/qgscomposeritemwidget.h | 2 + src/core/CMakeLists.txt | 2 + src/core/composer/qgscomposereffect.cpp | 51 ++++++++++++++++++++++ src/core/composer/qgscomposereffect.h | 44 +++++++++++++++++++ src/core/composer/qgscomposeritem.cpp | 24 ++++++++++ src/core/composer/qgscomposeritem.h | 14 +++++- src/core/composer/qgscomposition.cpp | 2 + src/core/qgsmaprenderer.h | 3 +- src/ui/qgscomposeritemwidgetbase.ui | 27 ++++++++++++ 10 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 src/core/composer/qgscomposereffect.cpp create mode 100644 src/core/composer/qgscomposereffect.h diff --git a/src/app/composer/qgscomposeritemwidget.cpp b/src/app/composer/qgscomposeritemwidget.cpp index 6e9b13086c5d..b1847d45e76a 100644 --- a/src/app/composer/qgscomposeritemwidget.cpp +++ b/src/app/composer/qgscomposeritemwidget.cpp @@ -354,6 +354,7 @@ void QgsComposerItemWidget::setValuesForGuiElements() mBackgroundGroupBox->blockSignals( true ); mItemIdLineEdit->blockSignals( true ); mItemUuidLineEdit->blockSignals( true ); + mBlendModeCombo->blockSignals( true ); // mTransparencySpinBox->blockSignals( true ); mBackgroundColorButton->setColor( mItem->brush().color() ); @@ -371,6 +372,7 @@ void QgsComposerItemWidget::setValuesForGuiElements() mItemUuidLineEdit->setText( mItem->uuid() ); mFrameGroupBox->setChecked( mItem->hasFrame() ); mBackgroundGroupBox->setChecked( mItem->hasBackground() ); + mBlendModeCombo->setBlendMode( mItem->blendMode() ); // mTransparencySlider->blockSignals( false ); mOutlineWidthSpinBox->blockSignals( false ); @@ -378,9 +380,18 @@ void QgsComposerItemWidget::setValuesForGuiElements() mBackgroundGroupBox->blockSignals( false ); mItemIdLineEdit->blockSignals( false ); mItemUuidLineEdit->blockSignals( false ); + mBlendModeCombo->blockSignals( false ); // mTransparencySpinBox->blockSignals( false ); } +void QgsComposerItemWidget::on_mBlendModeCombo_currentIndexChanged( int index ) +{ + Q_UNUSED( index ); + if ( mItem ) + { + mItem->setBlendMode(( QgsMapRenderer::BlendMode ) mBlendModeCombo->blendMode() ); + } +} void QgsComposerItemWidget::on_mItemIdLineEdit_editingFinished() { diff --git a/src/app/composer/qgscomposeritemwidget.h b/src/app/composer/qgscomposeritemwidget.h index 30c994fe8c28..c86ca2a0aa1f 100644 --- a/src/app/composer/qgscomposeritemwidget.h +++ b/src/app/composer/qgscomposeritemwidget.h @@ -70,6 +70,8 @@ class QgsComposerItemWidget: public QWidget, private Ui::QgsComposerItemWidgetBa void on_mLowerMiddleCheckBox_stateChanged( int state ) { Q_UNUSED( state ); changeItemPosition(); } void on_mLowerRightCheckBox_stateChanged( int state ) { Q_UNUSED( state ); changeItemPosition(); } + void on_mBlendModeCombo_currentIndexChanged( int index ); + void setValuesForGuiElements(); void setValuesForGuiPositionElements(); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e613df8a0fd4..bc3ea2048688 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -148,6 +148,7 @@ SET(QGIS_CORE_SRCS composer/qgscomposertexttable.cpp composer/qgscomposerscalebar.cpp composer/qgscomposershape.cpp + composer/qgscomposereffect.cpp composer/qgsatlascomposition.cpp composer/qgslegendmodel.cpp composer/qgscomposerlegend.cpp @@ -339,6 +340,7 @@ SET(QGIS_CORE_MOC_HDRS composer/qgscomposerattributetable.h composer/qgscomposerhtml.h composer/qgscomposermultiframe.h + composer/qgscomposereffect.h composer/qgsatlascomposition.h composer/qgscomposition.h diff --git a/src/core/composer/qgscomposereffect.cpp b/src/core/composer/qgscomposereffect.cpp new file mode 100644 index 000000000000..ed704a6c31e1 --- /dev/null +++ b/src/core/composer/qgscomposereffect.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + qgscomposereffect.cpp + ------------------- + begin : March 2013 + copyright : (C) 2013 by Nyall Dawson + email : nyall.dawson@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include + +#include "qgscomposereffect.h" + +QgsComposerEffect::QgsComposerEffect() + : mCompositionMode( QPainter::CompositionMode_SourceOver ) +{ +} + +QgsComposerEffect::~QgsComposerEffect() +{ +} + +void QgsComposerEffect::draw( QPainter *painter ) +{ + QPoint offset; + QPixmap pixmap; + + // Set desired composition mode then draw source + painter->setCompositionMode( mCompositionMode ); + drawSource( painter ); + +} + +void QgsComposerEffect::setCompositionMode( const QPainter::CompositionMode compositionMode ) +{ + mCompositionMode = compositionMode; + + // force redraw with new composition mode + update(); +} + + + diff --git a/src/core/composer/qgscomposereffect.h b/src/core/composer/qgscomposereffect.h new file mode 100644 index 000000000000..d27934ba593a --- /dev/null +++ b/src/core/composer/qgscomposereffect.h @@ -0,0 +1,44 @@ +/*************************************************************************** + qgscomposereffect.h + ------------------- + begin : March 2013 + copyright : (C) 2013 by Nyall Dawson + email : nyall.dawson@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSCOMPOSEREFFECT_H +#define QGSCOMPOSEREFFECT_H + +#include +#include + +class CORE_EXPORT QgsComposerEffect : public QGraphicsEffect +{ + Q_OBJECT + + public: + QgsComposerEffect(); + ~QgsComposerEffect(); + + void setCompositionMode( const QPainter::CompositionMode compositionMode ); + + protected: + /** Called whenever source needs to be drawn */ + virtual void draw( QPainter *painter ); + + private: + + QPainter::CompositionMode mCompositionMode; +}; + +#endif // QGSCOMPOSEREFFECT_H + diff --git a/src/core/composer/qgscomposeritem.cpp b/src/core/composer/qgscomposeritem.cpp index 07faf83124eb..6c7411476dac 100644 --- a/src/core/composer/qgscomposeritem.cpp +++ b/src/core/composer/qgscomposeritem.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "qgsproject.h" @@ -35,6 +36,7 @@ #include "qgsrectangle.h" //just for debugging #include "qgslogger.h" #include "qgssymbollayerv2utils.h" //for pointOnLineWithDistance +#include "qgsmaprenderer.h" //for getCompositionMode #include @@ -52,6 +54,7 @@ QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue , mItemPositionLocked( false ) , mLastValidViewScaleFactor( -1 ) , mRotation( 0 ) + , mBlendMode( QgsMapRenderer::BlendNormal ) , mLastUsedPositionMode( UpperLeft ) , mId( "" ) , mUuid( QUuid::createUuid().toString() ) @@ -71,6 +74,7 @@ QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, Q , mItemPositionLocked( false ) , mLastValidViewScaleFactor( -1 ) , mRotation( 0 ) + , mBlendMode( QgsMapRenderer::BlendNormal ) , mLastUsedPositionMode( UpperLeft ) , mId( "" ) , mUuid( QUuid::createUuid().toString() ) @@ -95,6 +99,10 @@ void QgsComposerItem::init( bool manageZValue ) { mComposition->addItemToZList( this ); } + + // Setup composer effect + mEffect = new QgsComposerEffect(); + setGraphicsEffect( mEffect ); } QgsComposerItem::~QgsComposerItem() @@ -105,6 +113,7 @@ QgsComposerItem::~QgsComposerItem() } delete mBoundingResizeRectangle; + delete mEffect; deleteAlignItems(); } @@ -192,6 +201,9 @@ bool QgsComposerItem::_writeXML( QDomElement& itemElem, QDomDocument& doc ) cons bgColorElem.setAttribute( "alpha", QString::number( bgColor.alpha() ) ); composerItemElem.appendChild( bgColorElem ); + //blend mode + composerItemElem.setAttribute( "blendMode", QString::number( mBlendMode ) ); + itemElem.appendChild( composerItemElem ); return true; @@ -311,6 +323,10 @@ bool QgsComposerItem::_readXML( const QDomElement& itemElem, const QDomDocument& setBrush( QBrush( brushColor ) ); } } + + //blend mode + setBlendMode(( QgsMapRenderer::BlendMode ) itemElem.attribute( "blendMode" , "0" ).toInt() ); + return true; } @@ -859,6 +875,14 @@ void QgsComposerItem::drawBackground( QPainter* p ) } } +void QgsComposerItem::setBlendMode( QgsMapRenderer::BlendMode blendMode ) +{ + mBlendMode = blendMode; + // Update the composer effect to use the new blend mode + mEffect->setCompositionMode( QgsMapRenderer::getCompositionMode( mBlendMode ) ); +} + + void QgsComposerItem::hoverMoveEvent( QGraphicsSceneHoverEvent * event ) { if ( isSelected() ) diff --git a/src/core/composer/qgscomposeritem.h b/src/core/composer/qgscomposeritem.h index 45064ae7cc27..e853b0b402db 100644 --- a/src/core/composer/qgscomposeritem.h +++ b/src/core/composer/qgscomposeritem.h @@ -18,6 +18,8 @@ #define QGSCOMPOSERITEM_H #include "qgscomposeritemcommand.h" +#include "qgscomposereffect.h" +#include "qgsmaprenderer.h" // for blend mode functions & enums #include #include @@ -195,6 +197,12 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem */ void setBackgroundEnabled( bool drawBackground ) {mBackground = drawBackground;} + /** Returns the item's composition blending mode */ + QgsMapRenderer::BlendMode blendMode() const {return mBlendMode;} + + /** Sets the item's composition blending mode*/ + void setBlendMode( QgsMapRenderer::BlendMode blendMode ); + /**Composite operations for item groups do nothing per default*/ virtual void addItem( QgsComposerItem* item ) { Q_UNUSED( item ); } virtual void removeItems() {} @@ -297,7 +305,6 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem /**True if item background needs to be painted*/ bool mBackground; - /**True if item position and size cannot be changed with mouse move @note: this member was added in version 1.2*/ bool mItemPositionLocked; @@ -308,6 +315,11 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem /**Item rotation in degrees, clockwise*/ double mRotation; + /**Composition blend mode for item*/ + QgsMapRenderer::BlendMode mBlendMode; + + QgsComposerEffect *mEffect; + /**The item's position mode @note: this member was added in version 2.0*/ ItemPositionMode mLastUsedPositionMode; diff --git a/src/core/composer/qgscomposition.cpp b/src/core/composer/qgscomposition.cpp index c53ff91c92c7..8848b1d595cb 100644 --- a/src/core/composer/qgscomposition.cpp +++ b/src/core/composer/qgscomposition.cpp @@ -46,6 +46,7 @@ #include #include + QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer ) : QGraphicsScene( 0 ), mMapRenderer( mapRenderer ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ), mSelectionTolerance( 0.0 ), mSnapToGrid( false ), mSnapGridResolution( 10.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mAlignmentSnap( true ), mAlignmentSnapTolerance( 2 ), @@ -64,6 +65,7 @@ QgsComposition::QgsComposition(): mAlignmentSnapTolerance( 2 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ), mAtlasComposition( this ) { loadSettings(); + } QgsComposition::~QgsComposition() diff --git a/src/core/qgsmaprenderer.h b/src/core/qgsmaprenderer.h index c98e2784604c..b04384c2044c 100644 --- a/src/core/qgsmaprenderer.h +++ b/src/core/qgsmaprenderer.h @@ -252,7 +252,7 @@ class CORE_EXPORT QgsMapRenderer : public QObject void setLabelingEngine( QgsLabelingEngineInterface* iface ); //! Returns a QPainter::CompositionMode corresponding to a BlendMode - QPainter::CompositionMode getCompositionMode( const QgsMapRenderer::BlendMode blendMode ); + static QPainter::CompositionMode getCompositionMode( const QgsMapRenderer::BlendMode blendMode ); signals: @@ -347,6 +347,7 @@ class CORE_EXPORT QgsMapRenderer : public QObject private: const QgsCoordinateTransform* tr( QgsMapLayer *layer ); + }; #endif diff --git a/src/ui/qgscomposeritemwidgetbase.ui b/src/ui/qgscomposeritemwidgetbase.ui index 50cc39ed9a6c..6aff479db356 100644 --- a/src/ui/qgscomposeritemwidgetbase.ui +++ b/src/ui/qgscomposeritemwidgetbase.ui @@ -337,6 +337,28 @@ + + + + Rendering + + + true + + + + + + Blending mode + + + + + + + + + @@ -367,6 +389,11 @@
qgscollapsiblegroupbox.h
1 + + QgsBlendModeComboBox + QComboBox +
qgsblendmodecombobox.h
+
From 32ec65cdd595ebe5838907d703afb569d94f5575 Mon Sep 17 00:00:00 2001 From: nyalldawson Date: Mon, 1 Apr 2013 21:01:56 +1100 Subject: [PATCH 2/3] Fix printing with composition effects --- src/core/composer/qgscomposereffect.cpp | 23 ++++++++++++++++++++++- src/core/composer/qgscomposeritem.cpp | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/core/composer/qgscomposereffect.cpp b/src/core/composer/qgscomposereffect.cpp index ed704a6c31e1..99a8a45e0520 100644 --- a/src/core/composer/qgscomposereffect.cpp +++ b/src/core/composer/qgscomposereffect.cpp @@ -35,7 +35,28 @@ void QgsComposerEffect::draw( QPainter *painter ) // Set desired composition mode then draw source painter->setCompositionMode( mCompositionMode ); - drawSource( painter ); + + if ( mCompositionMode == QPainter::CompositionMode_SourceOver ) + { + // Normal (sourceover) blending, do faster drawSource operation + drawSource( painter ); + return; + } + + // Otherwise, draw using pixmap so QPrinter output works as expected + if ( sourceIsPixmap() ) + { + // No point in drawing in device coordinates (pixmap will be scaled anyways). + pixmap = sourcePixmap( Qt::LogicalCoordinates, &offset ); + } + else + { + // Draw pixmap in device coordinates to avoid pixmap scaling; + pixmap = sourcePixmap( Qt::DeviceCoordinates, &offset ); + painter->setWorldTransform( QTransform() ); + } + + painter->drawPixmap( offset, pixmap ); } diff --git a/src/core/composer/qgscomposeritem.cpp b/src/core/composer/qgscomposeritem.cpp index 6c7411476dac..f35dca023e6c 100644 --- a/src/core/composer/qgscomposeritem.cpp +++ b/src/core/composer/qgscomposeritem.cpp @@ -103,6 +103,7 @@ void QgsComposerItem::init( bool manageZValue ) // Setup composer effect mEffect = new QgsComposerEffect(); setGraphicsEffect( mEffect ); + } QgsComposerItem::~QgsComposerItem() From 7b6e322bf9d9d00473cb4c8cd5483e3949487c66 Mon Sep 17 00:00:00 2001 From: nyalldawson Date: Mon, 1 Apr 2013 22:01:35 +1100 Subject: [PATCH 3/3] [FEATURE] Transparency control for composer items --- src/app/composer/qgscomposeritemwidget.cpp | 11 +++++++++++ src/app/composer/qgscomposeritemwidget.h | 1 + src/core/composer/qgscomposeritem.cpp | 14 ++++++++++++++ src/core/composer/qgscomposeritem.h | 8 ++++++++ src/ui/qgscomposeritemwidgetbase.ui | 17 +++++++++++++++++ 5 files changed, 51 insertions(+) diff --git a/src/app/composer/qgscomposeritemwidget.cpp b/src/app/composer/qgscomposeritemwidget.cpp index b1847d45e76a..f44689b9cdd9 100644 --- a/src/app/composer/qgscomposeritemwidget.cpp +++ b/src/app/composer/qgscomposeritemwidget.cpp @@ -355,6 +355,7 @@ void QgsComposerItemWidget::setValuesForGuiElements() mItemIdLineEdit->blockSignals( true ); mItemUuidLineEdit->blockSignals( true ); mBlendModeCombo->blockSignals( true ); + mTransparencySlider->blockSignals( true ); // mTransparencySpinBox->blockSignals( true ); mBackgroundColorButton->setColor( mItem->brush().color() ); @@ -373,6 +374,7 @@ void QgsComposerItemWidget::setValuesForGuiElements() mFrameGroupBox->setChecked( mItem->hasFrame() ); mBackgroundGroupBox->setChecked( mItem->hasBackground() ); mBlendModeCombo->setBlendMode( mItem->blendMode() ); + mTransparencySlider->setValue( mItem->transparency() ); // mTransparencySlider->blockSignals( false ); mOutlineWidthSpinBox->blockSignals( false ); @@ -381,6 +383,7 @@ void QgsComposerItemWidget::setValuesForGuiElements() mItemIdLineEdit->blockSignals( false ); mItemUuidLineEdit->blockSignals( false ); mBlendModeCombo->blockSignals( false ); + mTransparencySlider->blockSignals( false ); // mTransparencySpinBox->blockSignals( false ); } @@ -393,6 +396,14 @@ void QgsComposerItemWidget::on_mBlendModeCombo_currentIndexChanged( int index ) } } +void QgsComposerItemWidget::on_mTransparencySlider_valueChanged( int value ) +{ + if ( mItem ) + { + mItem->setTransparency( value ); + } +} + void QgsComposerItemWidget::on_mItemIdLineEdit_editingFinished() { if ( mItem ) diff --git a/src/app/composer/qgscomposeritemwidget.h b/src/app/composer/qgscomposeritemwidget.h index c86ca2a0aa1f..5fc2b7dd06a2 100644 --- a/src/app/composer/qgscomposeritemwidget.h +++ b/src/app/composer/qgscomposeritemwidget.h @@ -71,6 +71,7 @@ class QgsComposerItemWidget: public QWidget, private Ui::QgsComposerItemWidgetBa void on_mLowerRightCheckBox_stateChanged( int state ) { Q_UNUSED( state ); changeItemPosition(); } void on_mBlendModeCombo_currentIndexChanged( int index ); + void on_mTransparencySlider_valueChanged( int value ); void setValuesForGuiElements(); void setValuesForGuiPositionElements(); diff --git a/src/core/composer/qgscomposeritem.cpp b/src/core/composer/qgscomposeritem.cpp index f35dca023e6c..eccfa51fe9bd 100644 --- a/src/core/composer/qgscomposeritem.cpp +++ b/src/core/composer/qgscomposeritem.cpp @@ -55,6 +55,7 @@ QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue , mLastValidViewScaleFactor( -1 ) , mRotation( 0 ) , mBlendMode( QgsMapRenderer::BlendNormal ) + , mTransparency( 0 ) , mLastUsedPositionMode( UpperLeft ) , mId( "" ) , mUuid( QUuid::createUuid().toString() ) @@ -75,6 +76,7 @@ QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, Q , mLastValidViewScaleFactor( -1 ) , mRotation( 0 ) , mBlendMode( QgsMapRenderer::BlendNormal ) + , mTransparency( 0 ) , mLastUsedPositionMode( UpperLeft ) , mId( "" ) , mUuid( QUuid::createUuid().toString() ) @@ -205,6 +207,9 @@ bool QgsComposerItem::_writeXML( QDomElement& itemElem, QDomDocument& doc ) cons //blend mode composerItemElem.setAttribute( "blendMode", QString::number( mBlendMode ) ); + //transparency + composerItemElem.setAttribute( "transparency", QString::number( mTransparency ) ); + itemElem.appendChild( composerItemElem ); return true; @@ -328,6 +333,9 @@ bool QgsComposerItem::_readXML( const QDomElement& itemElem, const QDomDocument& //blend mode setBlendMode(( QgsMapRenderer::BlendMode ) itemElem.attribute( "blendMode" , "0" ).toInt() ); + //transparency + setTransparency( itemElem.attribute( "transparency" , "0" ).toInt() ); + return true; } @@ -883,6 +891,12 @@ void QgsComposerItem::setBlendMode( QgsMapRenderer::BlendMode blendMode ) mEffect->setCompositionMode( QgsMapRenderer::getCompositionMode( mBlendMode ) ); } +void QgsComposerItem::setTransparency( int transparency ) +{ + mTransparency = transparency; + // Set the QGraphicItem's opacity + setOpacity( 1. - ( transparency / 100. ) ); +} void QgsComposerItem::hoverMoveEvent( QGraphicsSceneHoverEvent * event ) { diff --git a/src/core/composer/qgscomposeritem.h b/src/core/composer/qgscomposeritem.h index e853b0b402db..890295e19323 100644 --- a/src/core/composer/qgscomposeritem.h +++ b/src/core/composer/qgscomposeritem.h @@ -203,6 +203,11 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem /** Sets the item's composition blending mode*/ void setBlendMode( QgsMapRenderer::BlendMode blendMode ); + /** Returns the item's transparency */ + int transparency() const {return mTransparency;} + /** Sets the item's transparency */ + void setTransparency( int transparency ); + /**Composite operations for item groups do nothing per default*/ virtual void addItem( QgsComposerItem* item ) { Q_UNUSED( item ); } virtual void removeItems() {} @@ -320,6 +325,9 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem QgsComposerEffect *mEffect; + /**Item transparency*/ + int mTransparency; + /**The item's position mode @note: this member was added in version 2.0*/ ItemPositionMode mLastUsedPositionMode; diff --git a/src/ui/qgscomposeritemwidgetbase.ui b/src/ui/qgscomposeritemwidgetbase.ui index 6aff479db356..01bde690b010 100644 --- a/src/ui/qgscomposeritemwidgetbase.ui +++ b/src/ui/qgscomposeritemwidgetbase.ui @@ -356,6 +356,23 @@ + + + + Transparency + + + + + + + 100 + + + Qt::Horizontal + + +