From db1e2ea3bf7dd1f5ac1960ca4c9dc17757649460 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Sat, 26 Jul 2025 23:11:28 +1000 Subject: dcontent: impl bt settings --- modules/detachedcontent/bluetooth/Settings.qml | 310 +++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 modules/detachedcontent/bluetooth/Settings.qml (limited to 'modules/detachedcontent/bluetooth/Settings.qml') diff --git a/modules/detachedcontent/bluetooth/Settings.qml b/modules/detachedcontent/bluetooth/Settings.qml new file mode 100644 index 0000000..808cd7c --- /dev/null +++ b/modules/detachedcontent/bluetooth/Settings.qml @@ -0,0 +1,310 @@ +pragma ComponentBehavior: Bound + +import ".." +import qs.widgets +import qs.services +import qs.config +import Quickshell.Bluetooth +import QtQuick +import QtQuick.Layouts +import QtQuick.Effects + +ColumnLayout { + id: root + + required property Session session + + spacing: Appearance.spacing.normal + + MaterialIcon { + Layout.alignment: Qt.AlignHCenter + text: "bluetooth" + font.pointSize: Appearance.font.size.extraLarge * 3 + font.bold: true + } + + StyledText { + Layout.alignment: Qt.AlignHCenter + text: qsTr("Bluetooth settings") + font.pointSize: Appearance.font.size.large + font.bold: true + } + + StyledText { + Layout.topMargin: Appearance.spacing.large + text: qsTr("Adapter status") + font.pointSize: Appearance.font.size.larger + font.weight: 500 + } + + StyledText { + text: qsTr("General adapter settings") + color: Colours.palette.m3outline + } + + StyledRect { + Layout.fillWidth: true + implicitHeight: adapterStatus.implicitHeight + Appearance.padding.large * 2 + + radius: Appearance.rounding.normal + color: Colours.palette.m3surfaceContainer + + ColumnLayout { + id: adapterStatus + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Appearance.padding.large + + spacing: Appearance.spacing.larger + + Toggle { + label: qsTr("Powered") + checked: Bluetooth.defaultAdapter?.enabled ?? false + toggle.onToggled: { + const adapter = Bluetooth.defaultAdapter; + if (adapter) + adapter.enabled = checked; + } + } + + Toggle { + label: qsTr("Discoverable") + checked: Bluetooth.defaultAdapter?.discoverable ?? false + toggle.onToggled: { + const adapter = Bluetooth.defaultAdapter; + if (adapter) + adapter.discoverable = checked; + } + } + } + } + + StyledText { + Layout.topMargin: Appearance.spacing.large + text: qsTr("Adapter properties") + font.pointSize: Appearance.font.size.larger + font.weight: 500 + } + + StyledText { + text: qsTr("Per-adapter settings") + color: Colours.palette.m3outline + } + + StyledRect { + Layout.fillWidth: true + implicitHeight: adapterSettings.implicitHeight + Appearance.padding.large * 2 + + radius: Appearance.rounding.normal + color: Colours.palette.m3surfaceContainer + + ColumnLayout { + id: adapterSettings + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Appearance.padding.large + + spacing: Appearance.spacing.larger + + RowLayout { + Layout.fillWidth: true + spacing: Appearance.spacing.normal + + StyledText { + Layout.fillWidth: true + text: qsTr("Current adapter") + } + + Item { + id: adapterPickerButton + + property bool expanded + + implicitWidth: adapterPicker.implicitWidth + Appearance.padding.normal * 2 + implicitHeight: adapterPicker.implicitHeight + Appearance.padding.normal * 2 + + StateLayer { + radius: Appearance.rounding.small + + function onClicked(): void { + adapterPickerButton.expanded = !adapterPickerButton.expanded; + } + } + + RowLayout { + id: adapterPicker + + anchors.fill: parent + anchors.margins: Appearance.padding.normal + spacing: Appearance.spacing.normal + + StyledText { + Layout.leftMargin: Appearance.padding.small + text: Bluetooth.defaultAdapter?.name ?? qsTr("None") + } + + MaterialIcon { + text: "expand_more" + } + } + + RectangularShadow { + anchors.fill: adapterListBg + radius: adapterListBg.radius + color: Qt.alpha(Colours.palette.m3shadow, 0.7) + opacity: adapterPickerButton.expanded ? 1 : 0 + scale: adapterPickerButton.expanded ? 1 : 0.7 + blur: 5 + spread: 0 + + Behavior on opacity { + Anim {} + } + + Behavior on scale { + Anim { + duration: Appearance.anim.durations.expressiveFastSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + } + } + } + + StyledClippingRect { + id: adapterListBg + + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + implicitHeight: adapterPickerButton.expanded ? adapterList.implicitHeight : adapterPickerButton.implicitHeight + + color: Colours.palette.m3secondaryContainer + radius: Appearance.rounding.small + opacity: adapterPickerButton.expanded ? 1 : 0 + scale: adapterPickerButton.expanded ? 1 : 0.7 + + ColumnLayout { + id: adapterList + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + + spacing: 0 + + Repeater { + model: Bluetooth.adapters + + Item { + id: adapter + + required property BluetoothAdapter modelData + + Layout.fillWidth: true + implicitHeight: adapterInner.implicitHeight + Appearance.padding.normal * 2 + + StateLayer { + enabled: adapterPickerButton.expanded + + function onClicked(): void { + adapterPickerButton.expanded = false; + root.session.bt.currentAdapter = adapter.modelData; + } + } + + RowLayout { + id: adapterInner + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Appearance.padding.normal + spacing: Appearance.spacing.normal + + StyledText { + Layout.fillWidth: true + Layout.leftMargin: Appearance.padding.small + text: adapter.modelData.name + color: Colours.palette.m3onSecondaryContainer + } + + MaterialIcon { + text: "check" + color: Colours.palette.m3onSecondaryContainer + visible: adapter.modelData === root.session.bt.currentAdapter + } + } + } + } + } + + Behavior on opacity { + Anim {} + } + + Behavior on scale { + Anim { + duration: Appearance.anim.durations.expressiveFastSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + } + } + + Behavior on implicitHeight { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + } + } + } + } + } + + RowLayout { + Layout.fillWidth: true + spacing: Appearance.spacing.normal + + StyledText { + Layout.fillWidth: true + text: qsTr("Discoverable timeout") + } + + CustomSpinBox { + min: 0 + value: root.session.bt.currentAdapter.discoverableTimeout + onValueModified: root.session.bt.currentAdapter.discoverableTimeout = value + } + } + } + } + + Item { + Layout.fillHeight: true + } + + component Toggle: RowLayout { + required property string label + property alias checked: toggle.checked + property alias toggle: toggle + + Layout.fillWidth: true + spacing: Appearance.spacing.normal + + StyledText { + Layout.fillWidth: true + text: parent.label + } + + StyledSwitch { + id: toggle + } + } + + component Anim: NumberAnimation { + duration: Appearance.anim.durations.normal + easing.type: Easing.BezierSpline + easing.bezierCurve: Appearance.anim.curves.standard + } +} -- cgit v1.2.3-freya