✨ ags(control-center/pages): better page widget, add PageButton widget for better looking buttons
This commit is contained in:
@@ -1,23 +1,24 @@
|
|||||||
import { bind, Variable } from "astal";
|
import { bind } from "astal";
|
||||||
import { Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
import AstalBluetooth from "gi://AstalBluetooth";
|
import AstalBluetooth from "gi://AstalBluetooth";
|
||||||
import { Page } from "./Page";
|
import { Page, PageButton } from "./Page";
|
||||||
import { Separator, SeparatorProps } from "../../Separator";
|
import { Separator, SeparatorProps } from "../../Separator";
|
||||||
|
|
||||||
|
|
||||||
const watchingDevices = new Variable<boolean>(false);
|
export const BluetoothPage: (() => Page) = () => new Page({
|
||||||
|
id: "bluetooth",
|
||||||
export const BluetoothPage: Page = new Page({
|
title: "Bluetooth",
|
||||||
title: "Bluetooth Devices",
|
|
||||||
description: "Manage your Bluetooth devices and add new ones.",
|
description: "Manage your Bluetooth devices and add new ones.",
|
||||||
className: "bluetooth",
|
className: "bluetooth",
|
||||||
headerButtons: () => [
|
headerButtons: [
|
||||||
new Widget.Button({
|
new Widget.Button({
|
||||||
className: "discover nf",
|
className: "discover nf",
|
||||||
label: watchingDevices(watching => !watching ? '' : ''),
|
label: bind(AstalBluetooth.get_default().adapter, "discovering").as((discovering) =>
|
||||||
tooltipText: watchingDevices(watching => !watching ? "Start discovering" : "Stop discovery"),
|
!discovering ? '' : ''),
|
||||||
|
tooltipText: bind(AstalBluetooth.get_default().adapter, "discovering").as((discovering) =>
|
||||||
|
!discovering ? "Start discovering" : "Stop discovery"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
if(watchingDevices.get()) {
|
if(AstalBluetooth.get_default().adapter.discovering) {
|
||||||
stopBluetoothDevicesWatch();
|
stopBluetoothDevicesWatch();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -27,64 +28,87 @@ export const BluetoothPage: Page = new Page({
|
|||||||
} as Widget.ButtonProps)
|
} as Widget.ButtonProps)
|
||||||
],
|
],
|
||||||
onClose: () => stopBluetoothDevicesWatch(),
|
onClose: () => stopBluetoothDevicesWatch(),
|
||||||
pageChild: () => new Widget.Box({
|
children: [
|
||||||
className: "connections",
|
new Widget.Box({
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
className: "adapters",
|
||||||
expand: true,
|
visible: bind(AstalBluetooth.get_default(), "adapters").as((adapters) =>
|
||||||
hexpand: true,
|
adapters.length > 1),
|
||||||
children: [
|
children: bind(AstalBluetooth.get_default(), "adapters").as((adapters) => [
|
||||||
new Widget.Box({
|
new Widget.Label({
|
||||||
className: "paired",
|
className: "sub-header",
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
label: "Adapters"
|
||||||
visible: bind(AstalBluetooth.get_default(), "devices").as((devs) =>
|
} as Widget.LabelProps),
|
||||||
devs.filter(dev => dev.paired || dev.connected).length > 0),
|
...adapters.map(adapter =>
|
||||||
children: bind(AstalBluetooth.get_default(), "devices").as((devs: Array<AstalBluetooth.Device>) => {
|
PageButton({
|
||||||
const connectedDevices = devs.filter((dev: AstalBluetooth.Device) => dev.connected || dev.paired)
|
title: adapter.alias ?? "Adapter",
|
||||||
|
icon: "bluetooth-active-symbolic",
|
||||||
|
onClick: () => AstalBluetooth.get_default(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
} as Widget.BoxProps),
|
||||||
|
new Widget.Box({
|
||||||
|
className: "connections",
|
||||||
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
hexpand: true,
|
||||||
|
children: [
|
||||||
|
new Widget.Box({
|
||||||
|
className: "paired",
|
||||||
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
visible: bind(AstalBluetooth.get_default(), "devices").as((devs) =>
|
||||||
|
devs.filter(dev => dev.paired || dev.connected).length > 0),
|
||||||
|
children: bind(AstalBluetooth.get_default(), "devices").as((devs: Array<AstalBluetooth.Device>) => {
|
||||||
|
const connectedDevices = devs.filter((dev: AstalBluetooth.Device) => dev.connected || dev.paired)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
className: "sub-header",
|
className: "sub-header",
|
||||||
label: "Paired Devices",
|
label: "Paired Devices",
|
||||||
xalign: 0,
|
xalign: 0,
|
||||||
} as Widget.LabelProps),
|
} as Widget.LabelProps),
|
||||||
...connectedDevices.map((dev: AstalBluetooth.Device) => DeviceWidget(dev))
|
...connectedDevices.map((dev: AstalBluetooth.Device) => DeviceWidget(dev))
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
} as Widget.BoxProps),
|
} as Widget.BoxProps),
|
||||||
new Widget.Box({
|
new Widget.Box({
|
||||||
className: "discovered",
|
className: "discovered",
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
visible: bind(AstalBluetooth.get_default(), "devices").as((devs) =>
|
visible: bind(AstalBluetooth.get_default(), "devices").as((devs) =>
|
||||||
devs.filter((dev) => !dev.connected && !dev.paired).length > 0),
|
devs.filter((dev) => !dev.connected && !dev.paired).length > 0),
|
||||||
children: bind(AstalBluetooth.get_default(), "devices").as((devices: Array<AstalBluetooth.Device>) => {
|
children: bind(AstalBluetooth.get_default(), "devices").as((devices: Array<AstalBluetooth.Device>) => {
|
||||||
const discoveredDevices = devices.filter((dev: AstalBluetooth.Device) => !dev.connected && !dev.paired);
|
const discoveredDevices = devices.filter((dev: AstalBluetooth.Device) => !dev.connected && !dev.paired);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
className: "sub-header",
|
className: "sub-header",
|
||||||
label: "Others",
|
label: "Others",
|
||||||
xalign: 0
|
xalign: 0
|
||||||
} as Widget.LabelProps),
|
} as Widget.LabelProps),
|
||||||
...discoveredDevices.map((dev: AstalBluetooth.Device) => DeviceWidget(dev))
|
...discoveredDevices.map((dev: AstalBluetooth.Device) => DeviceWidget(dev))
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
} as Widget.BoxProps),
|
} as Widget.BoxProps),
|
||||||
Separator({
|
Separator({
|
||||||
size: .2,
|
size: .2,
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
alpha: .2
|
alpha: .2
|
||||||
} as SeparatorProps),
|
} as SeparatorProps),
|
||||||
new Widget.Button({
|
new Widget.Button({
|
||||||
className: "more",
|
className: "more",
|
||||||
label: "More settings",
|
label: "More settings",
|
||||||
xalign: 0
|
xalign: 0
|
||||||
} as Widget.ButtonProps)
|
} as Widget.ButtonProps)
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps)
|
} as Widget.BoxProps)
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
function DeviceWidget(dev: AstalBluetooth.Device): Gtk.Widget {
|
function DeviceWidget(dev: AstalBluetooth.Device): Gtk.Widget {
|
||||||
return new Widget.Button({
|
return PageButton({
|
||||||
|
className: bind(dev, "connected").as((connected) => connected ? "connected" : ""),
|
||||||
|
title: bind(dev, "alias").as(alias => alias ?? "Unknown Device"),
|
||||||
|
icon: dev.icon ?? "bluetooth-active-symbolic",
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
if(dev.paired) {
|
if(dev.paired) {
|
||||||
dev.connected ?
|
dev.connected ?
|
||||||
@@ -99,46 +123,30 @@ function DeviceWidget(dev: AstalBluetooth.Device): Gtk.Widget {
|
|||||||
dev.disconnect_device(null)
|
dev.disconnect_device(null)
|
||||||
: dev.connect_device(null);
|
: dev.connect_device(null);
|
||||||
},
|
},
|
||||||
className: bind(dev, "connected").as((connected) => connected ? "connected" : ""),
|
endWidget: new Widget.Box({
|
||||||
child: new Widget.Box({
|
visible: bind(dev, "batteryPercentage").as((bat: number) =>
|
||||||
className: "device",
|
bat <= -1 ? false : true),
|
||||||
orientation: Gtk.Orientation.HORIZONTAL,
|
|
||||||
expand: true,
|
|
||||||
children: [
|
children: [
|
||||||
new Widget.Icon({
|
|
||||||
className: "icon",
|
|
||||||
icon: bind(dev, "icon").as((icon: string) =>
|
|
||||||
icon ? icon : "bluetooth-active-symbolic"),
|
|
||||||
css: "font-size: 20px; margin-right: 6px;"
|
|
||||||
} as Widget.IconProps),
|
|
||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
className: "alias",
|
|
||||||
halign: Gtk.Align.START,
|
|
||||||
hexpand: true,
|
|
||||||
label: bind(dev, "alias").as((alias) => alias.split('-').length === 6 ?
|
|
||||||
`Unknown (${alias})` : alias)
|
|
||||||
} as Widget.LabelProps),
|
|
||||||
new Widget.Label({
|
|
||||||
className: "battery",
|
|
||||||
halign: Gtk.Align.END,
|
halign: Gtk.Align.END,
|
||||||
visible: bind(dev, "batteryPercentage").as((bat: number) =>
|
|
||||||
bat <= -1 ? false : true),
|
|
||||||
label: bind(dev, "batteryPercentage").as((bat: number) =>
|
label: bind(dev, "batteryPercentage").as((bat: number) =>
|
||||||
` ${Math.floor(bat * 100)}%`)
|
`${Math.floor(bat * 100)}%`)
|
||||||
} as Widget.LabelProps)
|
} as Widget.LabelProps),
|
||||||
|
new Widget.Icon({
|
||||||
|
icon: "battery-symbolic",
|
||||||
|
css: "font-size: 18px; margin-left: 6px;"
|
||||||
|
} as Widget.IconProps)
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps)
|
} as Widget.BoxProps)
|
||||||
} as Widget.ButtonProps)
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function watchNewDevices(): void {
|
function watchNewDevices(): void {
|
||||||
watchingDevices.set(true);
|
|
||||||
!AstalBluetooth.get_default().adapter.discovering &&
|
!AstalBluetooth.get_default().adapter.discovering &&
|
||||||
AstalBluetooth.get_default().adapter.start_discovery();
|
AstalBluetooth.get_default().adapter.start_discovery();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stopBluetoothDevicesWatch(): void {
|
export function stopBluetoothDevicesWatch(): void {
|
||||||
watchingDevices.set(false);
|
|
||||||
AstalBluetooth.get_default().adapter.discovering &&
|
AstalBluetooth.get_default().adapter.discovering &&
|
||||||
AstalBluetooth.get_default().adapter.stop_discovery();
|
AstalBluetooth.get_default().adapter.stop_discovery();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
import { Page } from "./Page";
|
import { Page, PageButton } from "./Page";
|
||||||
import AstalNetwork from "gi://AstalNetwork";
|
import AstalNetwork from "gi://AstalNetwork";
|
||||||
import { bind } from "astal";
|
import { bind } from "astal";
|
||||||
import NM from "gi://NM";
|
import NM from "gi://NM";
|
||||||
@@ -7,10 +7,11 @@ import { Separator, SeparatorProps } from "../../Separator";
|
|||||||
import { Windows } from "../../../windows";
|
import { Windows } from "../../../windows";
|
||||||
import AstalHyprland from "gi://AstalHyprland?version=0.1";
|
import AstalHyprland from "gi://AstalHyprland?version=0.1";
|
||||||
|
|
||||||
export const PageNetwork = new Page({
|
export const PageNetwork: (() => Page) = () => new Page({
|
||||||
|
id: "network",
|
||||||
title: "Network",
|
title: "Network",
|
||||||
className: "network",
|
className: "network",
|
||||||
headerButtons: () => [
|
headerButtons: [
|
||||||
new Widget.Button({
|
new Widget.Button({
|
||||||
className: "reload nf",
|
className: "reload nf",
|
||||||
label: "",
|
label: "",
|
||||||
@@ -21,107 +22,89 @@ export const PageNetwork = new Page({
|
|||||||
onClick: () => AstalNetwork.get_default().wifi.scan()
|
onClick: () => AstalNetwork.get_default().wifi.scan()
|
||||||
} as Widget.ButtonProps)
|
} as Widget.ButtonProps)
|
||||||
],
|
],
|
||||||
pageChild: () => new Widget.Box({
|
children: [
|
||||||
expand: true,
|
new Widget.Box({
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
className: "devices",
|
||||||
children: [
|
hexpand: true,
|
||||||
new Widget.Box({
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
className: "devices",
|
visible: bind(AstalNetwork.get_default().get_client(), "devices").as((devs) => devs.length > 0),
|
||||||
hexpand: true,
|
children: bind(AstalNetwork.get_default().get_client(), "devices").as((devices) => {
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
devices = devices.filter(dev => dev.interface !== "lo");
|
||||||
visible: bind(AstalNetwork.get_default().get_client(), "devices").as((devs) => devs.length > 0),
|
|
||||||
children: bind(AstalNetwork.get_default().get_client(), "devices").as((devices) => {
|
|
||||||
devices = devices.filter(dev => dev.interface !== "lo");
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
label: "Devices",
|
label: "Devices",
|
||||||
xalign: 0,
|
xalign: 0,
|
||||||
className: "sub-header",
|
className: "sub-header",
|
||||||
} as Widget.LabelProps),
|
} as Widget.LabelProps),
|
||||||
...devices.filter(device => device.real).map(dev => new Widget.Button({
|
...devices.filter(device => device.real).map(dev => PageButton({
|
||||||
className: "device",
|
className: "device",
|
||||||
child: bind(AstalNetwork.get_default(), "client").as((client) => new Widget.Box({
|
icon: bind(dev, "deviceType").as(deviceType =>
|
||||||
children: [
|
deviceType === NM.DeviceType.WIFI ?
|
||||||
new Widget.Icon({
|
"network-wireless-symbolic"
|
||||||
className: "icon",
|
: "network-wired-symbolic"),
|
||||||
icon: bind(dev, "deviceType").as(deviceType =>
|
title: bind(dev, "interface").as(iface => iface ?? "Interface"),
|
||||||
deviceType === NM.DeviceType.WIFI ?
|
extraButtons: [
|
||||||
"network-wireless-symbolic"
|
new Widget.Button({
|
||||||
: "network-wired-symbolic"),
|
image: new Widget.Icon({
|
||||||
css: "font-size: 20px; margin-right: 6px;"
|
icon: "view-more-symbolic"
|
||||||
} as Widget.IconProps),
|
} as Widget.IconProps),
|
||||||
new Widget.Label({
|
onClick: () => {
|
||||||
className: "interface name",
|
Windows.close("control-center");
|
||||||
xalign: 0,
|
AstalHyprland.get_default().dispatch("exec",
|
||||||
hexpand: true,
|
`[animationstyle gnomed; float] nm-connection-editor --edit ${
|
||||||
label: bind(dev, "interface").as(iface => iface ?? "Unknown Interface")
|
dev.activeConnection?.connection.get_uuid()
|
||||||
} as Widget.LabelProps),
|
}`);
|
||||||
new Widget.Icon({
|
}
|
||||||
icon: "object-select-symbolic",
|
} as Widget.ButtonProps)
|
||||||
halign: Gtk.Align.END,
|
|
||||||
visible: bind(client, "primaryConnection").as((primaryConn) =>
|
|
||||||
primaryConn.devices.filter(device => device === dev)?.[0]).as(Boolean)
|
|
||||||
} as Widget.IconProps),
|
|
||||||
new Widget.EventBox({
|
|
||||||
child: new Widget.Icon({
|
|
||||||
icon: "view-more-symbolic"
|
|
||||||
} as Widget.IconProps),
|
|
||||||
onClick: () => {
|
|
||||||
Windows.close("control-center");
|
|
||||||
AstalHyprland.get_default().dispatch("exec",
|
|
||||||
`[animationstyle gnomed] nm-connection-editor --edit ${dev.get_udi()}`);
|
|
||||||
}
|
|
||||||
} as Widget.EventBoxProps)
|
|
||||||
]
|
|
||||||
} as Widget.BoxProps))
|
|
||||||
} as Widget.ButtonProps))
|
|
||||||
]
|
|
||||||
})
|
|
||||||
} as Widget.BoxProps),
|
|
||||||
new Widget.Box({
|
|
||||||
className: "wireless-aps",
|
|
||||||
visible: bind(AstalNetwork.get_default(), "primary").as((primary) => primary === AstalNetwork.Primary.WIFI),
|
|
||||||
hexpand: true,
|
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
|
||||||
children: AstalNetwork.get_default().wifi ? bind(AstalNetwork.get_default().wifi.get_device(), "accessPoints").as((aps) =>
|
|
||||||
aps.map(ap => new Widget.Button({
|
|
||||||
hexpand: true,
|
|
||||||
onClick: () => console.log("connect to " + ap.get_ssid().toArray().toString()), // TODO I don't have a WiFi board :(
|
|
||||||
child: new Widget.Box({
|
|
||||||
hexpand: true,
|
|
||||||
children: [
|
|
||||||
new Widget.Icon({
|
|
||||||
halign: Gtk.Align.START,
|
|
||||||
className: "icon",
|
|
||||||
icon: "network-wireless-signal-excellent-symbolic"
|
|
||||||
} as Widget.IconProps),
|
|
||||||
new Widget.Label({
|
|
||||||
className: "ssid",
|
|
||||||
halign: Gtk.Align.START,
|
|
||||||
label: ap.ssid.toArray().toString()
|
|
||||||
} as Widget.LabelProps),
|
|
||||||
new Widget.Label({
|
|
||||||
className: "status",
|
|
||||||
} as Widget.LabelProps)
|
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps)
|
})
|
||||||
} as Widget.ButtonProps))) : [],
|
)
|
||||||
} as Widget.BoxProps),
|
]
|
||||||
Separator({
|
})
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
} as Widget.BoxProps),
|
||||||
alpha: .2,
|
new Widget.Box({
|
||||||
size: .2
|
className: "wireless-aps",
|
||||||
} as SeparatorProps),
|
visible: bind(AstalNetwork.get_default(), "primary").as((primary) => primary === AstalNetwork.Primary.WIFI),
|
||||||
new Widget.Button({
|
hexpand: true,
|
||||||
label: "More settings",
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
xalign: 0,
|
children: AstalNetwork.get_default().wifi ? bind(AstalNetwork.get_default().wifi.get_device(), "accessPoints").as((aps) =>
|
||||||
onClick: () => {
|
aps.map(ap => new Widget.Button({
|
||||||
Windows.close("control-center");
|
hexpand: true,
|
||||||
AstalHyprland.get_default().dispatch("exec", "[animationstyle gnomed] nm-connection-editor");
|
onClick: () => console.log("connect to " + ap.get_ssid().toArray().toString()), // TODO I don't have a WiFi board :(
|
||||||
}
|
child: new Widget.Box({
|
||||||
} as Widget.ButtonProps)
|
hexpand: true,
|
||||||
]
|
children: [
|
||||||
} as Widget.BoxProps)
|
new Widget.Icon({
|
||||||
|
halign: Gtk.Align.START,
|
||||||
|
className: "icon",
|
||||||
|
icon: "network-wireless-signal-excellent-symbolic"
|
||||||
|
} as Widget.IconProps),
|
||||||
|
new Widget.Label({
|
||||||
|
className: "ssid",
|
||||||
|
halign: Gtk.Align.START,
|
||||||
|
label: ap.ssid.toArray().toString()
|
||||||
|
} as Widget.LabelProps),
|
||||||
|
new Widget.Label({
|
||||||
|
className: "status",
|
||||||
|
} as Widget.LabelProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
} as Widget.ButtonProps))) : [],
|
||||||
|
} as Widget.BoxProps),
|
||||||
|
Separator({
|
||||||
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
alpha: .2,
|
||||||
|
size: .2
|
||||||
|
} as SeparatorProps),
|
||||||
|
new Widget.Button({
|
||||||
|
label: "More settings",
|
||||||
|
xalign: 0,
|
||||||
|
onClick: () => {
|
||||||
|
Windows.close("control-center");
|
||||||
|
AstalHyprland.get_default().dispatch("exec", "[animationstyle gnomed] nm-connection-editor");
|
||||||
|
}
|
||||||
|
} as Widget.ButtonProps)
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,54 +1,50 @@
|
|||||||
import { Gtk, Widget } from "astal/gtk3";
|
import { Widget } from "astal/gtk3";
|
||||||
import { Page, PageProps } from "./Page";
|
import { Page, PageProps } from "./Page";
|
||||||
import { bind } from "astal";
|
import { bind } from "astal";
|
||||||
import { NightLight } from "../../../scripts/nightlight";
|
import { NightLight } from "../../../scripts/nightlight";
|
||||||
import { addSliderMarksFromMinMax } from "../../../scripts/widget-utils";
|
import { addSliderMarksFromMinMax } from "../../../scripts/widget-utils";
|
||||||
|
|
||||||
export const PageNightLight = new Page({
|
export const PageNightLight: (() => Page) = () => new Page({
|
||||||
|
id: "night-light",
|
||||||
title: "Night Light",
|
title: "Night Light",
|
||||||
description: "Control night light and gamma filters",
|
description: "Control night light and gamma filters",
|
||||||
|
className: "night-light",
|
||||||
pageChild: () => new Widget.Box({
|
children: [
|
||||||
hexpand: true,
|
new Widget.Label({
|
||||||
className: "night-light",
|
className: "sub-header",
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
label: "Temperature (blue-light filter)",
|
||||||
children: [
|
xalign: 0
|
||||||
new Widget.Label({
|
} as Widget.LabelProps),
|
||||||
className: "sub-header",
|
new Widget.Slider({
|
||||||
label: "Temperature (blue-light filter)",
|
className: "temperature",
|
||||||
xalign: 0
|
setup: (slider) => {
|
||||||
} as Widget.LabelProps),
|
slider.value = NightLight.getDefault().temperature;
|
||||||
new Widget.Slider({
|
addSliderMarksFromMinMax(slider, 5, "{}K");
|
||||||
className: "temperature",
|
},
|
||||||
setup: (slider) => {
|
value: bind(NightLight.getDefault(), "temperature"),
|
||||||
slider.value = NightLight.getDefault().temperature;
|
tooltipText: bind(NightLight.getDefault(), "temperature").as((temp) => `${temp}K`),
|
||||||
addSliderMarksFromMinMax(slider, 5, "{}K");
|
min: 1000,
|
||||||
},
|
max: bind(NightLight.getDefault(), "maxTemperature"),
|
||||||
value: bind(NightLight.getDefault(), "temperature"),
|
onDragged: (slider) =>
|
||||||
tooltipText: bind(NightLight.getDefault(), "temperature").as((temp) => `${temp}K`),
|
NightLight.getDefault().temperature = (Math.floor(slider.value)),
|
||||||
min: 1000,
|
} as Widget.SliderProps),
|
||||||
max: bind(NightLight.getDefault(), "maxTemperature"),
|
new Widget.Label({
|
||||||
onDragged: (slider) =>
|
className: "sub-header",
|
||||||
NightLight.getDefault().temperature = (Math.floor(slider.value)),
|
label: "Gamma (light filter)",
|
||||||
} as Widget.SliderProps),
|
css: "margin-top: 6px;",
|
||||||
new Widget.Label({
|
xalign: 0
|
||||||
className: "sub-header",
|
} as Widget.LabelProps),
|
||||||
label: "Gamma (light filter)",
|
new Widget.Slider({
|
||||||
css: "margin-top: 6px;",
|
className: "gamma",
|
||||||
xalign: 0
|
setup: (slider) => {
|
||||||
} as Widget.LabelProps),
|
slider.value = NightLight.getDefault().gamma;
|
||||||
new Widget.Slider({
|
addSliderMarksFromMinMax(slider, 5, "{}%");
|
||||||
className: "gamma",
|
},
|
||||||
setup: (slider) => {
|
value: bind(NightLight.getDefault(), "gamma"),
|
||||||
slider.value = NightLight.getDefault().gamma;
|
max: bind(NightLight.getDefault(), "maxGamma"),
|
||||||
addSliderMarksFromMinMax(slider, 5, "{}%");
|
tooltipText: bind(NightLight.getDefault(), "gamma").as((gamma) => `${gamma}%`),
|
||||||
},
|
onDragged: (slider) =>
|
||||||
value: bind(NightLight.getDefault(), "gamma"),
|
NightLight.getDefault().gamma = (Math.floor(slider.value)),
|
||||||
max: bind(NightLight.getDefault(), "maxGamma"),
|
} as Widget.SliderProps)
|
||||||
tooltipText: bind(NightLight.getDefault(), "gamma").as((gamma) => `${gamma}%`),
|
]
|
||||||
onDragged: (slider) =>
|
|
||||||
NightLight.getDefault().gamma = (Math.floor(slider.value)),
|
|
||||||
} as Widget.SliderProps)
|
|
||||||
]
|
|
||||||
} as Widget.BoxProps)
|
|
||||||
} as PageProps);
|
} as PageProps);
|
||||||
|
|||||||
@@ -1,41 +1,39 @@
|
|||||||
import { Binding, GObject, register } from "astal";
|
import { Binding, register } from "astal";
|
||||||
import { Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
|
|
||||||
export type PageProps = {
|
export type PageProps = {
|
||||||
setup?: () => void;
|
setup?: () => void;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
onOpen?: () => void;
|
onOpen?: () => void;
|
||||||
className?: string | Binding<string | undefined>;
|
id: string;
|
||||||
title: string | Binding<string | undefined>;
|
className?: string | Binding<string>;
|
||||||
description?: string | Binding<string | undefined>;
|
title: string | Binding<string>;
|
||||||
headerButtons?: () => Array<Gtk.Widget>;
|
description?: string | Binding<string>;
|
||||||
pageChild: () => Gtk.Widget;
|
headerButtons?: Array<Gtk.Button> | Binding<Array<Gtk.Button>>;
|
||||||
|
orientation?: Gtk.Orientation | Binding<Gtk.Orientation>;
|
||||||
|
child?: Gtk.Widget | Binding<Gtk.Widget>;
|
||||||
|
children?: Array<Gtk.Widget> | Binding<Array<Gtk.Widget>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@register({ GTypeName: "Page" })
|
export { Page };
|
||||||
class Page extends GObject.Object {
|
|
||||||
readonly #props: PageProps;
|
|
||||||
|
|
||||||
get props() { return this.#props; }
|
@register({ GTypeName: "Page" })
|
||||||
|
class Page extends Widget.Box {
|
||||||
|
readonly #id: string;
|
||||||
|
#title: string | Binding<string>;
|
||||||
|
#description: string | undefined | Binding<string>;
|
||||||
|
|
||||||
|
public get title() { return this.#title; }
|
||||||
|
public get description() { return this.#description; }
|
||||||
|
public get id() { return this.#id; }
|
||||||
|
|
||||||
constructor(props: PageProps) {
|
constructor(props: PageProps) {
|
||||||
super();
|
super({
|
||||||
this.#props = props;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getHeaderButtons(): (Array<Gtk.Widget>|null) {
|
|
||||||
return this.props.headerButtons ?
|
|
||||||
this.props.headerButtons()
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getPage(): Gtk.Widget {
|
|
||||||
return new Widget.Box({
|
|
||||||
className: (this.props.className instanceof Binding) ?
|
|
||||||
this.props.className.as((clsName: (string|undefined)) => `page ${ clsName || "" }`) : `page ${this.#props.className || ""}`,
|
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
|
||||||
hexpand: true,
|
hexpand: true,
|
||||||
setup: this.props.setup,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
className: (props.className instanceof Binding) ?
|
||||||
|
props.className.as((clsName) => `page ${ clsName ?? "" }`)
|
||||||
|
: `page ${props.className ?? ""}`,
|
||||||
children: [
|
children: [
|
||||||
new Widget.Box({
|
new Widget.Box({
|
||||||
className: "header",
|
className: "header",
|
||||||
@@ -43,22 +41,24 @@ class Page extends GObject.Object {
|
|||||||
hexpand: true,
|
hexpand: true,
|
||||||
children: [
|
children: [
|
||||||
new Widget.Box({
|
new Widget.Box({
|
||||||
className: "title",
|
className: "top",
|
||||||
children: [
|
children: [
|
||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
hexpand: true,
|
hexpand: true,
|
||||||
className: "title",
|
className: "title",
|
||||||
truncate: true,
|
truncate: true,
|
||||||
visible: (this.props.title instanceof Binding) ?
|
visible: (props.title instanceof Binding) ?
|
||||||
this.props.title.as(Boolean)
|
props.title.as(Boolean)
|
||||||
: (this.props.title ? true : false),
|
: (props.title ? true : false),
|
||||||
label: this.props.title,
|
label: props.title,
|
||||||
halign: Gtk.Align.START
|
halign: Gtk.Align.START
|
||||||
} as Widget.LabelProps),
|
} as Widget.LabelProps),
|
||||||
new Widget.Box({
|
new Widget.Box({
|
||||||
className: "button-row",
|
className: "button-row",
|
||||||
visible: Boolean(this.getHeaderButtons()),
|
visible: (props.headerButtons instanceof Binding) ?
|
||||||
children: this.getHeaderButtons() || undefined
|
props.headerButtons.as(Boolean)
|
||||||
|
: (props.headerButtons ? true : false),
|
||||||
|
children: props.headerButtons
|
||||||
} as Widget.BoxProps)
|
} as Widget.BoxProps)
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps),
|
} as Widget.BoxProps),
|
||||||
@@ -67,22 +67,74 @@ class Page extends GObject.Object {
|
|||||||
hexpand: true,
|
hexpand: true,
|
||||||
truncate: true,
|
truncate: true,
|
||||||
xalign: 0,
|
xalign: 0,
|
||||||
visible: (this.props.description instanceof Binding) ?
|
visible: (props.description instanceof Binding) ?
|
||||||
this.props.description.as(Boolean)
|
props.description.as(Boolean)
|
||||||
: this.props.description ? true : false,
|
: props.description ? true : false,
|
||||||
label: this.props.description
|
label: props.description
|
||||||
} as Widget.LabelProps),
|
} as Widget.LabelProps),
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps),
|
} as Widget.BoxProps),
|
||||||
new Widget.Box({
|
new Widget.Box({
|
||||||
className: "content",
|
className: "content",
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: props.orientation ?? Gtk.Orientation.VERTICAL,
|
||||||
expand: true,
|
expand: true,
|
||||||
setup: (_) => _.add(this.props.pageChild())
|
setup: props.setup,
|
||||||
|
child: props.child,
|
||||||
|
children: props.children
|
||||||
} as Widget.BoxProps)
|
} as Widget.BoxProps)
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps);
|
});
|
||||||
|
|
||||||
|
this.#id = props.id;
|
||||||
|
this.#title = props.title;
|
||||||
|
this.#description = props.description;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Page };
|
export function PageButton(props: {
|
||||||
|
className?: string | Binding<string>;
|
||||||
|
icon?: string | Binding<string>;
|
||||||
|
title: string | Binding<string>;
|
||||||
|
endWidget?: Gtk.Widget;
|
||||||
|
extraButtons?: Array<Widget.Button>;
|
||||||
|
onClick?: (self: Widget.Button) => void;
|
||||||
|
}): Gtk.Widget {
|
||||||
|
return new Widget.Box({
|
||||||
|
setup: (self) => {
|
||||||
|
self.add(new Widget.Button({
|
||||||
|
onClick: props.onClick,
|
||||||
|
className: props.className,
|
||||||
|
hexpand: true,
|
||||||
|
child: new Widget.Box({
|
||||||
|
className: "page-button",
|
||||||
|
orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
expand: true,
|
||||||
|
setup: (box) => {
|
||||||
|
box.set_children([
|
||||||
|
new Widget.Icon({
|
||||||
|
className: "icon",
|
||||||
|
icon: props.icon,
|
||||||
|
visible: props.icon,
|
||||||
|
css: "font-size: 20px; margin-right: 6px;"
|
||||||
|
} as Widget.IconProps),
|
||||||
|
new Widget.Label({
|
||||||
|
className: "title",
|
||||||
|
halign: Gtk.Align.START,
|
||||||
|
hexpand: true,
|
||||||
|
truncate: true,
|
||||||
|
label: props.title
|
||||||
|
} as Widget.LabelProps)
|
||||||
|
]);
|
||||||
|
|
||||||
|
props.endWidget && box.add(props.endWidget);
|
||||||
|
}
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
} as Widget.ButtonProps));
|
||||||
|
|
||||||
|
props.extraButtons && self.add(new Widget.Box({
|
||||||
|
className: "button-row extra-buttons",
|
||||||
|
children: props.extraButtons
|
||||||
|
} as Widget.BoxProps));
|
||||||
|
}
|
||||||
|
} as Widget.BoxProps);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user