From 8e00ed94760379ccba1ca04c8bcd069afaf30484 Mon Sep 17 00:00:00 2001 From: Aylur Date: Thu, 16 Jan 2025 18:18:36 +0100 Subject: add: OSD ts example #195 --- examples/gtk3/js/osd/README.md | 7 ++++ examples/gtk3/js/osd/app.ts | 11 ++++++ examples/gtk3/js/osd/osd/OSD.scss | 30 +++++++++++++++ examples/gtk3/js/osd/osd/OSD.tsx | 69 ++++++++++++++++++++++++++++++++++ examples/gtk3/js/osd/osd/brightness.ts | 45 ++++++++++++++++++++++ examples/gtk3/js/osd/style.scss | 1 + 6 files changed, 163 insertions(+) create mode 100644 examples/gtk3/js/osd/README.md create mode 100644 examples/gtk3/js/osd/app.ts create mode 100644 examples/gtk3/js/osd/osd/OSD.scss create mode 100644 examples/gtk3/js/osd/osd/OSD.tsx create mode 100644 examples/gtk3/js/osd/osd/brightness.ts create mode 100644 examples/gtk3/js/osd/style.scss (limited to 'examples/gtk3/js') diff --git a/examples/gtk3/js/osd/README.md b/examples/gtk3/js/osd/README.md new file mode 100644 index 0000000..ee1d497 --- /dev/null +++ b/examples/gtk3/js/osd/README.md @@ -0,0 +1,7 @@ +# On Screen Display + +![osd](https://github.com/user-attachments/assets/08e0e118-6b07-4cac-8ebc-08262594cee7) + +A simple widget that pops up when screen brightness or audio changes + +Uses the [WirePlumber library](https://aylur.github.io/astal/guide/libraries/wireplumber). diff --git a/examples/gtk3/js/osd/app.ts b/examples/gtk3/js/osd/app.ts new file mode 100644 index 0000000..50e314e --- /dev/null +++ b/examples/gtk3/js/osd/app.ts @@ -0,0 +1,11 @@ +import { App } from "astal/gtk3" +import style from "./style.scss" +import OSD from "./osd/OSD" + +App.start({ + instanceName: "osd-example", + css: style, + main() { + App.get_monitors().map(OSD) + }, +}) diff --git a/examples/gtk3/js/osd/osd/OSD.scss b/examples/gtk3/js/osd/osd/OSD.scss new file mode 100644 index 0000000..d0fe4d1 --- /dev/null +++ b/examples/gtk3/js/osd/osd/OSD.scss @@ -0,0 +1,30 @@ +$fg-color: #{"@theme_fg_color"}; +$bg-color: #{"@theme_bg_color"}; + +window.OSD { + box.OSD { + border-radius: 100px; + background-color: $bg-color; + padding: 13px 16px; + margin: 13px; + box-shadow: 3px 3px 7px 0 rgba(0,0,0,.4); + } + + icon { + font-size: 4rem; + } + + label { + font-size: 2.4rem; + } + + levelbar { + trough { + margin: 1 .6rem; + } + + block { + min-height: 2rem; + } + } +} diff --git a/examples/gtk3/js/osd/osd/OSD.tsx b/examples/gtk3/js/osd/osd/OSD.tsx new file mode 100644 index 0000000..df28da5 --- /dev/null +++ b/examples/gtk3/js/osd/osd/OSD.tsx @@ -0,0 +1,69 @@ +import { App, Astal, Gdk, Gtk } from "astal/gtk3" +import { timeout } from "astal/time" +import Variable from "astal/variable" +import Brightness from "./brightness" +import Wp from "gi://AstalWp" + +function OnScreenProgress({ visible }: { visible: Variable }) { + const brightness = Brightness.get_default() + const speaker = Wp.get_default()!.get_default_speaker() + + const iconName = Variable("") + const value = Variable(0) + + let count = 0 + function show(v: number, icon: string) { + visible.set(true) + value.set(v) + iconName.set(icon) + count++ + timeout(2000, () => { + count-- + if (count === 0) visible.set(false) + }) + } + + return ( + { + self.hook(brightness, "notify::screen", () => + show(brightness.screen, "display-brightness-symbolic"), + ) + + if (speaker) { + self.hook(speaker, "notify::volume", () => + show(speaker.volume, speaker.volumeIcon), + ) + } + }} + revealChild={visible()} + transitionType={Gtk.RevealerTransitionType.SLIDE_UP} + > + + + + + + ) +} + +export default function OSD(monitor: Gdk.Monitor) { + const visible = Variable(false) + + return ( + + visible.set(false)}> + + + + ) +} diff --git a/examples/gtk3/js/osd/osd/brightness.ts b/examples/gtk3/js/osd/osd/brightness.ts new file mode 100644 index 0000000..cf5060a --- /dev/null +++ b/examples/gtk3/js/osd/osd/brightness.ts @@ -0,0 +1,45 @@ +import GObject, { register, property } from "astal/gobject" +import { monitorFile, readFileAsync } from "astal/file" +import { exec, execAsync } from "astal/process" + +const get = (args: string) => Number(exec(`brightnessctl ${args}`)) +const screen = exec(`bash -c "ls -w1 /sys/class/backlight | head -1"`) + +@register({ GTypeName: "Brightness" }) +export default class Brightness extends GObject.Object { + static instance: Brightness + static get_default() { + if (!this.instance) + this.instance = new Brightness() + + return this.instance + } + + #screenMax = get("max") + #screen = get("get") / (get("max") || 1) + + @property(Number) + get screen() { return this.#screen } + + set screen(percent) { + if (percent < 0) + percent = 0 + + if (percent > 1) + percent = 1 + + execAsync(`brightnessctl set ${Math.floor(percent * 100)}% -q`).then(() => { + this.#screen = percent + this.notify("screen") + }) + } + + constructor() { + super() + monitorFile(`/sys/class/backlight/${screen}/brightness`, async f => { + const v = await readFileAsync(f) + this.#screen = Number(v) / this.#screenMax + this.notify("screen") + }) + } +} diff --git a/examples/gtk3/js/osd/style.scss b/examples/gtk3/js/osd/style.scss new file mode 100644 index 0000000..ba6f06d --- /dev/null +++ b/examples/gtk3/js/osd/style.scss @@ -0,0 +1 @@ +@use "./osd/OSD.scss"; -- cgit v1.2.3