| 1 | // Copyright (C) 2017 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 "qquickbasicdial_p.h" |
| 5 | |
| 6 | #include <QtCore/qmath.h> |
| 7 | #include <QtGui/qpainter.h> |
| 8 | #include <QtGui/qpainterpath.h> |
| 9 | #include <QtQuick/private/qquickitem_p.h> |
| 10 | |
| 11 | QT_BEGIN_NAMESPACE |
| 12 | |
| 13 | QQuickBasicDial::QQuickBasicDial(QQuickItem *parent) : |
| 14 | QQuickPaintedItem(parent) |
| 15 | { |
| 16 | } |
| 17 | |
| 18 | qreal QQuickBasicDial::progress() const |
| 19 | { |
| 20 | return m_progress; |
| 21 | } |
| 22 | |
| 23 | void QQuickBasicDial::setProgress(qreal progress) |
| 24 | { |
| 25 | if (progress == m_progress) |
| 26 | return; |
| 27 | |
| 28 | m_progress = progress; |
| 29 | update(); |
| 30 | } |
| 31 | |
| 32 | qreal QQuickBasicDial::startAngle() const |
| 33 | { |
| 34 | return m_startAngle; |
| 35 | } |
| 36 | |
| 37 | void QQuickBasicDial::setStartAngle(qreal startAngle) |
| 38 | { |
| 39 | if (startAngle == m_startAngle) |
| 40 | return; |
| 41 | |
| 42 | m_startAngle = startAngle; |
| 43 | update(); |
| 44 | } |
| 45 | |
| 46 | qreal QQuickBasicDial::endAngle() const |
| 47 | { |
| 48 | return m_endAngle; |
| 49 | } |
| 50 | |
| 51 | void QQuickBasicDial::setEndAngle(qreal endAngle) |
| 52 | { |
| 53 | if (endAngle == m_endAngle) |
| 54 | return; |
| 55 | |
| 56 | m_endAngle = endAngle; |
| 57 | update(); |
| 58 | } |
| 59 | |
| 60 | QColor QQuickBasicDial::color() const |
| 61 | { |
| 62 | return m_color; |
| 63 | } |
| 64 | |
| 65 | void QQuickBasicDial::setColor(const QColor &color) |
| 66 | { |
| 67 | if (color == m_color) |
| 68 | return; |
| 69 | |
| 70 | m_color = color; |
| 71 | update(); |
| 72 | } |
| 73 | |
| 74 | void QQuickBasicDial::paint(QPainter *painter) |
| 75 | { |
| 76 | if (width() <= 0 || height() <= 0) |
| 77 | return; |
| 78 | |
| 79 | QPen pen(m_color); |
| 80 | pen.setWidth(8); |
| 81 | pen.setCapStyle(Qt::FlatCap); |
| 82 | painter->setPen(pen); |
| 83 | |
| 84 | const QRectF bounds = boundingRect(); |
| 85 | const qreal smallest = qMin(a: bounds.width(), b: bounds.height()); |
| 86 | QRectF rect = QRectF(pen.widthF() / 2.0 + 1, pen.widthF() / 2.0 + 1, smallest - pen.widthF() - 2, smallest - pen.widthF() - 2); |
| 87 | rect.moveCenter(p: bounds.center()); |
| 88 | |
| 89 | // Make sure the arc is aligned to whole pixels. |
| 90 | if (rect.x() - int(rect.x()) > 0) |
| 91 | rect.setX(qCeil(v: rect.x())); |
| 92 | if (rect.y() - int(rect.y()) > 0) |
| 93 | rect.setY(qCeil(v: rect.y())); |
| 94 | if (rect.width() - int(rect.width()) > 0) |
| 95 | rect.setWidth(qFloor(v: rect.width())); |
| 96 | if (rect.height() - int(rect.height()) > 0) |
| 97 | rect.setHeight(qFloor(v: rect.height())); |
| 98 | |
| 99 | painter->setRenderHint(hint: QPainter::Antialiasing); |
| 100 | |
| 101 | const qreal startAngle = 90. - m_startAngle; |
| 102 | const qreal spanAngle = m_progress * (m_startAngle - m_endAngle); |
| 103 | QPainterPath path; |
| 104 | path.arcMoveTo(rect, angle: startAngle); |
| 105 | path.arcTo(rect, startAngle, arcLength: spanAngle); |
| 106 | painter->drawPath(path); |
| 107 | |
| 108 | rect.adjust(xp1: -pen.widthF() / 2.0, yp1: -pen.widthF() / 2.0, xp2: pen.widthF() / 2.0, yp2: pen.widthF() / 2.0); |
| 109 | pen.setWidth(1); |
| 110 | painter->setPen(pen); |
| 111 | |
| 112 | path = QPainterPath(); |
| 113 | path.arcMoveTo(rect, angle: 0); |
| 114 | path.arcTo(rect, startAngle: 0, arcLength: 360); |
| 115 | painter->drawPath(path); |
| 116 | } |
| 117 | |
| 118 | QT_END_NAMESPACE |
| 119 | |
| 120 | #include "moc_qquickbasicdial_p.cpp" |
| 121 | |