161 lines
6.1 KiB
Python
161 lines
6.1 KiB
Python
from fabric.bluetooth import BluetoothClient, BluetoothDevice
|
|
from fabric.widgets.box import Box
|
|
from fabric.widgets.button import Button
|
|
from fabric.widgets.centerbox import CenterBox
|
|
from fabric.widgets.image import Image
|
|
from fabric.widgets.label import Label
|
|
from fabric.widgets.scrolledwindow import ScrolledWindow
|
|
|
|
import modules.icons as icons
|
|
|
|
|
|
class BluetoothDeviceSlot(CenterBox):
|
|
def __init__(self, device: BluetoothDevice, **kwargs):
|
|
super().__init__(name="bluetooth-device", **kwargs)
|
|
self.device = device
|
|
self.device.connect("changed", self.on_changed)
|
|
self.device.connect(
|
|
"notify::closed", lambda *_: self.device.closed and self.destroy()
|
|
)
|
|
|
|
self.connection_label = Label(name="bluetooth-connection", markup=icons.bluetooth_disconnected)
|
|
self.connect_button = Button(
|
|
name="bluetooth-connect",
|
|
label="Connect",
|
|
on_clicked=lambda *_: self.device.set_connecting(not self.device.connected),
|
|
style_classes=["connected"] if self.device.connected else None,
|
|
)
|
|
|
|
self.start_children = [
|
|
Box(
|
|
spacing=8,
|
|
h_expand=True,
|
|
h_align="fill",
|
|
children=[
|
|
Image(icon_name=device.icon_name + "-symbolic", size=16),
|
|
Label(label=device.name, h_expand=True, h_align="start", ellipsization="end"),
|
|
self.connection_label,
|
|
],
|
|
)
|
|
]
|
|
self.end_children = self.connect_button
|
|
|
|
self.device.emit("changed")
|
|
|
|
def on_changed(self, *_):
|
|
self.connection_label.set_markup(
|
|
icons.bluetooth_connected if self.device.connected else icons.bluetooth_disconnected
|
|
)
|
|
if self.device.connecting:
|
|
self.connect_button.set_label(
|
|
"Connecting..." if not self.device.connecting else "..."
|
|
)
|
|
else:
|
|
self.connect_button.set_label(
|
|
"Connect" if not self.device.connected else "Disconnect"
|
|
)
|
|
if self.device.connected:
|
|
self.connect_button.add_style_class("connected")
|
|
else:
|
|
self.connect_button.remove_style_class("connected")
|
|
return
|
|
|
|
class BluetoothConnections(Box):
|
|
def __init__(self, **kwargs):
|
|
super().__init__(
|
|
name="bluetooth",
|
|
spacing=4,
|
|
orientation="vertical",
|
|
**kwargs,
|
|
)
|
|
|
|
self.widgets = kwargs["widgets"]
|
|
|
|
self.buttons = self.widgets.buttons.bluetooth_button
|
|
self.bt_status_text = self.buttons.bluetooth_status_text
|
|
self.bt_status_button = self.buttons.bluetooth_status_button
|
|
self.bt_icon = self.buttons.bluetooth_icon
|
|
self.bt_label = self.buttons.bluetooth_label
|
|
self.bt_menu_button = self.buttons.bluetooth_menu_button
|
|
self.bt_menu_label = self.buttons.bluetooth_menu_label
|
|
|
|
self.client = BluetoothClient(on_device_added=self.on_device_added)
|
|
self.scan_label = Label(name="bluetooth-scan-label", markup=icons.radar)
|
|
self.scan_button = Button(
|
|
name="bluetooth-scan",
|
|
child=self.scan_label,
|
|
tooltip_text="Scan for Bluetooth devices",
|
|
on_clicked=lambda *_: self.client.toggle_scan()
|
|
)
|
|
self.back_button = Button(
|
|
name="bluetooth-back",
|
|
child=Label(name="bluetooth-back-label", markup=icons.chevron_left),
|
|
on_clicked=lambda *_: self.widgets.show_notif()
|
|
)
|
|
|
|
self.client.connect("notify::enabled", lambda *_: self.status_label())
|
|
self.client.connect(
|
|
"notify::scanning",
|
|
lambda *_: self.update_scan_label()
|
|
)
|
|
|
|
self.paired_box = Box(spacing=2, orientation="vertical")
|
|
self.available_box = Box(spacing=2, orientation="vertical")
|
|
|
|
content_box = Box(spacing=4, orientation="vertical")
|
|
content_box.add(self.paired_box)
|
|
content_box.add(Label(name="bluetooth-section", label="Available"))
|
|
content_box.add(self.available_box)
|
|
|
|
self.children = [
|
|
CenterBox(
|
|
name="bluetooth-header",
|
|
start_children=self.back_button,
|
|
center_children=Label(name="bluetooth-text", label="Bluetooth Devices"),
|
|
end_children=self.scan_button
|
|
),
|
|
ScrolledWindow(
|
|
name="bluetooth-devices",
|
|
min_content_size=(-1, -1),
|
|
child=content_box,
|
|
v_expand=True,
|
|
propagate_width=False,
|
|
propagate_height=False,
|
|
),
|
|
]
|
|
|
|
self.client.notify("scanning")
|
|
self.client.notify("enabled")
|
|
|
|
def status_label(self):
|
|
print(self.client.enabled)
|
|
if self.client.enabled:
|
|
self.bt_status_text.set_label("Enabled")
|
|
for i in [self.bt_status_button, self.bt_status_text, self.bt_icon, self.bt_label, self.bt_menu_button, self.bt_menu_label]:
|
|
i.remove_style_class("disabled")
|
|
self.bt_icon.set_markup(icons.bluetooth)
|
|
else:
|
|
self.bt_status_text.set_label("Disabled")
|
|
for i in [self.bt_status_button, self.bt_status_text, self.bt_icon, self.bt_label, self.bt_menu_button, self.bt_menu_label]:
|
|
i.add_style_class("disabled")
|
|
self.bt_icon.set_markup(icons.bluetooth_off)
|
|
|
|
def on_device_added(self, client: BluetoothClient, address: str):
|
|
if not (device := client.get_device(address)):
|
|
return
|
|
slot = BluetoothDeviceSlot(device)
|
|
|
|
if device.paired:
|
|
return self.paired_box.add(slot)
|
|
return self.available_box.add(slot)
|
|
|
|
def update_scan_label(self):
|
|
if self.client.scanning:
|
|
self.scan_label.add_style_class("scanning")
|
|
self.scan_button.add_style_class("scanning")
|
|
self.scan_button.set_tooltip_text("Stop scanning for Bluetooth devices")
|
|
else:
|
|
self.scan_label.remove_style_class("scanning")
|
|
self.scan_button.remove_style_class("scanning")
|
|
self.scan_button.set_tooltip_text("Scan for Bluetooth devices")
|