diff options
Diffstat (limited to 'examples/gtk3/js')
-rw-r--r-- | examples/gtk3/js/osd/README.md | 7 | ||||
-rw-r--r-- | examples/gtk3/js/osd/app.ts | 11 | ||||
-rw-r--r-- | examples/gtk3/js/osd/osd/OSD.scss | 30 | ||||
-rw-r--r-- | examples/gtk3/js/osd/osd/OSD.tsx | 69 | ||||
-rw-r--r-- | examples/gtk3/js/osd/osd/brightness.ts | 45 | ||||
-rw-r--r-- | examples/gtk3/js/osd/style.scss | 1 |
6 files changed, 163 insertions, 0 deletions
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 + + + +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<boolean> }) { + 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 ( + <revealer + setup={(self) => { + 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} + > + <box className="OSD"> + <icon icon={iconName()} /> + <levelbar valign={Gtk.Align.CENTER} widthRequest={100} value={value()} /> + <label label={value(v => `${Math.floor(v * 100)}%`)} /> + </box> + </revealer> + ) +} + +export default function OSD(monitor: Gdk.Monitor) { + const visible = Variable(false) + + return ( + <window + gdkmonitor={monitor} + className="OSD" + namespace="osd" + application={App} + layer={Astal.Layer.OVERLAY} + keymode={Astal.Keymode.ON_DEMAND} + anchor={Astal.WindowAnchor.BOTTOM} + > + <eventbox onClick={() => visible.set(false)}> + <OnScreenProgress visible={visible} /> + </eventbox> + </window> + ) +} 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"; |