diff options
| author | Soramane <61896496+soramanew@users.noreply.github.com> | 2025-07-16 23:49:45 +1000 |
|---|---|---|
| committer | Soramane <61896496+soramanew@users.noreply.github.com> | 2025-07-16 23:49:45 +1000 |
| commit | 8784a015c2287a84eec226a32a9c11bfc95e8033 (patch) | |
| tree | 1b8290509650a63d188f6b1e9f1a48c6dccc5707 /modules/bar | |
| parent | internal: create service config (diff) | |
| download | caelestia-shell-8784a015c2287a84eec226a32a9c11bfc95e8033.tar.gz caelestia-shell-8784a015c2287a84eec226a32a9c11bfc95e8033.tar.bz2 caelestia-shell-8784a015c2287a84eec226a32a9c11bfc95e8033.zip | |
bluetooth: use qs bluetooth
Diffstat (limited to 'modules/bar')
| -rw-r--r-- | modules/bar/components/StatusIcons.qml | 44 | ||||
| -rw-r--r-- | modules/bar/popouts/Bluetooth.qml | 130 |
2 files changed, 155 insertions, 19 deletions
diff --git a/modules/bar/components/StatusIcons.qml b/modules/bar/components/StatusIcons.qml index 91f11be..b2cca54 100644 --- a/modules/bar/components/StatusIcons.qml +++ b/modules/bar/components/StatusIcons.qml @@ -3,6 +3,7 @@ import qs.services import qs.utils import qs.config import Quickshell +import Quickshell.Bluetooth import Quickshell.Services.UPower import QtQuick @@ -38,7 +39,7 @@ Item { anchors.topMargin: Appearance.spacing.smaller / 2 animate: true - text: Bluetooth.powered ? "bluetooth" : "bluetooth_disabled" + text: Bluetooth.defaultAdapter.enabled ? "bluetooth" : "bluetooth_disabled" color: root.colour } @@ -55,16 +56,35 @@ Item { id: repeater model: ScriptModel { - values: Bluetooth.devices.filter(d => d.connected) + values: Bluetooth.devices.values.filter(d => d.state !== BluetoothDeviceState.Disconnected) } MaterialIcon { - required property Bluetooth.Device modelData + id: device + + required property BluetoothDevice modelData animate: true text: Icons.getBluetoothIcon(modelData.icon) color: root.colour fill: 1 + + SequentialAnimation on opacity { + running: device.modelData.state !== BluetoothDeviceState.Connected + alwaysRunToEnd: true + loops: Animation.Infinite + + Anim { + from: 1 + to: 0 + easing.bezierCurve: Appearance.anim.curves.standardAccel + } + Anim { + from: 0 + to: 1 + easing.bezierCurve: Appearance.anim.curves.standardDecel + } + } } } } @@ -99,19 +119,13 @@ Item { fill: 1 } - Behavior on implicitWidth { - NumberAnimation { - duration: Appearance.anim.durations.normal - easing.type: Easing.BezierSpline - easing.bezierCurve: Appearance.anim.curves.emphasized - } + Behavior on implicitHeight { + Anim {} } - Behavior on implicitHeight { - NumberAnimation { - duration: Appearance.anim.durations.normal - easing.type: Easing.BezierSpline - easing.bezierCurve: Appearance.anim.curves.emphasized - } + component Anim: NumberAnimation { + duration: Appearance.anim.durations.large + easing.type: Easing.BezierSpline + easing.bezierCurve: Appearance.anim.curves.emphasized } } diff --git a/modules/bar/popouts/Bluetooth.qml b/modules/bar/popouts/Bluetooth.qml index f9ab3b3..245834e 100644 --- a/modules/bar/popouts/Bluetooth.qml +++ b/modules/bar/popouts/Bluetooth.qml @@ -1,18 +1,140 @@ +pragma ComponentBehavior: Bound + import qs.widgets -import qs.services import qs.config +import qs.utils +import Quickshell +import Quickshell.Bluetooth import QtQuick +import QtQuick.Layouts +import QtQuick.Controls -Column { +ColumnLayout { id: root spacing: Appearance.spacing.normal StyledText { - text: qsTr("Bluetooth %1").arg(Bluetooth.powered ? "enabled" : "disabled") + text: qsTr("Bluetooth %1").arg(BluetoothAdapterState.toString(Bluetooth.defaultAdapter.state).toLowerCase()) } StyledText { - text: Bluetooth.devices.some(d => d.connected) ? qsTr("Connected to: %1").arg(Bluetooth.devices.filter(d => d.connected).map(d => d.alias).join(", ")) : qsTr("No devices connected") + text: qsTr("%n connected device(s)", "", Bluetooth.devices.values.filter(d => d.connected).length) + } + + Repeater { + model: ScriptModel { + values: [...Bluetooth.devices.values].sort((a, b) => (b.connected - a.connected) || (b.paired - a.paired)) + } + + RowLayout { + id: device + + required property var modelData + readonly property bool loading: device.modelData.state === BluetoothDeviceState.Connecting || device.modelData.state === BluetoothDeviceState.Disconnecting + + Layout.fillWidth: true + spacing: Appearance.spacing.small + + opacity: 0 + scale: 0.7 + + Component.onCompleted: { + opacity = 1; + scale = 1; + } + + Behavior on opacity { + Anim {} + } + + Behavior on scale { + Anim {} + } + + MaterialIcon { + text: Icons.getBluetoothIcon(device.modelData.icon) + } + + StyledText { + Layout.fillWidth: true + text: device.modelData.name + } + + Item { + id: connectBtn + + implicitWidth: loadingIndicator.implicitWidth - Appearance.padding.small * 2 + implicitHeight: loadingIndicator.implicitHeight - Appearance.padding.small * 2 + + BusyIndicator { + id: loadingIndicator + + anchors.centerIn: parent + + implicitWidth: Appearance.font.size.large * 2 + Appearance.padding.small * 2 + implicitHeight: Appearance.font.size.large * 2 + Appearance.padding.small * 2 + + background: null + running: opacity > 0 + opacity: device.loading ? 1 : 0 + + Behavior on opacity { + Anim {} + } + } + + StateLayer { + radius: Appearance.rounding.full + disabled: device.loading + + function onClicked(): void { + device.modelData.connected = !device.modelData.connected; + } + } + + MaterialIcon { + anchors.centerIn: parent + animate: true + text: device.modelData.connected ? "link_off" : "link" + + font.pointSize: device.loading ? Appearance.font.size.normal : Appearance.font.size.larger + + Behavior on font.pointSize { + Anim { + duration: Appearance.anim.durations.small + } + } + } + } + + Loader { + asynchronous: true + active: device.modelData.paired + sourceComponent: Item { + implicitWidth: connectBtn.implicitWidth + implicitHeight: connectBtn.implicitHeight + + StateLayer { + radius: Appearance.rounding.full + + function onClicked(): void { + device.modelData.forget(); + } + } + + MaterialIcon { + anchors.centerIn: parent + text: "delete" + } + } + } + } + } + + component Anim: NumberAnimation { + duration: Appearance.anim.durations.normal + easing.type: Easing.BezierSpline + easing.bezierCurve: Appearance.anim.curves.standard } } |