extract BluetoothApplet, fold BluetoothMenu into BluetoothModule with hover+pin

This commit is contained in:
Damocles 2026-04-22 21:54:20 +02:00
parent c9c71c0e29
commit 5da7005ce7
4 changed files with 79 additions and 73 deletions

View file

@ -1,148 +0,0 @@
import QtQuick
import Quickshell
import "." as M
import "../services" as S
M.HoverPanel {
id: menuWindow
contentWidth: 250
panelNamespace: "nova-bluetooth"
popupMode: true
panelTitle: "Bluetooth"
titleActionsComponent: Component {
Item {
width: 20
height: 20
Text {
anchors.centerIn: parent
text: "\uF011"
color: S.BluetoothService.enabled ? menuWindow.accentColor : S.Theme.base04
font.pixelSize: S.Theme.fontSize
font.family: S.Theme.iconFontFamily
Behavior on color {
ColorAnimation {
duration: 100
}
}
}
HoverHandler {
cursorShape: Qt.PointingHandCursor
}
TapHandler {
onTapped: S.BluetoothService.setPower(!S.BluetoothService.enabled)
}
}
}
onVisibleChanged: if (visible)
S.BluetoothService.refresh()
Repeater {
model: S.BluetoothService.devices
delegate: Item {
id: entry
required property var modelData
required property int index
readonly property bool _pending: S.BluetoothService.pendingMac === entry.modelData.mac
width: menuWindow.contentWidth
height: 32
Rectangle {
anchors.fill: parent
anchors.leftMargin: 4
anchors.rightMargin: 4
color: entryHover.hovered ? S.Theme.base02 : "transparent"
radius: S.Theme.radius
}
Text {
id: btIcon
anchors.left: parent.left
anchors.leftMargin: 12
anchors.verticalCenter: parent.verticalCenter
text: "\uF294"
color: entry._pending ? menuWindow.accentColor : entry.modelData.connected ? menuWindow.accentColor : S.Theme.base04
font.pixelSize: S.Theme.fontSize + 1
font.family: S.Theme.iconFontFamily
}
Text {
anchors.left: btIcon.right
anchors.leftMargin: 8
anchors.right: _statusLabel.left
anchors.rightMargin: 4
anchors.verticalCenter: parent.verticalCenter
text: entry.modelData.name
color: entry._pending ? menuWindow.accentColor : entry.modelData.connected ? menuWindow.accentColor : S.Theme.base05
font.pixelSize: S.Theme.fontSize
font.family: S.Theme.fontFamily
font.bold: entry.modelData.connected || entry._pending
elide: Text.ElideRight
}
Text {
id: _statusLabel
anchors.right: parent.right
anchors.rightMargin: 12
anchors.verticalCenter: parent.verticalCenter
text: entry._pending ? (entry.modelData.connected ? "disconnecting..." : "connecting...") : (entry.modelData.battery >= 0 ? entry.modelData.battery + "%" : "")
color: entry._pending ? S.Theme.base04 : S.Theme.base04
font.pixelSize: S.Theme.fontSize - 1
font.family: S.Theme.fontFamily
font.italic: entry._pending
width: text ? implicitWidth : 0
}
// Pulse animation while pending
SequentialAnimation on opacity {
loops: Animation.Infinite
running: entry._pending
NumberAnimation {
to: 0.5
duration: 400
easing.type: Easing.InOutQuad
}
NumberAnimation {
to: 1
duration: 400
easing.type: Easing.InOutQuad
}
onRunningChanged: if (!running)
entry.opacity = 1
}
HoverHandler {
id: entryHover
cursorShape: Qt.PointingHandCursor
}
TapHandler {
onTapped: {
if (!entry._pending) {
S.BluetoothService.toggleDevice(entry.modelData.mac, !entry.modelData.connected);
menuWindow.keepOpen(500);
}
}
}
}
}
Text {
visible: S.BluetoothService.devices.length === 0
width: menuWindow.contentWidth
height: 32
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: S.BluetoothService.enabled ? "No paired devices" : "Bluetooth is off"
color: S.Theme.base04
font.pixelSize: S.Theme.fontSize
font.family: S.Theme.fontFamily
}
}