Improved gradient creator
[dashstudio.git] / src / components / colorpalette / private / gradientviewer.cpp
blobc176d3a70a66596b8a942d48a39a6a9232abc97d
1 /***************************************************************************
2 * Copyright (C) 2005 by Jorge Cuadrado *
3 * kuadrosx@toonka.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 class GradientViewer::ControlPoint
31 public:
32 ControlPoint()
34 currentIndex = 0;
35 points << QPointF(10,50) << QPointF(60,50);
37 ~ControlPoint() {}
38 QVector<QPointF> points;
39 int currentIndex;
41 void selectPoint(const QPointF &point)
43 int rate = 5;
44 QRectF rect(point - QPointF(rate/2,rate/2) , QSizeF(rate, rate ));
46 QVector<QPointF>::const_iterator it;
47 for (it = points.begin(); it != points.end(); ++it)
49 if( rect.contains(*it) )
51 currentIndex = points.indexOf(*it);
52 break;
56 void drawPoints(QPainter *p)
58 foreach(QPointF point, points)
60 if(point == points[currentIndex])
62 p->save();
63 p->setPen(QPen(Qt::red, 5, Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin ));
65 else
67 p->save();
68 p->setPen(QPen(Qt::blue, 5, Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin ));
70 p->drawPoint(point);
71 p->restore();
76 GradientViewer::GradientViewer(QWidget *parent)
77 : QFrame(parent), m_radius(50)
80 m_controlPoint = new ControlPoint();
81 // setMaximumSize(100,100);
82 // setMinimumSize(100,100);
83 m_type = QGradient::LinearGradient;
84 m_spread = QGradient::PadSpread;
85 setMidLineWidth(2);
86 setLineWidth(2);
87 setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
88 // m_gradientStops.append(qMakePair(0.5, QColor("#000000")));
89 createGradient();
90 repaint();
94 GradientViewer::~GradientViewer()
96 D_END;
97 delete m_controlPoint;
100 void GradientViewer::paintEvent( QPaintEvent* e)
102 createGradient();
103 QPainter p;
104 p.begin(this);
106 QBrush brush(m_gradient);
107 QMatrix m;
108 m.scale(100/rect().width(), 100/rect().height());
109 brush.setMatrix(m);
111 p.setBrush(brush);
113 p.drawRect(rect());
114 p.setPen(QPen(Qt::blue, 5, Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin ));
115 m_controlPoint->drawPoints(&p);
117 p.end();
119 QFrame::paintEvent(e);
122 QSize GradientViewer::sizeHint() const
124 return QSize(100,100);
127 void GradientViewer::resizeEvent ( QResizeEvent * event )
129 int s = qMin(event->size().width(), event->size().height());
130 resize(QSize(s,s));
133 void GradientViewer::createGradient()
135 switch(m_type)
137 case QGradient::LinearGradient:
139 m_gradient = QLinearGradient(m_controlPoint->points[0], m_controlPoint->points[1]);
140 break;
142 case QGradient::RadialGradient:
144 m_gradient = QRadialGradient(m_controlPoint->points[0], m_radius, m_controlPoint->points[1] );
145 break;
147 case QGradient::ConicalGradient:
149 m_gradient = QConicalGradient(m_controlPoint->points[0], DGraphics::Algorithm::angleForPos( m_controlPoint->points[1], m_controlPoint->points[0 ])*180/M_PI);
150 break;
152 default:
154 dFatal() << "Fatal error, the gradient type doesn't exists!";
157 m_gradient.setStops( m_gradientStops);
158 m_gradient.setSpread(m_spread);
161 void GradientViewer::changeGradientStops( const QGradientStops& stops)
163 m_gradientStops = stops;
165 repaint();
168 void GradientViewer::changeType(int type)
170 m_type = QGradient::Type(type);
171 repaint();
175 void GradientViewer::setSpread(int spread)
177 m_spread = QGradient::Spread(spread);
178 repaint();
183 QGradient GradientViewer::gradient()
185 QGradient gradientNormalized;
186 switch(m_gradient.type())
188 case QGradient::LinearGradient:
190 gradientNormalized = QLinearGradient(
191 normalizePoint(m_controlPoint->points[0]), normalizePoint(m_controlPoint->points[1]));
192 break;
194 case QGradient::RadialGradient:
196 gradientNormalized = QRadialGradient(normalizePoint(m_controlPoint->points[0]), m_radius, normalizePoint(m_controlPoint->points[1]) );
197 break;
199 case QGradient::ConicalGradient:
201 gradientNormalized = QConicalGradient(normalizePoint(m_controlPoint->points[0]), DGraphics::Algorithm::angleForPos(normalizePoint(m_controlPoint->points[1]), normalizePoint(m_controlPoint->points[0]))*180/M_PI);
202 break;
204 default:
206 dFatal() << "Fatal error, the gradient type doesn't exists!";
209 gradientNormalized.setStops( m_gradientStops);
210 gradientNormalized.setSpread(m_spread);
211 return gradientNormalized;
214 void GradientViewer::mousePressEvent(QMouseEvent *e)
216 m_controlPoint->selectPoint(e->pos());
218 update();
221 void GradientViewer::mouseMoveEvent( QMouseEvent * e )
223 m_controlPoint->points[m_controlPoint->currentIndex] = e->pos();
224 update();
225 emit gradientChanged();
228 void GradientViewer::changeRadius(int radius)
230 m_radius = radius;
231 update();
232 emit gradientChanged();
235 void GradientViewer::setGradient(const QGradient* gradient)
237 m_gradientStops = gradient->stops();
238 m_spread = gradient->spread();
239 m_type = gradient->type();
240 switch(m_type)
242 case QGradient::LinearGradient:
244 m_controlPoint->points[0] = static_cast<const QLinearGradient*>(gradient)->start();
245 m_controlPoint->points[1] = static_cast<const QLinearGradient*>(gradient)->finalStop();
246 break;
248 case QGradient::RadialGradient:
250 m_controlPoint->points[0] = static_cast<const QRadialGradient*>(gradient)->center();
251 m_controlPoint->points[1] = static_cast<const QRadialGradient*>(gradient)->focalPoint();
252 m_radius = static_cast<const QRadialGradient*>(gradient)->radius();
253 break;
255 case QGradient::ConicalGradient:
257 m_controlPoint->points[0] = static_cast<const QConicalGradient*>(gradient)->center();
259 double angle = static_cast<const QConicalGradient*>(gradient)->angle();
261 QMatrix m;
262 m.rotate(-angle);
263 QPointF point = m.map(QPointF(10, 0));
265 m_controlPoint->points[1] = point + m_controlPoint->points[0];
268 break;
270 default:
272 dFatal() << "Fatal error, the gradient type doesn't exists!";
275 repaint();
278 QPointF GradientViewer::normalizePoint(const QPointF & point)
280 return QPointF(point.x()*(100/width()), point.y()*(100/height()));