From 6b97709848e9900906bae04a1dab144e3cda2a00 Mon Sep 17 00:00:00 2001 From: Julien Cabieces Date: Tue, 13 Aug 2024 15:41:06 +0200 Subject: [PATCH] ui(ColorWidget): Display CMYK components as percent --- .../gui/auto_additions/qgscolorwidgets.py | 6 +++ .../gui/auto_generated/qgscolorwidgets.sip.in | 13 +++++ python/gui/auto_additions/qgscolorwidgets.py | 6 +++ .../gui/auto_generated/qgscolorwidgets.sip.in | 13 +++++ src/gui/qgscolorwidgets.cpp | 47 +++++++++++-------- src/gui/qgscolorwidgets.h | 16 +++++++ tests/src/gui/testqgscompoundcolorwidget.cpp | 37 ++++++++++++++- 7 files changed, 117 insertions(+), 21 deletions(-) diff --git a/python/PyQt6/gui/auto_additions/qgscolorwidgets.py b/python/PyQt6/gui/auto_additions/qgscolorwidgets.py index e004c681cafc..aa0263207d46 100644 --- a/python/PyQt6/gui/auto_additions/qgscolorwidgets.py +++ b/python/PyQt6/gui/auto_additions/qgscolorwidgets.py @@ -11,6 +11,12 @@ QgsColorWidget.Magenta = QgsColorWidget.ColorComponent.Magenta QgsColorWidget.Yellow = QgsColorWidget.ColorComponent.Yellow QgsColorWidget.Black = QgsColorWidget.ColorComponent.Black +# monkey patching scoped based enum +QgsColorWidget.ComponentUnit.Raw.__doc__ = "Raw values in the range 0-255" +QgsColorWidget.ComponentUnit.Percent.__doc__ = "Percent values in the range 0-100" +QgsColorWidget.ComponentUnit.Degree.__doc__ = "Degree values in the range 0-359" +QgsColorWidget.ComponentUnit.__doc__ = "Specified the color component unit\n\n" + '* ``Raw``: ' + QgsColorWidget.ComponentUnit.Raw.__doc__ + '\n' + '* ``Percent``: ' + QgsColorWidget.ComponentUnit.Percent.__doc__ + '\n' + '* ``Degree``: ' + QgsColorWidget.ComponentUnit.Degree.__doc__ +# -- QgsColorRampWidget.Horizontal = QgsColorRampWidget.Orientation.Horizontal QgsColorRampWidget.Vertical = QgsColorRampWidget.Orientation.Vertical QgsColorTextWidget.HexRgb = QgsColorTextWidget.ColorTextFormat.HexRgb diff --git a/python/PyQt6/gui/auto_generated/qgscolorwidgets.sip.in b/python/PyQt6/gui/auto_generated/qgscolorwidgets.sip.in index f23e64ec19e9..ddf0729d9e34 100644 --- a/python/PyQt6/gui/auto_generated/qgscolorwidgets.sip.in +++ b/python/PyQt6/gui/auto_generated/qgscolorwidgets.sip.in @@ -40,6 +40,13 @@ set to a color with an ambiguous hue (e.g., black or white shades). Black }; + enum class ComponentUnit + { + Raw, + Percent, + Degree + }; + QgsColorWidget( QWidget *parent /TransferThis/ = 0, ColorComponent component = Multiple ); %Docstring Construct a new color widget. @@ -102,6 +109,12 @@ Create an icon for dragging colors :param color: for icon %End + static ComponentUnit componentUnit( ColorComponent component ); +%Docstring +Returns color ``component`` unit +%End + + public slots: virtual void setColor( const QColor &color, bool emitSignals = false ); diff --git a/python/gui/auto_additions/qgscolorwidgets.py b/python/gui/auto_additions/qgscolorwidgets.py index f0bd913f00b7..90e69a218ffc 100644 --- a/python/gui/auto_additions/qgscolorwidgets.py +++ b/python/gui/auto_additions/qgscolorwidgets.py @@ -1,2 +1,8 @@ # The following has been generated automatically from src/gui/qgscolorwidgets.h +# monkey patching scoped based enum +QgsColorWidget.ComponentUnit.Raw.__doc__ = "Raw values in the range 0-255" +QgsColorWidget.ComponentUnit.Percent.__doc__ = "Percent values in the range 0-100" +QgsColorWidget.ComponentUnit.Degree.__doc__ = "Degree values in the range 0-359" +QgsColorWidget.ComponentUnit.__doc__ = "Specified the color component unit\n\n" + '* ``Raw``: ' + QgsColorWidget.ComponentUnit.Raw.__doc__ + '\n' + '* ``Percent``: ' + QgsColorWidget.ComponentUnit.Percent.__doc__ + '\n' + '* ``Degree``: ' + QgsColorWidget.ComponentUnit.Degree.__doc__ +# -- QgsColorTextWidget.ColorTextFormat.baseClass = QgsColorTextWidget diff --git a/python/gui/auto_generated/qgscolorwidgets.sip.in b/python/gui/auto_generated/qgscolorwidgets.sip.in index c9b47294de3d..affcc5a95f18 100644 --- a/python/gui/auto_generated/qgscolorwidgets.sip.in +++ b/python/gui/auto_generated/qgscolorwidgets.sip.in @@ -40,6 +40,13 @@ set to a color with an ambiguous hue (e.g., black or white shades). Black }; + enum class ComponentUnit + { + Raw, + Percent, + Degree + }; + QgsColorWidget( QWidget *parent /TransferThis/ = 0, ColorComponent component = Multiple ); %Docstring Construct a new color widget. @@ -102,6 +109,12 @@ Create an icon for dragging colors :param color: for icon %End + static ComponentUnit componentUnit( ColorComponent component ); +%Docstring +Returns color ``component`` unit +%End + + public slots: virtual void setColor( const QColor &color, bool emitSignals = false ); diff --git a/src/gui/qgscolorwidgets.cpp b/src/gui/qgscolorwidgets.cpp index 1ff6dca0d765..3f3da7281de8 100644 --- a/src/gui/qgscolorwidgets.cpp +++ b/src/gui/qgscolorwidgets.cpp @@ -92,6 +92,26 @@ QPixmap QgsColorWidget::createDragIcon( const QColor &color ) return pixmap; } +QgsColorWidget::ComponentUnit QgsColorWidget::componentUnit( ColorComponent component ) +{ + switch ( component ) + { + case QgsColorWidget::Hue: + return ComponentUnit::Degree; + case QgsColorWidget::Saturation: + case QgsColorWidget::Value: + case QgsColorWidget::Alpha: + case QgsColorWidget::Cyan: + case QgsColorWidget::Magenta: + case QgsColorWidget::Yellow: + case QgsColorWidget::Black: + return ComponentUnit::Percent; + + default: + return ComponentUnit::Raw; + } +} + int QgsColorWidget::componentValue( const QgsColorWidget::ColorComponent component ) const { return static_cast( std::round( componentValueF( component ) * static_cast( componentRange( component ) ) ) ); @@ -1445,15 +1465,6 @@ QgsColorSliderWidget::QgsColorSliderWidget( QWidget *parent, const ColorComponen mSpinBox->setMinimum( 0 ); mSpinBox->setMaximum( convertRealToDisplay( 1.f ) ); mSpinBox->setValue( convertRealToDisplay( componentValueF() ) ); - if ( component == QgsColorWidget::Hue ) - { - //degrees suffix for hue - mSpinBox->setSuffix( QChar( 176 ) ); - } - else if ( component == QgsColorWidget::Saturation || component == QgsColorWidget::Value || component == QgsColorWidget::Alpha ) - { - mSpinBox->setSuffix( tr( "%" ) ); - } hLayout->addWidget( mSpinBox ); setLayout( hLayout ); @@ -1466,15 +1477,13 @@ void QgsColorSliderWidget::setComponent( const QgsColorWidget::ColorComponent co { QgsColorWidget::setComponent( component ); mRampWidget->setComponent( component ); - mSpinBox->setMaximum( convertRealToDisplay( componentRange() ) ); - if ( component == QgsColorWidget::Hue ) + mSpinBox->setMaximum( convertRealToDisplay( static_cast( componentRange() ) ) ); + if ( componentUnit( component ) == ComponentUnit::Degree ) { - //degrees suffix for hue mSpinBox->setSuffix( QChar( 176 ) ); } - else if ( component == QgsColorWidget::Saturation || component == QgsColorWidget::Value || component == QgsColorWidget::Alpha ) + else if ( componentUnit( component ) == ComponentUnit::Percent ) { - //saturation, value and alpha are in % mSpinBox->setSuffix( tr( "%" ) ); } else @@ -1527,13 +1536,11 @@ void QgsColorSliderWidget::rampChanged( float value ) float QgsColorSliderWidget::convertRealToDisplay( const float realValue ) const { - //scale saturation, value or alpha to 0->100 range. This makes more sense for users - //for whom "255" is a totally arbitrary value! - if ( mComponent == QgsColorWidget::Saturation || mComponent == QgsColorWidget::Value || mComponent == QgsColorWidget::Alpha ) + if ( componentUnit( mComponent ) == ComponentUnit::Percent ) { return realValue * 100.f; } - else if ( mComponent == QgsColorWidget::Hue ) + else if ( componentUnit( mComponent ) == ComponentUnit::Degree ) { return realValue * HUE_MAX; } @@ -1545,11 +1552,11 @@ float QgsColorSliderWidget::convertRealToDisplay( const float realValue ) const float QgsColorSliderWidget::convertDisplayToReal( const float displayValue ) const { - if ( mComponent == QgsColorWidget::Saturation || mComponent == QgsColorWidget::Value || mComponent == QgsColorWidget::Alpha ) + if ( componentUnit( mComponent ) == ComponentUnit::Percent ) { return displayValue / 100.f; } - else if ( mComponent == QgsColorWidget::Hue ) + else if ( componentUnit( mComponent ) == ComponentUnit::Degree ) { return displayValue / HUE_MAX; } diff --git a/src/gui/qgscolorwidgets.h b/src/gui/qgscolorwidgets.h index 9b5c5bc3899b..e3f3bb880cf4 100644 --- a/src/gui/qgscolorwidgets.h +++ b/src/gui/qgscolorwidgets.h @@ -60,6 +60,16 @@ class GUI_EXPORT QgsColorWidget : public QWidget Black //!< Black component (based on CMYK model) of color }; + /** + * Specified the color component unit + */ + enum class ComponentUnit + { + Raw, //!< Raw values in the range 0-255 + Percent, //!< Percent values in the range 0-100 + Degree //!< Degree values in the range 0-359 + }; + /** * Construct a new color widget. * \param parent parent QWidget for the widget @@ -107,6 +117,12 @@ class GUI_EXPORT QgsColorWidget : public QWidget */ static QPixmap createDragIcon( const QColor &color ); + /** + * Returns color \a component unit + */ + static ComponentUnit componentUnit( ColorComponent component ); + + public slots: /** diff --git a/tests/src/gui/testqgscompoundcolorwidget.cpp b/tests/src/gui/testqgscompoundcolorwidget.cpp index 66d8f915103a..1150884c7472 100644 --- a/tests/src/gui/testqgscompoundcolorwidget.cpp +++ b/tests/src/gui/testqgscompoundcolorwidget.cpp @@ -45,6 +45,7 @@ class TestQgsCompoundColorWidget : public QgsTest void testModelChange(); void testTabChange(); void testSliderWidgets(); + void testSliderWidgetsCmyk(); }; void TestQgsCompoundColorWidget::initTestCase() @@ -232,7 +233,7 @@ void TestQgsCompoundColorWidget::testTabChange() void TestQgsCompoundColorWidget::testSliderWidgets() { - QgsCompoundColorWidget w( nullptr, QColor::fromRgbF( 0.12f, 0.34f, 0.56, 0.78 ) ); + QgsCompoundColorWidget w( nullptr, QColor::fromRgbF( 0.12f, 0.34f, 0.56f, 0.78f ) ); w.setVisible( true ); QCOMPARE( w.mRedSlider->mSpinBox->value(), 30.6 ); @@ -270,6 +271,40 @@ void TestQgsCompoundColorWidget::testSliderWidgets() compareFloat( w.mValueSlider->mRampWidget->color().greenF(), 0.5f ); } +void TestQgsCompoundColorWidget::testSliderWidgetsCmyk() +{ + QgsCompoundColorWidget w( nullptr, QColor::fromCmykF( 0.12f, 0.34f, 0.56f, 0.78f, 0.91f ) ); + w.setVisible( true ); + + QCOMPARE( w.mCyanSlider->mSpinBox->value(), 12 ); + compareFloat( w.mCyanSlider->mRampWidget->color().cyanF(), 0.12f ); + QCOMPARE( w.mMagentaSlider->mSpinBox->value(), 34 ); + compareFloat( w.mMagentaSlider->mRampWidget->color().magentaF(), 0.34f ); + QCOMPARE( w.mYellowSlider->mSpinBox->value(), 56 ); + compareFloat( w.mYellowSlider->mRampWidget->color().yellowF(), 0.56f ); + QCOMPARE( w.mBlackSlider->mSpinBox->value(), 78 ); + compareFloat( w.mBlackSlider->mRampWidget->color().blackF(), 0.78f ); + QCOMPARE( w.mAlphaSlider->mSpinBox->value(), 91 ); + compareFloat( w.mAlphaSlider->mRampWidget->color().alphaF(), 0.91f ); + + w.mCyanSlider->mRampWidget->setColorFromPoint( QPointF( static_cast( w.mCyanSlider->mRampWidget->width() ) / 2.f, 0.f ) ); + w.mMagentaSlider->mRampWidget->setColorFromPoint( QPointF( static_cast( w.mMagentaSlider->mRampWidget->width() ) / 2.f, 0.f ) ); + w.mYellowSlider->mRampWidget->setColorFromPoint( QPointF( static_cast( w.mYellowSlider->mRampWidget->width() ) / 2.f, 0.f ) ); + w.mBlackSlider->mRampWidget->setColorFromPoint( QPointF( static_cast( w.mBlackSlider->mRampWidget->width() ) / 2.f, 0.f ) ); + w.mAlphaSlider->mRampWidget->setColorFromPoint( QPointF( static_cast( w.mAlphaSlider->mRampWidget->width() ) / 2.f, 0.f ) ); + + QCOMPARE( w.mCyanSlider->mSpinBox->value(), 50 ); + compareFloat( w.mCyanSlider->mRampWidget->color().cyanF(), 0.5f ); + QCOMPARE( w.mMagentaSlider->mSpinBox->value(), 50 ); + compareFloat( w.mMagentaSlider->mRampWidget->color().magentaF(), 0.5f ); + QCOMPARE( w.mYellowSlider->mSpinBox->value(), 50 ); + compareFloat( w.mYellowSlider->mRampWidget->color().yellowF(), 0.5f ); + QCOMPARE( w.mBlackSlider->mSpinBox->value(), 50 ); + compareFloat( w.mBlackSlider->mRampWidget->color().blackF(), 0.5f ); + QCOMPARE( w.mAlphaSlider->mSpinBox->value(), 50 ); + compareFloat( w.mAlphaSlider->mRampWidget->color().alphaF(), 0.5f ); +} + QGSTEST_MAIN( TestQgsCompoundColorWidget ) #include "testqgscompoundcolorwidget.moc"