Implement circle progress bars in QML

This commit is contained in:
miruka 2020-05-21 19:54:35 -04:00
parent 35e6c1c7eb
commit 6f688ae1aa
6 changed files with 83 additions and 54 deletions

View File

@ -13,10 +13,8 @@ QRC_FILE = $$BUILD_DIR/resources.qrc
RESOURCES += $$QRC_FILE RESOURCES += $$QRC_FILE
HEADERS += src/utils.h src/clipboard.h \ HEADERS += src/utils.h src/clipboard.h \
submodules/RadialBarDemo/radialbar.h \
submodules/hsluv-c/src/hsluv.h submodules/hsluv-c/src/hsluv.h
SOURCES += src/main.cpp src/utils.cpp src/clipboard.cpp \ SOURCES += src/main.cpp src/utils.cpp src/clipboard.cpp \
submodules/RadialBarDemo/radialbar.cpp \
submodules/hsluv-c/src/hsluv.c submodules/hsluv-c/src/hsluv.c
TARGET = mirage TARGET = mirage

View File

@ -1,9 +1,19 @@
// SPDX-License-Identifier: LGPL-3.0-or-later // SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12 import QtQuick 2.12
import QtQuick.Controls 2.12
HCircleProgressBar { HCircleProgressBar {
indeterminate: true progress: 0.5
dialWidth: 2
label.visible: false
baseCircle.strokeWidth: 2
progressCircle.strokeWidth: 2
HNumberAnimation on rotation {
from: 0
to: 360
loops: Animation.Infinite
duration: theme ? (theme.animationDuration * 6) : 600
}
} }

View File

@ -1,50 +1,76 @@
// SPDX-License-Identifier: LGPL-3.0-or-later // SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12 import QtQuick 2.12
import RadialBar 1.0 import QtQuick.Shapes 1.12
RadialBar {
id: bar Item {
implicitWidth: 96 * (theme ? theme.uiScale : 1) implicitWidth: 96 * (theme ? theme.uiScale : 1)
implicitHeight: implicitWidth implicitHeight: implicitWidth
foregroundColor: theme.controls.circleProgressBar.background
progressColor: theme.controls.circleProgressBar.foreground
dialWidth: theme.controls.circleProgressBar.thickness
startAngle: 0
spanAngle: 360
from: 0 layer.enabled: true
to: 1 layer.samples: 4
value: 0 layer.smooth: true
showText: true
textFont.pixelSize: theme ? theme.fontSize.big : 22
textColor: theme ? theme.controls.circleProgressBar.text : "white"
property alias from: bar.minValue property real progress: 0 // 0-1
property alias to: bar.maxValue
property bool indeterminate: false
property real indeterminateSpan: readonly property alias baseCircle: baseCircle
theme.controls.circleProgressBar.indeterminateSpan readonly property alias progressCircle: progressCircle
readonly property alias label: label
Binding on value { HLabel {
value: bar.to * bar.indeterminateSpan id: label
when: bar.indeterminate anchors.centerIn: parent
text: progressNumber + "%"
font.pixelSize: theme ? theme.fontSize.big : 22
property int progressNumber: Math.floor(progress * 100)
Behavior on progressNumber { HNumberAnimation { factor: 2 } }
} }
Binding on showText { Shape {
value: false id: shape
when: bar.indeterminate anchors.fill: parent
asynchronous: true
ShapePath {
id: baseCircle
fillColor: "transparent"
strokeColor: theme.controls.circleProgressBar.background
strokeWidth: theme.controls.circleProgressBar.thickness
capStyle: ShapePath.RoundCap
startX: shape.width / 2
startY: strokeWidth
PathAngleArc {
centerX: shape.width / 2
centerY: shape.height / 2
radiusX: shape.width / 2 - baseCircle.strokeWidth
radiusY: shape.height / 2 - baseCircle.strokeWidth
sweepAngle: 360
}
} }
HNumberAnimation on rotation { ShapePath {
running: bar.indeterminate id: progressCircle
from: 0 fillColor: baseCircle.fillColor
to: 360 strokeColor: theme.controls.circleProgressBar.foreground
loops: Animation.Infinite strokeWidth: baseCircle.strokeWidth
duration: theme ? (theme.animationDuration * 6) : 600
PathAngleArc {
centerX: shape.width / 2
centerY: shape.height / 2
radiusX: shape.width / 2 - progressCircle.strokeWidth
radiusY: shape.height / 2 - progressCircle.strokeWidth
startAngle: 270
sweepAngle: progress * 360
Behavior on startAngle { HNumberAnimation {} }
Behavior on sweepAngle { HNumberAnimation {} }
}
}
} }
} }

View File

@ -110,10 +110,7 @@ Image {
sourceComponent: HCircleProgressBar { sourceComponent: HCircleProgressBar {
id: progressBar id: progressBar
value: image.progress progress: image.progress
text: Math.round(value * 100) + "%"
Behavior on value { HNumberAnimation { factor: 2 } }
} }
} }

View File

@ -4,15 +4,21 @@ import QtQuick 2.12
import "Base" import "Base"
Rectangle { Rectangle {
color: utils.hsluv(0, 0, 0, 0.5) color: utils.hsluv(0, 0, 0, 0.7)
HBusyIndicator { HBusyIndicator {
anchors.centerIn: parent anchors.centerIn: parent
width: Math.min(160, parent.width - 16, parent.height - 16) width: Math.min(160, parent.width - 16, parent.height - 16)
height: width height: width
indeterminateSpan: 0.5
foregroundColor: utils.hsluv(240, 60 / 1.5 * 2, 0, 0.7) // Because the theme is not loaded at this point, we must set these
progressColor: utils.hsluv(240, 60 * 1.5, 72) // properties manually:
baseCircle.strokeColor: utils.hsluv(240, 60 / 1.5 * 2, 0, 0.7)
progressCircle.strokeColor: utils.hsluv(240, 60 * 1.5, 72)
label.font.family: "Roboto"
label.font.pixelSize: 0
label.color: "black"
label.linkColor: "black"
} }
} }

View File

@ -16,8 +16,6 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#include "../submodules/RadialBarDemo/radialbar.h"
#include "utils.h" #include "utils.h"
#include "clipboard.h" #include "clipboard.h"
@ -149,12 +147,6 @@ int main(int argc, char *argv[]) {
} }
); );
// Register our custom visual items that will be importable from QML, e.g.
// import RadialBar 1.0
// ...
// RadialBar { ... }
qmlRegisterType<RadialBar>("RadialBar", 1, 0, "RadialBar");
// Create the QML root component by loading its file from the Qt Resource // Create the QML root component by loading its file from the Qt Resource
// System or local file system if not possible. // System or local file system if not possible.
QQmlComponent component( QQmlComponent component(