Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++ #include "qtgradientwidget_p.h"
++ #include <QtCore/qmap.h>
++ #include <QtGui/qimage.h>
++ #include <QtGui/qpainter.h>
++ #include <QtWidgets/qscrollbar.h>
++ #include <QtGui/qevent.h>
++ #include <QtGui/qregion.h>
++
++ #ifndef _USE_MATH_DEFINES
++ #define _USE_MATH_DEFINES
++ #endif
++
++ #include "qmath.h"
++
++ QT_BEGIN_NAMESPACE
++
++ class QtGradientWidgetPrivate
++ {
++ QtGradientWidget *q_ptr;
++ Q_DECLARE_PUBLIC(QtGradientWidget)
++ public:
++ QPointF fromViewport(QPointF point) const;
++ QPointF toViewport(QPointF point) const;
++ // void setupDrag(QtGradientStop *stop, int x);
++
++ QPointF checkRange(QPointF point) const;
++ QRectF pointRect(QPointF point, double size) const;
++
++ double correctAngle(double angle) const;
++ void setAngleConical(double angle);
++
++ void paintPoint(QPainter *painter, QPointF point, double size) const;
++
++ double m_handleSize;
++ bool m_backgroundCheckered;
++
++ QGradientStops m_gradientStops;
++ QGradient::Type m_gradientType;
++ QGradient::Spread m_gradientSpread;
++ QPointF m_startLinear;
++ QPointF m_endLinear;
++ QPointF m_centralRadial;
++ QPointF m_focalRadial;
++ qreal m_radiusRadial;
++ QPointF m_centralConical;
++ qreal m_angleConical;
++
++ enum Handle {
++ NoHandle,
++ StartLinearHandle,
++ EndLinearHandle,
++ CentralRadialHandle,
++ FocalRadialHandle,
++ RadiusRadialHandle,
++ CentralConicalHandle,
++ AngleConicalHandle
++ };
++
++ Handle m_dragHandle;
++ QPointF m_dragOffset;
++ //double m_radiusOffset;
++ double m_radiusFactor;
++ double m_dragRadius;
++ double m_angleOffset;
++ double m_dragAngle;
++ };
++
++ double QtGradientWidgetPrivate::correctAngle(double angle) const
++ {
++ double a = angle;
++ while (a >= 360)
++ a -= 360;
++ while (a < 0)
++ a += 360;
++ return a;
++ }
++
++ void QtGradientWidgetPrivate::setAngleConical(double angle)
++ {
++ double a = correctAngle(angle);
++ if (m_angleConical == a)
++ return;
++ m_angleConical = a;
++ emit q_ptr->angleConicalChanged(m_angleConical);
++ }
++
++ QRectF QtGradientWidgetPrivate::pointRect(QPointF point, double size) const
++ {
++ return QRectF(point.x() - size / 2, point.y() - size / 2, size, size);
++ }
++
++ QPointF QtGradientWidgetPrivate::checkRange(QPointF point) const
++ {
++ QPointF p = point;
++ if (p.x() > 1)
++ p.setX(1);
++ else if (p.x() < 0)
++ p.setX(0);
++ if (p.y() > 1)
++ p.setY(1);
++ else if (p.y() < 0)
++ p.setY(0);
++ return p;
++ }
++
++ QPointF QtGradientWidgetPrivate::fromViewport(QPointF point) const
++ {
++ QSize size = q_ptr->size();
++ return QPointF(point.x() / size.width(), point.y() / size.height());
++ }
++
++ QPointF QtGradientWidgetPrivate::toViewport(QPointF point) const
++ {
++ QSize size = q_ptr->size();
++ return QPointF(point.x() * size.width(), point.y() * size.height());
++ }
++
++ void QtGradientWidgetPrivate::paintPoint(QPainter *painter, QPointF point,
++ double size) const
++ {
++ QPointF pf = toViewport(point);
++ QRectF rf = pointRect(pf, size);
++
++ QPen pen;
++ pen.setWidthF(1);
++ QColor alphaZero = Qt::white;
++ alphaZero.setAlpha(0);
++
++ painter->save();
++ painter->drawEllipse(rf);
++
++ /*
++ painter->save();
++
++ QLinearGradient lgV(0, rf.top(), 0, rf.bottom());
++ lgV.setColorAt(0, alphaZero);
++ lgV.setColorAt(0.25, Qt::white);
++ lgV.setColorAt(0.25, Qt::white);
++ lgV.setColorAt(1, alphaZero);
++ pen.setBrush(lgV);
++ painter->setPen(pen);
++
++ painter->drawLine(QPointF(pf.x(), rf.top()), QPointF(pf.x(), rf.bottom()));
++
++ QLinearGradient lgH(rf.left(), 0, rf.right(), 0);
++ lgH.setColorAt(0, alphaZero);
++ lgH.setColorAt(0.5, Qt::white);
++ lgH.setColorAt(1, alphaZero);
++ pen.setBrush(lgH);
++ painter->setPen(pen);
++
++ painter->drawLine(QPointF(rf.left(), pf.y()), QPointF(rf.right(), pf.y()));
++
++ painter->restore();
++ */
++
++ painter->restore();
++ }
++
++ /*
++ void QtGradientWidgetPrivate::setupDrag(QtGradientStop *stop, int x)
++ {
++ m_model->setCurrentStop(stop);
++
++ int viewportX = qRound(toViewport(stop->position()));
++ m_dragOffset = x - viewportX;
++
++ const auto stops = m_stops;
++ m_stops.clear();
++ for (QtGradientStop *s : stops) {
++ if (m_model->isSelected(s) || s == stop) {
++ m_dragStops[s] = s->position() - stop->position();
++ m_stops.append(s);
++ } else {
++ m_dragOriginal[s->position()] = s->color();
++ }
++ }
++ for (QtGradientStop *s : stops) {
++ if (!m_model->isSelected(s))
++ m_stops.append(s);
++ }
++ m_stops.removeAll(stop);
++ m_stops.prepend(stop);
++ }
++ */
++ ////////////////////////////
++
++ QtGradientWidget::QtGradientWidget(QWidget *parent)
++ : QWidget(parent), d_ptr(new QtGradientWidgetPrivate)
++ {
++ d_ptr->q_ptr = this;
++ d_ptr->m_backgroundCheckered = true;
++ d_ptr->m_handleSize = 20.0;
++ d_ptr->m_gradientType = QGradient::LinearGradient;
++ d_ptr->m_startLinear = QPointF(0, 0);
++ d_ptr->m_endLinear = QPointF(1, 1);
++ d_ptr->m_centralRadial = QPointF(0.5, 0.5);
++ d_ptr->m_focalRadial = QPointF(0.5, 0.5);
++ d_ptr->m_radiusRadial = 0.5;
++ d_ptr->m_centralConical = QPointF(0.5, 0.5);
++ d_ptr->m_angleConical = 0;
++ d_ptr->m_dragHandle = QtGradientWidgetPrivate::NoHandle;
++
++ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
++ }
++
++ QtGradientWidget::~QtGradientWidget()
++ {
++ }
++
++ QSize QtGradientWidget::sizeHint() const
++ {
++ return QSize(176, 176);
++ }
++
++ QSize QtGradientWidget::minimumSizeHint() const
++ {
++ return QSize(128, 128);
++ }
++
++ int QtGradientWidget::heightForWidth(int w) const
++ {
++ return w;
++ }
++
++ void QtGradientWidget::setBackgroundCheckered(bool checkered)
++ {
++ if (d_ptr->m_backgroundCheckered == checkered)
++ return;
++ d_ptr->m_backgroundCheckered = checkered;
++ update();
++ }
++
++ bool QtGradientWidget::isBackgroundCheckered() const
++ {
++ return d_ptr->m_backgroundCheckered;
++ }
++
++ void QtGradientWidget::mousePressEvent(QMouseEvent *e)
++ {
++ if (e->button() != Qt::LeftButton)
++ return;
++
++ QPoint p = e->pos();
++ if (d_ptr->m_gradientType == QGradient::LinearGradient) {
++ QPointF startPoint = d_ptr->toViewport(d_ptr->m_startLinear);
++ double x = p.x() - startPoint.x();
++ double y = p.y() - startPoint.y();
++
++ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
++ d_ptr->m_dragHandle = QtGradientWidgetPrivate::StartLinearHandle;
++ d_ptr->m_dragOffset = QPointF(x, y);
++ update();
++ return;
++ }
++
++ QPointF endPoint = d_ptr->toViewport(d_ptr->m_endLinear);
++ x = p.x() - endPoint.x();
++ y = p.y() - endPoint.y();
++
++ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
++ d_ptr->m_dragHandle = QtGradientWidgetPrivate::EndLinearHandle;
++ d_ptr->m_dragOffset = QPointF(x, y);
++ update();
++ return;
++ }
++ } else if (d_ptr->m_gradientType == QGradient::RadialGradient) {
++ QPointF focalPoint = d_ptr->toViewport(d_ptr->m_focalRadial);
++ double x = p.x() - focalPoint.x();
++ double y = p.y() - focalPoint.y();
++
++ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 9) > (x * x + y * y)) {
++ d_ptr->m_dragHandle = QtGradientWidgetPrivate::FocalRadialHandle;
++ d_ptr->m_dragOffset = QPointF(x, y);
++ update();
++ return;
++ }
++
++ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralRadial);
++ x = p.x() - centralPoint.x();
++ y = p.y() - centralPoint.y();
++
++ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
++ d_ptr->m_dragHandle = QtGradientWidgetPrivate::CentralRadialHandle;
++ d_ptr->m_dragOffset = QPointF(x, y);
++ update();
++ return;
++ }
++
++ QPointF central = d_ptr->toViewport(d_ptr->m_centralRadial);
++ QRectF r = d_ptr->pointRect(central, 2 * d_ptr->m_handleSize / 3);
++ QRectF r1(0, r.y(), size().width(), r.height());
++ QRectF r2(r.x(), 0, r.width(), r.y());
++ QRectF r3(r.x(), r.y() + r.height(), r.width(), size().height() - r.y() - r.height());
++ QPointF pF(p.x(), p.y());
++ if (r1.contains(pF) || r2.contains(pF) || r3.contains(pF)) {
++ x = pF.x() / size().width() - d_ptr->m_centralRadial.x();
++ y = pF.y() / size().height() - d_ptr->m_centralRadial.y();
++ const double clickRadius = hypot(x, y);
++ //d_ptr->m_radiusOffset = d_ptr->m_radiusRadial - clickRadius;
++ d_ptr->m_radiusFactor = d_ptr->m_radiusRadial / clickRadius;
++ if (d_ptr->m_radiusFactor == 0)
++ d_ptr->m_radiusFactor = 1;
++ d_ptr->m_dragRadius = d_ptr->m_radiusRadial;
++ d_ptr->m_dragHandle = QtGradientWidgetPrivate::RadiusRadialHandle;
++ mouseMoveEvent(e);
++ update();
++ return;
++ }
++ } else if (d_ptr->m_gradientType == QGradient::ConicalGradient) {
++ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralConical);
++ double x = p.x() - centralPoint.x();
++ double y = p.y() - centralPoint.y();
++
++ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
++ d_ptr->m_dragHandle = QtGradientWidgetPrivate::CentralConicalHandle;
++ d_ptr->m_dragOffset = QPointF(x, y);
++ update();
++ return;
++ }
++ double radius = size().width();
++ if (size().height() < radius)
++ radius = size().height();
++ radius /= 2;
++ double corr = d_ptr->m_handleSize / 3;
++ radius -= corr;
++ QPointF vp = d_ptr->toViewport(d_ptr->m_centralConical);
++ x = p.x() - vp.x();
++ y = p.y() - vp.y();
++ if (((radius - corr) * (radius - corr) < (x * x + y * y)) &&
++ ((radius + corr) * (radius + corr) > (x * x + y * y))) {
++ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
++ QPointF current(e->pos().x(), e->pos().y());
++ x = current.x() - central.x();
++ y = current.y() - central.y();
++ x /= size().width() / 2;
++ y /= size().height() / 2;
++ const double angle = qRadiansToDegrees(atan2(-y, x));
++
++ d_ptr->m_angleOffset = d_ptr->m_angleConical - angle;
++ d_ptr->m_dragAngle = d_ptr->m_angleConical;
++ d_ptr->m_dragHandle = QtGradientWidgetPrivate::AngleConicalHandle;
++ update();
++ return;
++ }
++ }
++ }
++
++ void QtGradientWidget::mouseReleaseEvent(QMouseEvent *e)
++ {
++ Q_UNUSED(e);
++ d_ptr->m_dragHandle = QtGradientWidgetPrivate::NoHandle;
++ update();
++ }
++
++ void QtGradientWidget::mouseMoveEvent(QMouseEvent *e)
++ {
++ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::NoHandle)
++ return;
++
++ const QPointF newPos = e->position() - d_ptr->m_dragOffset;
++ QPointF newPoint = d_ptr->fromViewport(newPos);
++ if (newPoint.x() < 0)
++ newPoint.setX(0);
++ else if (newPoint.x() > 1)
++ newPoint.setX(1);
++ if (newPoint.y() < 0)
++ newPoint.setY(0);
++ else if (newPoint.y() > 1)
++ newPoint.setY(1);
++
++ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::StartLinearHandle) {
++ d_ptr->m_startLinear = newPoint;
++ emit startLinearChanged(newPoint);
++ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::EndLinearHandle) {
++ d_ptr->m_endLinear = newPoint;
++ emit endLinearChanged(newPoint);
++ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralRadialHandle) {
++ d_ptr->m_centralRadial = newPoint;
++ emit centralRadialChanged(newPoint);
++ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::FocalRadialHandle) {
++ d_ptr->m_focalRadial = newPoint;
++ emit focalRadialChanged(newPoint);
++ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::RadiusRadialHandle) {
++ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralRadial);
++ QPointF pF(e->pos().x(), e->pos().y());
++ double x = pF.x() - centralPoint.x();
++ double y = pF.y() - centralPoint.y();
++
++ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
++ if (d_ptr->m_radiusRadial != d_ptr->m_dragRadius) {
++ d_ptr->m_radiusRadial = d_ptr->m_dragRadius;
++ emit radiusRadialChanged(d_ptr->m_radiusRadial);
++ }
++ } else {
++ x = pF.x() / size().width() - d_ptr->m_centralRadial.x();
++ y = pF.y() / size().height() - d_ptr->m_centralRadial.y();
++ const double moveRadius = hypot(x, y);
++ //double newRadius = moveRadius + d_ptr->m_radiusOffset;
++ double newRadius = moveRadius * d_ptr->m_radiusFactor;
++ if (newRadius > 2)
++ newRadius = 2;
++ d_ptr->m_radiusRadial = newRadius;
++ emit radiusRadialChanged(d_ptr->m_radiusRadial);
++ }
++ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralConicalHandle) {
++ d_ptr->m_centralConical = newPoint;
++ emit centralConicalChanged(newPoint);
++ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::AngleConicalHandle) {
++ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralConical);
++ QPointF pF(e->pos().x(), e->pos().y());
++ double x = pF.x() - centralPoint.x();
++ double y = pF.y() - centralPoint.y();
++
++ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
++ if (d_ptr->m_angleConical != d_ptr->m_dragAngle) {
++ d_ptr->m_angleConical = d_ptr->m_dragAngle;
++ emit angleConicalChanged(d_ptr->m_angleConical);
++ }
++ } else {
++ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
++ QPointF current = pF;
++ x = current.x() - central.x();
++ y = current.y() - central.y();
++ x /= size().width() / 2;
++ y /= size().height() / 2;
++
++ const double angle = qRadiansToDegrees(atan2(-y, x)) + d_ptr->m_angleOffset;
++ d_ptr->setAngleConical(angle);
++ }
++ }
++ update();
++ }
++
++ void QtGradientWidget::mouseDoubleClickEvent(QMouseEvent *e)
++ {
++ mousePressEvent(e);
++ }
++
++ void QtGradientWidget::paintEvent(QPaintEvent *e)
++ {
++ Q_UNUSED(e);
++
++ QPainter p(this);
++
++ if (d_ptr->m_backgroundCheckered) {
++ int pixSize = 40;
++ QPixmap pm(2 * pixSize, 2 * pixSize);
++
++ QPainter pmp(&pm);
++ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
++ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
++ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
++ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
++
++ p.setBrushOrigin((size().width() % pixSize + pixSize) / 2, (size().height() % pixSize + pixSize) / 2);
++ p.fillRect(rect(), pm);
++ p.setBrushOrigin(0, 0);
++ }
++
++ QGradient *gradient = nullptr;
++ switch (d_ptr->m_gradientType) {
++ case QGradient::LinearGradient:
++ gradient = new QLinearGradient(d_ptr->m_startLinear, d_ptr->m_endLinear);
++ break;
++ case QGradient::RadialGradient:
++ gradient = new QRadialGradient(d_ptr->m_centralRadial, d_ptr->m_radiusRadial, d_ptr->m_focalRadial);
++ break;
++ case QGradient::ConicalGradient:
++ gradient = new QConicalGradient(d_ptr->m_centralConical, d_ptr->m_angleConical);
++ break;
++ default:
++ break;
++ }
++ if (!gradient)
++ return;
++
++ gradient->setStops(d_ptr->m_gradientStops);
++ gradient->setSpread(d_ptr->m_gradientSpread);
++
++ p.save();
++ p.scale(size().width(), size().height());
++ p.fillRect(QRect(0, 0, 1, 1), *gradient);
++ p.restore();
++
++ p.setRenderHint(QPainter::Antialiasing);
++
++ QColor c = QColor::fromRgbF(0.5, 0.5, 0.5, 0.5);
++ QBrush br(c);
++ p.setBrush(br);
++ QPen pen(Qt::white);
++ pen.setWidthF(1);
++ p.setPen(pen);
++ QPen dragPen = pen;
++ dragPen.setWidthF(2);
++ if (d_ptr->m_gradientType == QGradient::LinearGradient) {
++ p.save();
++ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::StartLinearHandle)
++ p.setPen(dragPen);
++ d_ptr->paintPoint(&p, d_ptr->m_startLinear, d_ptr->m_handleSize);
++ p.restore();
++
++ p.save();
++ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::EndLinearHandle)
++ p.setPen(dragPen);
++ d_ptr->paintPoint(&p, d_ptr->m_endLinear, d_ptr->m_handleSize);
++ p.restore();
++ } else if (d_ptr->m_gradientType == QGradient::RadialGradient) {
++ QPointF central = d_ptr->toViewport(d_ptr->m_centralRadial);
++
++ p.save();
++ QRectF r = d_ptr->pointRect(central, 2 * d_ptr->m_handleSize / 3);
++ QRectF r1(0, r.y(), size().width(), r.height());
++ QRectF r2(r.x(), 0, r.width(), r.y());
++ QRectF r3(r.x(), r.y() + r.height(), r.width(), size().height() - r.y() - r.height());
++ p.fillRect(r1, c);
++ p.fillRect(r2, c);
++ p.fillRect(r3, c);
++ p.setBrush(Qt::NoBrush);
++ p.save();
++ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralRadialHandle)
++ p.setPen(dragPen);
++ d_ptr->paintPoint(&p, d_ptr->m_centralRadial, d_ptr->m_handleSize);
++ p.restore();
++
++ const QRectF rect = QRectF(central.x() - d_ptr->m_radiusRadial * size().width(),
++ central.y() - d_ptr->m_radiusRadial * size().height(),
++ 2 * d_ptr->m_radiusRadial * size().width(),
++ 2 * d_ptr->m_radiusRadial * size().height());
++ QRegion region(r1.toRect());
++ region += r2.toRect();
++ region += r3.toRect();
++ p.setClipRegion(region);
++
++ p.drawEllipse(rect);
++ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::RadiusRadialHandle) {
++ p.save();
++ p.setPen(dragPen);
++ QRectF rect = QRectF(central.x() - d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().width(),
++ central.y() - d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().height(),
++ 2 * d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().width(),
++ 2 * d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().height());
++ p.drawEllipse(rect);
++
++ p.restore();
++ }
++ p.restore();
++
++ p.save();
++ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::FocalRadialHandle)
++ p.setPen(dragPen);
++ d_ptr->paintPoint(&p, d_ptr->m_focalRadial, 2 * d_ptr->m_handleSize / 3);
++ p.restore();
++ } else if (d_ptr->m_gradientType == QGradient::ConicalGradient) {
++ double radius = size().width();
++ if (size().height() < radius)
++ radius = size().height();
++ radius /= 2;
++ double corr = d_ptr->m_handleSize / 3;
++ radius -= corr;
++ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
++
++ p.save();
++ p.setBrush(Qt::NoBrush);
++ QPen pen2(c);
++ pen2.setWidthF(2 * d_ptr->m_handleSize / 3);
++ p.setPen(pen2);
++ p.drawEllipse(d_ptr->pointRect(central, 2 * radius));
++ p.restore();
++
++ p.save();
++ p.setBrush(Qt::NoBrush);
++ int pointCount = 2;
++ for (int i = 0; i < pointCount; i++) {
++ const qreal angle = qDegreesToRadians(i * 180.0 / pointCount + d_ptr->m_angleConical);
++ const QPointF ray(qCos(angle) * size().width() / 2,
++ -qSin(angle) * size().height() / 2);
++ const double mod = hypot(ray.x(), ray.y());
++ p.drawLine(QPointF(central.x() + ray.x() * (radius - corr) / mod,
++ central.y() + ray.y() * (radius - corr) / mod),
++ QPointF(central.x() + ray.x() * (radius + corr) / mod,
++ central.y() + ray.y() * (radius + corr) / mod));
++ p.drawLine(QPointF(central.x() - ray.x() * (radius - corr) / mod,
++ central.y() - ray.y() * (radius - corr) / mod),
++ QPointF(central.x() - ray.x() * (radius + corr) / mod,
++ central.y() - ray.y() * (radius + corr) / mod));
++ }
++ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::AngleConicalHandle) {
++ p.save();
++ p.setPen(dragPen);
++ const qreal angle = qDegreesToRadians(d_ptr->m_angleConical - d_ptr->m_angleOffset);
++ const QPointF ray(qCos(angle) * size().width() / 2,
++ -qSin(angle) * size().height() / 2);
++ const double mod = hypot(ray.x(), ray.y());
++ p.drawLine(QPointF(central.x() + ray.x() * (radius - corr) / mod,
++ central.y() + ray.y() * (radius - corr) / mod),
++ QPointF(central.x() + ray.x() * (radius + corr) / mod,
++ central.y() + ray.y() * (radius + corr) / mod));
++ p.restore();
++ }
++
++ p.restore();
++
++ p.save();
++ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralConicalHandle)
++ p.setPen(dragPen);
++ d_ptr->paintPoint(&p, d_ptr->m_centralConical, d_ptr->m_handleSize);
++ p.restore();
++
++ }
++
++ delete gradient;
++ }
++
++ void QtGradientWidget::setGradientStops(const QGradientStops &stops)
++ {
++ d_ptr->m_gradientStops = stops;
++ update();
++ }
++
++ QGradientStops QtGradientWidget::gradientStops() const
++ {
++ return d_ptr->m_gradientStops;
++ }
++
++ void QtGradientWidget::setGradientType(QGradient::Type type)
++ {
++ if (type == QGradient::NoGradient)
++ return;
++ if (d_ptr->m_gradientType == type)
++ return;
++
++ d_ptr->m_gradientType = type;
++ update();
++ }
++
++ QGradient::Type QtGradientWidget::gradientType() const
++ {
++ return d_ptr->m_gradientType;
++ }
++
++ void QtGradientWidget::setGradientSpread(QGradient::Spread spread)
++ {
++ if (d_ptr->m_gradientSpread == spread)
++ return;
++
++ d_ptr->m_gradientSpread = spread;
++ update();
++ }
++
++ QGradient::Spread QtGradientWidget::gradientSpread() const
++ {
++ return d_ptr->m_gradientSpread;
++ }
++
++ void QtGradientWidget::setStartLinear(QPointF point)
++ {
++ if (d_ptr->m_startLinear == point)
++ return;
++
++ d_ptr->m_startLinear = d_ptr->checkRange(point);
++ update();
++ }
++
++ QPointF QtGradientWidget::startLinear() const
++ {
++ return d_ptr->m_startLinear;
++ }
++
++ void QtGradientWidget::setEndLinear(QPointF point)
++ {
++ if (d_ptr->m_endLinear == point)
++ return;
++
++ d_ptr->m_endLinear = d_ptr->checkRange(point);
++ update();
++ }
++
++ QPointF QtGradientWidget::endLinear() const
++ {
++ return d_ptr->m_endLinear;
++ }
++
++ void QtGradientWidget::setCentralRadial(QPointF point)
++ {
++ if (d_ptr->m_centralRadial == point)
++ return;
++
++ d_ptr->m_centralRadial = point;
++ update();
++ }
++
++ QPointF QtGradientWidget::centralRadial() const
++ {
++ return d_ptr->m_centralRadial;
++ }
++
++ void QtGradientWidget::setFocalRadial(QPointF point)
++ {
++ if (d_ptr->m_focalRadial == point)
++ return;
++
++ d_ptr->m_focalRadial = point;
++ update();
++ }
++
++ QPointF QtGradientWidget::focalRadial() const
++ {
++ return d_ptr->m_focalRadial;
++ }
++
++ void QtGradientWidget::setRadiusRadial(qreal radius)
++ {
++ if (d_ptr->m_radiusRadial == radius)
++ return;
++
++ d_ptr->m_radiusRadial = radius;
++ update();
++ }
++
++ qreal QtGradientWidget::radiusRadial() const
++ {
++ return d_ptr->m_radiusRadial;
++ }
++
++ void QtGradientWidget::setCentralConical(QPointF point)
++ {
++ if (d_ptr->m_centralConical == point)
++ return;
++
++ d_ptr->m_centralConical = point;
++ update();
++ }
++
++ QPointF QtGradientWidget::centralConical() const
++ {
++ return d_ptr->m_centralConical;
++ }
++
++ void QtGradientWidget::setAngleConical(qreal angle)
++ {
++ if (d_ptr->m_angleConical == angle)
++ return;
++
++ d_ptr->m_angleConical = angle;
++ update();
++ }
++
++ qreal QtGradientWidget::angleConical() const
++ {
++ return d_ptr->m_angleConical;
++ }
++
++ QT_END_NAMESPACE