From 67ab932ee266b0074b3affbe0d205f242618a8c9 Mon Sep 17 00:00:00 2001 From: retrozinndev Date: Mon, 21 Apr 2025 17:49:04 -0300 Subject: [PATCH] :sparkles: ags(custom-dialog): added new dialog window function this function gives more options to create customized dialogs with: - custom options - title - text - extra GtkWidgets inside dialog - align options horizontally(default) or vertically --- ags/widget/CustomDialog.ts | 106 +++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 ags/widget/CustomDialog.ts diff --git a/ags/widget/CustomDialog.ts b/ags/widget/CustomDialog.ts new file mode 100644 index 0000000..4df6d66 --- /dev/null +++ b/ags/widget/CustomDialog.ts @@ -0,0 +1,106 @@ +import { Binding } from "astal"; +import { Astal, Gtk, Widget } from "astal/gtk3"; +import { Windows } from "../windows"; +import { PopupWindow, PopupWindowProps } from "./PopupWindow"; +import { Separator } from "./Separator"; +import { tr } from "../i18n/intl"; + +export type CustomDialogProps = { + namespace?: string | Binding; + className?: string | Binding; + cssBackground?: string; + title?: string | Binding; + text?: string | Binding; + heightRequest?: number | Binding; + widthRequest?: number | Binding; + childOrientation?: Gtk.Orientation | Binding; + children?: Array | Binding>; + child?: Gtk.Widget | Binding; + onFinish?: () => void; + options?: Array; + optionsOrientation?: Gtk.Orientation | Binding; +}; + +export interface CustomDialogOption { + onClick?: () => void; + text: string | Binding; + closeOnClick?: boolean | Binding; +} + +export function CustomDialog(props: CustomDialogProps = { + options: [{ text: tr("accept") }] +}): Widget.Window { + const window = Windows.createWindowForFocusedMonitor((mon: number) => PopupWindow({ + namespace: props.namespace ?? "custom-dialog", + monitor: mon, + cssBackgroundWindow: props.cssBackground ?? "background: rgba(0, 0, 0, .3);", + exclusivity: Astal.Exclusivity.IGNORE, + layer: Astal.Layer.OVERLAY, + widthRequest: props.widthRequest ?? 400, + heightRequest: props.heightRequest ?? 220, + onDestroy: props.onFinish, + child: new Widget.Box({ + className: props.className ?? "custom-dialog-container", + orientation: Gtk.Orientation.VERTICAL, + children: [ + new Widget.Label({ + className: "title", + visible: props.title, + label: props.title + } as Widget.LabelProps), + new Widget.Label({ + className: "text", + visible: props.text, + label: props.text, + yalign: 0, + expand: true + } as Widget.LabelProps), + new Widget.Box({ + className: "custom-children custom-child", + visible: props.children || props.child, + orientation: props.childOrientation ?? Gtk.Orientation.VERTICAL, + children: props.children, + child: props.child + } as Widget.BoxProps), + Separator({ + alpha: .2, + visible: props.options && props.options.length > 0, + orientation: Gtk.Orientation.VERTICAL + }), + new Widget.Box({ + className: "options", + orientation: props.optionsOrientation ?? Gtk.Orientation.HORIZONTAL, + hexpand: true, + heightRequest: 38, + homogeneous: true, + children: props.options && props.options.map(option => { + const onClick = () => { + option.onClick?.(); + (option.closeOnClick ?? true) && + window.close(); + }; + const connections: Array = []; + const btn = new Widget.Button({ + className: "option", + label: option.text, + hexpand: true, + setup: (self) => { + connections.push( + self.connect("click-release", (_, event: Astal.ClickEvent) => + event.button === Astal.MouseButton.PRIMARY && + onClick()), + self.connect("activate", (_) => onClick()) + ); + }, + onDestroy: (self) => connections.map(id => self.disconnect(id)) + } as Widget.ButtonProps); + + return btn; + }) + } as Widget.BoxProps) + ] + } as Widget.BoxProps) + } as PopupWindowProps))(); + + return window; +}