From bb17d1cc7e19f2531f11fd7c5a3c9b8c7c0cb0ac Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 23 Nov 2021 20:42:23 +1000 Subject: [PATCH] Add api to allow QgsBlendModeComboBox to show clipping style blend modes --- .../qgsblendmodecombobox.sip.in | 37 +++++++- src/gui/qgsblendmodecombobox.cpp | 92 +++++++++---------- src/gui/qgsblendmodecombobox.h | 50 +++++++--- 3 files changed, 116 insertions(+), 63 deletions(-) diff --git a/python/gui/auto_generated/qgsblendmodecombobox.sip.in b/python/gui/auto_generated/qgsblendmodecombobox.sip.in index 898704e283a..8184125acec 100644 --- a/python/gui/auto_generated/qgsblendmodecombobox.sip.in +++ b/python/gui/auto_generated/qgsblendmodecombobox.sip.in @@ -27,12 +27,45 @@ Constructor for QgsBlendModeComboBox QPainter::CompositionMode blendMode(); %Docstring -Function to read the selected blend mode as QPainter.CompositionMode +Returns the selected blend mode. + +.. seealso:: :py:func:`setBlendMode` %End + void setBlendMode( QPainter::CompositionMode blendMode ); %Docstring -Function to set the selected blend mode from QPainter.CompositionMode +Sets the selected blend mode. + +.. seealso:: :py:func:`blendMode` %End + + void setShowClippingModes( bool show ); +%Docstring +Sets whether composition modes which cause clipping are shown in the combo box. + +By default, these composition modes (such as QPainter.CompositionMode.CompositionMode_DestinationIn ) +are not shown in the combo box, as they can only be used with predictable results in a limited +set of circumstances. By setting ``show`` to ``True`` these additional composition modes +will be shown in the combo box. + +.. seealso:: :py:func:`showClippingModes` + +.. versionadded:: 3.24 +%End + + bool showClippingModes() const; +%Docstring +Returns ``True`` if composition modes which cause clipping are shown in the combo box. + +By default, these composition modes (such as QPainter.CompositionMode.CompositionMode_DestinationIn ) +are not shown in the combo box, as they can only be used with predictable results in a limited +set of circumstances. + +.. seealso:: :py:func:`setShowClippingModes` + +.. versionadded:: 3.24 +%End + public slots: void updateModes(); diff --git a/src/gui/qgsblendmodecombobox.cpp b/src/gui/qgsblendmodecombobox.cpp index 02022706e9a..6dc119e7114 100644 --- a/src/gui/qgsblendmodecombobox.cpp +++ b/src/gui/qgsblendmodecombobox.cpp @@ -25,63 +25,47 @@ #include #include -QgsBlendModeComboBox::QgsBlendModeComboBox( QWidget *parent ) : QComboBox( parent ) +QgsBlendModeComboBox::QgsBlendModeComboBox( QWidget *parent ) + : QComboBox( parent ) { updateModes(); } -QStringList QgsBlendModeComboBox::blendModesList() const -{ - return QStringList() << tr( "Normal" ) - << QStringLiteral( "-" ) - << tr( "Lighten" ) - << tr( "Screen" ) - << tr( "Dodge" ) - << tr( "Addition" ) - << QStringLiteral( "-" ) - << tr( "Darken" ) - << tr( "Multiply" ) - << tr( "Burn" ) - << QStringLiteral( "-" ) - << tr( "Overlay" ) - << tr( "Soft light" ) - << tr( "Hard light" ) - << QStringLiteral( "-" ) - << tr( "Difference" ) - << tr( "Subtract" ); -} - void QgsBlendModeComboBox::updateModes() { blockSignals( true ); clear(); - const QStringList myBlendModesList = blendModesList(); - QStringList::const_iterator blendModeIt = myBlendModesList.constBegin(); + // This list is designed to emulate GIMP's layer modes, where + // blending modes are grouped by their effect (lightening, darkening, etc) - mBlendModeToListIndex.resize( myBlendModesList.count() ); - mListIndexToBlendMode.resize( myBlendModesList.count() ); + addItem( tr( "Normal" ), static_cast< int >( QgsPainting::BlendMode::BlendNormal ) ); + insertSeparator( count() ); + addItem( tr( "Lighten" ), static_cast< int >( QgsPainting::BlendMode::BlendLighten ) ); + addItem( tr( "Screen" ), static_cast< int >( QgsPainting::BlendMode::BlendScreen ) ); + addItem( tr( "Dodge" ), static_cast< int >( QgsPainting::BlendMode::BlendDodge ) ); + addItem( tr( "Addition" ), static_cast< int >( QgsPainting::BlendMode::BlendAddition ) ); + insertSeparator( count() ); + addItem( tr( "Darken" ), static_cast< int >( QgsPainting::BlendMode::BlendDarken ) ); + addItem( tr( "Multiply" ), static_cast< int >( QgsPainting::BlendMode::BlendMultiply ) ); + addItem( tr( "Burn" ), static_cast< int >( QgsPainting::BlendMode::BlendBurn ) ); + insertSeparator( count() ); + addItem( tr( "Overlay" ), static_cast< int >( QgsPainting::BlendMode::BlendOverlay ) ); + addItem( tr( "Soft Light" ), static_cast< int >( QgsPainting::BlendMode::BlendSoftLight ) ); + addItem( tr( "Hard Light" ), static_cast< int >( QgsPainting::BlendMode::BlendHardLight ) ); + insertSeparator( count() ); + addItem( tr( "Difference" ), static_cast< int >( QgsPainting::BlendMode::BlendDifference ) ); + addItem( tr( "Subtract" ), static_cast< int >( QgsPainting::BlendMode::BlendSubtract ) ); - // Loop through blend modes - int index = 0; - int blendModeIndex = 0; - for ( ; blendModeIt != myBlendModesList.constEnd(); ++blendModeIt ) + if ( mShowClipModes ) { - if ( *blendModeIt == QLatin1String( "-" ) ) - { - // Add separator - insertSeparator( index ); - } - else - { - // Not a separator, so store indexes for translation - // between blend modes and combo box item index - addItem( *blendModeIt ); - mListIndexToBlendMode[ index ] = blendModeIndex; - mBlendModeToListIndex[ blendModeIndex ] = index; - blendModeIndex++; - } - index++; + insertSeparator( count() ); + addItem( tr( "Masked By Below" ), static_cast< int >( QgsPainting::BlendMode::BlendSourceIn ) ); + addItem( tr( "Mask Below" ), static_cast< int >( QgsPainting::BlendMode::BlendDestinationIn ) ); + addItem( tr( "Inverse Masked By Below" ), static_cast< int >( QgsPainting::BlendMode::BlendSourceOut ) ); + addItem( tr( "Inverse Mask Below" ), static_cast< int >( QgsPainting::BlendMode::BlendDestinationOut ) ); + addItem( tr( "Paint Inside Below" ), static_cast< int >( QgsPainting::BlendMode::BlendSourceAtop ) ); + addItem( tr( "Paint Below Inside" ), static_cast< int >( QgsPainting::BlendMode::BlendDestinationAtop ) ); } blockSignals( false ); @@ -89,11 +73,25 @@ void QgsBlendModeComboBox::updateModes() QPainter::CompositionMode QgsBlendModeComboBox::blendMode() { - return QgsPainting::getCompositionMode( ( QgsPainting::BlendMode ) mListIndexToBlendMode[ currentIndex()] ); + return QgsPainting::getCompositionMode( static_cast< QgsPainting::BlendMode >( currentData().toInt() ) ); } void QgsBlendModeComboBox::setBlendMode( QPainter::CompositionMode blendMode ) { - setCurrentIndex( mBlendModeToListIndex[( int ) QgsPainting::getBlendModeEnum( blendMode )] ); + setCurrentIndex( findData( static_cast< int >( QgsPainting::getBlendModeEnum( blendMode ) ) ) ); +} + +void QgsBlendModeComboBox::setShowClippingModes( bool show ) +{ + mShowClipModes = show; + const QPainter::CompositionMode mode = blendMode(); + updateModes(); + + setBlendMode( mode ); +} + +bool QgsBlendModeComboBox::showClippingModes() const +{ + return mShowClipModes; } diff --git a/src/gui/qgsblendmodecombobox.h b/src/gui/qgsblendmodecombobox.h index 5188e54e25b..0df02051830 100644 --- a/src/gui/qgsblendmodecombobox.h +++ b/src/gui/qgsblendmodecombobox.h @@ -35,24 +35,46 @@ class GUI_EXPORT QgsBlendModeComboBox : public QComboBox //! Constructor for QgsBlendModeComboBox QgsBlendModeComboBox( QWidget *parent SIP_TRANSFERTHIS = nullptr ); - //! Function to read the selected blend mode as QPainter::CompositionMode + /** + * Returns the selected blend mode. + * \see setBlendMode() + */ QPainter::CompositionMode blendMode(); - //! Function to set the selected blend mode from QPainter::CompositionMode - void setBlendMode( QPainter::CompositionMode blendMode ); - private: /** - * Returns a QStringList of the translated blend modes - * "-" is used to indicate the position of a separator in the list - * This list is designed to emulate GIMP's layer modes, where - * blending modes are grouped by their effect (lightening, darkening, etc) - */ - QStringList blendModesList() const; + * Sets the selected blend mode. + * \see blendMode() + */ + void setBlendMode( QPainter::CompositionMode blendMode ); - //! Used to map blend modes across to their corresponding - // index within the combo box - std::vector mBlendModeToListIndex; - std::vector mListIndexToBlendMode; + /** + * Sets whether composition modes which cause clipping are shown in the combo box. + * + * By default, these composition modes (such as QPainter::CompositionMode::CompositionMode_DestinationIn ) + * are not shown in the combo box, as they can only be used with predictable results in a limited + * set of circumstances. By setting \a show to TRUE these additional composition modes + * will be shown in the combo box. + * + * \see showClippingModes() + * \since QGIS 3.24 + */ + void setShowClippingModes( bool show ); + + /** + * Returns TRUE if composition modes which cause clipping are shown in the combo box. + * + * By default, these composition modes (such as QPainter::CompositionMode::CompositionMode_DestinationIn ) + * are not shown in the combo box, as they can only be used with predictable results in a limited + * set of circumstances. + * + * \see setShowClippingModes() + * \since QGIS 3.24 + */ + bool showClippingModes() const; + + private: + + bool mShowClipModes = false; public slots: