summaryrefslogtreecommitdiff
path: root/modules/detachedcontent
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-08-03 18:43:25 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-08-03 18:43:25 +1000
commit365b993221fe82c7e15ec79c7528799e6ea45cfc (patch)
treed19b72ef83af7786b7a3dc634bea1215ac567012 /modules/detachedcontent
parentdcontent: add info to bt settings (diff)
downloadcaelestia-shell-365b993221fe82c7e15ec79c7528799e6ea45cfc.tar.gz
caelestia-shell-365b993221fe82c7e15ec79c7528799e6ea45cfc.tar.bz2
caelestia-shell-365b993221fe82c7e15ec79c7528799e6ea45cfc.zip
dcontent: impl bt device details
Diffstat (limited to 'modules/detachedcontent')
-rw-r--r--modules/detachedcontent/Session.qml1
-rw-r--r--modules/detachedcontent/bluetooth/BtPane.qml3
-rw-r--r--modules/detachedcontent/bluetooth/Details.qml328
3 files changed, 326 insertions, 6 deletions
diff --git a/modules/detachedcontent/Session.qml b/modules/detachedcontent/Session.qml
index 4b27617..136454d 100644
--- a/modules/detachedcontent/Session.qml
+++ b/modules/detachedcontent/Session.qml
@@ -16,5 +16,6 @@ QtObject {
property BluetoothDevice active
property BluetoothAdapter currentAdapter: Bluetooth.defaultAdapter
property bool editingAdapterName
+ property bool fabMenuOpen
}
}
diff --git a/modules/detachedcontent/bluetooth/BtPane.qml b/modules/detachedcontent/bluetooth/BtPane.qml
index ff2cc0a..1428540 100644
--- a/modules/detachedcontent/bluetooth/BtPane.qml
+++ b/modules/detachedcontent/bluetooth/BtPane.qml
@@ -72,9 +72,6 @@ RowLayout {
id: details
Details {
- anchors.margins: Appearance.padding.normal
- anchors.leftMargin: Appearance.padding.normal / 2
-
session: root.session
}
}
diff --git a/modules/detachedcontent/bluetooth/Details.qml b/modules/detachedcontent/bluetooth/Details.qml
index b3f7e2a..6ca611e 100644
--- a/modules/detachedcontent/bluetooth/Details.qml
+++ b/modules/detachedcontent/bluetooth/Details.qml
@@ -1,15 +1,337 @@
+pragma ComponentBehavior: Bound
+
import ".."
import qs.widgets
import qs.services
import qs.config
-import Quickshell
+import qs.utils
import Quickshell.Bluetooth
+import QtQuick
import QtQuick.Layouts
+import QtQuick.Effects
-ColumnLayout {
+Item {
id: root
required property Session session
+ readonly property BluetoothDevice device: session.bt.active
+
+ StyledFlickable {
+ anchors.fill: parent
+
+ flickableDirection: Flickable.VerticalFlick
+ contentHeight: layout.height
+
+ ColumnLayout {
+ id: layout
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+ spacing: Appearance.spacing.normal
+
+ MaterialIcon {
+ Layout.alignment: Qt.AlignHCenter
+ text: Icons.getBluetoothIcon(root.device.icon)
+ font.pointSize: Appearance.font.size.extraLarge * 3
+ font.bold: true
+ }
+
+ StyledText {
+ Layout.alignment: Qt.AlignHCenter
+ text: root.device.name
+ font.pointSize: Appearance.font.size.large
+ font.bold: true
+ }
+
+ StyledText {
+ Layout.topMargin: Appearance.spacing.large
+ text: qsTr("Connection status")
+ font.pointSize: Appearance.font.size.larger
+ font.weight: 500
+ }
+
+ StyledText {
+ text: qsTr("Connection settings for this device")
+ 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("Connected")
+ checked: root.device.connected
+ toggle.onToggled: root.device.connected = checked
+ }
+
+ Toggle {
+ label: qsTr("Paired")
+ checked: root.device.paired
+ toggle.onToggled: {
+ if (root.device.paired)
+ root.device.forget();
+ else
+ root.device.pair();
+ }
+ }
+
+ Toggle {
+ label: qsTr("Blocked")
+ checked: root.device.blocked
+ toggle.onToggled: root.device.blocked = checked
+ }
+ }
+ }
+ }
+ }
+
+ ColumnLayout {
+ anchors.right: fabRoot.right
+ anchors.bottom: fabRoot.top
+ anchors.bottomMargin: Appearance.padding.normal
+
+ Repeater {
+ id: fabMenu
+
+ model: [
+ {
+ icon: "handshake",
+ label: root.device.trusted ? qsTr("Untrust") : qsTr("Trust"),
+ onClicked: () => root.device.trusted = !root.device.trusted
+ },
+ {
+ icon: "block",
+ label: root.device.blocked ? qsTr("Unblock") : qsTr("Block"),
+ onClicked: () => root.device.blocked = !root.device.blocked
+ },
+ {
+ icon: "missing_controller",
+ label: root.device.paired ? qsTr("Unpair") : qsTr("Pair"),
+ onClicked: () => {
+ if (root.device.paired)
+ root.device.forget();
+ else
+ root.device.pair();
+ }
+ },
+ {
+ icon: "bluetooth_connected",
+ label: root.device.connected ? qsTr("Disconnect") : qsTr("Connect"),
+ onClicked: () => root.device.connected = !root.device.connected
+ }
+ ]
+
+ StyledClippingRect {
+ id: fabMenuItem
+
+ required property var modelData
+ required property int index
+
+ Layout.alignment: Qt.AlignRight
+
+ implicitHeight: fabMenuItemInner.implicitHeight + Appearance.padding.larger * 2
+
+ radius: Appearance.rounding.full
+ color: Colours.palette.m3primaryContainer
+
+ opacity: 0
+
+ states: State {
+ name: "visible"
+ when: root.session.bt.fabMenuOpen
+
+ PropertyChanges {
+ fabMenuItem.implicitWidth: fabMenuItemInner.implicitWidth + Appearance.padding.large * 2
+ fabMenuItem.opacity: 1
+ fabMenuItemInner.opacity: 1
+ }
+ }
+
+ transitions: [
+ Transition {
+ to: "visible"
+
+ SequentialAnimation {
+ PauseAnimation {
+ duration: (fabMenu.count - 1 - fabMenuItem.index) * Appearance.anim.durations.small / 8
+ }
+ ParallelAnimation {
+ Anim {
+ property: "implicitWidth"
+ duration: Appearance.anim.durations.expressiveFastSpatial
+ easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
+ }
+ Anim {
+ property: "opacity"
+ duration: Appearance.anim.durations.small
+ }
+ }
+ }
+ },
+ Transition {
+ from: "visible"
+
+ SequentialAnimation {
+ PauseAnimation {
+ duration: fabMenuItem.index * Appearance.anim.durations.small / 8
+ }
+ ParallelAnimation {
+ Anim {
+ property: "implicitWidth"
+ duration: Appearance.anim.durations.expressiveFastSpatial
+ easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
+ }
+ Anim {
+ property: "opacity"
+ duration: Appearance.anim.durations.small
+ }
+ }
+ }
+ }
+ ]
+
+ StateLayer {
+ function onClicked(): void {
+ root.session.bt.fabMenuOpen = false;
+ fabMenuItem.modelData.onClicked();
+ }
+ }
+
+ RowLayout {
+ id: fabMenuItemInner
+
+ anchors.centerIn: parent
+ spacing: Appearance.spacing.normal
+ opacity: 0
+
+ MaterialIcon {
+ text: fabMenuItem.modelData.icon
+ color: Colours.palette.m3onPrimaryContainer
+ fill: 1
+ }
+
+ StyledText {
+ text: fabMenuItem.modelData.label
+ color: Colours.palette.m3onPrimaryContainer
+ }
+ }
+ }
+ }
+ }
+
+ Item {
+ id: fabRoot
+
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+
+ implicitWidth: 64
+ implicitHeight: 64
+
+ StyledRect {
+ id: fabBg
+
+ anchors.right: parent.right
+ anchors.top: parent.top
+
+ implicitWidth: 64
+ implicitHeight: 64
+
+ radius: Appearance.rounding.normal
+ color: root.session.bt.fabMenuOpen ? Colours.palette.m3primary : Colours.palette.m3primaryContainer
+
+ states: State {
+ name: "expanded"
+ when: root.session.bt.fabMenuOpen
+
+ PropertyChanges {
+ fabBg.implicitWidth: 48
+ fabBg.implicitHeight: 48
+ fabBg.radius: 48 / 2
+ fab.font.pointSize: Appearance.font.size.larger
+ }
+ }
+
+ transitions: Transition {
+ Anim {
+ properties: "implicitWidth,implicitHeight"
+ duration: Appearance.anim.durations.expressiveFastSpatial
+ easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
+ }
+ Anim {
+ properties: "radius,font.pointSize"
+ }
+ }
+
+ Elevation {
+ anchors.fill: parent
+ radius: parent.radius
+ z: -1
+ level: fabState.containsMouse && !fabState.pressed ? 4 : 3
+ }
+
+ StateLayer {
+ id: fabState
+
+ color: root.session.bt.fabMenuOpen ? Colours.palette.m3onPrimary : Colours.palette.m3onPrimaryContainer
+
+ function onClicked(): void {
+ root.session.bt.fabMenuOpen = !root.session.bt.fabMenuOpen;
+ }
+ }
+
+ MaterialIcon {
+ id: fab
+
+ anchors.centerIn: parent
+ animate: true
+ text: root.session.bt.fabMenuOpen ? "close" : "settings"
+ color: root.session.bt.fabMenuOpen ? Colours.palette.m3onPrimary : Colours.palette.m3onPrimaryContainer
+ font.pointSize: Appearance.font.size.large
+ fill: 1
+ }
+
+ Behavior on radius {
+ Anim {}
+ }
+ }
+ }
+
+ 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
+ }
+ }
- spacing: Appearance.spacing.normal
+ component Anim: NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
}