popouts: better bt loading icon

This commit is contained in:
2 * r + 2 * t 2025-07-22 17:51:13 +10:00
parent 32ff695d9e
commit b6d1b1922d
2 changed files with 103 additions and 16 deletions

View file

@ -7,14 +7,14 @@ import Quickshell
import Quickshell.Bluetooth
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
ColumnLayout {
id: root
spacing: Appearance.spacing.normal
spacing: Appearance.spacing.small / 2
StyledText {
Layout.bottomMargin: Appearance.spacing.small
text: qsTr("Bluetooth %1").arg(BluetoothAdapterState.toString(Bluetooth.defaultAdapter.state).toLowerCase())
}
@ -34,7 +34,7 @@ ColumnLayout {
readonly property bool loading: device.modelData.state === BluetoothDeviceState.Connecting || device.modelData.state === BluetoothDeviceState.Disconnecting
Layout.fillWidth: true
spacing: Appearance.spacing.small
spacing: Appearance.spacing.small / 2
opacity: 0
scale: 0.7
@ -53,6 +53,7 @@ ColumnLayout {
}
MaterialIcon {
Layout.rightMargin: Appearance.spacing.small
text: Icons.getBluetoothIcon(device.modelData.icon)
}
@ -64,18 +65,15 @@ ColumnLayout {
Item {
id: connectBtn
implicitWidth: loadingIndicator.implicitWidth - Appearance.padding.small * 2
implicitHeight: loadingIndicator.implicitHeight - Appearance.padding.small * 2
BusyIndicator {
id: loadingIndicator
implicitWidth: implicitHeight
implicitHeight: connectIcon.implicitHeight + Appearance.padding.small * 2
StyledBusyIndicator {
anchors.centerIn: parent
implicitWidth: Appearance.font.size.large * 2 + Appearance.padding.small * 2
implicitHeight: Appearance.font.size.large * 2 + Appearance.padding.small * 2
implicitWidth: implicitHeight
implicitHeight: connectIcon.implicitHeight
background: null
running: opacity > 0
opacity: device.loading ? 1 : 0
@ -94,16 +92,16 @@ ColumnLayout {
}
MaterialIcon {
id: connectIcon
anchors.centerIn: parent
animate: true
text: device.modelData.connected ? "link_off" : "link"
font.pointSize: device.loading ? Appearance.font.size.normal : Appearance.font.size.larger
opacity: device.loading ? 0 : 1
Behavior on font.pointSize {
Anim {
duration: Appearance.anim.durations.small
}
Behavior on opacity {
Anim {}
}
}
}

View file

@ -0,0 +1,89 @@
pragma ComponentBehavior: Bound
import qs.services
import qs.config
import QtQuick
import QtQuick.Controls
import QtQuick.Shapes
BusyIndicator {
id: root
property color fgColour: Colours.palette.m3onPrimaryContainer
property color bgColour: Colours.palette.m3primaryContainer
background: null
contentItem: Shape {
id: shape
preferredRendererType: Shape.CurveRenderer
RotationAnimator on rotation {
from: 0
to: 180
running: root.visible && root.running
loops: Animation.Infinite
duration: Appearance.anim.durations.extraLarge
easing.type: Easing.Linear
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
}
ShapePath {
strokeWidth: Math.min(root.implicitWidth, root.implicitHeight) * 0.18
strokeColor: root.bgColour
fillColor: "transparent"
capStyle: ShapePath.RoundCap
PathAngleArc {
centerX: shape.width / 2
centerY: shape.height / 2
radiusX: root.implicitWidth / 2
radiusY: root.implicitHeight / 2
startAngle: 0
sweepAngle: 360
}
Behavior on strokeColor {
ColorAnimation {
duration: Appearance.anim.durations.normal
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.standard
}
}
}
ShapePath {
strokeWidth: Math.min(root.implicitWidth, root.implicitHeight) * 0.18
strokeColor: root.fgColour
fillColor: "transparent"
capStyle: ShapePath.RoundCap
PathAngleArc {
centerX: shape.width / 2
centerY: shape.height / 2
radiusX: root.implicitWidth / 2
radiusY: root.implicitHeight / 2
startAngle: -sweepAngle / 2
sweepAngle: 60
}
PathAngleArc {
centerX: shape.width / 2
centerY: shape.height / 2
radiusX: root.implicitWidth / 2
radiusY: root.implicitHeight / 2
startAngle: 180 - sweepAngle / 2
sweepAngle: 60
}
Behavior on strokeColor {
ColorAnimation {
duration: Appearance.anim.durations.normal
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.standard
}
}
}
}
}