diff options
| author | ATMDA <atdma2600@gmail.com> | 2025-11-19 19:51:28 -0500 |
|---|---|---|
| committer | ATMDA <atdma2600@gmail.com> | 2025-11-19 19:51:28 -0500 |
| commit | ff4e9bbdfd13077f94e1a30ac1dd7e7df2238438 (patch) | |
| tree | feb9c4e079a33f7d732f50f263b3428e3bf24182 /modules/controlcenter/bluetooth/DeviceList.qml | |
| parent | refactor: SplitPaneWithDetails integrated (diff) | |
| download | caelestia-shell-ff4e9bbdfd13077f94e1a30ac1dd7e7df2238438.tar.gz caelestia-shell-ff4e9bbdfd13077f94e1a30ac1dd7e7df2238438.tar.bz2 caelestia-shell-ff4e9bbdfd13077f94e1a30ac1dd7e7df2238438.zip | |
refactor: Updated Bluetooth, Ethernet, and Wireless lists to use DeviceList component and improved layout structure
Diffstat (limited to '')
| -rw-r--r-- | modules/controlcenter/bluetooth/DeviceList.qml | 293 |
1 files changed, 106 insertions, 187 deletions
diff --git a/modules/controlcenter/bluetooth/DeviceList.qml b/modules/controlcenter/bluetooth/DeviceList.qml index 06700e8..b3db236 100644 --- a/modules/controlcenter/bluetooth/DeviceList.qml +++ b/modules/controlcenter/bluetooth/DeviceList.qml @@ -1,6 +1,7 @@ pragma ComponentBehavior: Bound import ".." +import "../components" import qs.components import qs.components.controls import qs.components.containers @@ -12,165 +13,144 @@ import Quickshell.Bluetooth import QtQuick import QtQuick.Layouts -ColumnLayout { +DeviceList { id: root required property Session session readonly property bool smallDiscoverable: width <= 540 readonly property bool smallPairable: width <= 480 - spacing: Appearance.spacing.small + title: qsTr("Devices (%1)").arg(Bluetooth.devices.values.length) + description: qsTr("All available bluetooth devices") + activeItem: session.bt.active - RowLayout { - spacing: Appearance.spacing.smaller + model: ScriptModel { + id: deviceModel - StyledText { - text: qsTr("Bluetooth") - font.pointSize: Appearance.font.size.large - font.weight: 500 - } - - Item { - Layout.fillWidth: true - } - - ToggleButton { - toggled: Bluetooth.defaultAdapter?.enabled ?? false - icon: "power" - accent: "Tertiary" - - function onClicked(): void { - const adapter = Bluetooth.defaultAdapter; - if (adapter) - adapter.enabled = !adapter.enabled; - } - } - - ToggleButton { - toggled: Bluetooth.defaultAdapter?.discoverable ?? false - icon: root.smallDiscoverable ? "group_search" : "" - label: root.smallDiscoverable ? "" : qsTr("Discoverable") - - function onClicked(): void { - const adapter = Bluetooth.defaultAdapter; - if (adapter) - adapter.discoverable = !adapter.discoverable; - } - } - - ToggleButton { - toggled: Bluetooth.defaultAdapter?.pairable ?? false - icon: "missing_controller" - label: root.smallPairable ? "" : qsTr("Pairable") - - function onClicked(): void { - const adapter = Bluetooth.defaultAdapter; - if (adapter) - adapter.pairable = !adapter.pairable; - } - } - - ToggleButton { - toggled: !root.session.bt.active - icon: "settings" - accent: "Primary" - - function onClicked(): void { - if (root.session.bt.active) - root.session.bt.active = null; - else { - root.session.bt.active = deviceModel.values[0] ?? null; - } - } - } + values: [...Bluetooth.devices.values].sort((a, b) => (b.connected - a.connected) || (b.paired - a.paired)) } - RowLayout { - Layout.topMargin: Appearance.spacing.large - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - ColumnLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.small + headerComponent: Component { + RowLayout { + spacing: Appearance.spacing.smaller StyledText { - Layout.fillWidth: true - text: qsTr("Devices (%1)").arg(Bluetooth.devices.values.length) - font.pointSize: Appearance.font.size.normal + text: qsTr("Bluetooth") + font.pointSize: Appearance.font.size.large font.weight: 500 } - StyledText { + Item { Layout.fillWidth: true - text: qsTr("All available bluetooth devices") - color: Colours.palette.m3outline } - } - StyledRect { - implicitWidth: implicitHeight - implicitHeight: scanIcon.implicitHeight + Appearance.padding.normal * 2 + ToggleButton { + toggled: Bluetooth.defaultAdapter?.enabled ?? false + icon: "power" + accent: "Tertiary" - radius: Bluetooth.defaultAdapter?.discovering ? Appearance.rounding.normal : implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) - color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer + function onClicked(): void { + const adapter = Bluetooth.defaultAdapter; + if (adapter) + adapter.enabled = !adapter.enabled; + } + } - StateLayer { - color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer + ToggleButton { + toggled: Bluetooth.defaultAdapter?.discoverable ?? false + icon: root.smallDiscoverable ? "group_search" : "" + label: root.smallDiscoverable ? "" : qsTr("Discoverable") function onClicked(): void { const adapter = Bluetooth.defaultAdapter; if (adapter) - adapter.discovering = !adapter.discovering; + adapter.discoverable = !adapter.discoverable; } } - MaterialIcon { - id: scanIcon + ToggleButton { + toggled: Bluetooth.defaultAdapter?.pairable ?? false + icon: "missing_controller" + label: root.smallPairable ? "" : qsTr("Pairable") - anchors.centerIn: parent - animate: true - text: "bluetooth_searching" - color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer - fill: Bluetooth.defaultAdapter?.discovering ? 1 : 0 + function onClicked(): void { + const adapter = Bluetooth.defaultAdapter; + if (adapter) + adapter.pairable = !adapter.pairable; + } } - Behavior on radius { - Anim {} + ToggleButton { + toggled: !root.session.bt.active + icon: "settings" + accent: "Primary" + + function onClicked(): void { + if (root.session.bt.active) + root.session.bt.active = null; + else { + root.session.bt.active = root.model.values[0] ?? null; + } + } } } } - StyledListView { - id: view + titleSuffix: Component { + RowLayout { + spacing: Appearance.spacing.normal - model: ScriptModel { - id: deviceModel + Item { + Layout.fillWidth: true + } - values: [...Bluetooth.devices.values].sort((a, b) => (b.connected - a.connected) || (b.paired - a.paired)) - } + StyledRect { + implicitWidth: implicitHeight + implicitHeight: scanIcon.implicitHeight + Appearance.padding.normal * 2 - Layout.fillWidth: true - Layout.fillHeight: true - clip: true - spacing: Appearance.spacing.small / 2 + radius: Bluetooth.defaultAdapter?.discovering ? Appearance.rounding.normal : implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) + color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer - StyledScrollBar.vertical: StyledScrollBar { - flickable: view + StateLayer { + color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer + + function onClicked(): void { + const adapter = Bluetooth.defaultAdapter; + if (adapter) + adapter.discovering = !adapter.discovering; + } + } + + MaterialIcon { + id: scanIcon + + anchors.centerIn: parent + animate: true + text: "bluetooth_searching" + color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer + fill: Bluetooth.defaultAdapter?.discovering ? 1 : 0 + } + + Behavior on radius { + Anim {} + } + } } + } - delegate: StyledRect { + delegate: Component { + StyledRect { id: device required property BluetoothDevice modelData readonly property bool loading: modelData && (modelData.state === BluetoothDeviceState.Connecting || modelData.state === BluetoothDeviceState.Disconnecting) readonly property bool connected: modelData && modelData.state === BluetoothDeviceState.Connected - anchors.left: view.contentItem.left - anchors.right: view.contentItem.right + anchors.left: parent.left + anchors.right: parent.right implicitHeight: deviceInner.implicitHeight + Appearance.padding.normal * 2 - color: Qt.alpha(Colours.tPalette.m3surfaceContainer, root.session.bt.active === modelData ? Colours.tPalette.m3surfaceContainer.a : 0) + color: Qt.alpha(Colours.tPalette.m3surfaceContainer, root.activeItem === modelData ? Colours.tPalette.m3surfaceContainer.a : 0) radius: Appearance.rounding.normal StateLayer { @@ -257,8 +237,18 @@ ColumnLayout { disabled: device.loading function onClicked(): void { - if (device.modelData) - device.modelData.connected = !device.modelData.connected; + if (device.loading) + return; + + if (device.connected) { + device.modelData.connected = false; + } else { + if (device.modelData.bonded) { + device.modelData.connected = true; + } else { + device.modelData.pair(); + } + } } } @@ -267,7 +257,7 @@ ColumnLayout { anchors.centerIn: parent animate: true - text: (device.modelData && device.modelData.connected) ? "link_off" : "link" + text: device.connected ? "link_off" : "link" color: device.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface opacity: device.loading ? 0 : 1 @@ -281,78 +271,7 @@ ColumnLayout { } } - component ToggleButton: StyledRect { - id: toggleBtn - - required property bool toggled - property string icon - property string label - property string accent: "Secondary" - - function onClicked(): void { - } - - Layout.preferredWidth: implicitWidth + (toggleStateLayer.pressed ? Appearance.padding.normal * 2 : toggled ? Appearance.padding.small * 2 : 0) - implicitWidth: toggleBtnInner.implicitWidth + Appearance.padding.large * 2 - implicitHeight: toggleBtnIcon.implicitHeight + Appearance.padding.normal * 2 - - radius: toggled || toggleStateLayer.pressed ? Appearance.rounding.small : Math.min(width, height) / 2 * Math.min(1, Appearance.rounding.scale) - color: toggled ? Colours.palette[`m3${accent.toLowerCase()}`] : Colours.palette[`m3${accent.toLowerCase()}Container`] - - StateLayer { - id: toggleStateLayer - - color: toggleBtn.toggled ? Colours.palette[`m3on${toggleBtn.accent}`] : Colours.palette[`m3on${toggleBtn.accent}Container`] - - function onClicked(): void { - toggleBtn.onClicked(); - } - } - - RowLayout { - id: toggleBtnInner - - anchors.centerIn: parent - spacing: Appearance.spacing.normal - - MaterialIcon { - id: toggleBtnIcon - - visible: !!text - fill: toggleBtn.toggled ? 1 : 0 - text: toggleBtn.icon - color: toggleBtn.toggled ? Colours.palette[`m3on${toggleBtn.accent}`] : Colours.palette[`m3on${toggleBtn.accent}Container`] - font.pointSize: Appearance.font.size.large - - Behavior on fill { - Anim {} - } - } - - Loader { - asynchronous: true - active: !!toggleBtn.label - visible: active - - sourceComponent: StyledText { - text: toggleBtn.label - color: toggleBtn.toggled ? Colours.palette[`m3on${toggleBtn.accent}`] : Colours.palette[`m3on${toggleBtn.accent}Container`] - } - } - } - - Behavior on radius { - Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } - } - - Behavior on Layout.preferredWidth { - Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } - } + onItemSelected: function(item) { + session.bt.active = item; } } |