2
#include "hoverpoints.h"
4
ShadeWidget::ShadeWidget(ShadeType type, QWidget *parent)
5
: QWidget(parent), m_shade_type(type), m_alpha_gradient(QLinearGradient(0, 0, 0, 0))
9
if (m_shade_type == ARGBShade) {
12
pmp.fillRect(0, 0, 10, 10, Qt::lightGray);
13
pmp.fillRect(10, 10, 10, 10, Qt::lightGray);
14
pmp.fillRect(0, 10, 10, 10, Qt::darkGray);
15
pmp.fillRect(10, 0, 10, 10, Qt::darkGray);
17
QPalette pal = palette();
18
pal.setBrush(backgroundRole(), QBrush(pm));
22
setAttribute(Qt::WA_NoBackground);
27
points << QPointF(0, sizeHint().height())
28
<< QPointF(sizeHint().width(), 0);
30
m_hoverPoints = new HoverPoints(this, HoverPoints::CircleShape);
31
// m_hoverPoints->setConnectionType(HoverPoints::LineConnection);
32
m_hoverPoints->setPoints(points);
33
m_hoverPoints->setPointLock(0, HoverPoints::LockToLeft);
34
m_hoverPoints->setPointLock(1, HoverPoints::LockToRight);
35
m_hoverPoints->setSortType(HoverPoints::XSort);
37
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
39
connect(m_hoverPoints, SIGNAL(pointsChanged(const QPolygonF &)), this, SIGNAL(colorsChanged()));
43
QPolygonF ShadeWidget::points() const
45
return m_hoverPoints->points();
49
uint ShadeWidget::colorAt(int x)
53
QPolygonF pts = m_hoverPoints->points();
54
for (int i=1; i < pts.size(); ++i) {
55
if (pts.at(i-1).x() <= x && pts.at(i).x() >= x) {
56
QLineF l(pts.at(i-1), pts.at(i));
57
l.setLength(l.length() * ((x - l.x1()) / l.dx()));
58
return m_shade.pixel(qRound(qMin(l.x2(), (double(m_shade.width() - 1)))),
59
qRound(qMin(l.y2(), double(m_shade.height() - 1))));
66
void ShadeWidget::setGradientStops(const QGradientStops &stops)
68
if (m_shade_type == ARGBShade) {
69
m_alpha_gradient = QLinearGradient(0, 0, width(), 0);
71
for (int i=0; i<stops.size(); ++i) {
72
QColor c = stops.at(i).second;
73
m_alpha_gradient.setColorAt(stops.at(i).first, QColor(c.red(), c.green(), c.blue()));
83
void ShadeWidget::paintEvent(QPaintEvent *)
88
p.drawImage(0, 0, m_shade);
90
p.setPen(QColor(146, 146, 146));
91
p.drawRect(0, 0, width() - 1, height() - 1);
95
void ShadeWidget::generateShade()
97
if (m_shade.isNull() || m_shade.size() != size()) {
99
if (m_shade_type == ARGBShade) {
100
m_shade = QImage(size(), QImage::Format_ARGB32_Premultiplied);
103
QPainter p(&m_shade);
104
p.fillRect(rect(), m_alpha_gradient);
106
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
107
QLinearGradient fade(0, 0, 0, height());
108
fade.setColorAt(0, QColor(0, 0, 0, 255));
109
fade.setColorAt(1, QColor(0, 0, 0, 0));
110
p.fillRect(rect(), fade);
113
m_shade = QImage(size(), QImage::Format_RGB32);
114
QLinearGradient shade(0, 0, 0, height());
115
shade.setColorAt(1, Qt::black);
117
if (m_shade_type == RedShade)
118
shade.setColorAt(0, Qt::red);
119
else if (m_shade_type == GreenShade)
120
shade.setColorAt(0, Qt::green);
122
shade.setColorAt(0, Qt::blue);
124
QPainter p(&m_shade);
125
p.fillRect(rect(), shade);
133
GradientEditor::GradientEditor(QWidget *parent)
136
QVBoxLayout *vbox = new QVBoxLayout(this);
140
m_red_shade = new ShadeWidget(ShadeWidget::RedShade, this);
141
m_green_shade = new ShadeWidget(ShadeWidget::GreenShade, this);
142
m_blue_shade = new ShadeWidget(ShadeWidget::BlueShade, this);
143
m_alpha_shade = new ShadeWidget(ShadeWidget::ARGBShade, this);
145
vbox->addWidget(m_red_shade);
146
vbox->addWidget(m_green_shade);
147
vbox->addWidget(m_blue_shade);
148
vbox->addWidget(m_alpha_shade);
150
connect(m_red_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
151
connect(m_green_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
152
connect(m_blue_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
153
connect(m_alpha_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
157
inline static bool x_less_than(const QPointF &p1, const QPointF &p2)
159
return p1.x() < p2.x();
163
void GradientEditor::pointsUpdated()
165
double w = m_alpha_shade->width();
167
QGradientStops stops;
171
points += m_red_shade->points();
172
points += m_green_shade->points();
173
points += m_blue_shade->points();
174
points += m_alpha_shade->points();
176
qSort(points.begin(), points.end(), x_less_than);
178
for (int i=0; i<points.size(); ++i) {
179
double x = int(points.at(i).x());
180
if (i < points.size() - 1 && x == points.at(i+1).x())
182
QColor color((0x00ff0000 & m_red_shade->colorAt(int(x))) >> 16,
183
(0x0000ff00 & m_green_shade->colorAt(int(x))) >> 8,
184
(0x000000ff & m_blue_shade->colorAt(int(x))),
185
(0xff000000 & m_alpha_shade->colorAt(int(x))) >> 24);
190
stops << QGradientStop(x / w, color);
193
m_alpha_shade->setGradientStops(stops);
195
emit gradientStopsChanged(stops);
199
static void set_shade_points(const QPolygonF &points, ShadeWidget *shade)
201
shade->hoverPoints()->setPoints(points);
202
shade->hoverPoints()->setPointLock(0, HoverPoints::LockToLeft);
203
shade->hoverPoints()->setPointLock(points.size() - 1, HoverPoints::LockToRight);
207
void GradientEditor::setGradientStops(const QGradientStops &stops)
209
QPolygonF pts_red, pts_green, pts_blue, pts_alpha;
211
double h_red = m_red_shade->height();
212
double h_green = m_green_shade->height();
213
double h_blue = m_blue_shade->height();
214
double h_alpha = m_alpha_shade->height();
216
for (int i=0; i<stops.size(); ++i) {
217
double pos = stops.at(i).first;
218
QRgb color = stops.at(i).second.rgba();
219
pts_red << QPointF(pos * m_red_shade->width(), h_red - qRed(color) * h_red / 255);
220
pts_green << QPointF(pos * m_green_shade->width(), h_green - qGreen(color) * h_green / 255);
221
pts_blue << QPointF(pos * m_blue_shade->width(), h_blue - qBlue(color) * h_blue / 255);
222
pts_alpha << QPointF(pos * m_alpha_shade->width(), h_alpha - qAlpha(color) * h_alpha / 255);
225
set_shade_points(pts_red, m_red_shade);
226
set_shade_points(pts_green, m_green_shade);
227
set_shade_points(pts_blue, m_blue_shade);
228
set_shade_points(pts_alpha, m_alpha_shade);
233
GradientWidget::GradientWidget(QWidget *parent)
236
setWindowTitle("Gradients");
238
m_renderer = new GradientRenderer(this);
240
ArthurGroupBox *mainGroup = new ArthurGroupBox(this);
241
mainGroup->setTitle("Gradients");
243
ArthurGroupBox *editorGroup = new ArthurGroupBox(mainGroup);
244
editorGroup->setAttribute(Qt::WA_ContentsPropagated);
245
editorGroup->setTitle("Color Editor");
246
m_editor = new GradientEditor(editorGroup);
248
ArthurGroupBox *typeGroup = new ArthurGroupBox(mainGroup);
249
typeGroup->setAttribute(Qt::WA_ContentsPropagated);
250
typeGroup->setTitle("Gradient Type");
251
m_linearButton = new QRadioButton("Linear Gradient", typeGroup);
252
m_radialButton = new QRadioButton("Radial Gradient", typeGroup);
253
m_conicalButton = new QRadioButton("Conical Gradient", typeGroup);
255
ArthurGroupBox *spreadGroup = new ArthurGroupBox(mainGroup);
256
spreadGroup->setAttribute(Qt::WA_ContentsPropagated);
257
spreadGroup->setTitle("Spread Method");
258
m_padSpreadButton = new QRadioButton("Pad Spread", spreadGroup);
259
m_reflectSpreadButton = new QRadioButton("Reflect Spread", spreadGroup);
260
m_repeatSpreadButton = new QRadioButton("Repeat Spread", spreadGroup);
262
ArthurGroupBox *defaultsGroup = new ArthurGroupBox(mainGroup);
263
defaultsGroup->setAttribute(Qt::WA_ContentsPropagated);
264
defaultsGroup->setTitle("Defaults");
265
QPushButton *default1Button = new QPushButton("1", defaultsGroup);
266
QPushButton *default2Button = new QPushButton("2", defaultsGroup);
267
QPushButton *default3Button = new QPushButton("3", defaultsGroup);
268
QPushButton *default4Button = new QPushButton("Reset", editorGroup);
270
QPushButton *showSourceButton = new QPushButton(mainGroup);
271
showSourceButton->setText("Show Source");
273
QPushButton *whatsThisButton = new QPushButton(mainGroup);
274
whatsThisButton->setText("What's This?");
275
whatsThisButton->setCheckable(true);
278
QHBoxLayout *mainLayout = new QHBoxLayout(this);
279
mainLayout->addWidget(m_renderer);
280
mainLayout->addWidget(mainGroup);
282
mainGroup->setFixedWidth(180);
283
QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
284
mainGroupLayout->addWidget(editorGroup);
285
mainGroupLayout->addWidget(typeGroup);
286
mainGroupLayout->addWidget(spreadGroup);
287
mainGroupLayout->addWidget(defaultsGroup);
288
mainGroupLayout->addStretch(1);
289
mainGroupLayout->addWidget(showSourceButton);
290
mainGroupLayout->addWidget(whatsThisButton);
292
QVBoxLayout *editorGroupLayout = new QVBoxLayout(editorGroup);
293
editorGroupLayout->addWidget(m_editor);
295
QVBoxLayout *typeGroupLayout = new QVBoxLayout(typeGroup);
296
typeGroupLayout->addWidget(m_linearButton);
297
typeGroupLayout->addWidget(m_radialButton);
298
typeGroupLayout->addWidget(m_conicalButton);
300
QVBoxLayout *spreadGroupLayout = new QVBoxLayout(spreadGroup);
301
spreadGroupLayout->addWidget(m_padSpreadButton);
302
spreadGroupLayout->addWidget(m_repeatSpreadButton);
303
spreadGroupLayout->addWidget(m_reflectSpreadButton);
305
QHBoxLayout *defaultsGroupLayout = new QHBoxLayout(defaultsGroup);
306
defaultsGroupLayout->addWidget(default1Button);
307
defaultsGroupLayout->addWidget(default2Button);
308
defaultsGroupLayout->addWidget(default3Button);
309
editorGroupLayout->addWidget(default4Button);
311
connect(m_editor, SIGNAL(gradientStopsChanged(const QGradientStops &)),
312
m_renderer, SLOT(setGradientStops(const QGradientStops &)));
314
connect(m_linearButton, SIGNAL(clicked()), m_renderer, SLOT(setLinearGradient()));
315
connect(m_radialButton, SIGNAL(clicked()), m_renderer, SLOT(setRadialGradient()));
316
connect(m_conicalButton, SIGNAL(clicked()), m_renderer, SLOT(setConicalGradient()));
318
connect(m_padSpreadButton, SIGNAL(clicked()), m_renderer, SLOT(setPadSpread()));
319
connect(m_reflectSpreadButton, SIGNAL(clicked()), m_renderer, SLOT(setReflectSpread()));
320
connect(m_repeatSpreadButton, SIGNAL(clicked()), m_renderer, SLOT(setRepeatSpread()));
322
connect(default1Button, SIGNAL(clicked()), this, SLOT(setDefault1()));
323
connect(default2Button, SIGNAL(clicked()), this, SLOT(setDefault2()));
324
connect(default3Button, SIGNAL(clicked()), this, SLOT(setDefault3()));
325
connect(default4Button, SIGNAL(clicked()), this, SLOT(setDefault4()));
327
connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource()));
329
connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool)));
330
connect(whatsThisButton, SIGNAL(clicked(bool)),
331
m_renderer->hoverPoints(), SLOT(setDisabled(bool)));
332
connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)),
333
whatsThisButton, SLOT(setChecked(bool)));
334
connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)),
335
m_renderer->hoverPoints(), SLOT(setDisabled(bool)));
337
m_renderer->loadSourceFile(":res/gradients.cpp");
338
m_renderer->loadDescription(":res/gradients.html");
340
QTimer::singleShot(50, this, SLOT(setDefault1()));
343
void GradientWidget::setDefault(int config)
345
QGradientStops stops;
349
stops << QGradientStop(0.00, QColor::fromRgba(0));
350
stops << QGradientStop(0.04, QColor::fromRgba(0xff131360));
351
stops << QGradientStop(0.08, QColor::fromRgba(0xff202ccc));
352
stops << QGradientStop(0.42, QColor::fromRgba(0xff93d3f9));
353
stops << QGradientStop(0.51, QColor::fromRgba(0xffb3e6ff));
354
stops << QGradientStop(0.73, QColor::fromRgba(0xffffffec));
355
stops << QGradientStop(0.92, QColor::fromRgba(0xff5353d9));
356
stops << QGradientStop(0.96, QColor::fromRgba(0xff262666));
357
stops << QGradientStop(1.00, QColor::fromRgba(0));
358
m_linearButton->animateClick();
359
m_repeatSpreadButton->animateClick();
363
stops << QGradientStop(0.00, QColor::fromRgba(0xffffffff));
364
stops << QGradientStop(0.11, QColor::fromRgba(0xfff9ffa0));
365
stops << QGradientStop(0.13, QColor::fromRgba(0xfff9ff99));
366
stops << QGradientStop(0.14, QColor::fromRgba(0xfff3ff86));
367
stops << QGradientStop(0.49, QColor::fromRgba(0xff93b353));
368
stops << QGradientStop(0.87, QColor::fromRgba(0xff264619));
369
stops << QGradientStop(0.96, QColor::fromRgba(0xff0c1306));
370
stops << QGradientStop(1.00, QColor::fromRgba(0));
371
m_radialButton->animateClick();
372
m_padSpreadButton->animateClick();
376
stops << QGradientStop(0.00, QColor::fromRgba(0));
377
stops << QGradientStop(0.10, QColor::fromRgba(0xffe0cc73));
378
stops << QGradientStop(0.17, QColor::fromRgba(0xffc6a006));
379
stops << QGradientStop(0.46, QColor::fromRgba(0xff600659));
380
stops << QGradientStop(0.72, QColor::fromRgba(0xff0680ac));
381
stops << QGradientStop(0.92, QColor::fromRgba(0xffb9d9e6));
382
stops << QGradientStop(1.00, QColor::fromRgba(0));
383
m_conicalButton->animateClick();
384
m_padSpreadButton->animateClick();
388
stops << QGradientStop(0.00, QColor::fromRgba(0xff000000));
389
stops << QGradientStop(1.00, QColor::fromRgba(0xffffffff));
393
qWarning("bad default: %d\n", config);
398
int h_off = m_renderer->width() / 10;
399
int v_off = m_renderer->height() / 8;
400
pts << QPointF(m_renderer->width() / 2, m_renderer->height() / 2)
401
<< QPointF(m_renderer->width() / 2 - h_off, m_renderer->height() / 2 - v_off);
403
m_editor->setGradientStops(stops);
404
m_renderer->hoverPoints()->setPoints(pts);
405
m_renderer->setGradientStops(stops);
409
GradientRenderer::GradientRenderer(QWidget *parent)
410
: ArthurFrame(parent)
412
m_hoverPoints = new HoverPoints(this, HoverPoints::CircleShape);
413
m_hoverPoints->setPointSize(QSize(20, 20));
414
m_hoverPoints->setConnectionType(HoverPoints::NoConnection);
415
m_hoverPoints->setEditable(false);
417
QVector<QPointF> points;
418
points << QPointF(100, 100) << QPointF(200, 200);
419
m_hoverPoints->setPoints(points);
421
m_spread = QGradient::PadSpread;
422
m_gradientType = Qt::LinearGradientPattern;
425
void GradientRenderer::setGradientStops(const QGradientStops &stops)
432
void GradientRenderer::mousePressEvent(QMouseEvent *)
434
setDescriptionEnabled(false);
437
void GradientRenderer::paint(QPainter *p)
439
QPolygonF pts = m_hoverPoints->points();
443
if (m_gradientType == Qt::LinearGradientPattern) {
444
g = QLinearGradient(pts.at(0), pts.at(1));
446
} else if (m_gradientType == Qt::RadialGradientPattern) {
447
g = QRadialGradient(pts.at(0), qMin(width(), height()) / 3.0, pts.at(1));
450
QLineF l(pts.at(0), pts.at(1));
451
double angle = l.angle(QLineF(0, 0, 1, 0));
454
g = QConicalGradient(pts.at(0), angle);
457
for (int i=0; i<m_stops.size(); ++i)
458
g.setColorAt(m_stops.at(i).first, m_stops.at(i).second);
460
g.setSpread(m_spread);
463
p->setPen(Qt::NoPen);