menu: bluetooth settings
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user