File indexing completed on 2024-05-12 05:38:56

0001 /* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
0002  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0003  */
0004 
0005 #include "breezedial.h"
0006 #include <QGuiApplication>
0007 #include <QPainter>
0008 
0009 class BreezeDialPrivate
0010 {
0011     Q_DECLARE_PUBLIC(BreezeDial)
0012     Q_DISABLE_COPY(BreezeDialPrivate)
0013 public:
0014     BreezeDialPrivate(BreezeDial *qq)
0015         : q_ptr(qq)
0016     {
0017     }
0018     BreezeDial *const q_ptr;
0019 
0020     QFontMetricsF fontMetrics = QFontMetricsF(QGuiApplication::font());
0021 
0022     QColor backgroundColor;
0023     QColor backgroundBorderColor;
0024     QColor fillColor;
0025     QColor fillBorderColor;
0026     qreal angle = -140.0; // Range of QQuickDial::angle() is -140 to 140
0027     qreal grooveThickness = 0;
0028     bool notchesVisible = false;
0029 };
0030 
0031 BreezeDial::BreezeDial(QQuickItem *parent)
0032     : QQuickPaintedItem(parent)
0033     , d_ptr(new BreezeDialPrivate(this))
0034 {
0035     Q_D(BreezeDial);
0036     connect(qGuiApp, &QGuiApplication::fontChanged, this, [this, d]() {
0037         d->fontMetrics = QFontMetricsF(QGuiApplication::font());
0038         update();
0039     });
0040 }
0041 
0042 BreezeDial::~BreezeDial() noexcept
0043 {
0044 }
0045 
0046 void BreezeDial::paint(QPainter *painter)
0047 {
0048     Q_D(BreezeDial);
0049     if (width() <= 0 || height() <= 0 || d->grooveThickness <= 0)
0050         return;
0051 
0052     QRectF paintRect;
0053     paintRect.setWidth(qMin(boundingRect().width() - d->grooveThickness, boundingRect().height() - d->grooveThickness));
0054     paintRect.setHeight(paintRect.width());
0055     paintRect.moveCenter(boundingRect().center());
0056 
0057     QPen backgroundBorderPen(d->backgroundBorderColor, d->grooveThickness, Qt::SolidLine, Qt::RoundCap);
0058     QPen backgroundPen(d->backgroundColor, d->grooveThickness - 2, Qt::SolidLine, Qt::RoundCap);
0059     QPen fillBorderPen(d->fillBorderColor, d->grooveThickness, Qt::SolidLine, Qt::RoundCap);
0060     QPen fillPen(d->fillColor, d->grooveThickness - 2, Qt::SolidLine, Qt::RoundCap);
0061 
0062     const qreal startAngle = -130 * 16;
0063     const qreal backgroundSpanAngle = -280 * 16;
0064     const qreal fillSpanAngle = (-d->angle - 140) * 16;
0065 
0066     painter->setRenderHint(QPainter::Antialiasing);
0067     painter->setPen(backgroundBorderPen);
0068     painter->drawArc(paintRect, startAngle, backgroundSpanAngle);
0069     painter->setPen(backgroundPen);
0070     painter->drawArc(paintRect, startAngle, backgroundSpanAngle);
0071     painter->setPen(fillBorderPen);
0072     painter->drawArc(paintRect, startAngle, fillSpanAngle);
0073     painter->setPen(fillPen);
0074     painter->drawArc(paintRect, startAngle, fillSpanAngle);
0075 }
0076 
0077 QColor BreezeDial::backgroundBorderColor() const
0078 {
0079     Q_D(const BreezeDial);
0080     return d->backgroundBorderColor;
0081 }
0082 
0083 void BreezeDial::setBackgroundBorderColor(const QColor &color)
0084 {
0085     Q_D(BreezeDial);
0086     if (d->backgroundBorderColor == color)
0087         return;
0088 
0089     d->backgroundBorderColor = color;
0090     update();
0091     Q_EMIT backgroundBorderColorChanged();
0092 }
0093 
0094 QColor BreezeDial::backgroundColor() const
0095 {
0096     Q_D(const BreezeDial);
0097     return d->backgroundColor;
0098 }
0099 
0100 void BreezeDial::setBackgroundColor(const QColor &color)
0101 {
0102     Q_D(BreezeDial);
0103     if (d->backgroundColor == color)
0104         return;
0105 
0106     d->backgroundColor = color;
0107     update();
0108     Q_EMIT backgroundColorChanged();
0109 }
0110 
0111 QColor BreezeDial::fillBorderColor() const
0112 {
0113     Q_D(const BreezeDial);
0114     return d->fillBorderColor;
0115 }
0116 
0117 void BreezeDial::setFillBorderColor(const QColor &color)
0118 {
0119     Q_D(BreezeDial);
0120     if (d->fillBorderColor == color)
0121         return;
0122 
0123     d->fillBorderColor = color;
0124     update();
0125     Q_EMIT fillBorderColorChanged();
0126 }
0127 
0128 QColor BreezeDial::fillColor() const
0129 {
0130     Q_D(const BreezeDial);
0131     return d->fillColor;
0132 }
0133 
0134 void BreezeDial::setFillColor(const QColor &color)
0135 {
0136     Q_D(BreezeDial);
0137     if (d->fillColor == color)
0138         return;
0139 
0140     d->fillColor = color;
0141     update();
0142     Q_EMIT fillColorChanged();
0143 }
0144 
0145 qreal BreezeDial::angle() const
0146 {
0147     Q_D(const BreezeDial);
0148     return d->angle;
0149 }
0150 
0151 void BreezeDial::setAngle(const qreal angle)
0152 {
0153     Q_D(BreezeDial);
0154     if (d->angle == angle)
0155         return;
0156 
0157     d->angle = angle;
0158     update();
0159     Q_EMIT angleChanged();
0160 }
0161 
0162 qreal BreezeDial::grooveThickness() const
0163 {
0164     Q_D(const BreezeDial);
0165     return d->grooveThickness;
0166 }
0167 
0168 void BreezeDial::setGrooveThickness(const qreal grooveThickness)
0169 {
0170     Q_D(BreezeDial);
0171     if (d->grooveThickness == grooveThickness)
0172         return;
0173 
0174     d->grooveThickness = grooveThickness;
0175     update();
0176     Q_EMIT grooveThicknessChanged();
0177 }
0178 
0179 bool BreezeDial::notchesVisible() const
0180 {
0181     Q_D(const BreezeDial);
0182     return d->notchesVisible;
0183 }
0184 
0185 void BreezeDial::setNotchesVisible(const qreal notchesVisible)
0186 {
0187     Q_D(BreezeDial);
0188     if (d->notchesVisible == notchesVisible)
0189         return;
0190 
0191     d->notchesVisible = notchesVisible;
0192     update();
0193     Q_EMIT notchesVisibleChanged();
0194 }
0195 
0196 #include "moc_breezedial.cpp"