00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef WW_NO_HUESATPICKER
00014
00015 #include "qwwhuesatpicker.h"
00016 #include <QPainter>
00017 #include <QImage>
00018 #include <QMouseEvent>
00019 #include <QResizeEvent>
00020 #include <QStyleOptionFrame>
00021 #include "wwglobal_p.h"
00022
00023 const int wid = 360;
00024 const int hei = 256;
00025
00026
00027 class QwwHueSatPickerPrivate : public QwwPrivate {
00028 public:
00029 QwwHueSatPickerPrivate(QwwHueSatPicker *q) : QwwPrivate(q) {
00030 m_minS = 0;
00031 m_maxS = 255;
00032 m_minH = 0;
00033 m_maxH = 359;
00034 m_v = 200;
00035 m_pt = QPoint(0, 0);
00036 }
00037 int hueFromX(int) const;
00038 int satFromY(int) const;
00039 int satToY(int) const;
00040 int hueToX(int) const;
00041 void buildPixmap();
00042 int m_minS;
00043 int m_maxS;
00044 int m_minH;
00045 int m_maxH;
00046 int m_v;
00047 QPoint m_pt;
00048 QPixmap px;
00049 QSize pxs;
00050 QColor m_color;
00051 WW_DECLARE_PUBLIC(QwwHueSatPicker);
00052 };
00053
00054
00055
00068 QwwHueSatPicker::QwwHueSatPicker(QWidget *parent)
00069 : QFrame(parent), QwwPrivatable(new QwwHueSatPickerPrivate(this)) {
00070 Q_D(QwwHueSatPicker);
00071 d->buildPixmap();
00072 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
00073 }
00074
00075
00079 QwwHueSatPicker::~QwwHueSatPicker() {}
00080
00085 void QwwHueSatPicker::setValue(int v) {
00086 Q_D(QwwHueSatPicker);
00087 if (d->m_v==v) return;
00088 if (v<0 || v>255) return;
00089 d->m_v = v;
00090 emit valueChanged(v);
00091 d->pxs=QSize();
00092 d->buildPixmap();
00093 update();
00094
00095 }
00096
00101 QSize QwwHueSatPicker::sizeHint() const {
00102 Q_D(const QwwHueSatPicker);
00103 return QSize((d->m_maxH-d->m_minH)+2*frameWidth(), (d->m_maxS-d->m_minS)+2*frameWidth());
00104 }
00105
00110 QSize QwwHueSatPicker::minimumSizeHint() const {
00111 Q_D(const QwwHueSatPicker);
00112 return QSize(qMin((d->m_maxH-d->m_minH)/4, 40)+2*frameWidth(), qMin((d->m_maxS-d->m_minS)/4, 40)+2*frameWidth());
00113 }
00114
00118 void QwwHueSatPickerPrivate::buildPixmap() {
00119 Q_Q(QwwHueSatPicker);
00120 int cy = q->contentsRect().height();
00121 int cx = q->contentsRect().width();
00122 QImage img(cx, cy, QImage::Format_RGB32);
00123 for (int y=0; y<cy;y++)
00124 for (int x=0; x<cx;x++) {
00125 QColor c;
00126 c.setHsv(hueFromX(x), satFromY(y), m_v);
00127 img.setPixel(x, y, c.rgb());
00128 }
00129 px = QPixmap::fromImage(img);
00130 pxs = px.size();
00131 }
00132
00136 void QwwHueSatPicker::paintEvent(QPaintEvent *) {
00137 Q_D(QwwHueSatPicker);
00138 QPainter p(this);
00139 drawFrame(&p);
00140 QRect rct = contentsRect();
00141 QStyleOptionFrame opt;
00142 opt.initFrom(this);
00143 if (opt.state & QStyle::State_Enabled) {
00144 p.drawPixmap(rct.topLeft(), d->px);
00145 drawCrosshair(&p, d->m_pt);
00146 } else {
00147 QIcon i(d->px);
00148 i.paint(&p, rct, 0, QIcon::Disabled);
00149 }
00150 }
00151
00155 int QwwHueSatPickerPrivate::hueFromX(int x) const {
00156 Q_Q(const QwwHueSatPicker);
00157 return m_maxH-x*(m_maxH-m_minH)/q->contentsRect().width();
00158 }
00159
00163 int QwwHueSatPickerPrivate::satFromY(int y) const {
00164 \
00165 Q_Q(const QwwHueSatPicker);
00166 return m_maxS-y*(m_maxS-m_minS)/q->contentsRect().height();
00167 }
00168
00174 int QwwHueSatPickerPrivate::satToY(int s) const {
00175 Q_Q(const QwwHueSatPicker);
00176 float ys = q->contentsRect().height()*1.0/(m_maxS-m_minS);
00177 float dist = s*ys;
00178 return (int)(q->contentsRect().height() - dist);
00179 }
00180
00181
00187 int QwwHueSatPickerPrivate::hueToX(int h) const {
00188 Q_Q(const QwwHueSatPicker);
00189 float xs = q->contentsRect().width()*1.0/(m_maxH-m_minH);
00190 float dist = h*xs;
00191 return (int)(q->contentsRect().width()-dist);
00192 }
00193
00194
00198 void QwwHueSatPicker::mousePressEvent(QMouseEvent * me) {
00199 Q_D(QwwHueSatPicker);
00200 QPoint pt = me->pos();
00201 int h = d->hueFromX(pt.x()-contentsRect().x());
00202 int s = d->satFromY(pt.y()-contentsRect().y());
00203 if (h<0 || s<0 || h>359 || s>255) return;
00204 emit colorPicked(QColor::fromHsv(h, s, d->m_v));
00205 d->m_pt = pt;
00206 update();
00207 }
00208
00212 void QwwHueSatPicker::mouseMoveEvent(QMouseEvent * me) {
00213 Q_D(QwwHueSatPicker);
00214 QPoint pt = me->pos();
00215 if (!contentsRect().contains(pt)) return;
00216 int h = d->hueFromX(pt.x()-contentsRect().x());
00217 int s = d->satFromY(pt.y()-contentsRect().y());
00218 if (h<0 || s<0 || h>359 || s>255) return;
00219 emit colorPicked(QColor::fromHsv(h, s, d->m_v));
00220 d->m_pt = pt;
00221 update();
00222 }
00223
00229 void QwwHueSatPicker::drawCrosshair(QPainter * p, const QPoint & pt) {
00230 p->save();
00231 p->setPen(Qt::black);
00232 p->drawLine(pt-QPoint(0, -3), pt-QPoint(0, -1));
00233 p->drawLine(pt-QPoint(0, 1), pt-QPoint(0, 3));
00234 p->drawLine(pt-QPoint(-3, 0), pt-QPoint(-1, 0));
00235 p->drawLine(pt-QPoint(1, 0), pt-QPoint(3, 0));
00236 p->restore();
00237 }
00238
00243 void QwwHueSatPicker::setMinimumSat(int v) {
00244 Q_D(QwwHueSatPicker);
00245 setSatRange(v, qMax(d->m_maxS, v));
00246 }
00247
00252 void QwwHueSatPicker::setMinimumHue(int h) {
00253 Q_D(QwwHueSatPicker);
00254 setHueRange(h, qMax(d->m_maxH, h));
00255 }
00256
00261 void QwwHueSatPicker::setMaximumHue(int h) {
00262 Q_D(QwwHueSatPicker);
00263 setHueRange(qMin(d->m_minH, h), h);
00264 }
00265
00271 void QwwHueSatPicker::setHueRange(int mi, int ma) {
00272 Q_D(QwwHueSatPicker);
00273 if (mi<0 || ma < 0 || mi > 359 || ma>359 || mi >ma) return;
00274 bool maC = d->m_maxH!=ma;
00275 bool miC = d->m_minH!=mi;
00276 d->m_maxH = ma;
00277 d->m_minH = mi;
00278 if (maC) emit maximumHueChanged(ma);
00279 if (miC) emit minimumHueChanged(mi);
00280 if (miC || maC) emit hueRangeChanged(mi, ma);
00281 else return;
00282
00283 updateGeometry();
00284 d->buildPixmap();
00285 update();
00286 }
00287
00292 void QwwHueSatPicker::setMaximumSat(int v) {
00293 Q_D(QwwHueSatPicker);
00294 setSatRange(qMin(d->m_minS, v), v);
00295 }
00296
00302 void QwwHueSatPicker::setSatRange(int mi, int ma) {
00303 Q_D(QwwHueSatPicker);
00304 if (mi<0 || ma < 0 || mi > 255 || ma>255 || mi >ma) return;
00305 bool maC = d->m_maxS!=ma;
00306 bool miC = d->m_minS!=mi;
00307 d->m_maxS = ma;
00308 d->m_minS = mi;
00309 if (maC) emit maximumSatChanged(ma);
00310 if (miC) emit minimumSatChanged(mi);
00311 if (miC || maC) emit satRangeChanged(mi, ma);
00312 else return;
00313
00314
00315 updateGeometry();
00316 d->buildPixmap();
00317 update();
00318 }
00319
00324 void QwwHueSatPicker::setColor(const QColor & c) {
00325 Q_D(QwwHueSatPicker);
00326 int h, s, v;
00327 if (d->m_color==c) return;
00328 c.getHsv(&h, &s, &v);
00329 if (d->m_v!=v) setValue(v);
00330 int Hspan = d->m_maxH - d->m_minH;
00331 int Sspan = d->m_maxS - d->m_minS;
00332 if (s<(d->m_minS) || s>(d->m_maxS)) {
00333 int ss = qMax(0, s-Sspan/2);
00334 setSatRange(ss, ss+Sspan);
00335 }
00336 if (h<(d->m_minH) || h>(d->m_maxH)) {
00337 int hh = qMax(0, h-Hspan/2);
00338 setHueRange(hh, hh+Hspan);
00339 }
00340 d->m_pt = QPoint(d->hueToX(h), d->satToY(s));
00341 d->m_color = c;
00342 emit colorPicked(c);
00343 update();
00344 }
00345
00349 void QwwHueSatPicker::resizeEvent(QResizeEvent *re) {
00350 Q_D(QwwHueSatPicker);
00351 QFrame::resizeEvent(re);
00352 d->buildPixmap();
00353 update();
00354 }
00355
00360 QColor QwwHueSatPicker::color() const {
00361 Q_D(const QwwHueSatPicker);
00362 return d->m_color;
00363 }
00364
00369 int QwwHueSatPicker::minimumSat() const {
00370 Q_D(const QwwHueSatPicker);
00371 return d->m_minS;
00372 }
00373
00378 int QwwHueSatPicker::maximumSat() const {
00379 Q_D(const QwwHueSatPicker);
00380 return d->m_maxS;
00381 }
00382
00387 int QwwHueSatPicker::maximumHue() const {
00388 Q_D(const QwwHueSatPicker);
00389 return d->m_maxH;
00390 }
00391
00396 int QwwHueSatPicker::minimumHue() const {
00397 Q_D(const QwwHueSatPicker);
00398 return d->m_minH;
00399 }
00400
00405 int QwwHueSatPicker::value() const {
00406 Q_D(const QwwHueSatPicker);
00407 return d->m_v;
00408 }
00409
00410 #endif