Merge pull request #57361 from troopa81/cmyk_colorwidget

[ColorWidget] Add CMYK support
This commit is contained in:
Julien Cabieces 2024-05-23 18:03:52 +02:00 committed by GitHub
commit eaa0261c5d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 1504 additions and 808 deletions

View File

@ -7,6 +7,10 @@ QgsColorWidget.Hue = QgsColorWidget.ColorComponent.Hue
QgsColorWidget.Saturation = QgsColorWidget.ColorComponent.Saturation
QgsColorWidget.Value = QgsColorWidget.ColorComponent.Value
QgsColorWidget.Alpha = QgsColorWidget.ColorComponent.Alpha
QgsColorWidget.Cyan = QgsColorWidget.ColorComponent.Cyan
QgsColorWidget.Magenta = QgsColorWidget.ColorComponent.Magenta
QgsColorWidget.Yellow = QgsColorWidget.ColorComponent.Yellow
QgsColorWidget.Black = QgsColorWidget.ColorComponent.Black
QgsColorRampWidget.Horizontal = QgsColorRampWidget.Orientation.Horizontal
QgsColorRampWidget.Vertical = QgsColorRampWidget.Orientation.Vertical
QgsColorTextWidget.HexRgb = QgsColorTextWidget.ColorTextFormat.HexRgb

View File

@ -33,7 +33,11 @@ set to a color with an ambiguous hue (e.g., black or white shades).
Hue,
Saturation,
Value,
Alpha
Alpha,
Cyan,
Magenta,
Yellow,
Black
};
QgsColorWidget( QWidget *parent /TransferThis/ = 0, ColorComponent component = Multiple );
@ -145,7 +149,7 @@ Returns the range of valid values for the color widget's component
:return: maximum value allowed for color component, or -1 if widget has multiple components
%End
int componentRange( ColorComponent component ) const;
static int componentRange( ColorComponent component );
%Docstring
Returns the range of valid values a color component
@ -172,7 +176,7 @@ as QColor returns a hue of -1 if the color's hue is ambiguous (e.g., if the satu
:return: explicitly set hue for widget
%End
void alterColor( QColor &color, QgsColorWidget::ColorComponent component, int newValue ) const;
static void alterColor( QColor &color, QgsColorWidget::ColorComponent component, int newValue );
%Docstring
Alters a color by modifying the value of a specific color component
@ -182,6 +186,16 @@ Alters a color by modifying the value of a specific color component
valid range for the color component.
%End
QColor::Spec colorSpec() const;
%Docstring
Returns color widget type of color, either RGB, HSV, CMYK, or Invalid if this component value is Multiple or Alpha
%End
static QColor::Spec colorSpec( QgsColorWidget::ColorComponent component );
%Docstring
Returns ``component`` type of color, either RGB, HSV, CMYK, or Invalid if ``component`` value is Multiple or Alpha
%End
static const QPixmap &transparentBackground();
%Docstring
Generates a checkboard pattern pixmap for use as a background to transparent colors
@ -201,6 +215,7 @@ Generates a checkboard pattern pixmap for use as a background to transparent col
virtual void mouseReleaseEvent( QMouseEvent *e );
};

View File

@ -33,7 +33,11 @@ set to a color with an ambiguous hue (e.g., black or white shades).
Hue,
Saturation,
Value,
Alpha
Alpha,
Cyan,
Magenta,
Yellow,
Black
};
QgsColorWidget( QWidget *parent /TransferThis/ = 0, ColorComponent component = Multiple );
@ -145,7 +149,7 @@ Returns the range of valid values for the color widget's component
:return: maximum value allowed for color component, or -1 if widget has multiple components
%End
int componentRange( ColorComponent component ) const;
static int componentRange( ColorComponent component );
%Docstring
Returns the range of valid values a color component
@ -172,7 +176,7 @@ as QColor returns a hue of -1 if the color's hue is ambiguous (e.g., if the satu
:return: explicitly set hue for widget
%End
void alterColor( QColor &color, QgsColorWidget::ColorComponent component, int newValue ) const;
static void alterColor( QColor &color, QgsColorWidget::ColorComponent component, int newValue );
%Docstring
Alters a color by modifying the value of a specific color component
@ -182,6 +186,16 @@ Alters a color by modifying the value of a specific color component
valid range for the color component.
%End
QColor::Spec colorSpec() const;
%Docstring
Returns color widget type of color, either RGB, HSV, CMYK, or Invalid if this component value is Multiple or Alpha
%End
static QColor::Spec colorSpec( QgsColorWidget::ColorComponent component );
%Docstring
Returns ``component`` type of color, either RGB, HSV, CMYK, or Invalid if ``component`` value is Multiple or Alpha
%End
static const QPixmap &transparentBackground();
%Docstring
Generates a checkboard pattern pixmap for use as a background to transparent colors
@ -201,6 +215,7 @@ Generates a checkboard pattern pixmap for use as a background to transparent col
virtual void mouseReleaseEvent( QMouseEvent *e );
};

View File

