menu: bluetooth settings

This commit is contained in:
2026-02-05 16:41:27 +02:00
parent a3a782163a
commit 887b477c5e
2 changed files with 150 additions and 20 deletions

View File

@@ -2,6 +2,7 @@ import QtQuick
import Quickshell import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Services.Mpris import Quickshell.Services.Mpris
import Quickshell.Bluetooth
FloatingWindow { FloatingWindow {
title: "Quickshell debugger" title: "Quickshell debugger"
@@ -43,6 +44,29 @@ FloatingWindow {
font.pixelSize: 32 font.pixelSize: 32
} }
Repeater {
model: Bluetooth.devices
Item {
y: 16 * index
Text {
text: "bt" + index + modelData.name
color: "#04047C"
font.family: "Determination Mono"
font.pixelSize: 16
y: 64 + 128 + 1
x: 64 + 1 + 512
}
Text {
text: "bt" + index + modelData.name
color: "#ff0000"
font.family: "Determination Mono"
font.pixelSize: 16
y: 64 + 128
x: 64 + 512
}
}
}
Repeater { Repeater {
model: Mpris.players model: Mpris.players
Item { Item {
@@ -54,7 +78,7 @@ FloatingWindow {
asynchronous: true asynchronous: true
} }
Text { Text {
text: "mpris" + index + JSON.stringify(modelData.metadata, undefined, "\t") text: "mpris" + index + JSON.stringify(modelData, undefined, "\t")
color: "#04047C" color: "#04047C"
font.family: "Determination Mono" font.family: "Determination Mono"
font.pixelSize: 16 font.pixelSize: 16
@@ -62,7 +86,7 @@ FloatingWindow {
x: 64 + 1 x: 64 + 1
} }
Text { Text {
text: "mpris" + index + JSON.stringify(modelData.metadata, undefined, "\t") text: "mpris" + index + JSON.stringify(modelData, undefined, "\t")
color: "#ff0000" color: "#ff0000"
font.family: "Determination Mono" font.family: "Determination Mono"
font.pixelSize: 16 font.pixelSize: 16

View File

@@ -1,4 +1,5 @@
import QtQuick import QtQuick
import Quickshell.Bluetooth
import Quickshell.Services.Pipewire import Quickshell.Services.Pipewire
import "../.." import "../.."
@@ -28,6 +29,7 @@ Item {
property ShellStateManager manager: null property ShellStateManager manager: null
property int activeSelection: 0 property int activeSelection: 0
property bool inBluetoothMenu: false
property bool isSelected: false property bool isSelected: false
@@ -35,20 +37,75 @@ Item {
return Math.max(lo, Math.min(hi, v)); return Math.max(lo, Math.min(hi, v));
} }
function wrapIndex(i) { function menuLength() {
if (actions.length === 0) if (!menuModel)
return 0; return 0;
return (i + actions.length) % actions.length; if (menuModel.count !== undefined)
return menuModel.count;
if (menuModel.length !== undefined)
return menuModel.length;
return 0;
}
function menuAt(index) {
if (!menuModel)
return null;
if (menuModel.get)
return menuModel.get(index);
if (menuModel.length !== undefined)
return menuModel[index];
return null;
}
function wrapIndex(i) {
const length = menuLength();
if (length === 0)
return 0;
return (i + length) % length;
} }
function currentAction() { function currentAction() {
return actions.length > 0 ? actions[activeSelection] : null; if (root.inBluetoothMenu)
return null;
return menuLength() > 0 ? menuAt(activeSelection) : null;
}
function clampSelection() {
const length = menuLength();
if (length === 0) {
activeSelection = 0;
return;
}
activeSelection = clamp(activeSelection, 0, length - 1);
}
function bluetoothDisplayName(device) {
if (!device)
return "";
if (device.name && device.name.length > 0)
return device.name;
return device.deviceName || "";
}
function bluetoothDisplayState(device) {
if (!device)
return "";
// dont change symbols
return device.connected ? "✓" : "";
}
function bluetoothDeviceAt(index) {
const item = bluetoothRepeater.itemAt(index);
if (!item)
return null;
return item.device || null;
} }
PwObjectTracker { PwObjectTracker {
objects: [Pipewire.defaultAudioSink] objects: [Pipewire.defaultAudioSink]
} }
property int bluetoothActionIndex: 1
property var actions: [ property var actions: [
{ {
name: "Master Volume", name: "Master Volume",
@@ -68,17 +125,44 @@ Item {
} }
}, },
{ {
name: "Controls", name: "Bluetooth",
ent: function () {}, ent: function () {
root.inBluetoothMenu = true;
root.isSelected = false;
root.activeSelection = 0;
root.clampSelection();
},
getState: function () { getState: function () {
console.log("deltarune tommorow");
return ""; return "";
} }
} }
] ]
property var menuModel: root.inBluetoothMenu ? Bluetooth.devices : actions
Connections {
target: Bluetooth.devices
ignoreUnknownSignals: true
function onCountChanged() {
if (root.inBluetoothMenu)
root.clampSelection();
}
function onModelReset() {
if (root.inBluetoothMenu)
root.clampSelection();
}
function onRowsInserted() {
if (root.inBluetoothMenu)
root.clampSelection();
}
function onRowsRemoved() {
if (root.inBluetoothMenu)
root.clampSelection();
}
}
Text { Text {
text: "CONFIG" text: root.inBluetoothMenu ? "BLUETOOTH" : "CONFIG"
font.family: "8bitoperator JVE" font.family: "8bitoperator JVE"
font.pixelSize: 71 font.pixelSize: 71
renderType: Text.NativeRendering renderType: Text.NativeRendering
@@ -91,7 +175,8 @@ Item {
} }
Repeater { Repeater {
model: root.actions id: bluetoothRepeater
model: root.menuModel
delegate: Item { delegate: Item {
width: root.width width: root.width
@@ -99,6 +184,8 @@ Item {
x: 0 x: 0
y: menuTop + index * lineHeight y: menuTop + index * lineHeight
property var device: root.inBluetoothMenu ? modelData : null
Image { Image {
source: "./soul.png" source: "./soul.png"
width: 36 width: 36
@@ -111,7 +198,7 @@ Item {
Text { Text {
x: 239 x: 239
y: 0 y: 0
text: modelData.name text: root.inBluetoothMenu ? root.bluetoothDisplayName(modelData) : modelData.name
font.family: "8bitoperator JVE" font.family: "8bitoperator JVE"
font.pixelSize: 71 font.pixelSize: 71
font.letterSpacing: 1 font.letterSpacing: 1
@@ -126,7 +213,7 @@ Item {
Text { Text {
x: menuLeft + stateColumnX x: menuLeft + stateColumnX
y: 4 y: 4
text: modelData.getState ? modelData.getState() : "" text: root.inBluetoothMenu ? root.bluetoothDisplayState(modelData) : (modelData.getState ? modelData.getState() : "")
font.family: "8bitoperator JVE" font.family: "8bitoperator JVE"
font.pixelSize: 71 font.pixelSize: 71
font.letterSpacing: 1 font.letterSpacing: 1
@@ -146,11 +233,11 @@ Item {
function handleKey(key) { function handleKey(key) {
switch (key) { switch (key) {
case Qt.Key_Up: case Qt.Key_Up:
if (root.isSelected === false) if (root.inBluetoothMenu || root.isSelected === false)
activeSelection = wrapIndex(activeSelection - 1); activeSelection = wrapIndex(activeSelection - 1);
return true; return true;
case Qt.Key_Down: case Qt.Key_Down:
if (root.isSelected === false) if (root.inBluetoothMenu || root.isSelected === false)
activeSelection = wrapIndex(activeSelection + 1); activeSelection = wrapIndex(activeSelection + 1);
return true; return true;
case Qt.Key_Left: case Qt.Key_Left:
@@ -171,18 +258,36 @@ Item {
case Qt.Key_Return: case Qt.Key_Return:
case Qt.Key_Enter: case Qt.Key_Enter:
{ {
const a = currentAction(); if (root.inBluetoothMenu) {
if (a && a.ent) { const device = bluetoothDeviceAt(activeSelection);
a.ent(); console.log(root.inBluetoothMenu, activeSelection, device);
if (device) {
if (!device.connected) {
device.connect();
} else {
device.disconnect();
}
// device.connected = !device.connected;
}
} else { } else {
root.isSelected = !root.isSelected; const a = currentAction();
if (a && a.ent) {
a.ent();
} else {
root.isSelected = !root.isSelected;
}
} }
return true; return true;
} }
case Qt.Key_X: case Qt.Key_X:
case Qt.Key_Shift: case Qt.Key_Shift:
case Qt.Key_Escape: case Qt.Key_Escape:
if (root.isSelected === true) { if (root.inBluetoothMenu) {
root.inBluetoothMenu = false;
root.isSelected = false;
root.activeSelection = root.bluetoothActionIndex;
root.clampSelection();
} else if (root.isSelected === true) {
root.isSelected = false; root.isSelected = false;
} else { } else {
if (manager && manager.closeQuickSettings) { if (manager && manager.closeQuickSettings) {
@@ -197,6 +302,7 @@ Item {
Component.onCompleted: { Component.onCompleted: {
root.activeSelection = 0; root.activeSelection = 0;
root.isSelected = false; root.isSelected = false;
root.inBluetoothMenu = false;
ShellInputManager.registerHandler("quickSettings", handleKey); ShellInputManager.registerHandler("quickSettings", handleKey);
} }