00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef WW_NO_HUESATRADIALPICKER
00013
00014 #include "qwwhuesatradialpicker.h"
00015 #include <QPainter>
00016 #include <QMouseEvent>
00017 #include <cmath>
00018 #include "wwglobal_p.h"
00019
00020 #ifndef M_PI
00021 #define M_PI 3.14159265358979323846
00022 #endif
00023
00024 class QwwHueSatRadialPickerPrivate : public QwwPrivate {
00025 public:
00026 QwwHueSatRadialPickerPrivate(QwwHueSatRadialPicker *parent) : QwwPrivate(parent) {
00027 m_value = 255;
00028 for (int i=0;i<360;i++) {
00029 conical.setColorAt(i*1.0/360, QColor::fromHsv(i, 255, m_value));
00030 }
00031 conical.setColorAt(1, QColor::fromHsv(359, 255, m_value));
00032 }
00033 void buildPixmap();
00034 QPixmap px;
00035 QConicalGradient conical;
00036 int m_value;
00037 QPoint m_pt;
00038 QColor m_color;
00039 int radius(const QPoint &pt) const;
00040 int hue(const QPoint &pt) const;
00041 WW_DECLARE_PUBLIC(QwwHueSatRadialPicker);
00042 };
00043
00056 QwwHueSatRadialPicker::QwwHueSatRadialPicker(QWidget *parent)
00057 : QWidget(parent), QwwPrivatable(new QwwHueSatRadialPickerPrivate(this)) {
00058 QSizePolicy policy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00059 policy.setHeightForWidth(true);
00060 setSizePolicy(policy);
00061 }
00062
00063
00067 QwwHueSatRadialPicker::~QwwHueSatRadialPicker() {}
00068
00069 void QwwHueSatRadialPicker::paintEvent(QPaintEvent *) {
00070 Q_D(QwwHueSatRadialPicker);
00071 if (d->px.isNull()) d->buildPixmap();
00072 QPainter p(this);
00073 p.drawPixmap(0, 0, d->px);
00074 drawCrosshair(&p, d->m_pt);
00075 }
00076
00077 void QwwHueSatRadialPickerPrivate::buildPixmap() {
00078
00079 Q_Q(QwwHueSatRadialPicker);
00080 conical.setCenter(q->rect().center());
00081 QImage huecircle(q->size(), QImage::Format_ARGB32);
00082 QPainter phcircle(&huecircle);
00083 phcircle.setRenderHint(QPainter::Antialiasing, true);
00084 phcircle.setBrush(QBrush(conical));
00085 phcircle.drawEllipse(q->rect().adjusted(1, 1, -1, -1));
00086 px = QPixmap::fromImage(huecircle);
00087
00088
00089 QRadialGradient rg(q->rect().center(), q->width()/2-2, q->rect().center());
00090
00091 for (float i=0;i<1;i+=0.1) {
00092 rg.setColorAt(i, QColor::fromHsv(0, 0, (int)(256*i)));
00093 }
00094 rg.setColorAt(1, Qt::white);
00095
00096
00097 QImage ac(q->size(), QImage::Format_RGB32);
00098 QPainter acpainter(&ac);
00099 acpainter.setPen(Qt::NoPen);
00100 acpainter.setBrush(QBrush(rg));
00101 acpainter.drawEllipse(q->rect().adjusted(1, 1, -1, -1));
00102 px.setAlphaChannel(QPixmap::fromImage(ac));
00103
00104
00105 QImage dst(q->size(), QImage::Format_ARGB32);
00106
00107 QPainter dstp(&dst);
00108 dstp.setBrush(QColor::fromHsv(0, 0, m_value));
00109 dstp.setRenderHint(QPainter::Antialiasing, true);
00110 dstp.drawEllipse(q->rect().adjusted(1, 1, -1, -1));
00111 dstp.setCompositionMode(QPainter::CompositionMode_SourceOver);
00112 dstp.drawPixmap(0, 0, px);
00113
00114
00115
00116
00117 px = QPixmap::fromImage(dst);
00118 }
00119
00124 void QwwHueSatRadialPicker::setValue(int v) {
00125 Q_D(QwwHueSatRadialPicker);
00126 if (v<0 || v>255 || v==d->m_value) return;
00127 d->m_value = v;
00128 emit valueChanged(v);
00129 d->conical.setStops(QGradientStops());
00130 for (int i=0;i<360;i++) {
00131 d->conical.setColorAt(i*1.0/360, QColor::fromHsv(i, 255, d->m_value));
00132 }
00133 d->conical.setColorAt(1, QColor::fromHsv(359, 255, d->m_value));
00134 d->buildPixmap();
00135 update();
00136 }
00137
00142 int QwwHueSatRadialPicker::value() const {
00143 Q_D(const QwwHueSatRadialPicker);
00144 return d->m_value;
00145 }
00146
00147 QSize QwwHueSatRadialPicker::sizeHint() const {
00148 return QSize(202, 202);
00149 }
00150
00151 QSize QwwHueSatRadialPicker::minimumSizeHint() const {
00152 return QSize(202, 202);
00153 }
00154
00155 int QwwHueSatRadialPicker::heightForWidth(int w) const {
00156 return w;
00157 }
00158
00159 void QwwHueSatRadialPicker::resizeEvent(QResizeEvent *) {
00160 Q_D(QwwHueSatRadialPicker);
00161 if (width()!=height()) {
00162 int s = qMin(width(), height());
00163 resize(s,s);
00164 return;
00165 }
00166 d->buildPixmap();
00167 update();
00168 }
00169
00170
00171
00172 void QwwHueSatRadialPicker::mousePressEvent(QMouseEvent * me) {
00173 Q_D(QwwHueSatRadialPicker);
00174 QPoint pt = me->pos();
00175 int r = d->radius(pt);
00176 if (r>=width()/2) return;
00177 d->m_pt = pt;
00178 int h = d->hue(pt);
00179 int s = (int)(r*255.0/(width()/2));
00180 emit colorPicked(QColor::fromHsv(h, s, d->m_value));
00181 update();
00182 }
00183
00184 void QwwHueSatRadialPicker::mouseMoveEvent(QMouseEvent * me) {
00185 Q_D(QwwHueSatRadialPicker);
00186 QPoint pt = me->pos();
00187 int r = d->radius(pt);
00188 if (r>=width()/2) {
00189 r = width()/2;
00190 pt = d->m_pt;
00191 }
00192 d->m_pt = pt;
00193 int h = d->hue(pt);
00194 int s = (int)(r*255.0/(width()/2));
00195 emit colorPicked(QColor::fromHsv(h, s, d->m_value));
00196 update();
00197 }
00198
00199 int QwwHueSatRadialPickerPrivate::radius(const QPoint & pt) const {
00200 Q_Q(const QwwHueSatRadialPicker);
00201 QPoint c = q->rect().center();
00202 int x = pt.x() - c.x();
00203 int y = pt.y() - c.y();
00204 int r = qRound(sqrt((double)(x*x + y*y)));
00205
00206 return r;
00207 }
00208
00214 void QwwHueSatRadialPicker::drawCrosshair(QPainter * p, const QPoint & pt) {
00215 if (pt.isNull()) return;
00216 p->save();
00217 p->setPen(Qt::black);
00218 p->drawLine(pt-QPoint(0, -3), pt-QPoint(0, -1));
00219 p->drawLine(pt-QPoint(0, 1), pt-QPoint(0, 3));
00220 p->drawLine(pt-QPoint(-3, 0), pt-QPoint(-1, 0));
00221 p->drawLine(pt-QPoint(1, 0), pt-QPoint(3, 0));
00222 p->restore();
00223 }
00224
00225 int QwwHueSatRadialPickerPrivate::hue(const QPoint & pt) const {
00226 Q_Q(const QwwHueSatRadialPicker);
00227 QPoint c = q->rect().center();
00228 int x = c.x()-pt.x();
00229 int y = pt.y()-c.y();
00230 double a = qAbs(y)*1.0 / qAbs(x);
00231 double rd = atan(a);
00232 double deg = rd * 180 / M_PI;
00233 int h = qRound(deg);
00234 if (x>=0 && y>=0) h=180+h;
00235 else if (x<0 && y>=0) h=360-h;
00236 else if (x<0 && y<0) h=h;
00237 else h=180-h;
00238 return h % 360;
00239 }
00240
00245 void QwwHueSatRadialPicker::setColor(const QColor & c) {
00246 Q_D(QwwHueSatRadialPicker);
00247 if (c==d->m_color) return;
00248 int h, s, v;
00249 c.getHsv(&h, &s, &v);
00250 if (v!=d->m_value) setValue(v);
00251 int r = qRound(s*1.0*(width()/2-2)/255.0);
00252 int x = qRound(r*cos(h*M_PI/180.0));
00253 int y = qRound(r*sin(h*M_PI/180.0));
00254 QPoint ctr = rect().center();
00255 d->m_pt = QPoint(x+ctr.x(), -y+ctr.y());
00256 d->m_color = c;
00257 emit colorPicked(c);
00258 update();
00259 }
00260
00265 const QColor QwwHueSatRadialPicker::color() const {
00266 Q_D(const QwwHueSatRadialPicker);
00267 return d->m_color;
00268 }
00269
00270 #endif