From a25468e54af6e90554fb4863271db0b2d873bac5 Mon Sep 17 00:00:00 2001 From: retrozinndev Date: Sun, 25 May 2025 14:55:37 -0300 Subject: [PATCH] :sparkles: 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 --- ags/style/_control-center.scss | 19 +++-- ags/widget/control-center/pages/Bluetooth.ts | 25 ++---- ags/widget/control-center/pages/Network.ts | 25 ++---- ags/widget/control-center/pages/Page.ts | 86 +++++++++++++++++++- 4 files changed, 114 insertions(+), 41 deletions(-) diff --git a/ags/style/_control-center.scss b/ags/style/_control-center.scss index 1680818..9b2c939 100644 --- a/ags/style/_control-center.scss +++ b/ags/style/_control-center.scss @@ -121,7 +121,7 @@ & .sub-header { font-size: 14px; font-weight: 500; - margin-bottom: 6px; + margin-bottom: 4px; } & button { @@ -135,6 +135,19 @@ } } + & .bottom-buttons button { + & label.title { + font-size: 14px; + font-weight: 500; + } + & label.description { + font-size: 10px; + margin-top: -1px; + font-weight: 400; + color: colors.$fg-disabled; + } + } + & .extra-buttons { margin-left: 2px; & > button { @@ -251,10 +264,6 @@ box.history { button.connected { background: colors.$bg-tertiary; } - - &.paired { - margin-bottom: 20px; - } } } diff --git a/ags/widget/control-center/pages/Bluetooth.ts b/ags/widget/control-center/pages/Bluetooth.ts index 3980915..8a2defc 100644 --- a/ags/widget/control-center/pages/Bluetooth.ts +++ b/ags/widget/control-center/pages/Bluetooth.ts @@ -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) ] diff --git a/ags/widget/control-center/pages/Network.ts b/ags/widget/control-center/pages/Network.ts index e7432f4..efd62ee 100644 --- a/ags/widget/control-center/pages/Network.ts +++ b/ags/widget/control-center/pages/Network.ts @@ -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) ] }); diff --git a/ags/widget/control-center/pages/Page.ts b/ags/widget/control-center/pages/Page.ts index 33f673c..3016b48 100644 --- a/ags/widget/control-center/pages/Page.ts +++ b/ags/widget/control-center/pages/Page.ts @@ -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; title: string | Binding; description?: string | Binding; headerButtons?: Array | Binding>; + bottomButtons?: Array | Binding>; orientation?: Gtk.Orientation | Binding; spacing?: number; child?: Gtk.Widget | Binding; children?: Array | Binding>; }; +export type BottomButton = { + title: string | Binding; + description?: string | Binding; + tooltipText?: string | Binding; + tooltipMarkup?: string | Binding; + onClick?: () => void; +}; + export { Page }; @register({ GTypeName: "Page" }) class Page extends Widget.Box { - readonly #id: string; + readonly #id: string | number; + readonly bottomButtons?: Array; + #title: string | Binding; - #description: string | undefined | Binding; + #description?: string | Binding; 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; } }