diff --git a/constants/Icons.qml b/constants/Icons.qml index 4126c27..b905db8 100644 --- a/constants/Icons.qml +++ b/constants/Icons.qml @@ -3,6 +3,10 @@ pragma Singleton import Quickshell Singleton { + property string batteryFull: "\u{E059}" + property string batteryMedium: "\u{E05b}" + property string batteryLow: "\u{E05a}" + property string batteryWarning: "\u{E3b0}" property string bell: "\u{E05d}" property string bellRing: "\u{E224}" property string bluetooth: "\u{E060}" diff --git a/modules/bar/components/bluetooth/BluetoothMenu.qml b/modules/bar/components/bluetooth/BluetoothMenu.qml index ed896c3..e7e4607 100644 --- a/modules/bar/components/bluetooth/BluetoothMenu.qml +++ b/modules/bar/components/bluetooth/BluetoothMenu.qml @@ -29,6 +29,7 @@ StyledPopupWindow { } Switch { + Layout.alignment: Qt.AlignRight checked: Bluetooth.defaultAdapter.enabled onClicked: Bluetooth.defaultAdapter.enabled = checked } @@ -43,12 +44,18 @@ StyledPopupWindow { spacing: 8 StyledText { + Layout.minimumWidth: 320 font.bold: true text: "Connected Devices" } - DeviceList { - devices: Bluetooth.connectedDevices + ColumnLayout { + Repeater { + model: Bluetooth.connectedDevices + delegate: ConnectedDevice { + Layout.fillWidth: true + } + } } StyledText { @@ -58,6 +65,9 @@ StyledPopupWindow { DeviceList { devices: Bluetooth.pairedDevices + onDeviceActivated: device => { + device.connect(); + } } StyledText { @@ -67,6 +77,9 @@ StyledPopupWindow { DeviceList { devices: Bluetooth.availableDevices + onDeviceActivated: device => { + device.pair(); + } } } } diff --git a/modules/bar/components/bluetooth/ConnectedDevice.qml b/modules/bar/components/bluetooth/ConnectedDevice.qml new file mode 100644 index 0000000..c59fa2b --- /dev/null +++ b/modules/bar/components/bluetooth/ConnectedDevice.qml @@ -0,0 +1,94 @@ +pragma ComponentBehavior: Bound + +import qs.config +import qs.constants +import qs.widgets +import QtQuick +import QtQuick.Layouts +import Quickshell +import Quickshell.Bluetooth +import Quickshell.Widgets + +StyledLabel { + id: device + required property BluetoothDevice modelData + + RowLayout { + id: row + + spacing: 8 + + Loader { + active: modelData.icon != undefined + sourceComponent: IconImage { + implicitSize: 18 + source: Quickshell.iconPath(modelData.icon) + } + } + + StyledText { + text: device.modelData.deviceName + } + + Loader { + active: device.modelData.batteryAvailable + sourceComponent: RowLayout { + StyledText { + id: icon + font.family: Theme.lucide.font.family + font.pixelSize: Dimensions.cpu.iconSize + font.bold: true + text: Icons.batteryFull + states: [ + State { + name: "full" + when: device.modelData.battery > 0.66 + }, + State { + name: "medium" + when: device.modelData.battery > 0.33 + PropertyChanges { + icon { + text: Icons.batteryFull + } + } + }, + State { + name: "low" + when: device.modelData.battery > 0.10 + PropertyChanges { + icon { + text: Icons.batteryFull + } + } + }, + State { + name: "critical" + when: device.modelData.battery > 0.10 + PropertyChanges { + icon { + text: Icons.batteryWarning + color: Theme.palette.error + } + } + } + ] + } + } + } + + StyledButton { + Layout.alignment: Qt.AlignRight + color: containsMouse ? Theme.palette.error : Theme.palette.base200 + content: StyledText { + text: 'Disconnect' + } + onClicked: { + if (modelData.state != BluetoothDeviceState.Connected) { + return; + } + modelData.disconnect(); + } + } + } +} diff --git a/modules/bar/components/bluetooth/DeviceList.qml b/modules/bar/components/bluetooth/DeviceList.qml index 6508c8a..c4e5d92 100644 --- a/modules/bar/components/bluetooth/DeviceList.qml +++ b/modules/bar/components/bluetooth/DeviceList.qml @@ -1,16 +1,18 @@ +pragma ComponentBehavior: Bound + import qs.config -import qs.constants -import qs.services import qs.styled import QtQuick import QtQuick.Layouts +import Quickshell.Bluetooth ColumnLayout { id: root required property var devices + signal deviceActivated(device: BluetoothDevice) Repeater { - model: devices + model: root.devices delegate: Clickable { id: device required property var modelData @@ -18,6 +20,9 @@ ColumnLayout { implicitWidth: row.width implicitHeight: row.height Layout.fillWidth: true + onClicked: { + root.deviceActivated(modelData); + } RowLayout { id: row