feat(control-center/page): add bottom-buttons prop to add page-bottom buttons easily

also, no need for widgets, you just use a jsobject to create a button inside the prop array
This commit is contained in:
retrozinndev
2025-05-25 14:55:37 -03:00
parent 73b2e96c93
commit a25468e54a
4 changed files with 114 additions and 41 deletions
+8 -17
View File
@@ -2,7 +2,6 @@ import { bind, Variable } from "astal";
import { Gtk, Widget } from "astal/gtk3";
import AstalBluetooth from "gi://AstalBluetooth";
import { Page, PageButton } from "./Page";
import { Separator, SeparatorProps } from "../../Separator";
import { tr } from "../../../i18n/intl";
import AstalHyprland from "gi://AstalHyprland";
import { Windows } from "../../../windows";
@@ -33,6 +32,13 @@ export const BluetoothPage: (() => Page) = () => new Page({
],
onClose: () => AstalBluetooth.get_default().adapter.discovering &&
AstalBluetooth.get_default().adapter.stop_discovery(),
bottomButtons: [{
title: tr("control_center.pages.more_settings"),
onClick: () => {
Windows.close("control-center");
AstalHyprland.get_default().dispatch("exec", "[float; animation slide right] overskride");
}
}],
spacing: 2,
children: [
new Widget.Box({
@@ -98,22 +104,7 @@ export const BluetoothPage: (() => Page) = () => new Page({
...discoveredDevices.map((dev: AstalBluetooth.Device) => DeviceWidget(dev))
]
})
} as Widget.BoxProps),
Separator({
size: .2,
orientation: Gtk.Orientation.VERTICAL,
cssColor: "gray",
alpha: .2
} as SeparatorProps),
new Widget.Button({
className: "more",
label: tr("control_center.pages.more_settings"),
onClick: () => {
Windows.close("control-center");
AstalHyprland.get_default().dispatch("exec", "[float; animation slide right] overskride");
},
setup: (self) => self.set_alignment(0, 0.5)
} as Widget.ButtonProps)
} as Widget.BoxProps)
]
} as Widget.BoxProps)
]
+9 -16
View File
@@ -3,9 +3,8 @@ import { Page, PageButton } from "./Page";
import AstalNetwork from "gi://AstalNetwork";
import { bind } from "astal";
import NM from "gi://NM";
import { Separator, SeparatorProps } from "../../Separator";
import { Windows } from "../../../windows";
import AstalHyprland from "gi://AstalHyprland?version=0.1";
import AstalHyprland from "gi://AstalHyprland";
import { tr } from "../../../i18n/intl";
export const PageNetwork: (() => Page) = () => new Page({
@@ -23,6 +22,13 @@ export const PageNetwork: (() => Page) = () => new Page({
onClick: () => AstalNetwork.get_default().wifi.scan()
} as Widget.ButtonProps)
],
bottomButtons: [{
title: tr("control_center.pages.more_settings"),
onClick: () => {
Windows.close("control-center");
AstalHyprland.get_default().dispatch("exec", "[animationstyle gnomed] nm-connection-editor");
}
}],
children: [
new Widget.Box({
className: "devices",
@@ -93,20 +99,7 @@ export const PageNetwork: (() => Page) = () => new Page({
]
} as Widget.BoxProps)
} as Widget.ButtonProps))) : [],
} as Widget.BoxProps),
Separator({
orientation: Gtk.Orientation.VERTICAL,
alpha: .2,
size: .2
} as SeparatorProps),
new Widget.Button({
label: tr("control_center.pages.more_settings"),
setup: (self) => self.set_alignment(0, 0.5),
onClick: () => {
Windows.close("control-center");
AstalHyprland.get_default().dispatch("exec", "[animationstyle gnomed] nm-connection-editor");
}
} as Widget.ButtonProps)
} as Widget.BoxProps)
]
});
+83 -3
View File
@@ -1,32 +1,44 @@
import { Binding, register } from "astal";
import { Gtk, Widget } from "astal/gtk3";
import { Separator, SeparatorProps } from "../../Separator";
export type PageProps = {
setup?: () => void;
onClose?: () => void;
onOpen?: () => void;
id: string;
className?: string | Binding<string>;
title: string | Binding<string>;
description?: string | Binding<string>;
headerButtons?: Array<Gtk.Button> | Binding<Array<Gtk.Button>>;
bottomButtons?: Array<BottomButton> | Binding<Array<BottomButton>>;
orientation?: Gtk.Orientation | Binding<Gtk.Orientation>;
spacing?: number;
child?: Gtk.Widget | Binding<Gtk.Widget>;
children?: Array<Gtk.Widget> | Binding<Array<Gtk.Widget>>;
};
export type BottomButton = {
title: string | Binding<string>;
description?: string | Binding<string>;
tooltipText?: string | Binding<string>;
tooltipMarkup?: string | Binding<string>;
onClick?: () => void;
};
export { Page };
@register({ GTypeName: "Page" })
class Page extends Widget.Box {
readonly #id: string;
readonly #id: string | number;
readonly bottomButtons?: Array<BottomButton>;
#title: string | Binding<string>;
#description: string | undefined | Binding<string>;
#description?: string | Binding<string>;
public get title() { return this.#title; }
public get description() { return this.#description; }
public get id() { return this.#id; }
public onClose?: () => void;
constructor(props: PageProps) {
super({
@@ -35,6 +47,7 @@ class Page extends Widget.Box {
className: (props.className instanceof Binding) ?
props.className.as((clsName) => `page ${ clsName ?? "" }`)
: `page ${props.className ?? ""}`,
setup: props.setup,
children: [
new Widget.Box({
className: "header",
@@ -83,6 +96,70 @@ class Page extends Widget.Box {
setup: props.setup,
child: props.child,
children: props.children
} as Widget.BoxProps),
Separator({
alpha: .2,
spacing: 6,
orientation: Gtk.Orientation.VERTICAL,
visible: (props.bottomButtons instanceof Binding) ?
props.bottomButtons.as(buttons => buttons.length > 0)
: (!props.bottomButtons ? false : props.bottomButtons.length > 0)
} as SeparatorProps),
new Widget.Box({
className: "bottom-buttons",
orientation: Gtk.Orientation.VERTICAL,
visible: (props.bottomButtons instanceof Binding) ?
props.bottomButtons.as(buttons => buttons.length > 0)
: (!props.bottomButtons ? false : props.bottomButtons.length > 0),
spacing: 2,
children: (props.bottomButtons instanceof Binding) ?
props.bottomButtons.as(buttons => buttons.map(button =>
new Widget.Button({
onClicked: button.onClick,
tooltipMarkup: button.tooltipMarkup,
tooltipText: button.tooltipText,
child: new Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
children: [
new Widget.Label({
className: "title",
label: button.title,
xalign: 0
} as Widget.LabelProps),
new Widget.Label({
className: "description",
label: button.description,
visible: Boolean(button.description),
xalign: 0
} as Widget.LabelProps)
]
} as Widget.BoxProps)
} as Widget.ButtonProps)
)
)
: (!props.bottomButtons ? [] : props.bottomButtons.map(button =>
new Widget.Button({
onClicked: button.onClick,
tooltipMarkup: button.tooltipMarkup,
tooltipText: button.tooltipText,
child: new Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
children: [
new Widget.Label({
className: "title",
label: button.title,
xalign: 0
} as Widget.LabelProps),
new Widget.Label({
className: "description",
label: button.description,
visible: Boolean(button.description),
xalign: 0
} as Widget.LabelProps)
]
} as Widget.BoxProps)
} as Widget.ButtonProps)
))
} as Widget.BoxProps)
]
});
@@ -90,6 +167,9 @@ class Page extends Widget.Box {
this.#id = props.id;
this.#title = props.title;
this.#description = props.description;
if(props.onClose)
this.onClose = props.onClose;
}
}