Kylin/Fluent/qml/ProgressRing.qml
2024-08-31 04:13:21 +08:00

93 lines
3.2 KiB
QML

import QtQuick as Quick
import QtQuick.Controls
import Fluent
ProgressBar{
property int duration: 2000
property real strokeWidth: 6
property bool progressVisible: false
property Quick.color color: FluTheme.primaryColor
property Quick.color backgroundColor : FluTheme.dark ? Qt.rgba(99/255,99/255,99/255,1) : Qt.rgba(214/255,214/255,214/255,1)
id:control
indeterminate : true
clip: true
background: Quick.Rectangle {
implicitWidth: 56
implicitHeight: 56
radius: control.width/2
color:"transparent"
border.color: control.backgroundColor
border.width: control.strokeWidth
}
onIndeterminateChanged:{
canvas.requestPaint()
}
Quick.QtObject{
id:d
property real _radius: control.width/2-control.strokeWidth/2
property real _progress: control.indeterminate ? 0.0 : control.visualPosition
on_ProgressChanged: {
canvas.requestPaint()
}
}
Quick.Connections{
target: FluTheme
function onDarkChanged(){
canvas.requestPaint()
}
}
contentItem: Quick.Item {
id:layout_item
Quick.Canvas {
id:canvas
anchors.fill: parent
antialiasing: true
renderTarget: Canvas.Image
property real startAngle: 0
property real sweepAngle: 0
Quick.SequentialAnimation on startAngle {
loops: Animation.Infinite
running: control.visible && control.indeterminate
Quick.PropertyAnimation { from: 0; to: 450; duration: control.duration/2 }
Quick.PropertyAnimation { from: 450; to: 1080; duration: control.duration/2 }
}
Quick.SequentialAnimation on sweepAngle {
loops: Animation.Infinite
running: control.visible && control.indeterminate
Quick.PropertyAnimation { from: 0; to: 180; duration: control.duration/2 }
Quick.PropertyAnimation { from: 180; to: 0; duration: control.duration/2 }
}
onStartAngleChanged: {
requestPaint()
}
onPaint: {
var ctx = canvas.getContext("2d")
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.save()
ctx.lineWidth = control.strokeWidth
ctx.strokeStyle = control.color
ctx.lineCap = "round"
ctx.beginPath()
if(control.indeterminate){
ctx.arc(width/2, height/2, d._radius , Math.PI * (startAngle - 90) / 180, Math.PI * (startAngle - 90 + sweepAngle) / 180)
}else{
ctx.arc(width/2, height/2, d._radius , -0.5 * Math.PI , -0.5 * Math.PI + d._progress * 2 * Math.PI)
}
ctx.stroke()
ctx.closePath()
ctx.restore()
}
}
}
Text{
text:(control.visualPosition * 100).toFixed(0) + "%"
visible: {
if(control.indeterminate){
return false
}
return control.progressVisible
}
anchors.centerIn: parent
}
}