bluetoothdevices: make popup window
This commit is contained in:
parent
6d5805e662
commit
0518ec4214
10 changed files with 179 additions and 39 deletions
43
scss/popdowns/bluetoothdevices.scss
Normal file
43
scss/popdowns/bluetoothdevices.scss
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
@use "sass:color";
|
||||
@use "../scheme";
|
||||
@use "../lib";
|
||||
@use "../font";
|
||||
|
||||
$-accent: scheme.$rosewater;
|
||||
|
||||
.bluetooth-devices {
|
||||
@include lib.popdown-window($-accent);
|
||||
|
||||
min-width: lib.s(500);
|
||||
min-height: lib.s(400);
|
||||
|
||||
.list {
|
||||
@include lib.spacing($vertical: true);
|
||||
|
||||
color: scheme.$text;
|
||||
|
||||
.device {
|
||||
@include lib.spacing(8);
|
||||
|
||||
.icon {
|
||||
font-size: lib.s(18);
|
||||
}
|
||||
|
||||
button {
|
||||
@include lib.rounded(5);
|
||||
@include lib.element-decel;
|
||||
|
||||
padding: lib.s(3) lib.s(8);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: scheme.$surface0;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: scheme.$surface1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
scss/popdowns/index.scss
Normal file
3
scss/popdowns/index.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@forward "notifications";
|
||||
@forward "updates";
|
||||
@forward "bluetoothdevices";
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
@use "sass:color";
|
||||
@use "scheme";
|
||||
@use "lib";
|
||||
@use "font";
|
||||
@use "../scheme";
|
||||
@use "../lib";
|
||||
@use "../font";
|
||||
|
||||
@mixin popup($accent) {
|
||||
.separator {
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
@use "sass:color";
|
||||
@use "scheme";
|
||||
@use "lib";
|
||||
@use "font";
|
||||
@use "../scheme";
|
||||
@use "../lib";
|
||||
@use "../font";
|
||||
|
||||
$accent: scheme.$blue;
|
||||
$-accent: scheme.$blue;
|
||||
|
||||
.updates {
|
||||
@include lib.popdown-window($accent);
|
||||
@include lib.popdown-window($-accent);
|
||||
|
||||
min-width: lib.s(600);
|
||||
min-height: lib.s(400);
|
||||
|
|
@ -16,11 +16,11 @@ $accent: scheme.$blue;
|
|||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: color.mix($accent, scheme.$base, 80%);
|
||||
color: color.mix($-accent, scheme.$base, 80%);
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: color.mix($accent, scheme.$base, 60%);
|
||||
color: color.mix($-accent, scheme.$base, 60%);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,6 +36,14 @@ const hookFocusedClientProp = (
|
|||
callback(lastClient);
|
||||
};
|
||||
|
||||
const togglePopup = (self: JSX.Element, event: Astal.ClickEvent, name: string) => {
|
||||
const popup = App.get_window(name) as PopupWindow | null;
|
||||
if (popup) {
|
||||
if (popup.visible) popup.hide();
|
||||
else popup.popup_at_widget(self, event);
|
||||
}
|
||||
};
|
||||
|
||||
const OSIcon = () => <label className="module os-icon" label={osIcon} />;
|
||||
|
||||
const ActiveWindow = () => (
|
||||
|
|
@ -315,10 +323,9 @@ const Network = () => (
|
|||
|
||||
const Bluetooth = () => (
|
||||
<button
|
||||
onClick={(_, event) => {
|
||||
if (event.button === Astal.MouseButton.PRIMARY) {
|
||||
// TODO: bluetooth panel
|
||||
} else if (event.button === Astal.MouseButton.SECONDARY) AstalBluetooth.get_default().toggle();
|
||||
onClick={(self, event) => {
|
||||
if (event.button === Astal.MouseButton.PRIMARY) togglePopup(self, event, "bluetooth-devices");
|
||||
else if (event.button === Astal.MouseButton.SECONDARY) AstalBluetooth.get_default().toggle();
|
||||
else if (event.button === Astal.MouseButton.MIDDLE)
|
||||
execAsync("uwsm app -- blueman-manager").catch(console.error);
|
||||
}}
|
||||
|
|
@ -366,15 +373,7 @@ const StatusIcons = () => (
|
|||
|
||||
const PkgUpdates = () => (
|
||||
<button
|
||||
onClick={(self, event) => {
|
||||
if (event.button === Astal.MouseButton.PRIMARY) {
|
||||
const popup = App.get_window("updates") as PopupWindow | null;
|
||||
if (popup) {
|
||||
if (popup.visible) popup.hide();
|
||||
else popup.popup_at_widget(self, event);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onClick={(self, event) => event.button === Astal.MouseButton.PRIMARY && togglePopup(self, event, "updates")}
|
||||
setup={self =>
|
||||
setupCustomTooltip(
|
||||
self,
|
||||
|
|
@ -391,15 +390,9 @@ const PkgUpdates = () => (
|
|||
|
||||
const NotifCount = () => (
|
||||
<button
|
||||
onClick={(self, event) => {
|
||||
if (event.button === Astal.MouseButton.PRIMARY) {
|
||||
const popup = App.get_window("notifications") as PopupWindow | null;
|
||||
if (popup) {
|
||||
if (popup.visible) popup.hide();
|
||||
else popup.popup_at_widget(self, event);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onClick={(self, event) =>
|
||||
event.button === Astal.MouseButton.PRIMARY && togglePopup(self, event, "notifications")
|
||||
}
|
||||
setup={self =>
|
||||
setupCustomTooltip(
|
||||
self,
|
||||
|
|
|
|||
93
src/modules/popdowns/bluetoothdevices.tsx
Normal file
93
src/modules/popdowns/bluetoothdevices.tsx
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import { bind, Variable } from "astal";
|
||||
import { Gtk } from "astal/gtk3";
|
||||
import AstalBluetooth from "gi://AstalBluetooth";
|
||||
import PopdownWindow from "../../widgets/popdownwindow";
|
||||
|
||||
const BluetoothDevice = (device: AstalBluetooth.Device) => (
|
||||
<box className="device">
|
||||
<icon className="icon" icon={bind(device, "icon").as(i => `${i}-symbolic`)} />
|
||||
<label
|
||||
truncate
|
||||
xalign={0}
|
||||
setup={self => {
|
||||
const update = () =>
|
||||
(self.label = `${device.alias}${
|
||||
device.connected || device.paired ? ` (${device.connected ? "Connected" : "Paired"})` : ""
|
||||
}`);
|
||||
self.hook(device, "notify::alias", update);
|
||||
self.hook(device, "notify::connected", update);
|
||||
self.hook(device, "notify::paired", update);
|
||||
update();
|
||||
}}
|
||||
/>
|
||||
<box hexpand />
|
||||
<button
|
||||
cursor="pointer"
|
||||
onClicked={self => {
|
||||
if (device.connected)
|
||||
device.disconnect_device((_, res) => {
|
||||
self.sensitive = true;
|
||||
device.disconnect_device_finish(res);
|
||||
});
|
||||
else
|
||||
device.connect_device((_, res) => {
|
||||
self.sensitive = true;
|
||||
device.connect_device_finish(res);
|
||||
});
|
||||
self.sensitive = false;
|
||||
}}
|
||||
label={bind(device, "connected").as(c => (c ? "Disconnect" : "Connect"))}
|
||||
/>
|
||||
<button
|
||||
cursor="pointer"
|
||||
onClicked={() => AstalBluetooth.get_default().adapter.remove_device(device)}
|
||||
label="Remove"
|
||||
/>
|
||||
</box>
|
||||
);
|
||||
|
||||
const List = () => (
|
||||
<box vertical valign={Gtk.Align.START} className="list">
|
||||
{bind(AstalBluetooth.get_default(), "devices").as(d => d.map(BluetoothDevice))}
|
||||
</box>
|
||||
);
|
||||
|
||||
export default () => {
|
||||
const bluetooth = AstalBluetooth.get_default();
|
||||
const label = Variable("");
|
||||
|
||||
const update = () => {
|
||||
const devices = bluetooth.get_devices();
|
||||
const connected = devices.filter(d => d.connected).length;
|
||||
label.set(`${connected} connected device${connected === 1 ? "" : "s"} (${devices.length} available)`);
|
||||
};
|
||||
bluetooth.get_devices().forEach(d => d.connect("notify::connected", update));
|
||||
bluetooth.connect("device-added", (_, device) => device.connect("notify::connected", update));
|
||||
bluetooth.connect("notify::devices", update);
|
||||
update();
|
||||
|
||||
return (
|
||||
<PopdownWindow
|
||||
name="bluetooth-devices"
|
||||
count={bind(bluetooth, "devices").as(n => n.length)}
|
||||
countLabel={bind(label)}
|
||||
headerButtons={[
|
||||
{
|
||||
label: bind(bluetooth, "isPowered").as(p => (p ? "Disable" : "Enable")),
|
||||
onClicked: () => bluetooth.toggle(),
|
||||
},
|
||||
{
|
||||
label: "Discovery",
|
||||
onClicked: () => {
|
||||
if (bluetooth.adapter.discovering) bluetooth.adapter.start_discovery();
|
||||
else bluetooth.adapter.stop_discovery();
|
||||
},
|
||||
enabled: bind(bluetooth.adapter, "discovering"),
|
||||
},
|
||||
]}
|
||||
emptyIcon="bluetooth_disabled"
|
||||
emptyLabel="No Bluetooth devices"
|
||||
list={<List />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
import BluetoothDevices from "./bluetoothdevices";
|
||||
import Notifications from "./notifications";
|
||||
import Updates from "./updates";
|
||||
|
||||
export default () => {
|
||||
<Notifications />;
|
||||
<Updates />;
|
||||
<BluetoothDevices />;
|
||||
|
||||
return null;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ export default () => (
|
|||
{
|
||||
label: "Silence",
|
||||
onClicked: () => (AstalNotifd.get_default().dontDisturb = !AstalNotifd.get_default().dontDisturb),
|
||||
className: bind(AstalNotifd.get_default(), "dontDisturb").as(d => (d ? "enabled" : "")),
|
||||
enabled: bind(AstalNotifd.get_default(), "dontDisturb"),
|
||||
},
|
||||
{
|
||||
label: "Clear",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import PopupWindow from "./popupwindow";
|
|||
export default ({
|
||||
name,
|
||||
count,
|
||||
countLabel = count.as(c => `${c} ${name.slice(0, -1)}${c === 1 ? "" : "s"}`),
|
||||
headerButtons,
|
||||
emptyIcon,
|
||||
emptyLabel,
|
||||
|
|
@ -12,7 +13,8 @@ export default ({
|
|||
}: {
|
||||
name: string;
|
||||
count: Binding<number>;
|
||||
headerButtons: { label: string; onClicked: () => void; className?: Binding<string> }[];
|
||||
countLabel?: Binding<string>;
|
||||
headerButtons: { label: string | Binding<string>; onClicked: () => void; enabled?: Binding<boolean> }[];
|
||||
emptyIcon: string;
|
||||
emptyLabel: string;
|
||||
list: JSX.Element;
|
||||
|
|
@ -20,10 +22,15 @@ export default ({
|
|||
<PopupWindow name={name}>
|
||||
<box vertical className={name}>
|
||||
<box className="header">
|
||||
<label label={count.as(c => `${c} ${name.slice(0, -1)}${c === 1 ? "" : "s"}`)} />
|
||||
<label label={countLabel} />
|
||||
<box hexpand />
|
||||
{headerButtons.map(({ label, onClicked, className }) => (
|
||||
<button cursor="pointer" onClicked={onClicked} label={label} className={className} />
|
||||
{headerButtons.map(({ label, onClicked, enabled }) => (
|
||||
<button
|
||||
cursor="pointer"
|
||||
onClicked={onClicked}
|
||||
label={label}
|
||||
className={enabled?.as(d => (d ? "enabled" : ""))}
|
||||
/>
|
||||
))}
|
||||
</box>
|
||||
<stack
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@
|
|||
@use "scss/notifpopups";
|
||||
@use "scss/launcher";
|
||||
@use "scss/osds";
|
||||
@use "scss/notifications";
|
||||
@use "scss/updates";
|
||||
@use "scss/popdowns";
|
||||
|
||||
* {
|
||||
all: unset; // Remove GTK theme styles
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue