Add api to allow QgsBlendModeComboBox to show clipping style blend modes

This commit is contained in:
Nyall Dawson 2021-11-23 20:42:23 +10:00
parent 22c16f2067
commit bb17d1cc7e
3 changed files with 116 additions and 63 deletions

View File

@ -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();

View File

@ -25,63 +25,47 @@
#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 );
@ -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;
}

View File

@ -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<int> mBlendModeToListIndex;
std::vector<int> 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: