qwwhuesatradialpicker.cpp

00001 //
00002 // C++ Implementation: %{MODULE}
00003 //
00004 // Description:
00005 //
00006 //
00007 // Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR}
00008 //
00009 // Copyright: See COPYING file that comes with this distribution
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  /* pi */
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     // build huecircle
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     // alpha gradient
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     // alpha channel
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     // destination image
00105     QImage dst(q->size(), QImage::Format_ARGB32);
00106     //dst.fill(QColor(Qt::white).rgb());
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     /*dstp.setCompositionMode(QPainter::CompositionMode_Source);
00114     dstp.setBrush(Qt::NoBrush);
00115     dstp.setPen(Qt::black);
00116     dstp.drawEllipse(rect()); */
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);   // tangent
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

Generated on Sat Apr 21 21:54:35 2007 for wwWidgets by  doxygen 1.5.1