19 #include <QResizeEvent> 20 #include <QStyleOptionFrameV3> 22 #include <QHBoxLayout> 25 #include <QFontMetrics> 26 #include <QToolButton> 40 , mCurrentColor(
Qt::red )
41 , mComponent( component )
61 pixmap.
fill( Qt::transparent );
63 painter.
begin( &pixmap );
145 color.
getHsv( &h, &s, &v, &a );
148 int clippedValue = qMin( qMax( 0, newValue ),
componentRange( component ) );
153 color.
setRed( clippedValue );
162 color.
setHsv( clippedValue, s, v, a );
165 color.
setHsv( h, clippedValue, v, a );
168 color.
setHsv( h, s, clippedValue, a );
182 if ( transpBkgrd.
isNull() )
204 bool hasAlpha =
false;
269 valueClipped = qMax( valueClipped, 0 );
281 if ( r == valueClipped )
288 if ( g == valueClipped )
295 if ( b == valueClipped )
302 if ( h == valueClipped )
309 if ( s == valueClipped )
316 if ( v == valueClipped )
323 if ( a == valueClipped )
352 if ( color.
hue() >= 0 )
373 , mWheelThickness( 18 )
375 , mWheelImage( nullptr )
376 , mTriangleImage( nullptr )
377 , mWidgetImage( nullptr )
378 , mWheelDirty( true )
379 , mTriangleDirty( true )
385 for (
int pos = 0;
pos <= wheelStops; ++
pos )
387 double relativePos = ( double )
pos / wheelStops;
388 gradColor.
setHsvF( relativePos, 1, 1 );
389 wheelGradient.
setColorAt( relativePos, gradColor );
391 mWheelBrush =
QBrush( wheelGradient );
397 delete mTriangleImage;
403 return QSize( 200, 200 );
414 option.state = this->
hasFocus() ? QStyle::State_Active : QStyle::State_None;
417 if ( !mWidgetImage || !mWheelImage || !mTriangleImage )
419 createImages(
size() );
423 mWidgetImage->
fill( Qt::transparent );
424 QPainter imagePainter( mWidgetImage );
435 imagePainter.
drawImage(
QPointF( center.
x() - ( mWheelImage->
width() / 2.0 ), center.
y() - ( mWheelImage->
height() / 2.0 ) ), *mWheelImage );
439 double length = mWheelImage->
width() / 2.0;
440 QLineF hueMarkerLine =
QLineF( center.
x(), center.
y(), center.
x() + length, center.
y() );
448 pen.
setColor( h > 20 && h < 200 ? Qt::black : Qt::white );
449 imagePainter.
setPen( pen );
450 imagePainter.
drawLine( hueMarkerLine );
454 if ( mTriangleDirty )
458 imagePainter.
drawImage(
QPointF( center.
x() - ( mWheelImage->
width() / 2.0 ), center.
y() - ( mWheelImage->
height() / 2.0 ) ), *mTriangleImage );
461 double triangleRadius = length - mWheelThickness - 1;
465 double hueRadians = ( h *
M_PI / 180.0 );
466 double hx = cos( hueRadians ) * triangleRadius;
467 double hy = -sin( hueRadians ) * triangleRadius;
468 double sx = -cos( -hueRadians + (
M_PI / 3.0 ) ) * triangleRadius;
469 double sy = -sin( -hueRadians + (
M_PI / 3.0 ) ) * triangleRadius;
470 double vx = -cos( hueRadians + (
M_PI / 3.0 ) ) * triangleRadius;
471 double vy = sin( hueRadians + (
M_PI / 3.0 ) ) * triangleRadius;
472 double mx = ( sx + vx ) / 2.0;
473 double my = ( sy + vy ) / 2.0;
476 double x = sx + ( vx - sx ) * lightness + ( hx - mx ) * a;
477 double y = sy + ( vy - sy ) * lightness + ( hy - my ) * a;
480 pen.
setColor( lightness > 0.7 ? Qt::black : Qt::white );
481 imagePainter.
setPen( pen );
482 imagePainter.
setBrush( Qt::NoBrush );
493 if ( color.
hue() >= 0 && color.
hue() !=
hue() )
496 mTriangleDirty =
true;
502 void QgsColorWheel::createImages(
const QSizeF size )
504 double wheelSize = qMin( size.
width(), size.
height() ) - mMargin * 2.0;
505 mWheelThickness = wheelSize / 15.0;
509 mWheelImage =
new QImage( wheelSize, wheelSize, QImage::Format_ARGB32 );
510 delete mTriangleImage;
511 mTriangleImage =
new QImage( wheelSize, wheelSize, QImage::Format_ARGB32 );
517 mTriangleDirty =
true;
523 createImages( event->
size() );
527 void QgsColorWheel::setColorFromPos(
const QPointF pos )
540 if ( mClickedPart == QgsColorWheel::Triangle )
545 double x = pos.
x() - center.
x();
546 double y = pos.
y() - center.
y();
548 double eventAngleRadians = line.
angle() *
M_PI / 180.0;
549 double hueRadians = h *
M_PI / 180.0;
550 double rad0 = fmod( eventAngleRadians + 2.0 *
M_PI - hueRadians, 2.0 *
M_PI );
551 double rad1 = fmod( rad0, (( 2.0 / 3.0 ) *
M_PI ) ) - (
M_PI / 3.0 );
552 double length = mWheelImage->
width() / 2.0;
553 double triangleLength = length - mWheelThickness - 1;
555 double a = 0.5 * triangleLength;
556 double b = tan( rad1 ) * a;
557 double r = sqrt( x * x + y * y );
558 double maxR = sqrt( a * a + b * b );
562 double dx = tan( rad1 ) * r;
563 double rad2 = atan( dx / maxR );
564 rad2 = qMin( rad2,
M_PI / 3.0 );
565 rad2 = qMax( rad2, -
M_PI / 3.0 );
566 eventAngleRadians += rad2 - rad1;
567 rad0 = fmod( eventAngleRadians + 2.0 *
M_PI - hueRadians, 2.0 *
M_PI );
568 rad1 = fmod( rad0, (( 2.0 / 3.0 ) *
M_PI ) ) - (
M_PI / 3.0 );
570 r = sqrt( a * a + b * b );
573 double triangleSideLength = sqrt( 3.0 ) * triangleLength;
574 double newL = (( -sin( rad0 ) * r ) / triangleSideLength ) + 0.5;
575 double widthShare = 1.0 - ( fabs( newL - 0.5 ) * 2.0 );
576 double newS = ((( cos( rad0 ) * r ) + ( triangleLength / 2.0 ) ) / ( 1.5 * triangleLength ) ) / widthShare;
577 s = qMin( qRound( qMax( 0.0, newS ) * 255.0 ), 255 );
578 l = qMin( qRound( qMax( 0.0, newL ) * 255.0 ), 255 );
581 newColor.setHsv( h, newColor.hsvSaturation(), newColor.value(), alpha );
583 else if ( mClickedPart == QgsColorWheel::Wheel )
588 int newHue = line.
angle();
591 mTriangleDirty =
true;
612 setColorFromPos( event->
posF() );
623 double innerLength = mWheelImage->
width() / 2.0 - mWheelThickness;
624 if ( line.
length() < innerLength )
626 mClickedPart = QgsColorWheel::Triangle;
630 mClickedPart = QgsColorWheel::Wheel;
632 setColorFromPos( event->
posF() );
638 mClickedPart = QgsColorWheel::None;
641 void QgsColorWheel::createWheel()
648 int maxSize = qMin( mWheelImage->
width(), mWheelImage->
height() );
649 double wheelRadius = maxSize / 2.0;
651 mWheelImage->
fill( Qt::transparent );
664 p.
drawEllipse(
QPointF( 0.0, 0.0 ), wheelRadius - mWheelThickness, wheelRadius - mWheelThickness );
670 void QgsColorWheel::createTriangle()
672 if ( !mWheelImage || !mTriangleImage )
678 mTriangleImage->
fill( Qt::transparent );
680 QPainter imagePainter( mTriangleImage );
684 double wheelRadius = mWheelImage->
width() / 2.0;
685 double triangleRadius = wheelRadius - mWheelThickness - 1;
694 QLineF line1 =
QLineF( center.
x(), center.
y(), center.
x() - triangleRadius * cos(
M_PI / 3.0 ), center.
y() - triangleRadius * sin(
M_PI / 3.0 ) );
695 QLineF line2 =
QLineF( center.
x(), center.
y(), center.
x() + triangleRadius, center.
y() );
696 QLineF line3 =
QLineF( center.
x(), center.
y(), center.
x() - triangleRadius * cos(
M_PI / 3.0 ), center.
y() + triangleRadius * sin(
M_PI / 3.0 ) );
697 QLineF line4 =
QLineF( center.
x(), center.
y(), center.
x() - triangleRadius * cos(
M_PI / 3.0 ), center.
y() );
698 QLineF line5 =
QLineF( center.
x(), center.
y(), ( line2.p2().x() + line1.
p2().
x() ) / 2.0, ( line2.p2().y() + line1.
p2().
y() ) / 2.0 );
700 line2.setAngle( line2.angle() +
angle );
701 line3.setAngle( line3.angle() +
angle );
702 line4.setAngle( line4.angle() +
angle );
703 line5.setAngle( line5.angle() +
angle );
719 triangle << p2 << p1 << p3 << p2;
720 imagePainter.
setPen( Qt::NoPen );
736 imagePainter.
setBrush( Qt::NoBrush );
737 imagePainter.
setPen(
QPen( Qt::transparent ) );
741 mTriangleDirty =
false;
753 , mBoxImage( nullptr )
757 setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
759 mBoxImage =
new QImage(
width() - mMargin * 2,
height() - mMargin * 2, QImage::Format_RGB32 );
769 return QSize( 200, 200 );
779 option.state =
hasFocus() ? QStyle::State_Active : QStyle::State_None;
791 double xPos = mMargin + (
width() - 2 * mMargin - 1 ) * (
double )xComponentValue() / ( double )valueRangeX();
792 double yPos = mMargin + (
height() - 2 * mMargin - 1 ) - (
height() - 2 * mMargin - 1 ) * (
double )yComponentValue() / ( double )valueRangeY();
795 painter.
setPen( Qt::NoPen );
797 painter.
drawRect( xPos - 1, mMargin, 3,
height() - 2 * mMargin - 1 );
798 painter.
drawRect( mMargin, yPos - 1,
width() - 2 * mMargin - 1, 3 );
799 painter.
setPen( Qt::black );
801 painter.
drawLine( mMargin, yPos,
width() - mMargin - 1, yPos );
850 mBoxImage =
new QImage( event->
size().
width() - mMargin * 2,
event->size().height() - mMargin * 2, QImage::Format_RGB32 );
856 setColorFromPoint( event->
pos() );
862 setColorFromPoint( event->
pos() );
865 void QgsColorBox::createBox()
867 int maxValueX = mBoxImage->
width();
868 int maxValueY = mBoxImage->
height();
872 int colorComponentValue;
874 for (
int y = 0;
y < maxValueY; ++
y )
876 QRgb* scanLine = ( QRgb* )mBoxImage->
scanLine(
y );
878 colorComponentValue = int( valueRangeY() - valueRangeY() * (
double(
y ) / maxValueY ) );
879 alterColor( currentColor, yComponent(), colorComponentValue );
880 for (
int x = 0;
x < maxValueX; ++
x )
882 colorComponentValue = int( valueRangeX() * (
double(
x ) / maxValueX ) );
883 alterColor( currentColor, xComponent(), colorComponentValue );
884 scanLine[
x] = currentColor.
rgb();
890 int QgsColorBox::valueRangeX()
const 895 int QgsColorBox::valueRangeY()
const 920 int QgsColorBox::yComponentValue()
const 945 int QgsColorBox::xComponentValue()
const 950 void QgsColorBox::setColorFromPoint(
QPoint point )
952 int valX = valueRangeX() * ( point.
x() - mMargin ) / (
width() - 2 * mMargin - 1 );
953 valX = qMin( qMax( valX, 0 ), valueRangeX() );
955 int valY = valueRangeY() - valueRangeY() * ( point.
y() - mMargin ) / (
height() - 2 * mMargin - 1 );
956 valY = qMin( qMax( valY, 0 ), valueRangeY() );
967 if ( color.
hue() >= 0 )
987 , mShowFrame( false )
1006 return QSize( 200, 28 );
1011 return QSize( 18, 200 );
1025 option.state =
hasFocus() ? QStyle::State_KeyboardFocusChange : QStyle::State_None;
1034 option.state = QStyle::State_KeyboardFocusChange;
1049 for (
int c = 0; c <= maxValue; ++c )
1058 if ( color.
hue() < 0 )
1067 painter.
drawLine( c + mMargin, mMargin, c + mMargin,
height() - mMargin - 1 );
1072 painter.
drawLine( mMargin, c + mMargin,
width() - mMargin - 1, c + mMargin );
1082 painter.
setPen( Qt::NoPen );
1083 painter.
drawRect( mMargin, mMargin,
width() - 2 * mMargin - 1,
height() - 2 * mMargin - 1 );
1103 painter.
drawRect( mMargin, mMargin,
width() - 2 * mMargin - 1,
height() - 2 * mMargin - 1 );
1111 painter.
setPen( Qt::NoPen );
1124 painter.
setPen( Qt::NoPen );
1125 painter.
drawRect( mMargin, ypos - 1,
width() - 2 * mMargin - 1, 3 );
1126 painter.
setPen( Qt::black );
1127 painter.
drawLine( mMargin, ypos,
width() - mMargin - 1, ypos );
1137 setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
1142 setSizePolicy( QSizePolicy::Fixed, QSizePolicy::MinimumExpanding );
1149 if ( margin == mMargin )
1159 if ( showFrame == mShowFrame )
1170 mTopTriangle <<
QPoint( -markerSize, 0 ) <<
QPoint( markerSize, 0 ) <<
QPoint( 0, markerSize );
1171 mBottomTriangle << QPoint( -markerSize, 0 ) << QPoint( markerSize, 0 ) << QPoint( 0, -markerSize );
1177 setColorFromPoint( event->
posF() );
1185 if ( event->
delta() > 0 )
1204 setColorFromPoint( event->
posF() );
1255 void QgsColorRampWidget::setColorFromPoint(
QPointF point )
1284 , mRampWidget( nullptr )
1285 , mSpinBox( nullptr )
1314 connect( mRampWidget, SIGNAL( valueChanged(
int ) ),
this, SLOT( rampChanged(
int ) ) );
1316 connect( mSpinBox, SIGNAL( valueChanged(
int ) ),
this, SLOT( spinChanged(
int ) ) );
1352 mSpinBox->
setValue( convertRealToDisplay( value ) );
1365 void QgsColorSliderWidget::rampColorChanged(
const QColor &
color )
1370 void QgsColorSliderWidget::spinChanged(
int value )
1372 int convertedValue = convertDisplayToReal( value );
1378 void QgsColorSliderWidget::rampChanged(
int value )
1381 mSpinBox->
setValue( convertRealToDisplay( value ) );
1386 int QgsColorSliderWidget::convertRealToDisplay(
const int realValue )
const 1392 return qRound( 100.0 * realValue / 255.0 );
1399 int QgsColorSliderWidget::convertDisplayToReal(
const int displayValue )
const 1404 return qRound( 255.0 * displayValue / 100.0 );
1408 return displayValue;
1417 , mLineEdit( nullptr )
1418 , mMenuButton( nullptr )
1430 mMenuButton->
setCursor( Qt::ArrowCursor );
1432 mMenuButton->
setStyleSheet(
"QToolButton { border: none; padding: 0px; }" );
1436 int frameWidth = mLineEdit->
style()->
pixelMetric( QStyle::PM_DefaultFrameWidth );
1440 connect( mLineEdit, SIGNAL( editingFinished() ),
this, SLOT( textChanged() ) );
1441 connect( mMenuButton, SIGNAL( clicked() ),
this, SLOT( showMenu() ) );
1445 mFormat = ( ColorTextFormat )settings.
value(
"/ColorWidgets/textWidgetFormat", 0 ).
toInt();
1466 mMenuButton->
move( mLineEdit->
rect().right() - frameWidth - sz.
width(),
1467 ( mLineEdit->
rect().bottom() + 1 - sz.
height() ) / 2 );
1470 void QgsColorTextWidget::updateText()
1489 void QgsColorTextWidget::textChanged()
1505 if ( !containsAlpha )
1516 void QgsColorTextWidget::showMenu()
1518 QMenu colorContextMenu;
1521 colorContextMenu.
addAction( hexRgbAction );
1523 colorContextMenu.
addAction( hexRgbaAction );
1525 colorContextMenu.
addAction( rgbAction );
1527 colorContextMenu.
addAction( rgbaAction );
1530 if ( selectedAction == hexRgbAction )
1532 mFormat = QgsColorTextWidget::HexRgb;
1534 else if ( selectedAction == hexRgbaAction )
1536 mFormat = QgsColorTextWidget::HexRgbA;
1538 else if ( selectedAction == rgbAction )
1540 mFormat = QgsColorTextWidget::Rgb;
1542 else if ( selectedAction == rgbaAction )
1544 mFormat = QgsColorTextWidget::Rgba;
1549 settings.
setValue(
"/ColorWidgets/textWidgetFormat", (
int )mFormat );
1573 painter.
setPen( Qt::NoPen );
1575 if ( color.
alpha() < 255 )
1611 int verticalSplit = qRound(
height() / 2.0 );
1613 drawColor( mColor2,
QRect( 0, verticalSplit,
width(),
height() - verticalSplit ), painter );
1625 return QSize( 200, 150 );
1630 if ( color == mColor2 )
1640 if ( e->
button() == Qt::LeftButton )
1642 mDragStartPosition = e->
pos();
1661 int verticalSplit = qRound(
height() / 2.0 );
1662 if ( mDragStartPosition.
y() >= verticalSplit )
1664 clickedColor = mColor2;
1675 if ( !( e->
buttons() & Qt::LeftButton ) )
1696 int verticalSplit = qRound(
height() / 2.0 );
1697 if ( mDragStartPosition.
y() >= verticalSplit )
1699 dragColor = mColor2;
1706 drag->
exec( Qt::CopyAction );
1717 , mColorWidget( colorWidget )
1718 , mSuppressRecurse( false )
1719 , mDismissOnColorSelection( true )
1725 connect( mColorWidget, SIGNAL(
hovered() ),
this, SLOT( onHover() ) );
1733 void QgsColorWidgetAction::onHover()
1736 if ( mSuppressRecurse )
1743 mSuppressRecurse =
true;
1745 mSuppressRecurse =
false;
1749 void QgsColorWidgetAction::setColor(
const QColor& color )
1753 if ( mMenu && mDismissOnColorSelection )
const QMimeData * mimeData() const
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
void fillRect(const QRectF &rectangle, const QBrush &brush)
void setCompositionMode(CompositionMode mode)
void setRenderHint(RenderHint hint, bool on)
void fill(const QColor &color)
void setSuffix(const QString &suffix)
void setMimeData(QMimeData *data)
void setText(const QString &)
void setColorAt(qreal position, const QColor &color)
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const=0
void setPixmap(const QPixmap &pixmap)
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
void paintEvent(QPaintEvent *event) override
void drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule)
virtual void mouseReleaseEvent(QMouseEvent *event) override
virtual QSize sizeHint() const override
virtual void mousePressEvent(QMouseEvent *event) override
void drawLine(const QLineF &line)
void acceptProposedAction()
QString tr(const char *sourceText, const char *disambiguation, int n)
static QPixmap getThemePixmap(const QString &theName)
Helper to get a theme icon as a pixmap.
void getHsl(int *h, int *s, int *l, int *a) const
void getHsv(int *h, int *s, int *v, int *a) const
QColor fromHsl(int h, int s, int l, int a)
QColor fromHsv(int h, int s, int v, int a)
virtual void mousePressEvent(QMouseEvent *event) override
void initFrom(const QWidget *widget)
Qt::DropAction exec(QFlags< Qt::DropAction > supportedActions)
void setValue(const QString &key, const QVariant &value)
void drawRect(const QRectF &rectangle)
QString number(int n, int base)
int toInt(bool *ok) const
void fill(uint pixelValue)
void setPen(const QColor &color)
void drawEllipse(const QRectF &rectangle)
void setAngle(qreal angle)
virtual void setColor(const QColor &color, const bool emitSignals=false) override
void resizeEvent(QResizeEvent *event) override
QgsColorWheel(QWidget *parent=nullptr)
Constructs a new color wheel widget.
void setBrush(const QBrush &brush)
void setColor(const QColor &color)
void paintEvent(QPaintEvent *event) override
virtual void setComponent(const ColorComponent component) override
Sets the color component which the widget controls.
void setMargin(int margin)
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
virtual void resizeEvent(QResizeEvent *event) override
bool blockSignals(bool block)
const QSize & size() const
QgsColorBox(QWidget *parent=nullptr, const ColorComponent component=Value)
Construct a new color box widget.
void setHsvF(qreal h, qreal s, qreal v, qreal a)
int width(const QString &text, int len) const
QVariant value(const QString &key, const QVariant &defaultValue) const
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, QFlags< Qt::ImageConversionFlag > flags)
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...
QgsColorTextWidget(QWidget *parent=nullptr)
Construct a new color line edit widget.
void getRgb(int *r, int *g, int *b, int *a) const
virtual void setColor(const QColor &color, const bool emitSignals=false) override
Sets the color for the widget.
virtual QSize sizeHint() const override
void translate(const QPointF &offset)
virtual void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const=0
qreal hslSaturationF() const
void setHsv(int h, int s, int v, int a)
virtual void setColor(const QColor &color, const bool emitSignals=false) override
virtual void mouseMoveEvent(QMouseEvent *event) override
const QPoint & pos() const
virtual void mouseMoveEvent(QMouseEvent *event) override
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual void resizeEvent(QResizeEvent *event) override
bool begin(QPaintDevice *device)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
A line edit widget which displays colors as text and accepts string representations of colors...
virtual ~QgsColorTextWidget()
void setSpacing(int spacing)
QColor fromHsvF(qreal h, qreal s, qreal v, qreal a)
int hsvSaturation() const