qtgradientwidget.cpp

来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 783 行 · 第 1/2 页

CPP
783
字号
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt Designer of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qtgradientwidget.h"#include <QMap>#include <QImage>#include <QPainter>#include <QScrollBar>#include <QMouseEvent>#define _USE_MATH_DEFINES#include "math.h"#include "qdebug.h"#ifndef M_PI#define M_PI 3.14159265358979323846#endifusing namespace qdesigner_internal;namespace qdesigner_internal {class QtGradientWidgetPrivate{    QtGradientWidget *q_ptr;    Q_DECLARE_PUBLIC(QtGradientWidget)public:    QPointF fromViewport(const QPointF &point) const;    QPointF toViewport(const QPointF &point) const;//    void setupDrag(QtGradientStop *stop, int x);    QPointF checkRange(const QPointF &point) const;    QRectF pointRect(const QPointF &point, double size) const;    double correctAngle(double angle) const;    void setAngleConical(double angle);    double m_handleSize;    bool m_backgroundTransparent;    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(const QPointF &point, double size) const{    return QRectF(point.x() - size / 2, point.y() - size / 2, size, size);}QPointF QtGradientWidgetPrivate::checkRange(const 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(const QPointF &point) const{    QSize size = q_ptr->size();    return QPointF(point.x() / size.width(), point.y() / size.height());}QPointF QtGradientWidgetPrivate::toViewport(const QPointF &point) const{    QSize size = q_ptr->size();    return QPointF(point.x() * size.width(), point.y() * size.height());}/*void QtGradientWidgetPrivate::setupDrag(QtGradientStop *stop, int x){    m_model->setCurrentStop(stop);    int viewportX = qRound(toViewport(stop->position()));    m_dragOffset = x - viewportX;    QList<QtGradientStop *> stops = m_stops;    m_stops.clear();    QListIterator<QtGradientStop *> itStop(stops);    while (itStop.hasNext()) {        QtGradientStop *s = itStop.next();        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();        }    }    itStop.toFront();    while (itStop.hasNext()) {        QtGradientStop *s = itStop.next();        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_backgroundTransparent = true;    d_ptr->m_handleSize = 30.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(){    delete d_ptr;}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::setBackgroundTransparent(bool transparent){    if (d_ptr->m_backgroundTransparent == transparent)        return;    d_ptr->m_backgroundTransparent = transparent;    update();}bool QtGradientWidget::backgroundTransparent() const{    return d_ptr->m_backgroundTransparent;}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();            double clickRadius = sqrt(x * x + y * 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;            double r = sqrt(x * x + y * y);            double arcSin = asin(y / r);            double arcCos = acos(x / r);            double angle = arcCos * 180 / M_PI;            if (arcSin > 0) {                angle = -angle;            }            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;    QPointF newPos = QPointF((double)e->pos().x() - d_ptr->m_dragOffset.x(),                (double)e->pos().y() - d_ptr->m_dragOffset.y());    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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?