diff options
Diffstat (limited to 'gjs/src')
-rw-r--r-- | gjs/src/astalify.ts | 63 | ||||
-rw-r--r-- | gjs/src/binding.ts | 8 | ||||
-rw-r--r-- | gjs/src/jsx/jsx-runtime.ts | 19 | ||||
-rw-r--r-- | gjs/src/overrides.ts | 23 |
4 files changed, 53 insertions, 60 deletions
diff --git a/gjs/src/astalify.ts b/gjs/src/astalify.ts index 2817606..f986716 100644 --- a/gjs/src/astalify.ts +++ b/gjs/src/astalify.ts @@ -1,7 +1,11 @@ -import Binding, { kebabify, type Connectable, type Subscribable } from "./binding.js" +import Binding, { kebabify, snakeify, type Connectable, type Subscribable } from "./binding.js" import { Astal, Gtk } from "./imports.js" import { execAsync } from "./process.js" -import { setChild } from "./overrides.js" + +Object.defineProperty(Astal.Box.prototype, "children", { + get() { return this.get_children() }, + set(v) { this.set_children(v) }, +}) export type Widget<C extends { new(...args: any): Gtk.Widget }> = InstanceType<C> & { className: string @@ -44,21 +48,15 @@ function hook( } function ctor(self: any, config: any = {}, ...children: Gtk.Widget[]) { - const { setup, child, ...props } = config + const { setup, ...props } = config props.visible ??= true - const pchildren = props.children - delete props.children - const bindings = Object.keys(props).reduce((acc: any, prop) => { if (props[prop] instanceof Binding) { - const bind = [prop, props[prop]] - prop === "child" - ? setChild(self, props[prop].get()) - : self[`set_${kebabify(prop)}`](props[prop].get()) - + const binding = props[prop] + self[`set_${snakeify(prop)}`](binding.get()) delete props[prop] - return [...acc, bind] + return [...acc, [prop, binding]] } return acc }, []) @@ -66,13 +64,16 @@ function ctor(self: any, config: any = {}, ...children: Gtk.Widget[]) { const onHandlers = Object.keys(props).reduce((acc: any, key) => { if (key.startsWith("on")) { const sig = kebabify(key).split("-").slice(1).join("-") - const handler = [sig, props[key]] + const handler = props[key] delete props[key] - return [...acc, handler] + return [...acc, [sig, handler]] } return acc }, []) + const pchildren = props.children + delete props.children + Object.assign(self, props) Object.assign(self, { hook(obj: any, sig: any, callback: any) { @@ -80,15 +81,6 @@ function ctor(self: any, config: any = {}, ...children: Gtk.Widget[]) { }, }) - if (child instanceof Binding) { - setChild(self, child.get()) - self.connect("destroy", child.subscribe(v => { - setChild(self, v) - })) - } else if (self instanceof Gtk.Container && child instanceof Gtk.Widget) { - self.add(child) - } - for (const [signal, callback] of onHandlers) { if (typeof callback === "function") { self.connect(signal, callback) @@ -100,19 +92,19 @@ function ctor(self: any, config: any = {}, ...children: Gtk.Widget[]) { } if (self instanceof Gtk.Container) { - if (pchildren) { - for (const child of pchildren) - self.add(child) - } if (children) { for (const child of children) self.add(child) } + if (pchildren && Array.isArray(pchildren)) { + for (const child of pchildren) + self.add(child) + } } for (const [prop, bind] of bindings) { self.connect("destroy", bind.subscribe((v: any) => { - self[`set_${kebabify(prop)}`](v) + self[`set_${snakeify(prop)}`](v) })) } @@ -138,6 +130,21 @@ function proxify< set(v) { Astal.widget_set_cursor(this, v) }, }) + klass.prototype.set_child = function(widget: Gtk.Widget) { + if (this instanceof Gtk.Bin) { + const rm = this.get_child() + if (rm) + this.remove(rm) + } + if (this instanceof Gtk.Container) + this.add(widget) + } + + Object.defineProperty(klass.prototype, "child", { + get() { return this.get_child?.() }, + set(v) { this.set_child(v) }, + }) + const proxy = new Proxy(klass, { construct(_, [conf, ...children]) { const self = new klass diff --git a/gjs/src/binding.ts b/gjs/src/binding.ts index a8b6d55..50d941d 100644 --- a/gjs/src/binding.ts +++ b/gjs/src/binding.ts @@ -1,8 +1,10 @@ -export const kebabify = (str: string) => str - .replace(/([a-z])([A-Z])/g, "$1-$2") - .replaceAll("_", "-") +export const snakeify = (str: string) => str + .replace(/([a-z])([A-Z])/g, "$1_$2") .toLowerCase() +export const kebabify = (str: string) => snakeify(str) + .replaceAll("_", "-") + export interface Subscribable<T = unknown> { subscribe(callback: () => void): () => void get(): T diff --git a/gjs/src/jsx/jsx-runtime.ts b/gjs/src/jsx/jsx-runtime.ts index 41aa447..5e7f23b 100644 --- a/gjs/src/jsx/jsx-runtime.ts +++ b/gjs/src/jsx/jsx-runtime.ts @@ -3,10 +3,9 @@ import * as Widget from "../widgets.js" import Binding from "../binding.js" function w(e: any) { - if (e instanceof Gtk.Widget || e instanceof Binding) - return e - - return Widget.Label({ label: String(e) }) + return e instanceof Gtk.Widget || e instanceof Binding + ? e + : Widget.Label({ label: String(e) }) } export function jsx( @@ -20,7 +19,15 @@ export function jsx( else children = children.flat() - if (ctor === "centerbox") { + // <box children={Binding} /> and <box>{Binding}</box> + if (ctor === "box" && children.length === 1 && children[0] instanceof Binding) { + props.children = children[0] + } + + // TODO: handle array of Binding + // is there a usecase? + + else if (ctor === "centerbox") { if (children[0]) props.startWidget = w(children[0]) if (children[1]) @@ -29,7 +36,7 @@ export function jsx( props.endWidget = w(children[2]) } - else if (ctor == "overlay") { + else if (ctor === "overlay") { const [child, ...overlays] = children if (child) props.child = child diff --git a/gjs/src/overrides.ts b/gjs/src/overrides.ts deleted file mode 100644 index e3d3df5..0000000 --- a/gjs/src/overrides.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Gtk, Astal } from "./imports.js" - -export function setChild(parent: Gtk.Widget, child: Gtk.Widget) { - if (parent instanceof Gtk.Bin) { - const rm = parent.get_child() - if (rm) - parent.remove(rm) - } - if (parent instanceof Gtk.Container) - parent.add(child) -} - -// gjs fails to map List types? -Object.defineProperty(Astal.Box.prototype, "children", { - get() { return this.get_children() }, - set(v) { this.set_children(v) }, -}) - -// gjs deprecated the child setter -Object.defineProperty(Gtk.Container.prototype, "child", { - get() { return this.get_child?.() }, - set(v) { setChild(this, v) }, -}) |