19 #include <QResizeEvent>
20 #include <QStyleOption>
21 #include <QtCore/qmath.h>
25 #include "colorwheel.h"
27 ColorWheel::ColorWheel(QWidget *parent) : QWidget(parent),
30 m_currentColor(Qt::red),
35 m_currentColor = m_currentColor.toHsv();
38 QColor ColorWheel::color()
40 return m_currentColor;
43 void ColorWheel::changeColor(
const QColor &color)
45 if (color == m_currentColor)
49 if (color.hue() != m_currentColor.hue())
51 hueChanged(color.hue());
54 if (color.saturation() != m_currentColor.saturation() ||
55 color.value() != m_currentColor.value() )
60 if(color.alpha() != m_currentColor.alpha())
62 alphaChanged(color.alpha());
68 void ColorWheel::setColor(
const QColor &color)
70 if (color == m_currentColor)
74 if (color.hue() != m_currentColor.hue())
76 hueChanged(color.hue());
79 if (color.saturation() != m_currentColor.saturation() ||
80 color.value() != m_currentColor.value() )
85 if ( color.alpha() != m_currentColor.alpha() )
87 alphaChanged(color.alpha());
91 emit colorSelected(color);
94 QColor ColorWheel::pickColor(
const QPoint& point)
96 if ( ! m_wheelPixmap.rect().contains(point) )
103 int r = qMin(width(), height()) / 2;
104 QString strDebug =
"";
105 strDebug += QString(
"Radius=%1").arg(r);
107 QPoint center(width() / 2, height() / 2);
109 QPoint diff = point - center;
110 strDebug += QString(
" Atan2=%1").arg(qAtan2(diff.y(), diff.x()));
112 hue = qAtan2( -diff.y(), diff.x() ) / M_PI * 180;
114 hue = fmod((hue + 360), 360);
116 strDebug += QString(
" Hue=%1").arg(hue);
119 hue = (hue > 359) ? 359 : hue;
120 hue = (hue < 0) ? 0 : hue;
122 return QColor::fromHsv(hue,
123 m_currentColor.saturation(),
124 m_currentColor.value());
126 else if (m_isInSquare)
128 QRect rect = m_squareRegion.boundingRect();
129 QPoint p = point - rect.topLeft();
131 QSizeF regionSize = rect.size() - QSizeF(1, 1);
134 return QColor::fromHsvF( m_currentColor.hueF(),
135 p.x() / regionSize.width(),
136 1.0 - (p.y() / regionSize.height()));
141 QSize ColorWheel::sizeHint ()
const
146 QSize ColorWheel::minimumSizeHint ()
const
151 void ColorWheel::mousePressEvent(QMouseEvent *event)
153 QPoint lastPos =
event->pos();
154 if (m_squareRegion.contains(lastPos))
158 QColor color = pickColor(lastPos);
161 else if (m_wheelRegion.contains(lastPos))
164 m_isInSquare =
false;
165 QColor color = pickColor(lastPos);
166 hueChanged(color.hue());
170 void ColorWheel::mouseMoveEvent(QMouseEvent* event)
172 QPoint lastPos =
event->pos();
173 if ( event->buttons() == Qt::NoButton )
179 QRect rect = m_squareRegion.boundingRect();
181 if ( lastPos.x() < rect.topLeft().x() )
183 lastPos.setX( rect.topLeft().x() );
185 else if ( lastPos.x() > rect.bottomRight().x() )
187 lastPos.setX( rect.bottomRight().x() );
190 if ( lastPos.y() < rect.topLeft().y() )
192 lastPos.setY( rect.topLeft().y() );
194 else if ( lastPos.y() > rect.bottomRight().y() )
196 lastPos.setY( rect.bottomRight().y() );
199 QColor color = pickColor(lastPos);
202 else if (m_wheelRegion.contains(lastPos) && m_isInWheel)
204 QColor color = pickColor(lastPos);
205 hueChanged(color.hue());
209 void ColorWheel::mouseReleaseEvent(QMouseEvent *)
212 m_isInSquare =
false;
213 emit colorSelected(m_currentColor);
216 void ColorWheel::resizeEvent(QResizeEvent *event)
218 m_wheelPixmap = QPixmap(event->size());
219 m_wheelPixmap.fill(palette().background().color());
220 drawWheelImage(event->size());
221 drawSquareImage(m_currentColor.hue());
225 void ColorWheel::paintEvent(QPaintEvent *)
227 QPainter painter(
this);
230 composeWheel(m_wheelPixmap);
231 painter.translate(width() / 2, height() / 2);
232 painter.translate(-m_wheelPixmap.width() / 2,-m_wheelPixmap.height() / 2);
233 painter.drawPixmap(0, 0, m_wheelPixmap);
234 style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter,
this);
237 void ColorWheel::drawWheelImage(
const QSize &newSize)
239 int r = qMin(newSize.width(), newSize.height());
242 option.initFrom(
this);
244 QBrush backgroundBrush = option.palette.window();
246 m_wheelImage = QImage(newSize, QImage::Format_ARGB32_Premultiplied);
250 QPainter painter(&m_wheelImage);
251 painter.setRenderHint(QPainter::Antialiasing);
253 painter.fillRect(m_wheelImage.rect(), backgroundBrush);
255 QConicalGradient conicalGradient(0, 0, 0);
257 for (
int hue = 0; hue < 360; hue +=1)
259 conicalGradient.setColorAt( hue / 360.0, QColor::fromHsv(hue, 255, 255));
262 qreal ir = r - m_wheelThickness;
265 painter.translate(width() / 2, height() / 2);
267 QBrush brush(conicalGradient);
268 painter.setPen(Qt::NoPen);
269 painter.setBrush(brush);
270 painter.drawEllipse(QPoint(0, 0), r/2, r/2);
273 painter.setBrush(backgroundBrush);
274 painter.drawEllipse(QPoint(0, 0), r/2 - m_wheelThickness, r/2 - m_wheelThickness);
277 qreal m1 = (m_wheelPixmap.width() / 2) - (ir / qSqrt(2));
278 qreal m2 = (m_wheelPixmap.height() / 2) - (ir / qSqrt(2));
281 qreal wheelWidth = 2 * ir / qSqrt(2);
284 m_wheelRegion = QRegion(m1, m2, wheelWidth, wheelWidth);
287 void ColorWheel::drawSquareImage(
const int &hue)
290 int w = qMin(width(), height());
294 qreal ir = r - m_wheelThickness;
297 qreal m1 = (width() / 2) - (ir / qSqrt(2));
298 qreal m2 = (height() / 2) - (ir / qSqrt(2));
300 QImage square(255, 255, QImage::Format_ARGB32_Premultiplied);
303 for (
int i = 0; i < 255; ++i)
305 for (
int j = 0; j < 255; ++j)
307 color = QColor::fromHsv(hue, i, 255 - j);
308 QRgb rgb = qRgb(color.red(), color.green(), color.blue());
309 square.setPixel(i, j, rgb);
313 qreal SquareWidth = 2 * ir / qSqrt(2.1);
314 m_squareImage = square.scaled(SquareWidth, SquareWidth);
315 m_squareRegion = QRegion(m1, m2, SquareWidth, SquareWidth);
318 void ColorWheel::drawHueIndicator(
const int &hue)
320 QPainter painter(&m_wheelPixmap);
321 painter.setRenderHint(QPainter::Antialiasing);
322 if(hue > 20 && hue < 200)
324 painter.setPen(Qt::black);
328 painter.setPen(Qt::white);
330 painter.setBrush(Qt::NoBrush);
332 QPen pen = painter.pen();
335 qreal r = qMin(height(), width());
336 painter.translate(width() / 2, height() / 2);
337 painter.rotate( -hue );
339 r = r / 2.0 - m_wheelThickness/2;
340 painter.drawEllipse(QPointF(r, 0), 7, 7);
343 void ColorWheel::drawPicker(
const QColor &color)
345 QPainter painter(&m_wheelPixmap);
346 painter.setRenderHint(QPainter::Antialiasing);
348 QPoint squareTopLeft = m_squareRegion.boundingRect().topLeft();
350 painter.translate(squareTopLeft.x(), squareTopLeft.y());
352 QSize squareSize = m_squareRegion.boundingRect().size();
354 qreal S = color.saturationF() * squareSize.width();
355 qreal V = squareSize.height() - (color.valueF() * squareSize.height());
359 if (color.saturation() > 30 || color.value() < 50)
361 pen.setColor(Qt::white);
365 painter.drawEllipse(S - 2, V - 2, 10, 10);
368 void ColorWheel::composeWheel( QPixmap& pixmap )
370 QPainter composePainter(&pixmap);
371 composePainter.drawImage(0, 0, m_wheelImage);
372 composePainter.translate(width() / 2, height() / 2);
373 composePainter.translate(-m_squareImage.width() / 2, -m_squareImage.height() / 2);
374 composePainter.drawImage(0, 0, m_squareImage);
375 composePainter.end();
376 drawHueIndicator(m_currentColor.hue());
377 drawPicker(m_currentColor);
380 void ColorWheel::hueChanged(
const int &hue)
382 if ( hue < 0 || hue > 359)
386 int s = m_currentColor.saturation();
387 int v = m_currentColor.value();
388 int a = m_currentColor.alpha();
390 m_currentColor.setHsv(hue, s, v, a);
397 drawSquareImage(hue);
400 emit colorChanged(m_currentColor);
403 void ColorWheel::svChanged(
const QColor &newcolor)
405 int hue = m_currentColor.hue();
406 int alpha = m_currentColor.alpha();
407 m_currentColor.setHsv(hue,
408 newcolor.saturation(),
417 emit colorChanged(m_currentColor);
420 void ColorWheel::alphaChanged(
const int &alpha)
422 m_currentColor.setAlpha(alpha);
429 emit colorChanged(m_currentColor);