Files
flake/modules/wm/ags/misc/popup.js

199 lines
4.1 KiB
JavaScript

// Stollen from https://github.com/Aylur/dotfiles/blob/main/ags/widget/PopupWindow.ts#
/** @typedef {import('../types/widgets/window').WindowProps} WindowProps */
/** @typedef {import('../types/widgets/revealer').RevealerProps} RevealerProps */
/** @typedef {import('../types/widgets/eventbox').EventBoxProps} EventBoxProps */
/** @typedef {import('gi://Gtk?version=3.0')} Gtk */
/**
* @param {string} name
* @param {EventBoxProps}
* @returns {any}
*/
export const Padding = (
name,
{ css = "", hexpand = true, vexpand = true } = {},
) =>
// Widget.Box({});
Widget.EventBox({
hexpand,
vexpand,
can_focus: false,
child: Widget.Box({ css }),
setup: (w) => w.on("button-press-event", () => App.toggleWindow(name)),
});
/**
* @param {string} name
* @param {Child} child
* @param {Transition} [transition="slide_down"]
* @param {number} duration
*/
const PopupRevealer = (
name,
child,
transition = "slide_down",
duration = 500,
) =>
Widget.Box(
{ css: "padding: 1px;" },
Widget.Revealer({
transition,
child: Widget.Box({
class_name: "window-content",
child,
}),
transitionDuration: duration,
setup: (self) =>
self.hook(App, (_, wname, visible) => {
if (wname === name) self.reveal_child = visible;
}),
}),
);
/**
* @param {string} name
* @param {Child} child
* @param {Transition} [transition]
* @param {number} [duration]
* @returns {{ center: () => any; top: () => any; "top-right": () => any; "top-center": () => any; "top-left": () => any; "bottom-left": () => any; "bottom-center": () => any; "bottom-right": () => any; }}
*/
const Layout = (name, child, transition, duration) => ({
center: () =>
Widget.CenterBox(
{},
Padding(name),
Widget.CenterBox(
{ vertical: true },
Padding(name),
PopupRevealer(name, child, transition, duration),
Padding(name),
),
Padding(name),
),
top: () =>
Widget.CenterBox(
{},
Padding(name),
Widget.Box(
{ vertical: true },
PopupRevealer(name, child, transition, duration),
Padding(name),
),
Padding(name),
),
"top-right": () =>
Widget.Box(
{},
Padding(name),
Widget.Box(
{
hexpand: false,
vertical: true,
},
PopupRevealer(name, child, transition, duration),
Padding(name),
),
),
"top-center": () =>
Widget.Box(
{},
Padding(name),
Widget.Box(
{
hexpand: false,
vertical: true,
},
PopupRevealer(name, child, transition, duration),
Padding(name),
),
Padding(name),
),
"top-left": () =>
Widget.Box(
{},
Widget.Box(
{
hexpand: false,
vertical: true,
},
PopupRevealer(name, child, transition, duration),
Padding(name),
),
Padding(name),
),
"bottom-left": () =>
Widget.Box(
{},
Widget.Box(
{
hexpand: false,
vertical: true,
},
Padding(name),
PopupRevealer(name, child, transition, duration),
),
Padding(name),
),
"bottom-center": () =>
Widget.Box(
{},
Padding(name),
Widget.Box(
{
hexpand: false,
vertical: true,
},
Padding(name),
PopupRevealer(name, child, transition, duration),
),
Padding(name),
),
"bottom-right": () =>
Widget.Box(
{},
Padding(name),
Widget.Box(
{
hexpand: false,
vertical: true,
},
Padding(name),
PopupRevealer(name, child, transition, duration),
),
),
});
/** @typedef {RevealerProps["transition"]} Transition */
/** @typedef {WindowProps["child"]} Child */
/**
* @typedef {Omit<WindowProps, "name"> & {
* name: string
* layout?: keyof ReturnType<typeof Layout>
* transition?: Transition,
* duration?: number
* }} PopupWindowProps
* @param {PopupWindowProps} props
*/
export default ({
name,
child,
layout = "center",
transition,
exclusivity = "ignore",
duration,
...props
}) =>
Widget.Window({
name,
class_names: [name, "popup-window"],
setup: (w) => w.keybind("Escape", () => App.closeWindow(name)),
visible: false,
keymode: "on-demand",
exclusivity,
layer: "top",
// anchor: ["top", "right"],
anchor: ["top", "bottom", "right", "left"],
child: Layout(name, child, transition, duration)[layout](),
...props,
});