23#include <QResizeEvent>
25#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
26#include <QStyleOptionFrameV3>
28#include <QStyleOptionFrame>
34#include <QFontMetrics>
50 , mCurrentColor( Qt::red )
51 , mComponent( component )
53 setAcceptDrops(
true );
65 QPixmap pixmap( iconSize, iconSize );
66 pixmap.fill( Qt::transparent );
68 painter.begin( &pixmap );
70 painter.fillRect( QRect( 0, 0, iconSize, iconSize ), QBrush( QColor( 200, 200, 200 ) ) );
72 QColor pixmapColor =
color;
73 pixmapColor.setAlpha( 255 );
74 painter.setBrush( QBrush( pixmapColor ) );
75 painter.setPen( QPen( Qt::white ) );
76 painter.drawRect( QRect( 1, 1, iconSize - 2, iconSize - 2 ) );
163 color.getCmyk( &
c, &m, &y, &k, &a );
168 if (
c == clippedValue )
172 color.setCmyk( clippedValue, m, y, k, a );
175 if ( m == clippedValue )
179 color.setCmyk(
c, clippedValue, y, k, a );
182 if ( y == clippedValue )
186 color.setCmyk(
c, m, clippedValue, k, a );
189 if ( k == clippedValue )
193 color.setCmyk(
c, m, y, clippedValue, a );
202 color.getRgb( &r, &g, &b, &a );
204 color.getHsv( &h, &s, &v );
209 if ( r == clippedValue )
213 color.setRed( clippedValue );
216 if ( g == clippedValue )
220 color.setGreen( clippedValue );
223 if ( b == clippedValue )
227 color.setBlue( clippedValue );
230 if ( h == clippedValue )
234 color.setHsv( clippedValue, s, v, a );
237 if ( s == clippedValue )
241 color.setHsv( h, clippedValue, v, a );
244 if ( v == clippedValue )
248 color.setHsv( h, s, clippedValue, a );
251 if ( a == clippedValue )
255 color.setAlpha( clippedValue );
270 return QColor::Spec::Rgb;
275 return QColor::Spec::Hsv;
281 return QColor::Spec::Cmyk;
284 return QColor::Spec::Invalid;
295 static QPixmap sTranspBkgrd;
297 if ( sTranspBkgrd.isNull() )
309 if ( mimeColor.isValid() )
312 e->acceptProposedAction();
319 bool hasAlpha =
false;
322 if ( mimeColor.isValid() )
325 e->acceptProposedAction();
414 if (
color.hue() >= 0 )
436 QConicalGradient wheelGradient = QConicalGradient( 0, 0, 0 );
437 const int wheelStops = 20;
438 QColor gradColor = QColor::fromHsvF( 1.0, 1.0, 1.0 );
439 for (
int pos = 0; pos <= wheelStops; ++pos )
441 const double relativePos =
static_cast<double>( pos ) / wheelStops;
442 gradColor.setHsvF( relativePos, 1, 1 );
443 wheelGradient.setColorAt( relativePos, gradColor );
445 mWheelBrush = QBrush( wheelGradient );
453 return QSize( size, size );
459 QPainter painter(
this );
461 if ( mWidgetImage.isNull() || mWheelImage.isNull() || mTriangleImage.isNull() )
463 createImages( size() );
467 mWidgetImage.fill( Qt::transparent );
468 QPainter imagePainter( &mWidgetImage );
469 imagePainter.setRenderHint( QPainter::Antialiasing );
478 const QPointF center = QPointF( mWidgetImage.width() / 2.0, mWidgetImage.height() / 2.0 );
479 imagePainter.drawImage( QPointF( center.x() - ( mWheelImage.width() / 2.0 ), center.y() - ( mWheelImage.height() / 2.0 ) ), mWheelImage );
483 const double length = mWheelImage.width() / 2.0;
484 QLineF hueMarkerLine = QLineF( center.x(), center.y(), center.x() + length, center.y() );
485 hueMarkerLine.setAngle( h );
488 imagePainter.setCompositionMode( QPainter::CompositionMode_SourceIn );
490 pen.setWidthF( 2 * devicePixelRatioF() );
492 pen.setColor( h > 20 && h < 200 ? Qt::black : Qt::white );
493 imagePainter.setPen( pen );
494 imagePainter.drawLine( hueMarkerLine );
495 imagePainter.restore();
498 if ( mTriangleDirty )
502 imagePainter.drawImage( QPointF( center.x() - ( mWheelImage.width() / 2.0 ), center.y() - ( mWheelImage.height() / 2.0 ) ), mTriangleImage );
505 const double triangleRadius = length - mWheelThickness * devicePixelRatioF() - 1;
509 const double hueRadians = ( h * M_PI / 180.0 );
510 const double hx = std::cos( hueRadians ) * triangleRadius;
511 const double hy = -std::sin( hueRadians ) * triangleRadius;
512 const double sx = -std::cos( -hueRadians + ( M_PI / 3.0 ) ) * triangleRadius;
513 const double sy = -std::sin( -hueRadians + ( M_PI / 3.0 ) ) * triangleRadius;
514 const double vx = -std::cos( hueRadians + ( M_PI / 3.0 ) ) * triangleRadius;
515 const double vy = std::sin( hueRadians + ( M_PI / 3.0 ) ) * triangleRadius;
516 const double mx = ( sx + vx ) / 2.0;
517 const double my = ( sy + vy ) / 2.0;
519 const double a = ( 1 - 2.0 * std::fabs( lightness - 0.5 ) ) *
mCurrentColor.hslSaturationF();
520 const double x = sx + ( vx - sx ) * lightness + ( hx - mx ) * a;
521 const double y = sy + ( vy - sy ) * lightness + ( hy - my ) * a;
524 pen.setColor( lightness > 0.7 ? Qt::black : Qt::white );
525 imagePainter.setPen( pen );
526 imagePainter.setBrush( Qt::NoBrush );
527 imagePainter.drawEllipse( QPointF( x + center.x(), y + center.y() ), 4.0 * devicePixelRatioF(), 4.0 * devicePixelRatioF() );
531 painter.drawImage( QRectF( 0, 0, width(), height() ), mWidgetImage );
540 mTriangleDirty =
true;
546void QgsColorWheel::createImages(
const QSizeF size )
548 const double wheelSize = std::min( size.width(), size.height() ) - mMargin * 2.0;
549 mWheelThickness = wheelSize / 15.0;
552 const double pixelRatio = devicePixelRatioF();
553 mWheelImage = QImage( wheelSize * pixelRatio,
554 wheelSize * pixelRatio, QImage::Format_ARGB32 );
555 mTriangleImage = QImage( wheelSize * pixelRatio,
556 wheelSize * pixelRatio, QImage::Format_ARGB32 );
557 mWidgetImage = QImage( size.width() * pixelRatio,
558 size.height() * pixelRatio, QImage::Format_ARGB32 );
562 mTriangleDirty =
true;
567 QgsColorWidget::resizeEvent( event );
570 if ( event->size().width() > parentWidget()->size().width() )
573 std::min( event->size().width(), parentWidget()->size().width() - 2 ),
574 std::min( event->size().height(), parentWidget()->size().height() - 2 )
577 createImages( newSize );
581 createImages( event->size() );
585 createImages( event->size() );
589void QgsColorWheel::setColorFromPos(
const QPointF pos )
591 const QPointF center = QPointF( width() / 2.0, height() / 2.0 );
593 const QLineF line = QLineF( center.x(), center.y(), pos.x(), pos.y() );
595 QColor newColor = QColor();
602 if ( mClickedPart == QgsColorWheel::Triangle )
607 const double x = pos.x() - center.x();
608 const double y = pos.y() - center.y();
610 double eventAngleRadians = line.angle() * M_PI / 180.0;
611 const double hueRadians = h * M_PI / 180.0;
612 double rad0 = std::fmod( eventAngleRadians + 2.0 * M_PI - hueRadians, 2.0 * M_PI );
613 double rad1 = std::fmod( rad0, ( ( 2.0 / 3.0 ) * M_PI ) ) - ( M_PI / 3.0 );
614 const double length = mWheelImage.width() / 2.0 / devicePixelRatioF();
615 const double triangleLength = length - mWheelThickness - 1;
617 const double a = 0.5 * triangleLength;
618 double b = std::tan( rad1 ) * a;
619 double r = std::sqrt( x * x + y * y );
620 const double maxR = std::sqrt( a * a + b * b );
624 const double dx = std::tan( rad1 ) * r;
625 double rad2 = std::atan( dx / maxR );
626 rad2 = std::min( rad2, M_PI / 3.0 );
627 rad2 = std::max( rad2, -M_PI / 3.0 );
628 eventAngleRadians += rad2 - rad1;
629 rad0 = std::fmod( eventAngleRadians + 2.0 * M_PI - hueRadians, 2.0 * M_PI );
630 rad1 = std::fmod( rad0, ( ( 2.0 / 3.0 ) * M_PI ) ) - ( M_PI / 3.0 );
631 b = std::tan( rad1 ) * a;
632 r = std::sqrt( a * a + b * b );
635 const double triangleSideLength = std::sqrt( 3.0 ) * triangleLength;
636 const double newL = ( ( -std::sin( rad0 ) * r ) / triangleSideLength ) + 0.5;
637 const double widthShare = 1.0 - ( std::fabs( newL - 0.5 ) * 2.0 );
638 const double newS = ( ( ( std::cos( rad0 ) * r ) + ( triangleLength / 2.0 ) ) / ( 1.5 * triangleLength ) ) / widthShare;
639 s = std::min(
static_cast< int >( std::round( std::max( 0.0, newS ) * 255.0 ) ), 255 );
640 l = std::min(
static_cast< int >( std::round( std::max( 0.0, newL ) * 255.0 ) ), 255 );
641 newColor = QColor::fromHsl( h, s, l );
643 newColor.setHsv( h, newColor.hsvSaturation(), newColor.value(), alpha );
645 else if ( mClickedPart == QgsColorWheel::Wheel )
650 const int newHue = line.angle();
651 newColor = QColor::fromHsv( newHue, s, v, alpha );
653 mTriangleDirty =
true;
675 setColorFromPos( event->pos() );
682 if ( event->button() == Qt::LeftButton )
688 const QLineF line = QLineF( width() / 2.0, height() / 2.0, event->pos().x(), event->pos().y() );
690 const double innerLength = mWheelImage.width() / 2.0 / devicePixelRatioF() - mWheelThickness;
691 if ( line.length() < innerLength )
693 mClickedPart = QgsColorWheel::Triangle;
697 mClickedPart = QgsColorWheel::Wheel;
699 setColorFromPos( event->pos() );
709 if ( event->button() == Qt::LeftButton )
712 mClickedPart = QgsColorWheel::None;
720void QgsColorWheel::createWheel()
722 if ( mWheelImage.isNull() )
727 const int maxSize = std::min( mWheelImage.width(), mWheelImage.height() );
728 const double wheelRadius = maxSize / 2.0;
730 mWheelImage.fill( Qt::transparent );
731 QPainter p( &mWheelImage );
732 p.setRenderHint( QPainter::Antialiasing );
733 p.setBrush( mWheelBrush );
734 p.setPen( Qt::NoPen );
737 p.translate( wheelRadius, wheelRadius );
738 p.drawEllipse( QPointF( 0.0, 0.0 ), wheelRadius, wheelRadius );
741 p.setCompositionMode( QPainter::CompositionMode_DestinationOut );
742 p.setBrush( QBrush( Qt::black ) );
743 p.drawEllipse( QPointF( 0,
745 wheelRadius - mWheelThickness * devicePixelRatioF(),
746 wheelRadius - mWheelThickness * devicePixelRatioF() );
752void QgsColorWheel::createTriangle()
754 if ( mWheelImage.isNull() || mTriangleImage.isNull() )
759 const QPointF center = QPointF( mWheelImage.width() / 2.0, mWheelImage.height() / 2.0 );
760 mTriangleImage.fill( Qt::transparent );
762 QPainter imagePainter( &mTriangleImage );
763 imagePainter.setRenderHint( QPainter::Antialiasing );
766 const double wheelRadius = mWheelImage.width() / 2.0;
767 const double triangleRadius = wheelRadius - mWheelThickness * devicePixelRatioF() - 1;
770 const QColor pureColor = QColor::fromHsv( angle, 255, 255 );
772 QColor alphaColor = QColor( pureColor );
773 alphaColor.setAlpha( 0 );
776 QLineF line1 = QLineF( center.x(), center.y(), center.x() - triangleRadius * std::cos( M_PI / 3.0 ), center.y() - triangleRadius * std::sin( M_PI / 3.0 ) );
777 QLineF line2 = QLineF( center.x(), center.y(), center.x() + triangleRadius, center.y() );
778 QLineF line3 = QLineF( center.x(), center.y(), center.x() - triangleRadius * std::cos( M_PI / 3.0 ), center.y() + triangleRadius * std::sin( M_PI / 3.0 ) );
779 QLineF line4 = QLineF( center.x(), center.y(), center.x() - triangleRadius * std::cos( M_PI / 3.0 ), center.y() );
780 QLineF line5 = QLineF( center.x(), center.y(), ( line2.p2().x() + line1.p2().x() ) / 2.0, ( line2.p2().y() + line1.p2().y() ) / 2.0 );
781 line1.setAngle( line1.angle() + angle );
782 line2.setAngle( line2.angle() + angle );
783 line3.setAngle( line3.angle() + angle );
784 line4.setAngle( line4.angle() + angle );
785 line5.setAngle( line5.angle() + angle );
786 const QPointF p1 = line1.p2();
787 const QPointF p2 = line2.p2();
788 const QPointF p3 = line3.p2();
789 const QPointF p4 = line4.p2();
790 const QPointF p5 = line5.p2();
793 QLinearGradient colorGrad = QLinearGradient( p4.x(), p4.y(), p2.x(), p2.y() );
794 colorGrad.setColorAt( 0, alphaColor );
795 colorGrad.setColorAt( 1, pureColor );
796 QLinearGradient whiteGrad = QLinearGradient( p3.x(), p3.y(), p5.x(), p5.y() );
797 whiteGrad.setColorAt( 0, QColor( 255, 255, 255, 255 ) );
798 whiteGrad.setColorAt( 1, QColor( 255, 255, 255, 0 ) );
801 triangle << p2 << p1 << p3 << p2;
802 imagePainter.setPen( Qt::NoPen );
804 imagePainter.setBrush( QBrush( Qt::black ) );
805 imagePainter.drawPolygon( triangle );
807 imagePainter.setBrush( QBrush( colorGrad ) );
808 imagePainter.drawPolygon( triangle );
810 imagePainter.setCompositionMode( QPainter::CompositionMode_Plus );
811 imagePainter.setBrush( QBrush( whiteGrad ) );
812 imagePainter.drawPolygon( triangle );
817 imagePainter.setCompositionMode( QPainter::CompositionMode_Source );
818 imagePainter.setBrush( Qt::NoBrush );
819 imagePainter.setPen( QPen( Qt::transparent ) );
820 imagePainter.drawPolygon( triangle );
823 mTriangleDirty =
false;
835 setFocusPolicy( Qt::StrongFocus );
836 setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
838 mBoxImage =
new QImage( width() - mMargin * 2, height() - mMargin * 2, QImage::Format_RGB32 );
849 return QSize( size, size );
855 QPainter painter(
this );
857 QStyleOptionFrame option;
858 option.initFrom(
this );
859 option.state = hasFocus() ? QStyle::State_Active : QStyle::State_None;
860 style()->drawPrimitive( QStyle::PE_Frame, &option, &painter );
868 painter.drawImage( QPoint( mMargin, mMargin ), *mBoxImage );
871 const double xPos = mMargin + ( width() - 2 * mMargin - 1 ) *
static_cast<double>( xComponentValue() ) /
static_cast<double>( valueRangeX() );
872 const double yPos = mMargin + ( height() - 2 * mMargin - 1 ) - ( height() - 2 * mMargin - 1 ) *
static_cast<double>( yComponentValue() ) /
static_cast<double>( valueRangeY() );
874 painter.setBrush( Qt::white );
875 painter.setPen( Qt::NoPen );
877 painter.drawRect( xPos - 1, mMargin, 3, height() - 2 * mMargin - 1 );
878 painter.drawRect( mMargin, yPos - 1, width() - 2 * mMargin - 1, 3 );
879 painter.setPen( Qt::black );
880 painter.drawLine( xPos, mMargin, xPos, height() - mMargin - 1 );
881 painter.drawLine( mMargin, yPos, width() - mMargin - 1, yPos );
919 mBoxImage =
new QImage( event->size().width() - mMargin * 2, event->size().height() - mMargin * 2, QImage::Format_RGB32 );
920 QgsColorWidget::resizeEvent( event );
927 setColorFromPoint( event->pos() );
934 if ( event->button() == Qt::LeftButton )
937 setColorFromPoint( event->pos() );
947 if ( event->button() == Qt::LeftButton )
957void QgsColorBox::createBox()
959 const int maxValueX = mBoxImage->width();
960 const int maxValueY = mBoxImage->height();
964 int colorComponentValue;
966 for (
int y = 0; y < maxValueY; ++y )
968 QRgb *scanLine = ( QRgb * )mBoxImage->scanLine( y );
970 colorComponentValue = int( valueRangeY() - valueRangeY() * (
double( y ) / maxValueY ) );
971 alterColor( currentColor, yComponent(), colorComponentValue );
972 for (
int x = 0; x < maxValueX; ++x )
974 colorComponentValue = int( valueRangeX() * (
double( x ) / maxValueX ) );
975 alterColor( currentColor, xComponent(), colorComponentValue );
976 scanLine[x] = currentColor.rgb();
982int QgsColorBox::valueRangeX()
const
987int QgsColorBox::valueRangeY()
const
1020int QgsColorBox::yComponentValue()
const
1053int QgsColorBox::xComponentValue()
const
1058void QgsColorBox::setColorFromPoint( QPoint point )
1060 int valX = valueRangeX() * ( point.x() - mMargin ) / ( width() - 2 * mMargin - 1 );
1061 valX = std::min( std::max( valX, 0 ), valueRangeX() );
1063 int valY = valueRangeY() - valueRangeY() * ( point.y() - mMargin ) / ( height() - 2 * mMargin - 1 );
1064 valY = std::min( std::max( valY, 0 ), valueRangeY() );
1075 if (
color.hue() >= 0 )
1095 setFocusPolicy( Qt::StrongFocus );
1119 QPainter painter(
this );
1124 QStyleOptionFrame option;
1125 option.initFrom(
this );
1126 option.state = hasFocus() ? QStyle::State_KeyboardFocusChange : QStyle::State_None;
1127 style()->drawPrimitive( QStyle::PE_Frame, &option, &painter );
1133 QStyleOptionFocusRect option;
1134 option.initFrom(
this );
1135 option.state = QStyle::State_KeyboardFocusChange;
1136 style()->drawPrimitive( QStyle::PE_FrameFocusRect, &option, &painter );
1143 color.setAlpha( 255 );
1150 painter.setPen( pen );
1151 painter.setBrush( Qt::NoBrush );
1154 for (
int c = 0;
c <= maxValue; ++
c )
1156 int colorVal =
static_cast<int>(
componentRange() *
static_cast<double>(
c ) / maxValue );
1163 if (
color.hue() < 0 )
1167 pen.setColor(
color );
1168 painter.setPen( pen );
1172 painter.drawLine( QLineF(
c + mMargin, mMargin,
c + mMargin, height() - mMargin - 1 ) );
1177 painter.drawLine( QLineF( mMargin,
c + mMargin, width() - mMargin - 1,
c + mMargin ) );
1186 painter.setBrush( checkBrush );
1187 painter.setPen( Qt::NoPen );
1188 painter.drawRect( QRectF( mMargin, mMargin, width() - 2 * mMargin - 1, height() - 2 * mMargin - 1 ) );
1189 QLinearGradient colorGrad;
1193 colorGrad = QLinearGradient( mMargin, 0, width() - mMargin - 1, 0 );
1198 colorGrad = QLinearGradient( 0, mMargin, 0, height() - mMargin - 1 );
1201 transparent.setAlpha( 0 );
1202 colorGrad.setColorAt( 0, transparent );
1204 opaque.setAlpha( 255 );
1205 colorGrad.setColorAt( 1, opaque );
1206 const QBrush colorBrush = QBrush( colorGrad );
1207 painter.setBrush( colorBrush );
1208 painter.drawRect( QRectF( mMargin, mMargin, width() - 2 * mMargin - 1, height() - 2 * mMargin - 1 ) );
1214 painter.setRenderHint( QPainter::Antialiasing );
1215 painter.setBrush( QBrush( Qt::black ) );
1216 painter.setPen( Qt::NoPen );
1218 painter.drawPolygon( mTopTriangle );
1219 painter.translate( 0, height() - mMargin - 2 );
1220 painter.setBrush( QBrush( Qt::white ) );
1221 painter.drawPolygon( mBottomTriangle );
1227 const double ypos = mMargin + ( height() - 2 * mMargin - 1 ) - ( height() - 2 * mMargin - 1 ) *
static_cast<double>(
componentValue() ) /
componentRange();
1228 painter.setBrush( Qt::white );
1229 painter.setPen( Qt::NoPen );
1230 painter.drawRect( QRectF( mMargin, ypos - 1, width() - 2 * mMargin - 1, 3 ) );
1231 painter.setPen( Qt::black );
1232 painter.drawLine( QLineF( mMargin, ypos, width() - mMargin - 1, ypos ) );
1242 setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
1247 setSizePolicy( QSizePolicy::Fixed, QSizePolicy::MinimumExpanding );
1254 if ( margin == mMargin )
1275 mTopTriangle << QPoint( -markerSize, 0 ) << QPoint( markerSize, 0 ) << QPoint( 0, markerSize );
1276 mBottomTriangle << QPoint( -markerSize, 0 ) << QPoint( markerSize, 0 ) << QPoint( 0, -markerSize );
1284 setColorFromPoint( event->pos() );
1294 if ( event->angleDelta().y() > 0 )
1315 if ( event->button() == Qt::LeftButton )
1318 setColorFromPoint( event->pos() );
1328 if ( event->button() == Qt::LeftButton )
1330 mIsDragging =
false;
1374 QgsColorWidget::keyPressEvent( event );
1386void QgsColorRampWidget::setColorFromPoint( QPointF point )
1392 val =
componentRange() * ( point.x() - mMargin ) / ( width() - 2 * mMargin );
1417 QHBoxLayout *hLayout =
new QHBoxLayout();
1418 hLayout->setContentsMargins( 0, 0, 0, 0 );
1419 hLayout->setSpacing( 5 );
1423 hLayout->addWidget( mRampWidget, 1 );
1425 mSpinBox =
new QSpinBox();
1427 const int largestCharWidth = mSpinBox->fontMetrics().horizontalAdvance( QStringLiteral(
"888%" ) );
1428 mSpinBox->setMinimumWidth( largestCharWidth + 35 );
1429 mSpinBox->setMinimum( 0 );
1430 mSpinBox->setMaximum( convertRealToDisplay(
componentRange() ) );
1435 mSpinBox->setSuffix( QChar( 176 ) );
1439 mSpinBox->setSuffix( tr(
"%" ) );
1441 hLayout->addWidget( mSpinBox );
1442 setLayout( hLayout );
1446 connect( mSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ),
this, &QgsColorSliderWidget::spinChanged );
1453 mSpinBox->setMaximum( convertRealToDisplay(
componentRange() ) );
1457 mSpinBox->setSuffix( QChar( 176 ) );
1462 mSpinBox->setSuffix( tr(
"%" ) );
1467 mSpinBox->setSuffix( QString() );
1474 mRampWidget->blockSignals(
true );
1476 mRampWidget->blockSignals(
false );
1477 mSpinBox->blockSignals(
true );
1478 mSpinBox->setValue( convertRealToDisplay( value ) );
1479 mSpinBox->blockSignals(
false );
1486 mSpinBox->blockSignals(
true );
1488 mSpinBox->blockSignals(
false );
1491void QgsColorSliderWidget::rampColorChanged(
const QColor &color )
1496void QgsColorSliderWidget::spinChanged(
int value )
1498 const int convertedValue = convertDisplayToReal( value );
1504void QgsColorSliderWidget::rampChanged(
int value )
1506 mSpinBox->blockSignals(
true );
1507 mSpinBox->setValue( convertRealToDisplay( value ) );
1508 mSpinBox->blockSignals(
false );
1512int QgsColorSliderWidget::convertRealToDisplay(
const int realValue )
const
1518 return std::round( 100.0 * realValue / 255.0 );
1525int QgsColorSliderWidget::convertDisplayToReal(
const int displayValue )
const
1530 return std::round( 255.0 * displayValue / 100.0 );
1534 return displayValue;
1544 QHBoxLayout *hLayout =
new QHBoxLayout();
1545 hLayout->setContentsMargins( 0, 0, 0, 0 );
1546 hLayout->setSpacing( 0 );
1548 mLineEdit =
new QLineEdit(
nullptr );
1549 hLayout->addWidget( mLineEdit );
1551 mMenuButton =
new QToolButton( mLineEdit );
1553 mMenuButton->setCursor( Qt::ArrowCursor );
1554 mMenuButton->setFocusPolicy( Qt::NoFocus );
1555 mMenuButton->setStyleSheet( QStringLiteral(
"QToolButton { border: none; padding: 0px; }" ) );
1557 setLayout( hLayout );
1559 const int frameWidth = mLineEdit->style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
1560 mLineEdit->setStyleSheet( QStringLiteral(
"QLineEdit { padding-right: %1px; } " )
1561 .arg( mMenuButton->sizeHint().width() + frameWidth + 1 ) );
1563 connect( mLineEdit, &QLineEdit::editingFinished,
this, &QgsColorTextWidget::textChanged );
1564 connect( mMenuButton, &QAbstractButton::clicked,
this, &QgsColorTextWidget::showMenu );
1568 mFormat = settings.
enumValue( QStringLiteral(
"ColorWidgets/textWidgetFormat" ),
HexRgb );
1582 const QSize sz = mMenuButton->sizeHint();
1583 const int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
1584 mMenuButton->move( mLineEdit->rect().right() - frameWidth - sz.width(),
1585 ( mLineEdit->rect().bottom() + 1 - sz.height() ) / 2 );
1588void QgsColorTextWidget::updateText()
1607void QgsColorTextWidget::textChanged()
1609 const QString testString = mLineEdit->text();
1612 if ( !
color.isValid() )
1623 if ( !containsAlpha )
1634void QgsColorTextWidget::showMenu()
1636 QMenu colorContextMenu;
1637 QAction *hexRgbaAction =
nullptr;
1638 QAction *rgbaAction =
nullptr;
1640 QAction *hexRgbAction =
new QAction( tr(
"#RRGGBB" ),
nullptr );
1641 colorContextMenu.addAction( hexRgbAction );
1644 hexRgbaAction =
new QAction( tr(
"#RRGGBBAA" ),
nullptr );
1645 colorContextMenu.addAction( hexRgbaAction );
1647 QAction *rgbAction =
new QAction( tr(
"rgb( r, g, b )" ),
nullptr );
1648 colorContextMenu.addAction( rgbAction );
1651 rgbaAction =
new QAction( tr(
"rgba( r, g, b, a )" ),
nullptr );
1652 colorContextMenu.addAction( rgbaAction );
1655 QAction *selectedAction = colorContextMenu.exec( QCursor::pos() );
1656 if ( selectedAction == hexRgbAction )
1660 else if ( hexRgbaAction && selectedAction == hexRgbaAction )
1664 else if ( selectedAction == rgbAction )
1668 else if ( rgbaAction && selectedAction == rgbaAction )
1675 settings.
setEnumValue( QStringLiteral(
"ColorWidgets/textWidgetFormat" ), mFormat );
1682 mAllowAlpha = allowOpacity;
1691 , mColor2( QColor() )
1696void QgsColorPreviewWidget::drawColor(
const QColor &color, QRect rect, QPainter &painter )
1698 painter.setPen( Qt::NoPen );
1700 if (
color.alpha() < 255 )
1703 painter.setBrush( checkBrush );
1704 painter.drawRect( rect );
1709 const QBrush colorBrush = QBrush(
color );
1710 painter.setBrush( colorBrush );
1711 painter.drawRect( std::floor( rect.width() / 2.0 ) + rect.left(), rect.top(), rect.width() - std::floor( rect.width() / 2.0 ), rect.height() );
1713 QColor opaqueColor = QColor(
color );
1714 opaqueColor.setAlpha( 255 );
1715 const QBrush opaqueBrush = QBrush( opaqueColor );
1716 painter.setBrush( opaqueBrush );
1717 painter.drawRect( rect.left(), rect.top(), std::ceil( rect.width() / 2.0 ), rect.height() );
1722 const QBrush brush = QBrush(
color );
1723 painter.setBrush( brush );
1724 painter.drawRect( rect );
1731 QPainter painter(
this );
1733 if ( mColor2.isValid() )
1736 const int verticalSplit = std::round( height() / 2.0 );
1737 drawColor(
mCurrentColor, QRect( 0, 0, width(), verticalSplit ), painter );
1738 drawColor( mColor2, QRect( 0, verticalSplit, width(), height() - verticalSplit ), painter );
1742 drawColor(
mCurrentColor, QRect( 0, 0, width(), height() ), painter );
1755 if (
color == mColor2 )
1765 if ( e->button() == Qt::LeftButton )
1767 mDragStartPosition = e->pos();
1774 if ( ( e->pos() - mDragStartPosition ).manhattanLength() >= QApplication::startDragDistance() )
1783 if ( mColor2.isValid() )
1786 const int verticalSplit = std::round( height() / 2.0 );
1787 if ( mDragStartPosition.y() >= verticalSplit )
1789 clickedColor = mColor2;
1800 if ( !( e->buttons() & Qt::LeftButton ) )
1807 if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
1818 if ( mColor2.isValid() )
1821 const int verticalSplit = std::round( height() / 2.0 );
1822 if ( mDragStartPosition.y() >= verticalSplit )
1824 dragColor = mColor2;
1828 QDrag *drag =
new QDrag(
this );
1831 drag->exec( Qt::CopyAction );
1840 : QWidgetAction( parent )
1842 , mColorWidget( colorWidget )
1843 , mSuppressRecurse( false )
1844 , mDismissOnColorSelection( true )
1846 setDefaultWidget( mColorWidget );
1849 connect(
this, &QAction::hovered,
this, &QgsColorWidgetAction::onHover );
1853void QgsColorWidgetAction::onHover()
1856 if ( mSuppressRecurse )
1863 mSuppressRecurse =
true;
1864 mMenu->setActiveAction(
this );
1865 mSuppressRecurse =
false;
1869void QgsColorWidgetAction::setColor(
const QColor &color )
1872 if ( mMenu && mDismissOnColorSelection )
static const double UI_SCALE_FACTOR
UI scaling factor.
static QPixmap getThemePixmap(const QString &name, const QColor &foreColor=QColor(), const QColor &backColor=QColor(), int size=16)
Helper to get a theme icon as a pixmap.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
QSize sizeHint() const override
void resizeEvent(QResizeEvent *event) override
void mouseReleaseEvent(QMouseEvent *event) override
void mousePressEvent(QMouseEvent *event) override
void setComponent(ColorComponent component) override
Sets the color component which the widget controls.
void setColor(const QColor &color, bool emitSignals=false) override
void mouseMoveEvent(QMouseEvent *event) override
void paintEvent(QPaintEvent *event) override
QgsColorBox(QWidget *parent=nullptr, ColorComponent component=Value)
Construct a new color box widget.
QgsColorTextWidget(QWidget *parent=nullptr)
Construct a new color line edit widget.
@ Rgba
Rgba( r, g, b, a ) format, with alpha.
@ Rgb
Rgb( r, g, b ) format.
@ HexRgbA
#RRGGBBAA in hexadecimal, with alpha
@ HexRgb
#RRGGBB in hexadecimal
void setColor(const QColor &color, bool emitSignals=false) override
Sets the color for the widget.
void setAllowOpacity(bool allowOpacity)
Sets whether opacity modification (transparency) is permitted.
void resizeEvent(QResizeEvent *event) override
void paintEvent(QPaintEvent *event) override
QgsColorWheel(QWidget *parent=nullptr)
Constructs a new color wheel widget.
void mousePressEvent(QMouseEvent *event) override
QSize sizeHint() const override
void mouseReleaseEvent(QMouseEvent *event) override
void mouseMoveEvent(QMouseEvent *event) override
void resizeEvent(QResizeEvent *event) override
void setColor(const QColor &color, bool emitSignals=false) override
~QgsColorWheel() override
This class is a composition of two QSettings instances:
void setEnumValue(const QString &key, const T &value, const Section section=NoSection)
Set the value of a setting based on an enum.
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
static QColor parseColorWithAlpha(const QString &colorStr, bool &containsAlpha, bool strictEval=false)
Attempts to parse a string as a color using a variety of common formats, including hex codes,...
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c