@ -102,6 +102,14 @@ int QgsColorWidget::componentValue( const QgsColorWidget::ColorComponent compone
return mCurrentColor.value();
case QgsColorWidget::Alpha:
return mCurrentColor.alpha();
case QgsColorWidget::Cyan:
return mCurrentColor.cyan();
case QgsColorWidget::Yellow:
return mCurrentColor.yellow();
case QgsColorWidget::Magenta:
return mCurrentColor.magenta();
case QgsColorWidget::Black:
return mCurrentColor.black();
default:
return -1;
}
@ -112,7 +120,7 @@ int QgsColorWidget::componentRange() const
return componentRange( mComponent );
}
int QgsColorWidget::componentRange( const QgsColorWidget::ColorComponent component ) const
int QgsColorWidget::componentRange( const QgsColorWidget::ColorComponent component )
{
if ( component == QgsColorWidget::Multiple )
{
@ -144,42 +152,144 @@ int QgsColorWidget::hue() const
}
}
void QgsColorWidget::alterColor( QColor &color, const QgsColorWidget::ColorComponent component, const int newValue ) const
void QgsColorWidget::alterColor( QColor &color, const QgsColorWidget::ColorComponent component, const int newValue )
{
int h, s, v, a;
color.getHsv( &h, &s, &v, &a );
//clip value to sensible range
const int clippedValue = std::min( std::max( 0, newValue ), componentRange( component ) );
if ( colorSpec( component ) == QColor::Spec::Cmyk )
{
int c, m, y, k, a;
color.getCmyk( &c, &m, &y, &k, &a );
switch ( component )
{
case QgsColorWidget::Cyan:
if ( c == clippedValue )
{
return;
}
color.setCmyk( clippedValue, m, y, k, a );
break;
case QgsColorWidget::Magenta:
if ( m == clippedValue )
{
return;
}
color.setCmyk( c, clippedValue, y, k, a );
break;
case QgsColorWidget::Yellow:
if ( y == clippedValue )
{
return;
}
color.setCmyk( c, m, clippedValue, k, a );
break;
case QgsColorWidget::Black:
if ( k == clippedValue )
{
return;
}
color.setCmyk( c, m, y, clippedValue, a );
break;
default:
return;
}
}
else
{
int r, g, b, a;
color.getRgb( &r, &g, &b, &a );
int h, s, v;
color.getHsv( &h, &s, &v );
switch ( component )
{
case QgsColorWidget::Red:
if ( r == clippedValue )
{
return;
}
color.setRed( clippedValue );
break;
case QgsColorWidget::Green:
if ( g == clippedValue )
{
return;
}
color.setGreen( clippedValue );
break;
case QgsColorWidget::Blue:
if ( b == clippedValue )
{
return;
}
color.setBlue( clippedValue );
break;
case QgsColorWidget::Hue:
if ( h == clippedValue )
{
return;
}
color.setHsv( clippedValue, s, v, a );
break;
case QgsColorWidget::Saturation:
if ( s == clippedValue )
{
return;
}
color.setHsv( h, clippedValue, v, a );
break;
case QgsColorWidget::Value:
if ( v == clippedValue )
{
return;
}
color.setHsv( h, s, clippedValue, a );
break;
case QgsColorWidget::Alpha:
if ( a == clippedValue )
{
return;
}
color.setAlpha( clippedValue );
break;
default:
return;
}
}
}
QColor::Spec QgsColorWidget::colorSpec( QgsColorWidget::ColorComponent component )
{
switch ( component )
{
case QgsColorWidget::Red:
color.setRed( clippedValue );
return;
case QgsColorWidget::Green:
color.setGreen( clippedValue );
return;
case QgsColorWidget::Blue:
color.setBlue( clippedValue );
return;
case QgsColorWidget::Hue:
color.setHsv( clippedValue, s, v, a );
return;
case QgsColorWidget::Saturation:
color.setHsv( h, clippedValue, v, a );
return;
case QgsColorWidget::Value:
color.setHsv( h, s, clippedValue, a );
return;
case QgsColorWidget::Alpha:
color.setAlpha( clippedValue );
return;
case Red:
case Green:
case Blue:
return QColor::Spec::Rgb;
case Hue:
case Saturation:
case Value:
return QColor::Spec::Hsv;
case Cyan:
case Magenta:
case Yellow:
case Black:
return QColor::Spec::Cmyk;
default:
return;
return QColor::Spec::Invalid;
}
}
QColor::Spec QgsColorWidget::colorSpec() const
{
return colorSpec( mComponent );
}
const QPixmap &QgsColorWidget::transparentBackground()
{
static QPixmap sTranspBkgrd;
@ -269,72 +379,19 @@ void QgsColorWidget::setComponentValue( const int value )
return;
}
//clip value to valid range
int valueClipped = std::min( value, componentRange() );
valueClipped = std::max( valueClipped, 0 );
int r, g, b, a;
mCurrentColor.getRgb( &r, &g, &b, &a );
int h, s, v;
mCurrentColor.getHsv( &h, &s, &v );
//overwrite hue with explicit hue if required
h = hue();
switch ( mComponent )
if ( mComponent == QgsColorWidget::Saturation || mComponent == QgsColorWidget::Value )
{
case QgsColorWidget::Red:
if ( r == valueClipped )
{
return;
}
mCurrentColor.setRed( valueClipped );
break;
case QgsColorWidget::Green:
if ( g == valueClipped )
{
return;
}
mCurrentColor.setGreen( valueClipped );
break;
case QgsColorWidget::Blue:
if ( b == valueClipped )
{
return;
}
mCurrentColor.setBlue( valueClipped );
break;
case QgsColorWidget::Hue:
if ( h == valueClipped )
{
return;
}
mCurrentColor.setHsv( valueClipped, s, v, a );
break;
case QgsColorWidget::Saturation:
if ( s == valueClipped )
{
return;
}
mCurrentColor.setHsv( h, valueClipped, v, a );
break;
case QgsColorWidget::Value:
if ( v == valueClipped )
{
return;
}
mCurrentColor.setHsv( h, s, valueClipped, a );
break;
case QgsColorWidget::Alpha:
if ( a == valueClipped )
{
return;
}
mCurrentColor.setAlpha( valueClipped );
break;
default:
return;
int h, s, v, a;
mCurrentColor.getHsv( &h, &s, &v, &a );
h = hue();
mCurrentColor.setHsv( h, s, v, a );
}
alterColor( mCurrentColor, mComponent, value );
//update recorded hue
if ( mCurrentColor.hue() >= 0 )
{
@ -839,30 +896,19 @@ void QgsColorBox::setComponent( const QgsColorWidget::ColorComponent component )
void QgsColorBox::setColor( const QColor &color, const bool emitSignals )
{
//check if we need to redraw the box image
if ( mComponent == QgsColorWidget::Red && mCurrentColor.red() != color.red() )
{
mDirty = true;
}
else if ( mComponent == QgsColorWidget::Green && mCurrentColor.green() != color.green() )
{
mDirty = true;
}
else if ( mComponent == QgsColorWidget::Blue && mCurrentColor.blue() != color.blue() )
{
mDirty = true;
}
else if ( mComponent == QgsColorWidget::Hue && color.hsvHue() >= 0 && hue() != color.hsvHue() )
{
mDirty = true;
}
else if ( mComponent == QgsColorWidget::Saturation && mCurrentColor.hsvSaturation() != color.hsvSaturation() )
{
mDirty = true;
}
else if ( mComponent == QgsColorWidget::Value && mCurrentColor.value() != color.value() )
{
mDirty = true;
}
mDirty |= (
( mComponent == QgsColorWidget::Red && mCurrentColor.red() != color.red() ) ||
( mComponent == QgsColorWidget::Green && mCurrentColor.green() != color.green() ) ||
( mComponent == QgsColorWidget::Blue && mCurrentColor.blue() != color.blue() ) ||
( mComponent == QgsColorWidget::Hue && color.hsvHue() >= 0 && hue() != color.hsvHue() ) ||
( mComponent == QgsColorWidget::Saturation && mCurrentColor.hsvSaturation() != color.hsvSaturation() ) ||
( mComponent == QgsColorWidget::Value && mCurrentColor.value() != color.value() ) ||
( mComponent == QgsColorWidget::Cyan && mCurrentColor.cyan() != color.cyan() ) ||
( mComponent == QgsColorWidget::Magenta && mCurrentColor.magenta() != color.magenta() ) ||
( mComponent == QgsColorWidget::Yellow && mCurrentColor.yellow() != color.yellow() ) ||
( mComponent == QgsColorWidget::Black && mCurrentColor.black() != color.black() )
);
QgsColorWidget::setColor( color, emitSignals );
}
@ -949,14 +995,22 @@ QgsColorWidget::ColorComponent QgsColorBox::yComponent() const
{
case QgsColorWidget::Red:
return QgsColorWidget::Green;
case QgsColorWidget:: Green:
case QgsColorWidget:: Blue:
case QgsColorWidget::Green:
case QgsColorWidget::Blue:
return QgsColorWidget::Red;
case QgsColorWidget::Hue:
return QgsColorWidget:: Saturation;
case QgsColorWidget:: Saturation:
case QgsColorWidget:: Value:
return QgsColorWidget::Hue;
return QgsColorWidget::Saturation;
case QgsColorWidget::Saturation:
case QgsColorWidget::Value:
return QgsColorWidget::Hue;
case QgsColorWidget::Magenta:
return QgsColorWidget::Yellow;
case QgsColorWidget::Yellow:
case QgsColorWidget::Cyan:
return QgsColorWidget::Magenta;
default:
//should not occur
return QgsColorWidget::Red;
@ -972,16 +1026,24 @@ QgsColorWidget::ColorComponent QgsColorBox::xComponent() const
{
switch ( mComponent )
{
case QgsColorWidget::Red:
case QgsColorWidget:: Green:
case QgsColorWidget::Red:
case QgsColorWidget::Green:
return QgsColorWidget::Blue;
case QgsColorWidget:: Blue:
case QgsColorWidget::Blue:
return QgsColorWidget::Green;
case QgsColorWidget::Hue:
case QgsColorWidget:: Saturation:
return QgsColorWidget:: Value;
case QgsColorWidget:: Value:
return QgsColorWidget::Saturation;
case QgsColorWidget::Saturation:
return QgsColorWidget::Value;
case QgsColorWidget::Value:
return QgsColorWidget::Saturation;
case QgsColorWidget::Magenta:
case QgsColorWidget::Yellow:
return QgsColorWidget::Cyan;
case QgsColorWidget::Cyan:
return QgsColorWidget::Yellow;
default:
//should not occur
return QgsColorWidget::Red;

View File

@ -53,7 +53,11 @@ class GUI_EXPORT QgsColorWidget : public QWidget
Hue, //!< Hue component of color (based on HSV model)
Saturation, //!< Saturation component of color (based on HSV model)
Value, //!< Value component of color (based on HSV model)
Alpha //!< Alpha component (opacity) of color
Alpha, //!< Alpha component (opacity) of color
Cyan, //!< Cyan component (based on CMYK model) of color
Magenta, //!< Magenta component (based on CMYK model) of color
Yellow, //!< Yellow component (based on CMYK model) of color
Black //!< Black component (based on CMYK model) of color
};
/**
@ -155,7 +159,7 @@ class GUI_EXPORT QgsColorWidget : public QWidget
* Returns the range of valid values a color component
* \returns maximum value allowed for color component
*/
int componentRange( ColorComponent component ) const;
static int componentRange( ColorComponent component );
/**
* Returns the value of a component of the widget's current color. This method correctly
@ -180,7 +184,17 @@ class GUI_EXPORT QgsColorWidget : public QWidget
* \param newValue new value of color component. Values are automatically clipped to a
* valid range for the color component.
*/
void alterColor( QColor &color, QgsColorWidget::ColorComponent component, int newValue ) const;
static void alterColor( QColor &color, QgsColorWidget::ColorComponent component, int newValue );
/**
* Returns color widget type of color, either RGB, HSV, CMYK, or Invalid if this component value is Multiple or Alpha
*/
QColor::Spec colorSpec() const;
/**
* Returns \a component type of color, either RGB, HSV, CMYK, or Invalid if \a component value is Multiple or Alpha
*/
static QColor::Spec colorSpec( QgsColorWidget::ColorComponent component );
/**
* Generates a checkboard pattern pixmap for use as a background to transparent colors
@ -197,6 +211,8 @@ class GUI_EXPORT QgsColorWidget : public QWidget
void mouseMoveEvent( QMouseEvent *e ) override;
void mousePressEvent( QMouseEvent *e ) override;
void mouseReleaseEvent( QMouseEvent *e ) override;
friend class TestQgsCompoundColorWidget;
};

View File

@ -22,6 +22,7 @@
#include "qgsscreenhelper.h"
#include "qgsguiutils.h"
#include <QButtonGroup>
#include <QHeaderView>
#include <QPushButton>
#include <QMenu>
@ -41,18 +42,55 @@ QgsCompoundColorWidget::QgsCompoundColorWidget( QWidget *parent, const QColor &c
mScreenHelper = new QgsScreenHelper( this );
connect( mHueRadio, &QRadioButton::toggled, this, &QgsCompoundColorWidget::mHueRadio_toggled );
connect( mSaturationRadio, &QRadioButton::toggled, this, &QgsCompoundColorWidget::mSaturationRadio_toggled );
connect( mValueRadio, &QRadioButton::toggled, this, &QgsCompoundColorWidget::mValueRadio_toggled );
connect( mRedRadio, &QRadioButton::toggled, this, &QgsCompoundColorWidget::mRedRadio_toggled );
connect( mGreenRadio, &QRadioButton::toggled, this, &QgsCompoundColorWidget::mGreenRadio_toggled );
connect( mBlueRadio, &QRadioButton::toggled, this, &QgsCompoundColorWidget::mBlueRadio_toggled );
mRgbRadios =
{
{ mHueRadio, QgsColorWidget::ColorComponent::Hue },
{ mSaturationRadio, QgsColorWidget::ColorComponent::Saturation },
{ mValueRadio, QgsColorWidget::ColorComponent::Value },
{ mRedRadio, QgsColorWidget::ColorComponent::Red },
{ mGreenRadio, QgsColorWidget::ColorComponent::Green },
{ mBlueRadio, QgsColorWidget::ColorComponent::Blue }
};
mCmykRadios =
{
{ mCyanRadio, QgsColorWidget::ColorComponent::Cyan },
{ mMagentaRadio, QgsColorWidget::ColorComponent::Magenta },
{ mYellowRadio, QgsColorWidget::ColorComponent::Yellow },
{ mBlackRadio, QgsColorWidget::ColorComponent::Black }
};
mRgbGroup = new QButtonGroup( this );
int i = 0;
for ( auto colorRadio : mRgbRadios )
mRgbGroup->addButton( colorRadio.first, i++ );
mCmykGroup = new QButtonGroup( this );
i = 0;
for ( auto colorRadio : mCmykRadios )
mCmykGroup->addButton( colorRadio.first, i++ );
connect( mRgbGroup, &QButtonGroup::idToggled, this, &QgsCompoundColorWidget::onColorButtonGroupToggled );
connect( mCmykGroup, &QButtonGroup::idToggled, this, &QgsCompoundColorWidget::onColorButtonGroupToggled );
connect( mAddColorToSchemeButton, &QPushButton::clicked, this, &QgsCompoundColorWidget::mAddColorToSchemeButton_clicked );
connect( mAddCustomColorButton, &QPushButton::clicked, this, &QgsCompoundColorWidget::mAddCustomColorButton_clicked );
connect( mSampleButton, &QPushButton::clicked, this, &QgsCompoundColorWidget::mSampleButton_clicked );
connect( mTabWidget, &QTabWidget::currentChanged, this, &QgsCompoundColorWidget::mTabWidget_currentChanged );
connect( mActionShowInButtons, &QAction::toggled, this, &QgsCompoundColorWidget::mActionShowInButtons_toggled );
mColorModel->addItem( tr( "RGB" ), QColor::Spec::Rgb );
mColorModel->addItem( tr( "CMYK" ), QColor::Spec::Cmyk );
connect( mColorModel, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this]( int )
{
const QColor::Spec spec = static_cast< QColor::Spec >( mColorModel->currentData().toInt() );
if ( spec == QColor::Spec::Cmyk )
setColor( this->color().toCmyk() );
else
setColor( this->color().toRgb() );
updateComponent();
} );
if ( widgetLayout == LayoutVertical )
{
// shuffle stuff around
@ -112,7 +150,7 @@ QgsCompoundColorWidget::QgsCompoundColorWidget( QWidget *parent, const QColor &c
mSchemeToolButton->setMenu( schemeMenu );
connect( mSchemeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsCompoundColorWidget::schemeIndexChanged );
connect( mSchemeList, &QgsColorSchemeList::colorSelected, this, &QgsCompoundColorWidget::setColor );
connect( mSchemeList, &QgsColorSchemeList::colorSelected, this, &QgsCompoundColorWidget::_setColor );
mOldColorLabel->hide();
@ -127,6 +165,10 @@ QgsCompoundColorWidget::QgsCompoundColorWidget( QWidget *parent, const QColor &c
mSaturationSlider->setComponent( QgsColorWidget::Saturation );
mValueSlider->setComponent( QgsColorWidget::Value );
mAlphaSlider->setComponent( QgsColorWidget::Alpha );
mCyanSlider->setComponent( QgsColorWidget::Cyan );
mMagentaSlider->setComponent( QgsColorWidget::Magenta );
mYellowSlider->setComponent( QgsColorWidget::Yellow );
mBlackSlider->setComponent( QgsColorWidget::Black );
mSwatchButton1->setShowMenu( false );
mSwatchButton1->setBehavior( QgsColorButton::SignalOnly );
@ -232,61 +274,51 @@ QgsCompoundColorWidget::QgsCompoundColorWidget( QWidget *parent, const QColor &c
setColor( color );
}
//restore active component radio button
const int activeRadio = settings.value( QStringLiteral( "Windows/ColorDialog/activeComponent" ), 2 ).toInt();
switch ( activeRadio )
{
case 0:
mHueRadio->setChecked( true );
break;
case 1:
mSaturationRadio->setChecked( true );
break;
case 2:
mValueRadio->setChecked( true );
break;
case 3:
mRedRadio->setChecked( true );
break;
case 4:
mGreenRadio->setChecked( true );
break;
case 5:
mBlueRadio->setChecked( true );
break;
}
// restore active Rgb/Cmyk component radio button
const int activeRgbRadio = settings.value( QStringLiteral( "Windows/ColorDialog/activeComponent" ), 2 ).toInt();
if ( QAbstractButton *rgbRadio = mRgbGroup->button( activeRgbRadio ) )
rgbRadio->setChecked( true );
const int activeCmykRadio = settings.value( QStringLiteral( "Windows/ColorDialog/activeCmykComponent" ), 0 ).toInt();
if ( QAbstractButton *cmykRadio = mCmykGroup->button( activeCmykRadio ) )
cmykRadio->setChecked( true );
const int currentTab = settings.value( QStringLiteral( "Windows/ColorDialog/activeTab" ), 0 ).toInt();
mTabWidget->setCurrentIndex( currentTab );
//setup connections
connect( mColorBox, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mColorWheel, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mColorText, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mVerticalRamp, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mRedSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mGreenSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mBlueSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mHueSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mValueSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mSaturationSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mAlphaSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mColorPreview, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton1, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton2, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton3, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton4, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton5, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton6, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton7, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton8, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton9, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton10, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton11, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton12, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton13, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton14, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton15, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mSwatchButton16, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::setColor );
connect( mColorBox, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mColorWheel, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mColorText, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mVerticalRamp, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mRedSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mGreenSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mBlueSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mHueSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mValueSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mCyanSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mMagentaSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mYellowSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mBlackSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mSaturationSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mAlphaSlider, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mColorPreview, &QgsColorWidget::colorChanged, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton1, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton2, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton3, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton4, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton5, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton6, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton7, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton8, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton9, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton10, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton11, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton12, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton13, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton14, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton15, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
connect( mSwatchButton16, &QgsColorButton::colorClicked, this, &QgsCompoundColorWidget::_setColor );
}
QgsCompoundColorWidget::~QgsCompoundColorWidget()
@ -601,12 +633,9 @@ void QgsCompoundColorWidget::mTabWidget_currentChanged( int index )
{
//disable radio buttons if not using the first tab, as they have no meaning for other tabs
const bool enabled = index == 0;
mRedRadio->setEnabled( enabled );
mBlueRadio->setEnabled( enabled );
mGreenRadio->setEnabled( enabled );
mHueRadio->setEnabled( enabled );
mSaturationRadio->setEnabled( enabled );
mValueRadio->setEnabled( enabled );
const QList<QRadioButton *> colorRadios{ mHueRadio, mSaturationRadio, mValueRadio, mRedRadio, mGreenRadio, mBlueRadio, mCyanRadio, mMagentaRadio, mYellowRadio, mBlackRadio };
for ( QRadioButton *colorRadio : colorRadios )
colorRadio->setEnabled( enabled );
}
void QgsCompoundColorWidget::mActionShowInButtons_toggled( bool state )
@ -641,21 +670,9 @@ void QgsCompoundColorWidget::saveSettings()
QgsSettings settings;
//record active component
int activeRadio = 0;
if ( mHueRadio->isChecked() )
activeRadio = 0;
if ( mSaturationRadio->isChecked() )
activeRadio = 1;
if ( mValueRadio->isChecked() )
activeRadio = 2;
if ( mRedRadio->isChecked() )
activeRadio = 3;
if ( mGreenRadio->isChecked() )
activeRadio = 4;
if ( mBlueRadio->isChecked() )
activeRadio = 5;
settings.setValue( QStringLiteral( "Windows/ColorDialog/activeComponent" ), activeRadio );
// record active component
settings.setValue( QStringLiteral( "Windows/ColorDialog/activeComponent" ), mRgbGroup->checkedId() );
settings.setValue( QStringLiteral( "Windows/ColorDialog/activeCmykComponent" ), mCmykGroup->checkedId() );
//record current scheme
settings.setValue( QStringLiteral( "Windows/ColorDialog/activeScheme" ), mSchemeComboBox->currentIndex() );
@ -707,6 +724,15 @@ void QgsCompoundColorWidget::stopPicking( QPoint eventPos, const bool takeSample
}
void QgsCompoundColorWidget::setColor( const QColor &color )
{
const QColor::Spec colorSpec = color.spec() == QColor::Cmyk ? QColor::Cmyk : QColor::Rgb;
mColorModel->setCurrentIndex( mColorModel->findData( colorSpec ) );
mRGB->setVisible( color.spec() != QColor::Cmyk );
mCMYK->setVisible( color.spec() == QColor::Cmyk );
_setColor( color );
}
void QgsCompoundColorWidget::_setColor( const QColor &color )
{
if ( !color.isValid() )
{
@ -719,6 +745,12 @@ void QgsCompoundColorWidget::setColor( const QColor &color )
//opacity disallowed, so don't permit transparent colors
fixedColor.setAlpha( 255 );
}
if ( mColorModel->currentIndex() && fixedColor.spec() != QColor::Cmyk )
{
fixedColor = fixedColor.toCmyk();
}
const QList<QgsColorWidget *> colorWidgets = this->findChildren<QgsColorWidget *>();
const auto constColorWidgets = colorWidgets;
for ( QgsColorWidget *widget : constColorWidgets )
@ -731,6 +763,8 @@ void QgsCompoundColorWidget::setColor( const QColor &color )
widget->setColor( fixedColor );
widget->blockSignals( false );
}
emit currentColorChanged( fixedColor );
}
@ -850,58 +884,26 @@ void QgsCompoundColorWidget::keyPressEvent( QKeyEvent *e )
stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
}
void QgsCompoundColorWidget::mHueRadio_toggled( bool checked )
void QgsCompoundColorWidget::updateComponent()
{
if ( checked )
const bool isCmyk = mColorModel->currentData().toInt() == QColor::Spec::Cmyk;
const auto radios = isCmyk ? mCmykRadios : mRgbRadios;
const QButtonGroup *group = isCmyk ? mCmykGroup : mRgbGroup;
const int id = group->checkedId();
if ( id >= 0 && id < radios.count() )
{
mColorBox->setComponent( QgsColorWidget::Hue );
mVerticalRamp->setComponent( QgsColorWidget::Hue );
const QgsColorWidget::ColorComponent component = radios.at( group->checkedId() ).second;
mColorBox->setComponent( component );
mVerticalRamp->setComponent( component );
}
}
void QgsCompoundColorWidget::mSaturationRadio_toggled( bool checked )
void QgsCompoundColorWidget::onColorButtonGroupToggled( int, bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Saturation );
mVerticalRamp->setComponent( QgsColorWidget::Saturation );
}
}
void QgsCompoundColorWidget::mValueRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Value );
mVerticalRamp->setComponent( QgsColorWidget::Value );
}
}
void QgsCompoundColorWidget::mRedRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Red );
mVerticalRamp->setComponent( QgsColorWidget::Red );
}
}
void QgsCompoundColorWidget::mGreenRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Green );
mVerticalRamp->setComponent( QgsColorWidget::Green );
}
}
void QgsCompoundColorWidget::mBlueRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Blue );
mVerticalRamp->setComponent( QgsColorWidget::Blue );
}
updateComponent();
}
void QgsCompoundColorWidget::mAddColorToSchemeButton_clicked()

View File

@ -146,12 +146,7 @@ class GUI_EXPORT QgsCompoundColorWidget : public QgsPanelWidget, private Ui::Qgs
private slots:
void mHueRadio_toggled( bool checked );
void mSaturationRadio_toggled( bool checked );
void mValueRadio_toggled( bool checked );
void mRedRadio_toggled( bool checked );
void mGreenRadio_toggled( bool checked );
void mBlueRadio_toggled( bool checked );
void onColorButtonGroupToggled( int, bool checked );
void mAddColorToSchemeButton_clicked();
@ -167,14 +162,24 @@ class GUI_EXPORT QgsCompoundColorWidget : public QgsPanelWidget, private Ui::Qgs
void mSampleButton_clicked();
void mTabWidget_currentChanged( int index );
private slots:
void mActionShowInButtons_toggled( bool state );
/**
* Internal color setter. Set \a color without changing current color model (RGB or CMYK),
* contrary to public setColor()
*/
void _setColor( const QColor &color );
private:
static QScreen *findScreenAt( QPoint pos );
/**
* Helper method to update current widget display with current component according to
* color model and selected color component radio button
*/
void updateComponent();
QgsScreenHelper *mScreenHelper = nullptr;
bool mAllowAlpha = true;
@ -185,6 +190,11 @@ class GUI_EXPORT QgsCompoundColorWidget : public QgsPanelWidget, private Ui::Qgs
bool mDiscarded = false;
QList<QPair<QRadioButton *, QgsColorWidget::ColorComponent>> mRgbRadios;
QList<QPair<QRadioButton *, QgsColorWidget::ColorComponent>> mCmykRadios;
QButtonGroup *mCmykGroup = nullptr;
QButtonGroup *mRgbGroup = nullptr;
/**
* Saves all widget settings
*/
@ -224,6 +234,8 @@ class GUI_EXPORT QgsCompoundColorWidget : public QgsPanelWidget, private Ui::Qgs
//! Updates the state of actions for the current selected scheme
void updateActionsForCurrentScheme();
friend class TestQgsCompoundColorWidget;
};
#endif // QGSCOMPOUNDCOLORWIDGET_H

File diff suppressed because it is too large Load Diff

View File

@ -74,6 +74,7 @@ set(TESTS
testqgsexternalresourcewidgetwrapper.cpp
testqgsquerybuilder.cpp
testqgsqueryresultwidget.cpp
testqgscompoundcolorwidget.cpp
)
foreach(TESTSRC ${TESTS})

View File

@ -0,0 +1,229 @@
/***************************************************************************
testqgscompoundcolorwidget.cpp
---------------------
begin : 2024/05/07
copyright : (C) 2024 by Julien Cabieces
email : julien dot cabieces at oslandia dot 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 "qgstest.h"
#include "qgscompoundcolorwidget.h"
#include "qgssettings.h"
Q_DECLARE_METATYPE( QgsColorWidget::ColorComponent )
class TestQgsCompoundColorWidget : public QgsTest
{
Q_OBJECT
public:
TestQgsCompoundColorWidget() : QgsTest( QStringLiteral( "Compound color widget Tests" ) ) {}
private slots:
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.
void init();// will be called before each testfunction is executed.
void cleanup();// will be called after every testfunction.
void testCmykConversion();
void testComponentChange();
void testComponentSettings_data();
void testComponentSettings();
void testModelChange();
void testTabChange();
};
void TestQgsCompoundColorWidget::initTestCase()
{
// Set up the QgsSettings environment
QCoreApplication::setOrganizationName( QStringLiteral( "QGIS" ) );
QCoreApplication::setOrganizationDomain( QStringLiteral( "qgis.org" ) );
QCoreApplication::setApplicationName( QStringLiteral( "QGIS-TEST" ) );
}
void TestQgsCompoundColorWidget::cleanupTestCase()
{
}
void TestQgsCompoundColorWidget::init()
{
}
void TestQgsCompoundColorWidget::cleanup()
{
}
void TestQgsCompoundColorWidget::testCmykConversion()
{
QgsCompoundColorWidget w( nullptr, QColor( 10, 20, 30, 50 ) );
w.setVisible( true );
QCOMPARE( w.color(), QColor( 10, 20, 30, 50 ) );
QCOMPARE( w.mColorModel->currentIndex(), 0 );
QVERIFY( w.mRGB->isVisible() );
QVERIFY( !w.mCMYK->isVisible() );
// switch to CMYK
w.mColorModel->setCurrentIndex( 1 );
QVERIFY( !w.mRGB->isVisible() );
QVERIFY( w.mCMYK->isVisible() );
QCOMPARE( w.mColorModel->currentIndex(), 1 );
QCOMPARE( w.color(), QColor::fromCmyk( 170, 85, 0, 225, 50 ) );
// switch back to RGB
w.mColorModel->setCurrentIndex( 0 );
QVERIFY( w.mRGB->isVisible() );
QVERIFY( !w.mCMYK->isVisible() );
QCOMPARE( w.mColorModel->currentIndex(), 0 );
QCOMPARE( w.color(), QColor( 10, 20, 30, 50 ) );
// edit color in CMYK mode
w.mColorModel->setCurrentIndex( 1 );
QVERIFY( !w.mRGB->isVisible() );
QVERIFY( w.mCMYK->isVisible() );
QCOMPARE( w.mColorModel->currentIndex(), 1 );
QCOMPARE( w.color(), QColor::fromCmyk( 170, 85, 0, 225, 50 ) );
w.mCyanSlider->setColor( QColor::fromCmyk( 120, 85, 0, 225, 50 ), true );
QCOMPARE( w.color(), QColor::fromCmyk( 120, 85, 0, 225, 50 ) );
// edit color in RGB, the returned color is still CMYK
w.mColorWheel->setColor( QColor( 10, 20, 30, 50 ), true );
QCOMPARE( w.color(), QColor::fromCmyk( 170, 85, 0, 225, 50 ) );
}
void TestQgsCompoundColorWidget::testComponentSettings_data()
{
QTest::addColumn<int>( "settingsComponent" );
QTest::addColumn<QgsColorWidget::ColorComponent>( "expectedComponent" );
QTest::addColumn<QgsColorWidget::ColorComponent>( "newComponent" );
QTest::addColumn<int>( "newSettingsComponent" );
QTest::newRow( "hue" ) << 0 << QgsColorWidget::ColorComponent::Hue << QgsColorWidget::ColorComponent::Saturation << 1;
QTest::newRow( "saturation" ) << 1 << QgsColorWidget::ColorComponent::Saturation << QgsColorWidget::ColorComponent::Value << 2;
QTest::newRow( "value" ) << 2 << QgsColorWidget::ColorComponent::Value << QgsColorWidget::ColorComponent::Red << 3;
QTest::newRow( "red" ) << 3 << QgsColorWidget::ColorComponent::Red << QgsColorWidget::ColorComponent::Green << 4;
QTest::newRow( "green" ) << 4 << QgsColorWidget::ColorComponent::Green << QgsColorWidget::ColorComponent::Blue << 5;
QTest::newRow( "blue" ) << 5 << QgsColorWidget::ColorComponent::Blue << QgsColorWidget::ColorComponent::Hue << 0;
QTest::newRow( "cyan" ) << 0 << QgsColorWidget::ColorComponent::Cyan << QgsColorWidget::ColorComponent::Magenta << 1;
QTest::newRow( "magenta" ) << 1 << QgsColorWidget::ColorComponent::Magenta << QgsColorWidget::ColorComponent::Yellow << 2;
QTest::newRow( "yellow" ) << 2 << QgsColorWidget::ColorComponent::Yellow << QgsColorWidget::ColorComponent::Black << 3;
QTest::newRow( "black" ) << 3 << QgsColorWidget::ColorComponent::Black << QgsColorWidget::ColorComponent::Cyan << 0;
}
void TestQgsCompoundColorWidget::testComponentSettings()
{
QFETCH( int, settingsComponent );
QFETCH( QgsColorWidget::ColorComponent, expectedComponent );
QFETCH( QgsColorWidget::ColorComponent, newComponent );
QFETCH( int, newSettingsComponent );
QgsSettings().setValue( QgsColorWidget::colorSpec( expectedComponent ) == QColor::Cmyk ?
QStringLiteral( "Windows/ColorDialog/activeCmykComponent" ) : QStringLiteral( "Windows/ColorDialog/activeComponent" ), settingsComponent );
QgsCompoundColorWidget w( nullptr, QgsColorWidget::colorSpec( expectedComponent ) == QColor::Cmyk ?
QColor::fromCmyk( 1, 2, 3, 4 ) : QColor( 10, 20, 30, 50 ) );
w.setVisible( true );
QCOMPARE( w.mColorBox->component(), expectedComponent );
QCOMPARE( w.mVerticalRamp->component(), expectedComponent );
( QgsColorWidget::colorSpec( expectedComponent ) == QColor::Cmyk ? w.mCmykRadios : w.mRgbRadios ).at( newSettingsComponent ).first->setChecked( true );
QCOMPARE( w.mColorBox->component(), newComponent );
QCOMPARE( w.mVerticalRamp->component(), newComponent );
w.saveSettings();
const int newValue = QgsSettings().value( QgsColorWidget::colorSpec( expectedComponent ) == QColor::Cmyk ?
QStringLiteral( "Windows/ColorDialog/activeCmykComponent" ) : QStringLiteral( "Windows/ColorDialog/activeComponent" ), -1 ).toInt();
QCOMPARE( newValue, newSettingsComponent );
}
void TestQgsCompoundColorWidget::testComponentChange()
{
QgsSettings().setValue( QStringLiteral( "Windows/ColorDialog/activeComponent" ), 3 );
QgsCompoundColorWidget w( nullptr, QColor( 10, 20, 30, 50 ) );
w.setVisible( true );
QCOMPARE( w.mColorBox->component(), QgsColorWidget::Red );
QCOMPARE( w.mVerticalRamp->component(), QgsColorWidget::Red );
const QList<QPair<QRadioButton *, QgsColorWidget::ColorComponent>> colors =
{
{ w.mHueRadio, QgsColorWidget::Hue },
{ w.mSaturationRadio, QgsColorWidget::Saturation },
{ w.mValueRadio, QgsColorWidget::Value },
{ w.mRedRadio, QgsColorWidget::Red },
{ w.mGreenRadio, QgsColorWidget::Green },
{ w.mBlueRadio, QgsColorWidget::Blue },
{ w.mCyanRadio, QgsColorWidget::Cyan },
{ w.mMagentaRadio, QgsColorWidget::Magenta },
{ w.mYellowRadio, QgsColorWidget::Yellow },
{ w.mBlackRadio, QgsColorWidget::Black }
};
for ( QPair<QRadioButton *, QgsColorWidget::ColorComponent> color : colors )
{
if ( QgsColorWidget::colorSpec( color.second ) != w.mColorModel->currentData() )
w.mColorModel->setCurrentIndex( w.mColorModel->findData( QgsColorWidget::colorSpec( color.second ) ) );
color.first->setChecked( true );
QCOMPARE( w.mColorBox->component(), color.second );
QCOMPARE( w.mVerticalRamp->component(), color.second );
}
}
void TestQgsCompoundColorWidget::testModelChange()
{
QgsCompoundColorWidget w( nullptr, QColor( 10, 20, 30, 50 ) );
w.setVisible( true );
QCOMPARE( w.mColorModel->currentData(), QColor::Rgb );
w.mColorModel->setCurrentIndex( w.mColorModel->findData( QColor::Cmyk ) );
QCOMPARE( w.mColorModel->currentData(), QColor::Cmyk );
w.setColor( QColor( 1, 2, 3 ) );
QCOMPARE( w.mColorModel->currentData(), QColor::Rgb );
}
void TestQgsCompoundColorWidget::testTabChange()
{
QgsCompoundColorWidget w( nullptr, QColor( 10, 20, 30, 50 ) );
w.setVisible( true );
QCOMPARE( w.mTabWidget->currentIndex(), 0 );
QVERIFY( w.mRedRadio->isEnabled() );
QVERIFY( w.mBlueRadio->isEnabled() );
QVERIFY( w.mGreenRadio->isEnabled() );
QVERIFY( w.mHueRadio->isEnabled() );
QVERIFY( w.mSaturationRadio->isEnabled() );
QVERIFY( w.mCyanRadio->isEnabled() );
QVERIFY( w.mMagentaRadio->isEnabled() );
QVERIFY( w.mYellowRadio->isEnabled() );
QVERIFY( w.mBlackRadio->isEnabled() );
w.mTabWidget->setCurrentIndex( 1 );
QVERIFY( !w.mRedRadio->isEnabled() );
QVERIFY( !w.mBlueRadio->isEnabled() );
QVERIFY( !w.mGreenRadio->isEnabled() );
QVERIFY( !w.mHueRadio->isEnabled() );
QVERIFY( !w.mSaturationRadio->isEnabled() );
QVERIFY( !w.mCyanRadio->isEnabled() );
QVERIFY( !w.mMagentaRadio->isEnabled() );
QVERIFY( !w.mYellowRadio->isEnabled() );
QVERIFY( !w.mBlackRadio->isEnabled() );
}
QGSTEST_MAIN( TestQgsCompoundColorWidget )
#include "testqgscompoundcolorwidget.moc"

View File

@ -0,0 +1,172 @@
"""QGIS Unit tests for QgsColorWidget
.. note:: 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.
"""
__author__ = 'Julien Cabieces'
__date__ = '02/05/2024'
__copyright__ = 'Copyright 2024, The QGIS Project'
from qgis.PyQt.QtGui import QColor
from qgis.gui import QgsColorWidget
import unittest
from qgis.testing import start_app, QgisTestCase
start_app()
class TestQgsColorWidget(QgisTestCase):
def testAlterColor(self):
"""
test alterColor method
"""
# rgb
color = QColor(12, 34, 56)
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Red, 112)
self.assertEqual(color, QColor(112, 34, 56, 255))
self.assertEqual(color.spec(), QColor.Spec.Rgb)
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Green, 134)
self.assertEqual(color.spec(), QColor.Spec.Rgb)
self.assertEqual(color, QColor(112, 134, 56, 255))
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Blue, 156)
self.assertEqual(color.spec(), QColor.Spec.Rgb)
self.assertEqual(color, QColor(112, 134, 156, 255))
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Alpha, 210)
self.assertEqual(color.spec(), QColor.Spec.Rgb)
self.assertEqual(color, QColor(112, 134, 156, 210))
# hsv
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Hue, 100)
self.assertEqual(color.spec(), QColor.Spec.Hsv)
self.assertEqual(color, QColor.fromHsv(100, 72, 156, 210))
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Saturation, 150)
self.assertEqual(color.spec(), QColor.Spec.Hsv)
self.assertEqual(color, QColor.fromHsv(100, 150, 156, 210))
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Value, 200)
self.assertEqual(color.spec(), QColor.Spec.Hsv)
self.assertEqual(color, QColor.fromHsv(100, 150, 200, 210))
# clipped value
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Value, 300)
self.assertEqual(color.spec(), QColor.Spec.Hsv)
self.assertEqual(color, QColor.fromHsv(100, 150, 255, 210))
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Value, -2)
self.assertEqual(color.spec(), QColor.Spec.Hsv)
self.assertEqual(color, QColor.fromHsv(100, 150, 0, 210))
# cmyk
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Cyan, 22)
self.assertEqual(color.spec(), QColor.Spec.Cmyk)
self.assertEqual(color, QColor.fromCmyk(22, 0, 0, 255, 210))
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Magenta, 33)
self.assertEqual(color.spec(), QColor.Spec.Cmyk)
self.assertEqual(color, QColor.fromCmyk(22, 33, 0, 255, 210))
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Yellow, 44)
self.assertEqual(color.spec(), QColor.Spec.Cmyk)
self.assertEqual(color, QColor.fromCmyk(22, 33, 44, 255, 210))
QgsColorWidget.alterColor(color, QgsColorWidget.ColorComponent.Black, 55)
self.assertEqual(color.spec(), QColor.Spec.Cmyk)
self.assertEqual(color, QColor.fromCmyk(22, 33, 44, 55, 210))
def testSetComponentValue(self):
"""
test setComponentValue method
"""
w = QgsColorWidget()
w.setColor(QColor(12, 34, 56))
self.assertEqual(w.color(), QColor(12, 34, 56))
# rgb
w.setComponent(QgsColorWidget.ColorComponent.Red)
w.setComponentValue(112)
self.assertEqual(w.color(), QColor(112, 34, 56, 255))
self.assertEqual(w.color().spec(), QColor.Spec.Rgb)
w.setComponent(QgsColorWidget.ColorComponent.Green)
w.setComponentValue(134)
self.assertEqual(w.color().spec(), QColor.Spec.Rgb)
self.assertEqual(w.color(), QColor(112, 134, 56, 255))
w.setComponent(QgsColorWidget.ColorComponent.Blue)
w.setComponentValue(156)
self.assertEqual(w.color().spec(), QColor.Spec.Rgb)
self.assertEqual(w.color(), QColor(112, 134, 156, 255))
w.setComponent(QgsColorWidget.ColorComponent.Alpha)
w.setComponentValue(210)
self.assertEqual(w.color().spec(), QColor.Spec.Rgb)
self.assertEqual(w.color(), QColor(112, 134, 156, 210))
# hsv
w.setComponent(QgsColorWidget.ColorComponent.Hue)
w.setComponentValue(100)
self.assertEqual(w.color().spec(), QColor.Spec.Hsv)
self.assertEqual(w.color(), QColor.fromHsv(100, 72, 156, 210))
w.setComponent(QgsColorWidget.ColorComponent.Saturation)
w.setComponentValue(150)
self.assertEqual(w.color().spec(), QColor.Spec.Hsv)
self.assertEqual(w.color(), QColor.fromHsv(100, 150, 156, 210))
w.setComponent(QgsColorWidget.ColorComponent.Value)
w.setComponentValue(200)
self.assertEqual(w.color().spec(), QColor.Spec.Hsv)
self.assertEqual(w.color(), QColor.fromHsv(100, 150, 200, 210))
# clipped value
w.setComponent(QgsColorWidget.ColorComponent.Value)
w.setComponentValue(300)
self.assertEqual(w.color().spec(), QColor.Spec.Hsv)
self.assertEqual(w.color(), QColor.fromHsv(100, 150, 255, 210))
w.setComponent(QgsColorWidget.ColorComponent.Value)
w.setComponentValue(-2)
self.assertEqual(w.color().spec(), QColor.Spec.Hsv)
self.assertEqual(w.color(), QColor.fromHsv(100, 150, 0, 210))
# Multiple component has no effect
w.setComponent(QgsColorWidget.ColorComponent.Multiple)
w.setComponentValue(18)
self.assertEqual(w.color().spec(), QColor.Spec.Hsv)
self.assertEqual(w.color(), QColor.fromHsv(100, 150, 0, 210))
# set an achromatic color to check it keeps the hue
w.setColor(QColor(130, 130, 130, 255))
self.assertEqual(w.color().spec(), QColor.Spec.Rgb)
self.assertEqual(w.color(), QColor(130, 130, 130, 255))
w.setComponent(QgsColorWidget.ColorComponent.Value)
w.setComponentValue(42)
self.assertEqual(w.color(), QColor.fromHsv(100, 0, 42, 255))
self.assertEqual(w.componentValue(QgsColorWidget.ColorComponent.Hue), 100)
# cmyk
w.setComponent(QgsColorWidget.ColorComponent.Cyan)
w.setComponentValue(22)
self.assertEqual(w.color().spec(), QColor.Spec.Cmyk)
self.assertEqual(w.color(), QColor.fromCmyk(22, 0, 0, 213, 255))
w.setComponent(QgsColorWidget.ColorComponent.Magenta)
w.setComponentValue(33)
self.assertEqual(w.color().spec(), QColor.Spec.Cmyk)
self.assertEqual(w.color(), QColor.fromCmyk(22, 33, 0, 213, 255))
w.setComponent(QgsColorWidget.ColorComponent.Yellow)
w.setComponentValue(44)
self.assertEqual(w.color().spec(), QColor.Spec.Cmyk)
self.assertEqual(w.color(), QColor.fromCmyk(22, 33, 44, 213, 255))
w.setComponent(QgsColorWidget.ColorComponent.Black)
w.setComponentValue(55)
self.assertEqual(w.color().spec(), QColor.Spec.Cmyk)
self.assertEqual(w.color(), QColor.fromCmyk(22, 33, 44, 55, 255))
# set an achromatic color to check it keeps the hue (set from former cmyk values)
self.assertEqual(w.color().hue(), 30)
w.setColor(QColor(130, 130, 130, 255))
self.assertEqual(w.color().spec(), QColor.Spec.Rgb)
self.assertEqual(w.color(), QColor(130, 130, 130, 255))
w.setComponent(QgsColorWidget.ColorComponent.Value)
w.setComponentValue(42)
self.assertEqual(w.color(), QColor.fromHsv(30, 0, 42, 255))
self.assertEqual(w.componentValue(QgsColorWidget.ColorComponent.Hue), 30)
if __name__ == '__main__':
unittest.main()