- Save/load palettes properly
[dashstudio.git] / src / components / colorpalette / private / gradientviewer.cpp
blob1bff234c130b34fa6920ee6b19a08b9e5e2d9355
1 /***************************************************************************
2 * Copyright (C) 2005 by Jorge Cuadrado *
3 * kuadrosx@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "gradientviewer.h"
22 #include <QPainter>
23 #include <dcore/debug.h>
24 #include <dgraphics/algorithm.h>
26 #include <QMouseEvent>
27 #include <QRectF>
29 struct GradientViewer::Private
31 class ControlPoint
33 public:
34 ControlPoint()
36 QRadialGradient gradient(QPoint(5, 5), 10, QPoint(5,5) );
38 gradient.setColorAt(0.5, Qt::gray);
39 gradient.setColorAt(0, Qt::blue);
41 normalPoint = QBrush(gradient);
43 gradient.setColorAt(0, Qt::red);
44 selectedPoint = QBrush(gradient);
46 currentIndex = 0;
47 points << QPointF(10,50) << QPointF(60,50);
49 ~ControlPoint() {}
50 QVector<QPointF> points;
51 int currentIndex;
53 void selectPoint(const QPointF &point)
55 int rate = 10;
56 QRectF rect(point - QPointF(rate/2,rate/2) , QSizeF(rate, rate ));
58 QVector<QPointF>::const_iterator it;
59 for (it = points.begin(); it != points.end(); ++it)
61 if( rect.contains(*it) )
63 currentIndex = points.indexOf(*it);
64 break;
68 void drawPoints(QPainter *p)
70 foreach(QPointF point, points)
72 QRectF br( point - QPoint(5,5), QSizeF(10,10) );
73 p->save();
74 p->setRenderHint(QPainter::Antialiasing);
75 if(point == points[currentIndex])
77 selectedPoint.setMatrix(QMatrix().translate(br.x(), br.y()));
78 p->setBrush(selectedPoint);
80 else
82 normalPoint.setMatrix(QMatrix().translate(br.x(), br.y()));
83 p->setBrush(normalPoint);
86 p->drawEllipse(br);
87 p->restore();
89 // p->drawPoint(point);
93 QBrush normalPoint;
94 QBrush selectedPoint;
96 ControlPoint *controlPoint;
97 QGradientStops gradientStops;
98 QGradient gradient;
100 double radius;
101 QGradient::Type type;
102 QGradient::Spread spread;
107 GradientViewer::GradientViewer(QWidget *parent)
108 : QFrame(parent), d(new Private)
110 d->radius = 50;
112 d->controlPoint = new Private::ControlPoint();
113 d->type = QGradient::LinearGradient;
114 d->spread = QGradient::PadSpread;
115 setMidLineWidth(2);
116 setLineWidth(2);
117 setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
118 createGradient();
119 repaint();
121 // setMinimumSize(sizeHint());
125 GradientViewer::~GradientViewer()
127 delete d->controlPoint;
128 delete d;
131 void GradientViewer::paintEvent( QPaintEvent* e)
133 createGradient();
134 QPainter p(this);
136 p.setPen(Qt::NoPen);
137 QBrush brush(d->gradient);
139 QMatrix m;
140 m.scale(100/rect().width(), 100/rect().height());
141 brush.setMatrix(m);
143 p.setBrush(brush);
145 p.drawRect(rect());
147 if(isEnabled () )
149 d->controlPoint->drawPoints(&p);
151 else
153 QColor disabled = palette().color(QPalette::Disabled, QPalette::WindowText);
154 disabled.setAlpha(120);
155 p.fillRect(rect(), disabled);
158 p.end();
160 QFrame::paintEvent(e);
163 QSize GradientViewer::sizeHint() const
165 return QSize(100,100);
168 void GradientViewer::resizeEvent ( QResizeEvent * event )
170 int s = qMin(event->size().width(), event->size().height());
171 resize(QSize(s,s));
174 void GradientViewer::createGradient()
176 switch(d->type)
178 case QGradient::LinearGradient:
180 d->gradient = QLinearGradient(d->controlPoint->points[0], d->controlPoint->points[1]);
181 break;
183 case QGradient::RadialGradient:
185 d->gradient = QRadialGradient(d->controlPoint->points[0], d->radius, d->controlPoint->points[1] );
186 break;
188 case QGradient::ConicalGradient:
190 d->gradient = QConicalGradient(d->controlPoint->points[0], DGraphics::Algorithm::angleForPos( d->controlPoint->points[1], d->controlPoint->points[0 ])*180/M_PI);
191 break;
193 default:
195 dFatal() << "Fatal error, the gradient type doesn't exists!";
198 d->gradient.setStops( d->gradientStops);
199 d->gradient.setSpread(d->spread);
202 void GradientViewer::changeGradientStops( const QGradientStops& stops)
204 d->gradientStops = stops;
206 repaint();
209 void GradientViewer::changeType(int type)
211 d->type = QGradient::Type(type);
212 repaint();
216 void GradientViewer::setSpread(int spread)
218 d->spread = QGradient::Spread(spread);
219 repaint();
224 QGradient GradientViewer::gradient()
226 QGradient gradientNormalized;
227 switch(d->gradient.type())
229 case QGradient::LinearGradient:
231 gradientNormalized = QLinearGradient(
232 normalizePoint(d->controlPoint->points[0]), normalizePoint(d->controlPoint->points[1]));
233 break;
235 case QGradient::RadialGradient:
237 gradientNormalized = QRadialGradient(normalizePoint(d->controlPoint->points[0]), d->radius, normalizePoint(d->controlPoint->points[1]) );
238 break;
240 case QGradient::ConicalGradient:
242 gradientNormalized = QConicalGradient(normalizePoint(d->controlPoint->points[0]), DGraphics::Algorithm::angleForPos(normalizePoint(d->controlPoint->points[1]), normalizePoint(d->controlPoint->points[0]))*180/M_PI);
243 break;
245 default:
247 dFatal() << "Fatal error, the gradient type doesn't exists!";
250 gradientNormalized.setStops( d->gradientStops);
251 gradientNormalized.setSpread(d->spread);
252 return gradientNormalized;
255 void GradientViewer::mousePressEvent(QMouseEvent *e)
257 d->controlPoint->selectPoint(e->pos());
259 update();
262 void GradientViewer::mouseMoveEvent( QMouseEvent * e )
264 d->controlPoint->points[d->controlPoint->currentIndex] = e->pos();
265 update();
266 emit gradientChanged();
269 void GradientViewer::changeRadius(int radius)
271 d->radius = radius;
272 update();
273 emit gradientChanged();
276 void GradientViewer::setGradient(const QGradient* gradient)
278 d->gradientStops = gradient->stops();
279 d->spread = gradient->spread();
280 d->type = gradient->type();
281 switch(d->type)
283 case QGradient::LinearGradient:
285 d->controlPoint->points[0] = static_cast<const QLinearGradient*>(gradient)->start();
286 d->controlPoint->points[1] = static_cast<const QLinearGradient*>(gradient)->finalStop();
287 break;
289 case QGradient::RadialGradient:
291 d->controlPoint->points[0] = static_cast<const QRadialGradient*>(gradient)->center();
292 d->controlPoint->points[1] = static_cast<const QRadialGradient*>(gradient)->focalPoint();
293 d->radius = static_cast<const QRadialGradient*>(gradient)->radius();
294 break;
296 case QGradient::ConicalGradient:
298 d->controlPoint->points[0] = static_cast<const QConicalGradient*>(gradient)->center();
300 double angle = static_cast<const QConicalGradient*>(gradient)->angle();
302 QMatrix m;
303 m.rotate(-angle);
304 QPointF point = m.map(QPointF(10, 0));
306 d->controlPoint->points[1] = point + d->controlPoint->points[0];
309 break;
311 default:
313 dFatal() << "Fatal error, the gradient type doesn't exists!";
316 repaint();
319 QPointF GradientViewer::normalizePoint(const QPointF & point)
321 return QPointF(point.x()*(100/width()), point.y()*(100/height()));