summaryrefslogtreecommitdiff
path: root/src/widgets
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-26 22:36:23 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-26 22:36:23 +1000
commit3c579d0e275cdaf6f2c9589abade94bde7905c82 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/widgets
parentschemes: fix (diff)
downloadcaelestia-shell-3c579d0e275cdaf6f2c9589abade94bde7905c82.tar.gz
caelestia-shell-3c579d0e275cdaf6f2c9589abade94bde7905c82.tar.bz2
caelestia-shell-3c579d0e275cdaf6f2c9589abade94bde7905c82.zip
clean
Remove everything
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/notification.tsx179
-rw-r--r--src/widgets/popupwindow.ts75
-rw-r--r--src/widgets/screencorner.tsx49
-rw-r--r--src/widgets/slider.tsx64
4 files changed, 0 insertions, 367 deletions
diff --git a/src/widgets/notification.tsx b/src/widgets/notification.tsx
deleted file mode 100644
index 0dfd368..0000000
--- a/src/widgets/notification.tsx
+++ /dev/null
@@ -1,179 +0,0 @@
-import { desktopEntrySubs } from "@/utils/icons";
-import Thumbnailer from "@/utils/thumbnailer";
-import { setupCustomTooltip } from "@/utils/widgets";
-import { bind, GLib, register, timeout, Variable } from "astal";
-import { Astal, Gtk, Widget } from "astal/gtk3";
-import { notifpopups as config } from "config";
-import AstalNotifd from "gi://AstalNotifd";
-
-const urgencyToString = (urgency: AstalNotifd.Urgency) => {
- switch (urgency) {
- case AstalNotifd.Urgency.LOW:
- return "low";
- case AstalNotifd.Urgency.NORMAL:
- return "normal";
- case AstalNotifd.Urgency.CRITICAL:
- return "critical";
- }
-};
-
-const getTime = (time: number) => {
- const messageTime = GLib.DateTime.new_from_unix_local(time);
- const now = GLib.DateTime.new_now_local();
- const todayDay = now.get_day_of_year();
-
- if (config.agoTime.get()) {
- const diff = now.difference(messageTime) / 1e6;
- if (diff < 60) return "Now";
- if (diff < 3600) {
- const d = Math.floor(diff / 60);
- return `${d} min${d === 1 ? "" : "s"} ago`;
- }
- if (diff < 86400) {
- const d = Math.floor(diff / 3600);
- return `${d} hour${d === 1 ? "" : "s"} ago`;
- }
- } else if (messageTime.get_day_of_year() === todayDay) {
- const aMinuteAgo = GLib.DateTime.new_now_local().add_seconds(-60);
- return aMinuteAgo !== null && messageTime.compare(aMinuteAgo) > 0 ? "Now" : messageTime.format("%H:%M")!;
- }
-
- if (messageTime.get_day_of_year() === todayDay - 1) return "Yesterday";
- return messageTime.format("%d/%m")!;
-};
-
-const AppIcon = ({ appIcon, desktopEntry }: { appIcon: string; desktopEntry: string }) => {
- // Try app icon
- let icon = Astal.Icon.lookup_icon(appIcon) && appIcon;
- // Try desktop entry
- if (!icon) {
- if (desktopEntrySubs.hasOwnProperty(desktopEntry)) icon = desktopEntrySubs[desktopEntry];
- else if (Astal.Icon.lookup_icon(desktopEntry)) icon = desktopEntry;
- }
- return icon ? <icon className="app-icon" icon={icon} /> : null;
-};
-
-const Image = ({ compact, icon }: { compact?: boolean; icon: string }) => {
- if (GLib.file_test(icon, GLib.FileTest.EXISTS))
- return (
- <box
- valign={Gtk.Align.START}
- className={`image ${compact ? "small" : ""}`}
- setup={self =>
- Thumbnailer.thumbnail(icon)
- .then(p => (self.css = `background-image: url("${p}");`))
- .catch(console.error)
- }
- />
- );
- if (Astal.Icon.lookup_icon(icon))
- return <icon valign={Gtk.Align.START} className={`image ${compact ? "small" : ""}`} icon={icon} />;
- return null;
-};
-
-@register()
-export default class Notification extends Widget.Box {
- readonly #revealer;
- #destroyed = false;
-
- constructor({
- notification,
- popup,
- compact = popup,
- }: {
- notification: AstalNotifd.Notification;
- popup?: boolean;
- compact?: boolean;
- }) {
- super({ className: "notification" });
-
- const time = Variable(getTime(notification.time)).poll(60000, () => getTime(notification.time));
- this.hook(config.agoTime, () => time.set(getTime(notification.time)));
-
- this.#revealer = (
- <revealer
- revealChild={popup}
- transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN}
- transitionDuration={150}
- >
- <box className="wrapper">
- <box vertical className={`inner ${urgencyToString(notification.urgency)}`}>
- <box className="header">
- <AppIcon appIcon={notification.appIcon} desktopEntry={notification.appName} />
- <label className="app-name" label={notification.appName ?? "Unknown"} />
- <box hexpand />
- <label className="time" label={bind(time)} onDestroy={() => time.drop()} />
- </box>
- <box hexpand className="separator" />
- <box className="content">
- {notification.image && <Image compact={compact} icon={notification.image} />}
- <box vertical>
- <label className="summary" xalign={0} label={notification.summary} truncate />
- {notification.body && (
- <label
- className="body"
- xalign={0}
- label={compact ? notification.body.split("\n")[0] : notification.body}
- wrap
- lines={compact ? 1 : -1}
- truncate={compact}
- setup={self => compact && !popup && setupCustomTooltip(self, notification.body)}
- />
- )}
- </box>
- </box>
- {!popup && (
- <box className="actions">
- <button
- hexpand
- cursor="pointer"
- onClicked={() => notification.dismiss()}
- label="Close"
- />
- {notification.actions.map(a => (
- <button hexpand cursor="pointer" onClicked={() => notification.invoke(a.id)}>
- {notification.actionIcons ? <icon icon={a.label} /> : a.label}
- </button>
- ))}
- </box>
- )}
- </box>
- </box>
- </revealer>
- ) as Widget.Revealer;
- this.add(this.#revealer);
-
- // Init animation
- const width = this.get_preferred_width()[1];
- if (popup) this.css = `margin-left: ${width}px; margin-right: -${width}px;`;
- timeout(1, () => {
- this.#revealer.revealChild = true;
- this.css = `transition: 300ms cubic-bezier(0.05, 0.9, 0.1, 1.1); margin-left: 0; margin-right: 0;`;
- });
-
- // Close popup after timeout if transient or expire enabled in config
- if (popup && (config.expire.get() || notification.transient))
- timeout(
- notification.expireTimeout > 0
- ? notification.expireTimeout
- : notification.urgency === AstalNotifd.Urgency.CRITICAL
- ? 10000
- : 5000,
- () => this.destroyWithAnims()
- );
- }
-
- destroyWithAnims() {
- if (this.#destroyed) return;
- this.#destroyed = true;
-
- const animTime = 120;
- const animMargin = this.get_allocated_width();
- this.css = `transition: ${animTime}ms cubic-bezier(0.85, 0, 0.15, 1);
- margin-left: ${animMargin}px; margin-right: -${animMargin}px;`;
- timeout(animTime, () => {
- this.#revealer.revealChild = false;
- timeout(this.#revealer.transitionDuration, () => this.destroy());
- });
- }
-}
diff --git a/src/widgets/popupwindow.ts b/src/widgets/popupwindow.ts
deleted file mode 100644
index 5ffa061..0000000
--- a/src/widgets/popupwindow.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { Binding, register } from "astal";
-import { App, Astal, Gdk, Widget } from "astal/gtk3";
-import { bar } from "config";
-import AstalHyprland from "gi://AstalHyprland";
-
-const extendProp = <T>(
- prop: T | Binding<T | undefined> | undefined,
- override: (prop: T | undefined) => T | undefined
-) => prop && (prop instanceof Binding ? prop.as(override) : override(prop));
-
-@register()
-export default class PopupWindow extends Widget.Window {
- constructor(props: Widget.WindowProps) {
- super({
- keymode: Astal.Keymode.ON_DEMAND,
- borderWidth: 20, // To allow shadow, cause if not it gets cut off
- ...props,
- visible: false,
- application: App,
- name: props.monitor ? extendProp(props.name, n => (n ? n + props.monitor : undefined)) : props.name,
- namespace: extendProp(props.name, n => `caelestia-${n}`),
- onKeyPressEvent: (self, event) => {
- // Close window on escape
- if (event.get_keyval()[1] === Gdk.KEY_Escape) self.hide();
-
- return props.onKeyPressEvent?.(self, event);
- },
- });
- }
-
- popup_at_widget(widget: JSX.Element, event: Gdk.Event | Astal.ClickEvent) {
- const { width, height } = widget.get_allocation();
- const { width: mWidth, height: mHeight } = AstalHyprland.get_default().get_focused_monitor();
- const pWidth = this.get_preferred_width()[1];
- const pHeight = this.get_preferred_height()[1];
- const [, x, y] = event instanceof Gdk.Event ? event.get_coords() : [null, event.x, event.y];
- const { x: cx, y: cy } = AstalHyprland.get_default().get_cursor_position();
-
- let marginLeft = 0;
- let marginTop = 0;
- if (bar.vertical.get()) {
- marginLeft = cx + (width - x);
- marginTop = cy + ((height - pHeight) / 2 - y);
- if (marginTop < 0) marginTop = 0;
- else if (marginTop + pHeight > mHeight) marginTop = mHeight - pHeight;
- } else {
- marginLeft = cx + ((width - pWidth) / 2 - x);
- if (marginLeft < 0) marginLeft = 0;
- else if (marginLeft + pWidth > mWidth) marginLeft = mWidth - pWidth;
- marginTop = cy + (height - y);
- }
-
- this.anchor = Astal.WindowAnchor.TOP | Astal.WindowAnchor.LEFT;
- this.exclusivity = Astal.Exclusivity.IGNORE;
- this.marginLeft = marginLeft;
- this.marginTop = marginTop;
-
- this.show();
- }
-
- popup_at_corner(corner: `${"top" | "bottom"} ${"left" | "right"}`) {
- let anchor = 0;
- if (corner.includes("top")) anchor |= Astal.WindowAnchor.TOP;
- else anchor |= Astal.WindowAnchor.BOTTOM;
- if (corner.includes("left")) anchor |= Astal.WindowAnchor.LEFT;
- else anchor |= Astal.WindowAnchor.RIGHT;
-
- this.anchor = anchor;
- this.exclusivity = Astal.Exclusivity.NORMAL;
- this.marginLeft = 0;
- this.marginTop = 0;
-
- this.show();
- }
-}
diff --git a/src/widgets/screencorner.tsx b/src/widgets/screencorner.tsx
deleted file mode 100644
index a55d782..0000000
--- a/src/widgets/screencorner.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import type { Binding } from "astal";
-import { Gtk, type Widget } from "astal/gtk3";
-import type cairo from "cairo";
-
-type Place = "topleft" | "topright" | "bottomleft" | "bottomright";
-
-export default ({ place, ...rest }: Widget.DrawingAreaProps & { place: Place | Binding<Place> }) => (
- <drawingarea
- {...rest}
- className="screen-corner"
- setup={self => {
- self.connect("realize", () => self.get_window()?.set_pass_through(true));
-
- const r = self.get_style_context().get_property("border-radius", Gtk.StateFlags.NORMAL) as number;
- self.set_size_request(r, r);
- self.connect("draw", (_, cr: cairo.Context) => {
- const c = self.get_style_context().get_background_color(Gtk.StateFlags.NORMAL);
- const r = self.get_style_context().get_property("border-radius", Gtk.StateFlags.NORMAL) as number;
- self.set_size_request(r, r);
-
- switch (typeof place === "string" ? place : place.get()) {
- case "topleft":
- cr.arc(r, r, r, Math.PI, (3 * Math.PI) / 2);
- cr.lineTo(0, 0);
- break;
-
- case "topright":
- cr.arc(0, r, r, (3 * Math.PI) / 2, 2 * Math.PI);
- cr.lineTo(r, 0);
- break;
-
- case "bottomleft":
- cr.arc(r, 0, r, Math.PI / 2, Math.PI);
- cr.lineTo(0, r);
- break;
-
- case "bottomright":
- cr.arc(0, 0, r, 0, Math.PI / 2);
- cr.lineTo(r, r);
- break;
- }
-
- cr.closePath();
- cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
- cr.fill();
- });
- }}
- />
-);
diff --git a/src/widgets/slider.tsx b/src/widgets/slider.tsx
deleted file mode 100644
index 0a66609..0000000
--- a/src/widgets/slider.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import { bind, type Binding } from "astal";
-import { Gdk, Gtk, type Widget } from "astal/gtk3";
-import type cairo from "cairo";
-
-export default ({
- value,
- onChange,
-}: {
- value: Binding<number>;
- onChange?: (self: Widget.DrawingArea, value: number) => void;
-}) => (
- <drawingarea
- hexpand
- valign={Gtk.Align.CENTER}
- className="slider"
- css={bind(value).as(v => `font-size: ${Math.min(1, Math.max(0, v))}px;`)}
- setup={self => {
- const halfPi = Math.PI / 2;
-
- const styleContext = self.get_style_context();
- self.set_size_request(-1, styleContext.get_property("min-height", Gtk.StateFlags.NORMAL) as number);
-
- self.connect("draw", (_, cr: cairo.Context) => {
- const styleContext = self.get_style_context();
-
- const width = self.get_allocated_width();
- const height = styleContext.get_property("min-height", Gtk.StateFlags.NORMAL) as number;
- self.set_size_request(-1, height);
-
- const progressValue = styleContext.get_property("font-size", Gtk.StateFlags.NORMAL) as number;
- let radius = styleContext.get_property("border-radius", Gtk.StateFlags.NORMAL) as number;
-
- const bg = styleContext.get_background_color(Gtk.StateFlags.NORMAL);
- cr.setSourceRGBA(bg.red, bg.green, bg.blue, bg.alpha);
-
- // Background
- cr.arc(radius, radius, radius, -Math.PI, -halfPi); // Top left
- cr.arc(width - radius, radius, radius, -halfPi, 0); // Top right
- cr.arc(width - radius, height - radius, radius, 0, halfPi); // Bottom right
- cr.arc(radius, height - radius, radius, halfPi, Math.PI); // Bottom left
- cr.fill();
-
- // Flatten when near 0
- radius = Math.min(radius, Math.min(width * progressValue, height) / 2);
-
- const progressPosition = width * progressValue - radius;
- const fg = styleContext.get_color(Gtk.StateFlags.NORMAL);
- cr.setSourceRGBA(fg.red, fg.green, fg.blue, fg.alpha);
-
- // Foreground
- cr.arc(radius, radius, radius, -Math.PI, -halfPi); // Top left
- cr.arc(progressPosition, radius, radius, -halfPi, 0); // Top right
- cr.arc(progressPosition, height - radius, radius, 0, halfPi); // Bottom right
- cr.arc(radius, height - radius, radius, halfPi, Math.PI); // Bottom left
- cr.fill();
- });
-
- self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK);
- self.connect("button-press-event", (_, event: Gdk.Event) =>
- onChange?.(self, event.get_coords()[1] / self.get_allocated_width())
- );
- }}
- />
-);