Navigation Menu

Skip to content

Commit

Permalink
Add api to allow QgsBlendModeComboBox to show clipping style blend modes
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 24, 2021
1 parent 22c16f2 commit bb17d1c
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 62 deletions.
37 changes: 35 additions & 2 deletions python/gui/auto_generated/qgsblendmodecombobox.sip.in
Expand Up @@ -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();
Expand Down
92 changes: 45 additions & 47 deletions src/gui/qgsblendmodecombobox.cpp
Expand Up @@ -25,75 +25,73 @@
#include <QSettings>
#include <QLineEdit>

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 );
}

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;
}

48 changes: 35 additions & 13 deletions src/gui/qgsblendmodecombobox.h
Expand Up @@ -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

/**
* Sets the selected blend mode.
* \see blendMode()
*/
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 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:

//! Used to map blend modes across to their corresponding
// index within the combo box
std::vector<int> mBlendModeToListIndex;
std::vector<int> mListIndexToBlendMode;
bool mShowClipModes = false;

public slots:

Expand Down

0 comments on commit bb17d1c

Please sign in to comment.