Commit 47d29cc9 authored by Noah Davis's avatar Noah Davis 🌵
Browse files

Change Dial style

parent f1dc8eab
......@@ -6,6 +6,7 @@ set(qqc2breezestyle_SRCS
impl/iconlabellayout.cpp
impl/qquickicon.cpp
impl/kcolorutilssingleton.cpp
impl/breezedial.cpp
)
#[[ I don't actually know if this would work.
......
/* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
* SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "breezedial.h"
#include <QGuiApplication>
#include <QPainter>
class BreezeDialPrivate
{
Q_DECLARE_PUBLIC(BreezeDial)
Q_DISABLE_COPY(BreezeDialPrivate)
public:
BreezeDialPrivate(BreezeDial *qq)
: q_ptr(qq)
{
}
BreezeDial *const q_ptr;
QFontMetricsF fontMetrics = QFontMetricsF(QGuiApplication::font());
QColor backgroundColor;
QColor backgroundBorderColor;
QColor fillColor;
QColor fillBorderColor;
qreal angle = -140.0; // Range of QQuickDial::angle() is -140 to 140
qreal grooveThickness = 0;
bool notchesVisible = false;
};
BreezeDial::BreezeDial(QQuickItem *parent)
: QQuickPaintedItem(parent)
, d_ptr(new BreezeDialPrivate(this))
{
Q_D(BreezeDial);
connect(qGuiApp, &QGuiApplication::fontChanged, this, [this, d]() {
d->fontMetrics = QFontMetricsF(QGuiApplication::font());
update();
});
}
BreezeDial::~BreezeDial() noexcept
{
}
void BreezeDial::paint(QPainter *painter)
{
Q_D(BreezeDial);
if (width() <= 0 || height() <= 0 || d->grooveThickness <= 0)
return;
QRectF paintRect;
paintRect.setWidth(qMin(boundingRect().width() - d->grooveThickness, boundingRect().height() - d->grooveThickness));
paintRect.setHeight(paintRect.width());
paintRect.moveCenter(boundingRect().center());
QPen backgroundBorderPen(d->backgroundBorderColor, d->grooveThickness, Qt::SolidLine, Qt::RoundCap);
QPen backgroundPen(d->backgroundColor, d->grooveThickness - 2, Qt::SolidLine, Qt::RoundCap);
QPen fillBorderPen(d->fillBorderColor, d->grooveThickness, Qt::SolidLine, Qt::RoundCap);
QPen fillPen(d->fillColor, d->grooveThickness - 2, Qt::SolidLine, Qt::RoundCap);
const qreal startAngle = -130 * 16;
const qreal backgroundSpanAngle = -280 * 16;
const qreal fillSpanAngle = (-d->angle - 140) * 16;
painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(backgroundBorderPen);
painter->drawArc(paintRect, startAngle, backgroundSpanAngle);
painter->setPen(backgroundPen);
painter->drawArc(paintRect, startAngle, backgroundSpanAngle);
painter->setPen(fillBorderPen);
painter->drawArc(paintRect, startAngle, fillSpanAngle);
painter->setPen(fillPen);
painter->drawArc(paintRect, startAngle, fillSpanAngle);
}
QColor BreezeDial::backgroundBorderColor() const
{
Q_D(const BreezeDial);
return d->backgroundBorderColor;
}
void BreezeDial::setBackgroundBorderColor(const QColor &color)
{
Q_D(BreezeDial);
if (d->backgroundBorderColor == color)
return;
d->backgroundBorderColor = color;
update();
Q_EMIT backgroundBorderColorChanged();
}
QColor BreezeDial::backgroundColor() const
{
Q_D(const BreezeDial);
return d->backgroundColor;
}
void BreezeDial::setBackgroundColor(const QColor &color)
{
Q_D(BreezeDial);
if (d->backgroundColor == color)
return;
d->backgroundColor = color;
update();
Q_EMIT backgroundColorChanged();
}
QColor BreezeDial::fillBorderColor() const
{
Q_D(const BreezeDial);
return d->fillBorderColor;
}
void BreezeDial::setFillBorderColor(const QColor &color)
{
Q_D(BreezeDial);
if (d->fillBorderColor == color)
return;
d->fillBorderColor = color;
update();
Q_EMIT fillBorderColorChanged();
}
QColor BreezeDial::fillColor() const
{
Q_D(const BreezeDial);
return d->fillColor;
}
void BreezeDial::setFillColor(const QColor &color)
{
Q_D(BreezeDial);
if (d->fillColor == color)
return;
d->fillColor = color;
update();
Q_EMIT fillColorChanged();
}
qreal BreezeDial::angle() const
{
Q_D(const BreezeDial);
return d->angle;
}
void BreezeDial::setAngle(const qreal angle)
{
Q_D(BreezeDial);
if (d->angle == angle)
return;
d->angle = angle;
update();
Q_EMIT angleChanged();
}
qreal BreezeDial::grooveThickness() const
{
Q_D(const BreezeDial);
return d->grooveThickness;
}
void BreezeDial::setGrooveThickness(const qreal grooveThickness)
{
Q_D(BreezeDial);
if (d->grooveThickness == grooveThickness)
return;
d->grooveThickness = grooveThickness;
update();
Q_EMIT grooveThicknessChanged();
}
bool BreezeDial::notchesVisible() const
{
Q_D(const BreezeDial);
return d->notchesVisible;
}
void BreezeDial::setNotchesVisible(const qreal notchesVisible)
{
Q_D(BreezeDial);
if (d->notchesVisible == notchesVisible)
return;
d->notchesVisible = notchesVisible;
update();
Q_EMIT notchesVisibleChanged();
}
/* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
* SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef BREEZEDIAL_H
#define BREEZEDIAL_H
#include <QtQuick>
class BreezeDialPrivate;
class BreezeDial : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QColor backgroundBorderColor READ backgroundBorderColor WRITE setBackgroundBorderColor NOTIFY backgroundBorderColorChanged)
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
Q_PROPERTY(QColor fillBorderColor READ fillBorderColor WRITE setFillBorderColor NOTIFY fillBorderColorChanged)
Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor NOTIFY fillColorChanged)
Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
Q_PROPERTY(qreal grooveThickness READ grooveThickness WRITE setGrooveThickness NOTIFY grooveThicknessChanged)
Q_PROPERTY(bool notchesVisible READ notchesVisible WRITE setNotchesVisible NOTIFY notchesVisibleChanged)
QML_NAMED_ELEMENT(BreezeDial)
public:
explicit BreezeDial(QQuickItem *parent = nullptr);
~BreezeDial();
void paint(QPainter *painter) override;
QColor backgroundBorderColor() const;
void setBackgroundBorderColor(const QColor &color);
QColor backgroundColor() const;
void setBackgroundColor(const QColor &color);
QColor fillBorderColor() const;
void setFillBorderColor(const QColor &color);
QColor fillColor() const;
void setFillColor(const QColor &color);
qreal angle() const;
void setAngle(const qreal angle);
qreal grooveThickness() const;
void setGrooveThickness(const qreal grooveThickness);
bool notchesVisible() const;
void setNotchesVisible(const qreal notchesVisible);
Q_SIGNALS:
void backgroundBorderColorChanged();
void backgroundColorChanged();
void fillBorderColorChanged();
void fillColorChanged();
void angleChanged();
void grooveThicknessChanged();
void notchesVisibleChanged();
private:
const std::unique_ptr<BreezeDialPrivate> d_ptr;
Q_DECLARE_PRIVATE(BreezeDial)
Q_DISABLE_COPY(BreezeDial)
};
#endif
......@@ -6,6 +6,7 @@
*/
#include "qqc2breezestyleplugin.h"
#include "impl/breezedial.h"
#include "impl/iconlabellayout.h"
#include "impl/kcolorutilssingleton.h"
#include "impl/paintedsymbolitem.h"
......@@ -37,6 +38,7 @@ void QQC2BreezeStylePlugin::registerTypes(const char *uri)
qmlRegisterModule(uri, 1, 0);
qmlRegisterType<PaintedSymbolItem>(uri, 1, 0, "PaintedSymbol");
qmlRegisterType<IconLabelLayout>(uri, 1, 0, "IconLabelLayout");
qmlRegisterType<BreezeDial>(uri, 1, 0, "BreezeDial");
// KColorUtilsSingleton only has invocable functions.
// Would this be better off being a SingletonInstance?
qmlRegisterSingletonType<KColorUtilsSingleton>(uri, 1, 0, "KColorUtils", [](QQmlEngine *, QJSEngine *) -> QObject * {
......
// NOTE: replace this
/* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
* SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.15
import QtQuick.Controls 2.15 as Controls
import QtQuick.Controls.impl 2.15
import QtQuick.Templates 2.15 as T
import org.kde.kirigami 2.14 as Kirigami
import org.kde.breeze 1.0
import "impl"
T.Dial {
id: control
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding) || 184 // ### remove 184 in Qt 6
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding) || 184 // ### remove 184 in Qt 6
background: DialImpl {
implicitWidth: 184
implicitHeight: 184
color: control.visualFocus ? control.palette.highlight : control.palette.dark
progress: control.position
opacity: control.enabled ? 1 : 0.3
implicitContentHeight + topPadding + bottomPadding)
wrap: true
Kirigami.Theme.colorSet: Kirigami.Theme.Button
Kirigami.Theme.inherit: false
background: BreezeDial {
implicitWidth: 100
implicitHeight: 100
backgroundBorderColor: Kirigami.Theme.separatorColor
backgroundColor: Kirigami.Theme.backgroundColor
fillBorderColor: Kirigami.Theme.focusColor
fillColor: Kirigami.Theme.alternateBackgroundColor
angle: control.angle
grooveThickness: Kirigami.Units.grooveHeight
Behavior on angle {
enabled: !Kirigami.Settings.hasTransientTouchInput
SmoothedAnimation {
duration: Kirigami.Units.longDuration
velocity: 800
//SmoothedAnimations have a hardcoded InOutQuad easing
}
}
}
handle: ColorImage {
x: control.background.x + control.background.width / 2 - control.handle.width / 2
y: control.background.y + control.background.height / 2 - control.handle.height / 2
width: 14
height: 10
defaultColor: "#353637"
color: control.visualFocus ? control.palette.highlight : control.palette.dark
source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/images/dial-indicator.png"
antialiasing: true
opacity: control.enabled ? 1 : 0.3
transform: [
Translate {
y: -Math.min(control.background.width, control.background.height) * 0.4 + control.handle.height / 2
},
Rotation {
angle: control.angle
origin.x: control.handle.width / 2
origin.y: control.handle.height / 2
}
]
handle: Kirigami.ShadowedRectangle {
id: handle
x: control.background.x + (control.background.width - control.handle.width) / 2
y: control.background.y + (control.background.height - control.handle.height) / 2
implicitWidth: implicitHeight
implicitHeight: 100 - Kirigami.Units.grooveHeight * 4 + 4
width: height
height: Math.min(control.background.width, control.background.height) - Kirigami.Units.grooveHeight * 4 + 4
radius: height/2
color: Kirigami.Theme.backgroundColor
border {
width: Kirigami.Units.smallBorder
color: control.pressed || control.visualFocus || control.hovered
? Kirigami.Theme.focusColor : Kirigami.Theme.separatorColor
}
shadow {
color: control.pressed ? "transparent" : Qt.rgba(0,0,0,0.2)
size: control.enabled ? 9 : 0
yOffset: 2
}
//opacity: control.enabled ? 1 : 0.3
Kirigami.ShadowedRectangle {
anchors.fill: parent
anchors.margins: parent.border.width
color: parent.color
radius: height/2
rotation: control.angle
Behavior on rotation {
enabled: !Kirigami.Settings.hasTransientTouchInput
SmoothedAnimation {
duration: Kirigami.Units.longDuration
velocity: 800
//SmoothedAnimations have a hardcoded InOutQuad easing
}
}
Rectangle {
id: handleTriangle
property real colorPosition: Math.abs(control.angle) / 140
z: -1
implicitWidth: Kirigami.Units.gridUnit + Kirigami.Units.grooveHeight
implicitHeight: Kirigami.Units.gridUnit + Kirigami.Units.grooveHeight
anchors.verticalCenter: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenterOffset: height/6
rotation: 45
antialiasing: true
color: control.pressed || control.hovered || !control.enabled
? parent.color
: KColorUtils.mix(topColor(parent.color), bottomColor(parent.color), colorPosition)
border.color: control.pressed || control.hovered || !control.enabled
? handle.border.color
: KColorUtils.mix(topColor(handle.border.color), bottomColor(handle.border.color), colorPosition)
border.width: handle.border.width
Behavior on color {
enabled: control.pressed || control.visualFocus || control.hovered
ColorAnimation {
duration: Kirigami.Units.shortDuration
easing.type: Easing.OutCubic
}
}
function topColor(color) {
return Qt.tint(color, Qt.rgba(1,1,1,0.03125))
}
function bottomColor(color) {
return Qt.tint(color, Qt.rgba(0,0,0,0.0625))
}
}
Rectangle {
id: handleDot
radius: width/2
anchors.verticalCenter: parent.top
anchors.horizontalCenter: parent.horizontalCenter
width: 4
height: 4
color: control.enabled ? Kirigami.Theme.focusColor : Kirigami.Theme.separatorColor
}
}
Behavior on border.color {
enabled: control.pressed || control.visualFocus || control.hovered
ColorAnimation {
duration: Kirigami.Units.shortDuration
easing.type: Easing.OutCubic
}
}
Behavior on shadow.color {
enabled: control.pressed
ColorAnimation {
duration: Kirigami.Units.shortDuration
easing.type: Easing.OutCubic
}
}
FocusRect {
z: -1
baseRadius: parent.radius
visible: control.visualFocus
}
Rectangle {
radius: parent.radius
opacity: control.pressed || control.hovered ? 0 : 1
visible: control.enabled
anchors.fill: parent
anchors.margins: parent.border.width
gradient: Gradient {
GradientStop {
position: 0
color: Qt.rgba(1,1,1,0.03125)
}
GradientStop {
position: 1
color: Qt.rgba(0,0,0,0.0625)
}
}
Behavior on opacity {
OpacityAnimator {
duration: Kirigami.Units.shortDuration
easing.type: Easing.OutCubic
}
}
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment