1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qtgradientwidget.h"
5#include <QtCore/QMap>
6#include <QtGui/QImage>
7#include <QtGui/QPainter>
8#include <QtWidgets/QScrollBar>
9#include <QtGui/QMouseEvent>
10#include <QtGui/QRegion>
11
12#ifndef _USE_MATH_DEFINES
13#define _USE_MATH_DEFINES
14#endif
15
16#include "qmath.h"
17
18QT_BEGIN_NAMESPACE
19
20class QtGradientWidgetPrivate
21{
22 QtGradientWidget *q_ptr;
23 Q_DECLARE_PUBLIC(QtGradientWidget)
24public:
25 QPointF fromViewport(const QPointF &point) const;
26 QPointF toViewport(const QPointF &point) const;
27// void setupDrag(QtGradientStop *stop, int x);
28
29 QPointF checkRange(const QPointF &point) const;
30 QRectF pointRect(const QPointF &point, double size) const;
31
32 double correctAngle(double angle) const;
33 void setAngleConical(double angle);
34
35 void paintPoint(QPainter *painter, const QPointF &point, double size) const;
36
37 double m_handleSize;
38 bool m_backgroundCheckered;
39
40 QGradientStops m_gradientStops;
41 QGradient::Type m_gradientType;
42 QGradient::Spread m_gradientSpread;
43 QPointF m_startLinear;
44 QPointF m_endLinear;
45 QPointF m_centralRadial;
46 QPointF m_focalRadial;
47 qreal m_radiusRadial;
48 QPointF m_centralConical;
49 qreal m_angleConical;
50
51 enum Handle {
52 NoHandle,
53 StartLinearHandle,
54 EndLinearHandle,
55 CentralRadialHandle,
56 FocalRadialHandle,
57 RadiusRadialHandle,
58 CentralConicalHandle,
59 AngleConicalHandle
60 };
61
62 Handle m_dragHandle;
63 QPointF m_dragOffset;
64 //double m_radiusOffset;
65 double m_radiusFactor;
66 double m_dragRadius;
67 double m_angleOffset;
68 double m_dragAngle;
69};
70
71double QtGradientWidgetPrivate::correctAngle(double angle) const
72{
73 double a = angle;
74 while (a >= 360)
75 a -= 360;
76 while (a < 0)
77 a += 360;
78 return a;
79}
80
81void QtGradientWidgetPrivate::setAngleConical(double angle)
82{
83 double a = correctAngle(angle);
84 if (m_angleConical == a)
85 return;
86 m_angleConical = a;
87 emit q_ptr->angleConicalChanged(angle: m_angleConical);
88}
89
90QRectF QtGradientWidgetPrivate::pointRect(const QPointF &point, double size) const
91{
92 return QRectF(point.x() - size / 2, point.y() - size / 2, size, size);
93}
94
95QPointF QtGradientWidgetPrivate::checkRange(const QPointF &point) const
96{
97 QPointF p = point;
98 if (p.x() > 1)
99 p.setX(1);
100 else if (p.x() < 0)
101 p.setX(0);
102 if (p.y() > 1)
103 p.setY(1);
104 else if (p.y() < 0)
105 p.setY(0);
106 return p;
107}
108
109QPointF QtGradientWidgetPrivate::fromViewport(const QPointF &point) const
110{
111 QSize size = q_ptr->size();
112 return QPointF(point.x() / size.width(), point.y() / size.height());
113}
114
115QPointF QtGradientWidgetPrivate::toViewport(const QPointF &point) const
116{
117 QSize size = q_ptr->size();
118 return QPointF(point.x() * size.width(), point.y() * size.height());
119}
120
121void QtGradientWidgetPrivate::paintPoint(QPainter *painter, const QPointF &point, double size) const
122{
123 QPointF pf = toViewport(point);
124 QRectF rf = pointRect(point: pf, size);
125
126 QPen pen;
127 pen.setWidthF(1);
128 QColor alphaZero = Qt::white;
129 alphaZero.setAlpha(0);
130
131 painter->save();
132 painter->drawEllipse(r: rf);
133
134 /*
135 painter->save();
136
137 QLinearGradient lgV(0, rf.top(), 0, rf.bottom());
138 lgV.setColorAt(0, alphaZero);
139 lgV.setColorAt(0.25, Qt::white);
140 lgV.setColorAt(0.25, Qt::white);
141 lgV.setColorAt(1, alphaZero);
142 pen.setBrush(lgV);
143 painter->setPen(pen);
144
145 painter->drawLine(QPointF(pf.x(), rf.top()), QPointF(pf.x(), rf.bottom()));
146
147 QLinearGradient lgH(rf.left(), 0, rf.right(), 0);
148 lgH.setColorAt(0, alphaZero);
149 lgH.setColorAt(0.5, Qt::white);
150 lgH.setColorAt(1, alphaZero);
151 pen.setBrush(lgH);
152 painter->setPen(pen);
153
154 painter->drawLine(QPointF(rf.left(), pf.y()), QPointF(rf.right(), pf.y()));
155
156 painter->restore();
157 */
158
159 painter->restore();
160}
161
162/*
163void QtGradientWidgetPrivate::setupDrag(QtGradientStop *stop, int x)
164{
165 m_model->setCurrentStop(stop);
166
167 int viewportX = qRound(toViewport(stop->position()));
168 m_dragOffset = x - viewportX;
169
170 const auto stops = m_stops;
171 m_stops.clear();
172 for (QtGradientStop *s : stops) {
173 if (m_model->isSelected(s) || s == stop) {
174 m_dragStops[s] = s->position() - stop->position();
175 m_stops.append(s);
176 } else {
177 m_dragOriginal[s->position()] = s->color();
178 }
179 }
180 for (QtGradientStop *s : stops) {
181 if (!m_model->isSelected(s))
182 m_stops.append(s);
183 }
184 m_stops.removeAll(stop);
185 m_stops.prepend(stop);
186}
187*/
188////////////////////////////
189
190QtGradientWidget::QtGradientWidget(QWidget *parent)
191 : QWidget(parent), d_ptr(new QtGradientWidgetPrivate)
192{
193 d_ptr->q_ptr = this;
194 d_ptr->m_backgroundCheckered = true;
195 d_ptr->m_handleSize = 20.0;
196 d_ptr->m_gradientType = QGradient::LinearGradient;
197 d_ptr->m_startLinear = QPointF(0, 0);
198 d_ptr->m_endLinear = QPointF(1, 1);
199 d_ptr->m_centralRadial = QPointF(0.5, 0.5);
200 d_ptr->m_focalRadial = QPointF(0.5, 0.5);
201 d_ptr->m_radiusRadial = 0.5;
202 d_ptr->m_centralConical = QPointF(0.5, 0.5);
203 d_ptr->m_angleConical = 0;
204 d_ptr->m_dragHandle = QtGradientWidgetPrivate::NoHandle;
205
206 setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
207}
208
209QtGradientWidget::~QtGradientWidget()
210{
211}
212
213QSize QtGradientWidget::sizeHint() const
214{
215 return QSize(176, 176);
216}
217
218QSize QtGradientWidget::minimumSizeHint() const
219{
220 return QSize(128, 128);
221}
222
223int QtGradientWidget::heightForWidth(int w) const
224{
225 return w;
226}
227
228void QtGradientWidget::setBackgroundCheckered(bool checkered)
229{
230 if (d_ptr->m_backgroundCheckered == checkered)
231 return;
232 d_ptr->m_backgroundCheckered = checkered;
233 update();
234}
235
236bool QtGradientWidget::isBackgroundCheckered() const
237{
238 return d_ptr->m_backgroundCheckered;
239}
240
241void QtGradientWidget::mousePressEvent(QMouseEvent *e)
242{
243 if (e->button() != Qt::LeftButton)
244 return;
245
246 QPoint p = e->pos();
247 if (d_ptr->m_gradientType == QGradient::LinearGradient) {
248 QPointF startPoint = d_ptr->toViewport(point: d_ptr->m_startLinear);
249 double x = p.x() - startPoint.x();
250 double y = p.y() - startPoint.y();
251
252 if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
253 d_ptr->m_dragHandle = QtGradientWidgetPrivate::StartLinearHandle;
254 d_ptr->m_dragOffset = QPointF(x, y);
255 update();
256 return;
257 }
258
259 QPointF endPoint = d_ptr->toViewport(point: d_ptr->m_endLinear);
260 x = p.x() - endPoint.x();
261 y = p.y() - endPoint.y();
262
263 if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
264 d_ptr->m_dragHandle = QtGradientWidgetPrivate::EndLinearHandle;
265 d_ptr->m_dragOffset = QPointF(x, y);
266 update();
267 return;
268 }
269 } else if (d_ptr->m_gradientType == QGradient::RadialGradient) {
270 QPointF focalPoint = d_ptr->toViewport(point: d_ptr->m_focalRadial);
271 double x = p.x() - focalPoint.x();
272 double y = p.y() - focalPoint.y();
273
274 if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 9) > (x * x + y * y)) {
275 d_ptr->m_dragHandle = QtGradientWidgetPrivate::FocalRadialHandle;
276 d_ptr->m_dragOffset = QPointF(x, y);
277 update();
278 return;
279 }
280
281 QPointF centralPoint = d_ptr->toViewport(point: d_ptr->m_centralRadial);
282 x = p.x() - centralPoint.x();
283 y = p.y() - centralPoint.y();
284
285 if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
286 d_ptr->m_dragHandle = QtGradientWidgetPrivate::CentralRadialHandle;
287 d_ptr->m_dragOffset = QPointF(x, y);
288 update();
289 return;
290 }
291
292 QPointF central = d_ptr->toViewport(point: d_ptr->m_centralRadial);
293 QRectF r = d_ptr->pointRect(point: central, size: 2 * d_ptr->m_handleSize / 3);
294 QRectF r1(0, r.y(), size().width(), r.height());
295 QRectF r2(r.x(), 0, r.width(), r.y());
296 QRectF r3(r.x(), r.y() + r.height(), r.width(), size().height() - r.y() - r.height());
297 QPointF pF(p.x(), p.y());
298 if (r1.contains(p: pF) || r2.contains(p: pF) || r3.contains(p: pF)) {
299 x = pF.x() / size().width() - d_ptr->m_centralRadial.x();
300 y = pF.y() / size().height() - d_ptr->m_centralRadial.y();
301 const double clickRadius = hypot(x: x, y: y);
302 //d_ptr->m_radiusOffset = d_ptr->m_radiusRadial - clickRadius;
303 d_ptr->m_radiusFactor = d_ptr->m_radiusRadial / clickRadius;
304 if (d_ptr->m_radiusFactor == 0)
305 d_ptr->m_radiusFactor = 1;
306 d_ptr->m_dragRadius = d_ptr->m_radiusRadial;
307 d_ptr->m_dragHandle = QtGradientWidgetPrivate::RadiusRadialHandle;
308 mouseMoveEvent(e);
309 update();
310 return;
311 }
312 } else if (d_ptr->m_gradientType == QGradient::ConicalGradient) {
313 QPointF centralPoint = d_ptr->toViewport(point: d_ptr->m_centralConical);
314 double x = p.x() - centralPoint.x();
315 double y = p.y() - centralPoint.y();
316
317 if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
318 d_ptr->m_dragHandle = QtGradientWidgetPrivate::CentralConicalHandle;
319 d_ptr->m_dragOffset = QPointF(x, y);
320 update();
321 return;
322 }
323 double radius = size().width();
324 if (size().height() < radius)
325 radius = size().height();
326 radius /= 2;
327 double corr = d_ptr->m_handleSize / 3;
328 radius -= corr;
329 QPointF vp = d_ptr->toViewport(point: d_ptr->m_centralConical);
330 x = p.x() - vp.x();
331 y = p.y() - vp.y();
332 if (((radius - corr) * (radius - corr) < (x * x + y * y)) &&
333 ((radius + corr) * (radius + corr) > (x * x + y * y))) {
334 QPointF central = d_ptr->toViewport(point: d_ptr->m_centralConical);
335 QPointF current(e->pos().x(), e->pos().y());
336 x = current.x() - central.x();
337 y = current.y() - central.y();
338 x /= size().width() / 2;
339 y /= size().height() / 2;
340 const double angle = qRadiansToDegrees(radians: atan2(y: -y, x: x));
341
342 d_ptr->m_angleOffset = d_ptr->m_angleConical - angle;
343 d_ptr->m_dragAngle = d_ptr->m_angleConical;
344 d_ptr->m_dragHandle = QtGradientWidgetPrivate::AngleConicalHandle;
345 update();
346 return;
347 }
348 }
349}
350
351void QtGradientWidget::mouseReleaseEvent(QMouseEvent *e)
352{
353 Q_UNUSED(e);
354 d_ptr->m_dragHandle = QtGradientWidgetPrivate::NoHandle;
355 update();
356}
357
358void QtGradientWidget::mouseMoveEvent(QMouseEvent *e)
359{
360 if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::NoHandle)
361 return;
362
363 const QPointF newPos = e->position() - d_ptr->m_dragOffset;
364 QPointF newPoint = d_ptr->fromViewport(point: newPos);
365 if (newPoint.x() < 0)
366 newPoint.setX(0);
367 else if (newPoint.x() > 1)
368 newPoint.setX(1);
369 if (newPoint.y() < 0)
370 newPoint.setY(0);
371 else if (newPoint.y() > 1)
372 newPoint.setY(1);
373
374 if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::StartLinearHandle) {
375 d_ptr->m_startLinear = newPoint;
376 emit startLinearChanged(point: newPoint);
377 } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::EndLinearHandle) {
378 d_ptr->m_endLinear = newPoint;
379 emit endLinearChanged(point: newPoint);
380 } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralRadialHandle) {
381 d_ptr->m_centralRadial = newPoint;
382 emit centralRadialChanged(point: newPoint);
383 } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::FocalRadialHandle) {
384 d_ptr->m_focalRadial = newPoint;
385 emit focalRadialChanged(point: newPoint);
386 } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::RadiusRadialHandle) {
387 QPointF centralPoint = d_ptr->toViewport(point: d_ptr->m_centralRadial);
388 QPointF pF(e->pos().x(), e->pos().y());
389 double x = pF.x() - centralPoint.x();
390 double y = pF.y() - centralPoint.y();
391
392 if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
393 if (d_ptr->m_radiusRadial != d_ptr->m_dragRadius) {
394 d_ptr->m_radiusRadial = d_ptr->m_dragRadius;
395 emit radiusRadialChanged(radius: d_ptr->m_radiusRadial);
396 }
397 } else {
398 x = pF.x() / size().width() - d_ptr->m_centralRadial.x();
399 y = pF.y() / size().height() - d_ptr->m_centralRadial.y();
400 const double moveRadius = hypot(x: x, y: y);
401 //double newRadius = moveRadius + d_ptr->m_radiusOffset;
402 double newRadius = moveRadius * d_ptr->m_radiusFactor;
403 if (newRadius > 2)
404 newRadius = 2;
405 d_ptr->m_radiusRadial = newRadius;
406 emit radiusRadialChanged(radius: d_ptr->m_radiusRadial);
407 }
408 } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralConicalHandle) {
409 d_ptr->m_centralConical = newPoint;
410 emit centralConicalChanged(point: newPoint);
411 } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::AngleConicalHandle) {
412 QPointF centralPoint = d_ptr->toViewport(point: d_ptr->m_centralConical);
413 QPointF pF(e->pos().x(), e->pos().y());
414 double x = pF.x() - centralPoint.x();
415 double y = pF.y() - centralPoint.y();
416
417 if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
418 if (d_ptr->m_angleConical != d_ptr->m_dragAngle) {
419 d_ptr->m_angleConical = d_ptr->m_dragAngle;
420 emit angleConicalChanged(angle: d_ptr->m_angleConical);
421 }
422 } else {
423 QPointF central = d_ptr->toViewport(point: d_ptr->m_centralConical);
424 QPointF current = pF;
425 x = current.x() - central.x();
426 y = current.y() - central.y();
427 x /= size().width() / 2;
428 y /= size().height() / 2;
429
430 const double angle = qRadiansToDegrees(radians: atan2(y: -y, x: x)) + d_ptr->m_angleOffset;
431 d_ptr->setAngleConical(angle);
432 }
433 }
434 update();
435}
436
437void QtGradientWidget::mouseDoubleClickEvent(QMouseEvent *e)
438{
439 mousePressEvent(e);
440}
441
442void QtGradientWidget::paintEvent(QPaintEvent *e)
443{
444 Q_UNUSED(e);
445
446 QPainter p(this);
447
448 if (d_ptr->m_backgroundCheckered) {
449 int pixSize = 40;
450 QPixmap pm(2 * pixSize, 2 * pixSize);
451
452 QPainter pmp(&pm);
453 pmp.fillRect(x: 0, y: 0, w: pixSize, h: pixSize, c: Qt::white);
454 pmp.fillRect(x: pixSize, y: pixSize, w: pixSize, h: pixSize, c: Qt::white);
455 pmp.fillRect(x: 0, y: pixSize, w: pixSize, h: pixSize, c: Qt::black);
456 pmp.fillRect(x: pixSize, y: 0, w: pixSize, h: pixSize, c: Qt::black);
457
458 p.setBrushOrigin(x: (size().width() % pixSize + pixSize) / 2, y: (size().height() % pixSize + pixSize) / 2);
459 p.fillRect(rect(), pm);
460 p.setBrushOrigin(x: 0, y: 0);
461 }
462
463 QGradient *gradient = nullptr;
464 switch (d_ptr->m_gradientType) {
465 case QGradient::LinearGradient:
466 gradient = new QLinearGradient(d_ptr->m_startLinear, d_ptr->m_endLinear);
467 break;
468 case QGradient::RadialGradient:
469 gradient = new QRadialGradient(d_ptr->m_centralRadial, d_ptr->m_radiusRadial, d_ptr->m_focalRadial);
470 break;
471 case QGradient::ConicalGradient:
472 gradient = new QConicalGradient(d_ptr->m_centralConical, d_ptr->m_angleConical);
473 break;
474 default:
475 break;
476 }
477 if (!gradient)
478 return;
479
480 gradient->setStops(d_ptr->m_gradientStops);
481 gradient->setSpread(d_ptr->m_gradientSpread);
482
483 p.save();
484 p.scale(sx: size().width(), sy: size().height());
485 p.fillRect(QRect(0, 0, 1, 1), *gradient);
486 p.restore();
487
488 p.setRenderHint(hint: QPainter::Antialiasing);
489
490 QColor c = QColor::fromRgbF(r: 0.5, g: 0.5, b: 0.5, a: 0.5);
491 QBrush br(c);
492 p.setBrush(br);
493 QPen pen(Qt::white);
494 pen.setWidthF(1);
495 p.setPen(pen);
496 QPen dragPen = pen;
497 dragPen.setWidthF(2);
498 if (d_ptr->m_gradientType == QGradient::LinearGradient) {
499 p.save();
500 if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::StartLinearHandle)
501 p.setPen(dragPen);
502 d_ptr->paintPoint(painter: &p, point: d_ptr->m_startLinear, size: d_ptr->m_handleSize);
503 p.restore();
504
505 p.save();
506 if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::EndLinearHandle)
507 p.setPen(dragPen);
508 d_ptr->paintPoint(painter: &p, point: d_ptr->m_endLinear, size: d_ptr->m_handleSize);
509 p.restore();
510 } else if (d_ptr->m_gradientType == QGradient::RadialGradient) {
511 QPointF central = d_ptr->toViewport(point: d_ptr->m_centralRadial);
512
513 p.save();
514 QRectF r = d_ptr->pointRect(point: central, size: 2 * d_ptr->m_handleSize / 3);
515 QRectF r1(0, r.y(), size().width(), r.height());
516 QRectF r2(r.x(), 0, r.width(), r.y());
517 QRectF r3(r.x(), r.y() + r.height(), r.width(), size().height() - r.y() - r.height());
518 p.fillRect(r1, color: c);
519 p.fillRect(r2, color: c);
520 p.fillRect(r3, color: c);
521 p.setBrush(Qt::NoBrush);
522 p.save();
523 if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralRadialHandle)
524 p.setPen(dragPen);
525 d_ptr->paintPoint(painter: &p, point: d_ptr->m_centralRadial, size: d_ptr->m_handleSize);
526 p.restore();
527
528 const QRectF rect = QRectF(central.x() - d_ptr->m_radiusRadial * size().width(),
529 central.y() - d_ptr->m_radiusRadial * size().height(),
530 2 * d_ptr->m_radiusRadial * size().width(),
531 2 * d_ptr->m_radiusRadial * size().height());
532 QRegion region(r1.toRect());
533 region += r2.toRect();
534 region += r3.toRect();
535 p.setClipRegion(region);
536
537 p.drawEllipse(r: rect);
538 if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::RadiusRadialHandle) {
539 p.save();
540 p.setPen(dragPen);
541 QRectF rect = QRectF(central.x() - d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().width(),
542 central.y() - d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().height(),
543 2 * d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().width(),
544 2 * d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().height());
545 p.drawEllipse(r: rect);
546
547 p.restore();
548 }
549 p.restore();
550
551 p.save();
552 if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::FocalRadialHandle)
553 p.setPen(dragPen);
554 d_ptr->paintPoint(painter: &p, point: d_ptr->m_focalRadial, size: 2 * d_ptr->m_handleSize / 3);
555 p.restore();
556 } else if (d_ptr->m_gradientType == QGradient::ConicalGradient) {
557 double radius = size().width();
558 if (size().height() < radius)
559 radius = size().height();
560 radius /= 2;
561 double corr = d_ptr->m_handleSize / 3;
562 radius -= corr;
563 QPointF central = d_ptr->toViewport(point: d_ptr->m_centralConical);
564
565 p.save();
566 p.setBrush(Qt::NoBrush);
567 QPen pen2(c);
568 pen2.setWidthF(2 * d_ptr->m_handleSize / 3);
569 p.setPen(pen2);
570 p.drawEllipse(r: d_ptr->pointRect(point: central, size: 2 * radius));
571 p.restore();
572
573 p.save();
574 p.setBrush(Qt::NoBrush);
575 int pointCount = 2;
576 for (int i = 0; i < pointCount; i++) {
577 const qreal angle = qDegreesToRadians(degrees: i * 180.0 / pointCount + d_ptr->m_angleConical);
578 const QPointF ray(qCos(v: angle) * size().width() / 2,
579 -qSin(v: angle) * size().height() / 2);
580 const double mod = hypot(x: ray.x(), y: ray.y());
581 p.drawLine(p1: QPointF(central.x() + ray.x() * (radius - corr) / mod,
582 central.y() + ray.y() * (radius - corr) / mod),
583 p2: QPointF(central.x() + ray.x() * (radius + corr) / mod,
584 central.y() + ray.y() * (radius + corr) / mod));
585 p.drawLine(p1: QPointF(central.x() - ray.x() * (radius - corr) / mod,
586 central.y() - ray.y() * (radius - corr) / mod),
587 p2: QPointF(central.x() - ray.x() * (radius + corr) / mod,
588 central.y() - ray.y() * (radius + corr) / mod));
589 }
590 if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::AngleConicalHandle) {
591 p.save();
592 p.setPen(dragPen);
593 const qreal angle = qDegreesToRadians(degrees: d_ptr->m_angleConical - d_ptr->m_angleOffset);
594 const QPointF ray(qCos(v: angle) * size().width() / 2,
595 -qSin(v: angle) * size().height() / 2);
596 const double mod = hypot(x: ray.x(), y: ray.y());
597 p.drawLine(p1: QPointF(central.x() + ray.x() * (radius - corr) / mod,
598 central.y() + ray.y() * (radius - corr) / mod),
599 p2: QPointF(central.x() + ray.x() * (radius + corr) / mod,
600 central.y() + ray.y() * (radius + corr) / mod));
601 p.restore();
602 }
603
604 p.restore();
605
606 p.save();
607 if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralConicalHandle)
608 p.setPen(dragPen);
609 d_ptr->paintPoint(painter: &p, point: d_ptr->m_centralConical, size: d_ptr->m_handleSize);
610 p.restore();
611
612 }
613
614 delete gradient;
615}
616
617void QtGradientWidget::setGradientStops(const QGradientStops &stops)
618{
619 d_ptr->m_gradientStops = stops;
620 update();
621}
622
623QGradientStops QtGradientWidget::gradientStops() const
624{
625 return d_ptr->m_gradientStops;
626}
627
628void QtGradientWidget::setGradientType(QGradient::Type type)
629{
630 if (type == QGradient::NoGradient)
631 return;
632 if (d_ptr->m_gradientType == type)
633 return;
634
635 d_ptr->m_gradientType = type;
636 update();
637}
638
639QGradient::Type QtGradientWidget::gradientType() const
640{
641 return d_ptr->m_gradientType;
642}
643
644void QtGradientWidget::setGradientSpread(QGradient::Spread spread)
645{
646 if (d_ptr->m_gradientSpread == spread)
647 return;
648
649 d_ptr->m_gradientSpread = spread;
650 update();
651}
652
653QGradient::Spread QtGradientWidget::gradientSpread() const
654{
655 return d_ptr->m_gradientSpread;
656}
657
658void QtGradientWidget::setStartLinear(const QPointF &point)
659{
660 if (d_ptr->m_startLinear == point)
661 return;
662
663 d_ptr->m_startLinear = d_ptr->checkRange(point);
664 update();
665}
666
667QPointF QtGradientWidget::startLinear() const
668{
669 return d_ptr->m_startLinear;
670}
671
672void QtGradientWidget::setEndLinear(const QPointF &point)
673{
674 if (d_ptr->m_endLinear == point)
675 return;
676
677 d_ptr->m_endLinear = d_ptr->checkRange(point);
678 update();
679}
680
681QPointF QtGradientWidget::endLinear() const
682{
683 return d_ptr->m_endLinear;
684}
685
686void QtGradientWidget::setCentralRadial(const QPointF &point)
687{
688 if (d_ptr->m_centralRadial == point)
689 return;
690
691 d_ptr->m_centralRadial = point;
692 update();
693}
694
695QPointF QtGradientWidget::centralRadial() const
696{
697 return d_ptr->m_centralRadial;
698}
699
700void QtGradientWidget::setFocalRadial(const QPointF &point)
701{
702 if (d_ptr->m_focalRadial == point)
703 return;
704
705 d_ptr->m_focalRadial = point;
706 update();
707}
708
709QPointF QtGradientWidget::focalRadial() const
710{
711 return d_ptr->m_focalRadial;
712}
713
714void QtGradientWidget::setRadiusRadial(qreal radius)
715{
716 if (d_ptr->m_radiusRadial == radius)
717 return;
718
719 d_ptr->m_radiusRadial = radius;
720 update();
721}
722
723qreal QtGradientWidget::radiusRadial() const
724{
725 return d_ptr->m_radiusRadial;
726}
727
728void QtGradientWidget::setCentralConical(const QPointF &point)
729{
730 if (d_ptr->m_centralConical == point)
731 return;
732
733 d_ptr->m_centralConical = point;
734 update();
735}
736
737QPointF QtGradientWidget::centralConical() const
738{
739 return d_ptr->m_centralConical;
740}
741
742void QtGradientWidget::setAngleConical(qreal angle)
743{
744 if (d_ptr->m_angleConical == angle)
745 return;
746
747 d_ptr->m_angleConical = angle;
748 update();
749}
750
751qreal QtGradientWidget::angleConical() const
752{
753 return d_ptr->m_angleConical;
754}
755
756QT_END_NAMESPACE
757

source code of qttools/src/shared/qtgradienteditor/qtgradientwidget.cpp