19 #include <QResizeEvent>
20 #include <QStyleOptionFrameV3>
22 #include <QHBoxLayout>
25 #include <QFontMetrics>
26 #include <QToolButton>
39 , mCurrentColor(
Qt::red )
40 , mComponent( component )
60 pixmap.
fill( Qt::transparent );
62 painter.
begin( &pixmap );
144 color.
getHsv( &h, &s, &v, &a );
147 int clippedValue = qMin( qMax( 0, newValue ),
componentRange( component ) );
152 color.
setRed( clippedValue );
161 color.
setHsv( clippedValue, s, v, a );
164 color.
setHsv( h, clippedValue, v, a );
167 color.
setHsv( h, s, clippedValue, a );
181 if ( transpBkgrd.
isNull() )
203 bool hasAlpha =
false;
249 valueClipped = qMax( valueClipped, 0 );
261 if ( r == valueClipped )
268 if ( g == valueClipped )
275 if ( b == valueClipped )
282 if ( h == valueClipped )
289 if ( s == valueClipped )
296 if ( v == valueClipped )
303 if ( a == valueClipped )
332 if ( color.
hue() >= 0 )
353 , mWheelThickness( 18 )
356 , mTriangleImage( 0 )
358 , mWheelDirty( true )
359 , mTriangleDirty( true )
365 for (
int pos = 0;
pos <= wheelStops; ++
pos )
367 double relativePos = ( double )
pos / wheelStops;
368 gradColor.
setHsvF( relativePos, 1, 1 );
369 wheelGradient.
setColorAt( relativePos, gradColor );
371 mWheelBrush =
QBrush( wheelGradient );
377 delete mTriangleImage;
389 option.state = this->
hasFocus() ? QStyle::State_Active : QStyle::State_None;
392 if ( !mWidgetImage || !mWheelImage || !mTriangleImage )
394 createImages(
size() );
398 mWidgetImage->
fill( Qt::transparent );
399 QPainter imagePainter( mWidgetImage );
410 imagePainter.
drawImage(
QPointF( center.
x() - ( mWheelImage->
width() / 2.0 ), center.
y() - ( mWheelImage->
height() / 2.0 ) ), *mWheelImage );
414 double length = mWheelImage->
width() / 2.0;
415 QLineF hueMarkerLine =
QLineF( center.
x(), center.
y(), center.
x() + length, center.
y() );
423 pen.
setColor( h > 20 && h < 200 ? Qt::black : Qt::white );
424 imagePainter.
setPen( pen );
425 imagePainter.
drawLine( hueMarkerLine );
429 if ( mTriangleDirty )
433 imagePainter.
drawImage(
QPointF( center.
x() - ( mWheelImage->
width() / 2.0 ), center.
y() - ( mWheelImage->
height() / 2.0 ) ), *mTriangleImage );
436 double triangleRadius = length - mWheelThickness - 1;
440 double hueRadians = ( h *
M_PI / 180.0 );
441 double hx = cos( hueRadians ) * triangleRadius;
442 double hy = -sin( hueRadians ) * triangleRadius;
443 double sx = -cos( -hueRadians + (
M_PI / 3.0 ) ) * triangleRadius;
444 double sy = -sin( -hueRadians + (
M_PI / 3.0 ) ) * triangleRadius;
445 double vx = -cos( hueRadians + (
M_PI / 3.0 ) ) * triangleRadius;
446 double vy = sin( hueRadians + (
M_PI / 3.0 ) ) * triangleRadius;
447 double mx = ( sx + vx ) / 2.0;
448 double my = ( sy + vy ) / 2.0;
451 double x = sx + ( vx - sx ) * lightness + ( hx - mx ) * a;
452 double y = sy + ( vy - sy ) * lightness + ( hy - my ) * a;
455 pen.
setColor( lightness > 0.7 ? Qt::black : Qt::white );
456 imagePainter.
setPen( pen );
457 imagePainter.
setBrush( Qt::NoBrush );
468 if ( color.
hue() >= 0 && color.
hue() !=
hue() )
471 mTriangleDirty =
true;
477 void QgsColorWheel::createImages(
const QSizeF size )
479 double wheelSize = qMin( size.
width(), size.
height() ) - mMargin * 2.0;
480 mWheelThickness = wheelSize / 15.0;
484 mWheelImage =
new QImage( wheelSize, wheelSize, QImage::Format_ARGB32 );
485 delete mTriangleImage;
486 mTriangleImage =
new QImage( wheelSize, wheelSize, QImage::Format_ARGB32 );
492 mTriangleDirty =
true;
498 createImages( event->
size() );
502 void QgsColorWheel::setColorFromPos(
const QPointF pos )
515 if ( mClickedPart == QgsColorWheel::Triangle )
520 double x = pos.
x() - center.
x();
521 double y = pos.
y() - center.
y();
523 double eventAngleRadians = line.
angle() *
M_PI / 180.0;
524 double hueRadians = h *
M_PI / 180.0;
525 double rad0 = fmod( eventAngleRadians + 2.0 *
M_PI - hueRadians, 2.0 *
M_PI );
526 double rad1 = fmod( rad0, (( 2.0 / 3.0 ) *
M_PI ) ) - (
M_PI / 3.0 );
527 double length = mWheelImage->
width() / 2.0;
528 double triangleLength = length - mWheelThickness - 1;
530 double a = 0.5 * triangleLength;
531 double b = tan( rad1 ) * a;
532 double r = sqrt( x * x + y * y );
533 double maxR = sqrt( a * a + b * b );
537 double dx = tan( rad1 ) * r;
538 double rad2 = atan( dx / maxR );
539 rad2 = qMin( rad2,
M_PI / 3.0 );
540 rad2 = qMax( rad2, -
M_PI / 3.0 );
541 eventAngleRadians += rad2 - rad1;
542 rad0 = fmod( eventAngleRadians + 2.0 *
M_PI - hueRadians, 2.0 *
M_PI );
543 rad1 = fmod( rad0, (( 2.0 / 3.0 ) *
M_PI ) ) - (
M_PI / 3.0 );
545 r = sqrt( a * a + b * b );
548 double triangleSideLength = sqrt( 3.0 ) * triangleLength;
549 double newL = (( -sin( rad0 ) * r ) / triangleSideLength ) + 0.5;
550 double widthShare = 1.0 - ( fabs( newL - 0.5 ) * 2.0 );
551 double newS = ((( cos( rad0 ) * r ) + ( triangleLength / 2.0 ) ) / ( 1.5 * triangleLength ) ) / widthShare;
552 s = qMin( qRound( qMax( 0.0, newS ) * 255.0 ), 255 );
553 l = qMin( qRound( qMax( 0.0, newL ) * 255.0 ), 255 );
556 newColor.setHsv( h, newColor.hsvSaturation(), newColor.value(), alpha );
558 else if ( mClickedPart == QgsColorWheel::Wheel )
563 int newHue = line.
angle();
566 mTriangleDirty =
true;
587 setColorFromPos( event->
posF() );
597 double innerLength = mWheelImage->
width() / 2.0 - mWheelThickness;
598 if ( line.
length() < innerLength )
600 mClickedPart = QgsColorWheel::Triangle;
604 mClickedPart = QgsColorWheel::Wheel;
606 setColorFromPos( event->
posF() );
612 mClickedPart = QgsColorWheel::None;
615 void QgsColorWheel::createWheel()
622 int maxSize = qMin( mWheelImage->
width(), mWheelImage->
height() );
623 double wheelRadius = maxSize / 2.0;
625 mWheelImage->
fill( Qt::transparent );
627 p.setRenderHint( QPainter::Antialiasing );
628 p.setBrush( mWheelBrush );
629 p.setPen( Qt::NoPen );
632 p.translate( wheelRadius, wheelRadius );
633 p.drawEllipse(
QPointF( 0.0, 0.0 ), wheelRadius, wheelRadius );
636 p.setCompositionMode( QPainter::CompositionMode_DestinationOut );
637 p.setBrush(
QBrush( Qt::black ) );
638 p.drawEllipse(
QPointF( 0.0, 0.0 ), wheelRadius - mWheelThickness, wheelRadius - mWheelThickness );
644 void QgsColorWheel::createTriangle()
646 if ( !mWheelImage || !mTriangleImage )
652 mTriangleImage->
fill( Qt::transparent );
654 QPainter imagePainter( mTriangleImage );
655 imagePainter.setRenderHint( QPainter::Antialiasing );
658 double wheelRadius = mWheelImage->
width() / 2.0;
659 double triangleRadius = wheelRadius - mWheelThickness - 1;
668 QLineF line1 =
QLineF( center.
x(), center.
y(), center.
x() - triangleRadius * cos(
M_PI / 3.0 ), center.
y() - triangleRadius * sin(
M_PI / 3.0 ) );
669 QLineF line2 =
QLineF( center.
x(), center.
y(), center.
x() + triangleRadius, center.
y() );
670 QLineF line3 =
QLineF( center.
x(), center.
y(), center.
x() - triangleRadius * cos(
M_PI / 3.0 ), center.
y() + triangleRadius * sin(
M_PI / 3.0 ) );
671 QLineF line4 =
QLineF( center.
x(), center.
y(), center.
x() - triangleRadius * cos(
M_PI / 3.0 ), center.
y() );
672 QLineF line5 =
QLineF( center.
x(), center.
y(), ( line2.p2().x() + line1.
p2().
x() ) / 2.0, ( line2.p2().y() + line1.
p2().
y() ) / 2.0 );
674 line2.setAngle( line2.angle() +
angle );
675 line3.setAngle( line3.angle() +
angle );
676 line4.setAngle( line4.angle() +
angle );
677 line5.setAngle( line5.angle() +
angle );
693 triangle << p2 << p1 << p3 << p2;
694 imagePainter.setPen( Qt::NoPen );
696 imagePainter.setBrush(
QBrush( Qt::black ) );
697 imagePainter.drawPolygon( triangle );
699 imagePainter.setBrush(
QBrush( colorGrad ) );
700 imagePainter.drawPolygon( triangle );
702 imagePainter.setCompositionMode( QPainter::CompositionMode_Plus );
703 imagePainter.setBrush(
QBrush( whiteGrad ) );
704 imagePainter.drawPolygon( triangle );
709 imagePainter.setCompositionMode( QPainter::CompositionMode_Source );
710 imagePainter.setBrush( Qt::NoBrush );
711 imagePainter.setPen(
QPen( Qt::transparent ) );
712 imagePainter.drawPolygon( triangle );
715 mTriangleDirty =
false;
731 setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
733 mBoxImage =
new QImage(
width() - mMargin * 2,
height() - mMargin * 2, QImage::Format_RGB32 );
743 return QSize( 200, 200 );
753 option.state =
hasFocus() ? QStyle::State_Active : QStyle::State_None;
765 double xPos = mMargin + (
width() - 2 * mMargin - 1 ) * (
double )xComponentValue() / ( double )valueRangeX();
766 double yPos = mMargin + (
height() - 2 * mMargin - 1 ) - (
height() - 2 * mMargin - 1 ) * (
double )yComponentValue() / ( double )valueRangeY();
769 painter.
setPen( Qt::NoPen );
771 painter.
drawRect( xPos - 1, mMargin, 3,
height() - 2 * mMargin - 1 );
772 painter.
drawRect( mMargin, yPos - 1,
width() - 2 * mMargin - 1, 3 );
773 painter.
setPen( Qt::black );
775 painter.
drawLine( mMargin, yPos,
width() - mMargin - 1, yPos );
824 mBoxImage =
new QImage( event->
size().
width() - mMargin * 2,
event->size().height() - mMargin * 2, QImage::Format_RGB32 );
830 setColorFromPoint( event->
pos() );
835 setColorFromPoint( event->
pos() );
838 void QgsColorBox::createBox()
840 int maxValueX = mBoxImage->
width();
841 int maxValueY = mBoxImage->
height();
845 int colorComponentValue;
847 for (
int y = 0; y < maxValueY; ++
y )
849 QRgb* scanLine = ( QRgb* )mBoxImage->
scanLine( y );
851 colorComponentValue = int( valueRangeY() - valueRangeY() * (
double( y ) / maxValueY ) );
852 alterColor( currentColor, yComponent(), colorComponentValue );
853 for (
int x = 0; x < maxValueX; ++
x )
855 colorComponentValue = int( valueRangeX() * (
double( x ) / maxValueX ) );
856 alterColor( currentColor, xComponent(), colorComponentValue );
857 scanLine[
x] = currentColor.
rgb();
863 int QgsColorBox::valueRangeX()
const
868 int QgsColorBox::valueRangeY()
const
893 int QgsColorBox::yComponentValue()
const
918 int QgsColorBox::xComponentValue()
const
923 void QgsColorBox::setColorFromPoint(
const QPoint &point )
925 int valX = valueRangeX() * ( point.
x() - mMargin ) / (
width() - 2 * mMargin - 1 );
926 valX = qMin( qMax( valX, 0 ), valueRangeX() );
928 int valY = valueRangeY() - valueRangeY() * ( point.
y() - mMargin ) / (
height() - 2 * mMargin - 1 );
929 valY = qMin( qMax( valY, 0 ), valueRangeY() );
940 if ( color.
hue() >= 0 )
960 , mShowFrame( false )
979 return QSize( 200, 28 );
984 return QSize( 18, 200 );
998 option.state =
hasFocus() ? QStyle::State_KeyboardFocusChange : QStyle::State_None;
1007 option.state = QStyle::State_KeyboardFocusChange;
1022 for (
int c = 0; c <= maxValue; ++c )
1031 if ( color.
hue() < 0 )
1040 painter.
drawLine( c + mMargin, mMargin, c + mMargin,
height() - mMargin - 1 );
1045 painter.
drawLine( mMargin, c + mMargin,
width() - mMargin - 1, c + mMargin );
1055 painter.
setPen( Qt::NoPen );
1056 painter.
drawRect( mMargin, mMargin,
width() - 2 * mMargin - 1,
height() - 2 * mMargin - 1 );
1076 painter.
drawRect( mMargin, mMargin,
width() - 2 * mMargin - 1,
height() - 2 * mMargin - 1 );
1084 painter.
setPen( Qt::NoPen );
1097 painter.
setPen( Qt::NoPen );
1098 painter.
drawRect( mMargin, ypos - 1,
width() - 2 * mMargin - 1, 3 );
1099 painter.
setPen( Qt::black );
1100 painter.
drawLine( mMargin, ypos,
width() - mMargin - 1, ypos );
1110 setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
1115 setSizePolicy( QSizePolicy::Fixed, QSizePolicy::MinimumExpanding );
1122 if ( margin == mMargin )
1132 if ( showFrame == mShowFrame )
1143 mTopTriangle <<
QPoint( -markerSize, 0 ) <<
QPoint( markerSize, 0 ) <<
QPoint( 0, markerSize );
1144 mBottomTriangle << QPoint( -markerSize, 0 ) << QPoint( markerSize, 0 ) << QPoint( 0, -markerSize );
1150 setColorFromPoint( event->
posF() );
1155 setColorFromPoint( event->
posF() );
1206 void QgsColorRampWidget::setColorFromPoint(
const QPointF &point )
1265 connect( mRampWidget, SIGNAL( valueChanged(
int ) ),
this, SLOT( rampChanged(
int ) ) );
1267 connect( mSpinBox, SIGNAL( valueChanged(
int ) ),
this, SLOT( spinChanged(
int ) ) );
1303 mSpinBox->
setValue( convertRealToDisplay( value ) );
1316 void QgsColorSliderWidget::rampColorChanged(
const QColor &color )
1321 void QgsColorSliderWidget::spinChanged(
int value )
1323 int convertedValue = convertDisplayToReal( value );
1329 void QgsColorSliderWidget::rampChanged(
int value )
1332 mSpinBox->
setValue( convertRealToDisplay( value ) );
1337 int QgsColorSliderWidget::convertRealToDisplay(
const int realValue )
const
1343 return qRound( 100.0 * realValue / 255.0 );
1350 int QgsColorSliderWidget::convertDisplayToReal(
const int displayValue )
const
1355 return qRound( 255.0 * displayValue / 100.0 );
1359 return displayValue;
1381 mMenuButton->
setCursor( Qt::ArrowCursor );
1383 mMenuButton->
setStyleSheet(
"QToolButton { border: none; padding: 0px; }" );
1387 int frameWidth = mLineEdit->
style()->
pixelMetric( QStyle::PM_DefaultFrameWidth );
1391 connect( mLineEdit, SIGNAL( editingFinished() ),
this, SLOT( textChanged() ) );
1392 connect( mMenuButton, SIGNAL( clicked() ),
this, SLOT( showMenu() ) );
1396 mFormat = ( ColorTextFormat )settings.
value(
"/ColorWidgets/textWidgetFormat", 0 ).
toInt();
1417 mMenuButton->
move( mLineEdit->
rect().right() - frameWidth - sz.
width(),
1418 ( mLineEdit->
rect().bottom() + 1 - sz.
height() ) / 2 );
1421 void QgsColorTextWidget::updateText()
1440 void QgsColorTextWidget::textChanged()
1456 if ( !containsAlpha )
1467 void QgsColorTextWidget::showMenu()
1469 QMenu colorContextMenu;
1472 colorContextMenu.
addAction( hexRgbAction );
1474 colorContextMenu.
addAction( hexRgbaAction );
1476 colorContextMenu.
addAction( rgbAction );
1478 colorContextMenu.
addAction( rgbaAction );
1481 if ( selectedAction == hexRgbAction )
1483 mFormat = QgsColorTextWidget::HexRgb;
1485 else if ( selectedAction == hexRgbaAction )
1487 mFormat = QgsColorTextWidget::HexRgbA;
1489 else if ( selectedAction == rgbAction )
1491 mFormat = QgsColorTextWidget::Rgb;
1493 else if ( selectedAction == rgbaAction )
1495 mFormat = QgsColorTextWidget::Rgba;
1500 settings.
setValue(
"/ColorWidgets/textWidgetFormat", (
int )mFormat );
1522 void QgsColorPreviewWidget::drawColor(
const QColor &color,
const QRect &rect,
QPainter& painter )
1524 painter.
setPen( Qt::NoPen );
1526 if ( color.
alpha() < 255 )
1562 int verticalSplit = qRound(
height() / 2.0 );
1564 drawColor( mColor2,
QRect( 0, verticalSplit,
width(),
height() - verticalSplit ), painter );
1576 if ( color == mColor2 )
1586 if ( e->
button() == Qt::LeftButton )
1588 mDragStartPosition = e->
pos();
1607 int verticalSplit = qRound(
height() / 2.0 );
1608 if ( mDragStartPosition.
y() >= verticalSplit )
1610 clickedColor = mColor2;
1621 if ( !( e->
buttons() & Qt::LeftButton ) )
1642 int verticalSplit = qRound(
height() / 2.0 );
1643 if ( mDragStartPosition.
y() >= verticalSplit )
1645 dragColor = mColor2;
1652 drag->
exec( Qt::CopyAction );
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
void setBrush(const QBrush &brush)
QgsColorTextWidget(QWidget *parent=0)
Construct a new color line edit widget.
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
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...
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.
QgsColorWheel(QWidget *parent=0)
Constructs a new color wheel widget.
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
QgsColorBox(QWidget *parent=0, const ColorComponent component=Value)
Construct a new color box widget.