parent
8bd0b732e7
commit
557e4c7a52
32 changed files with 281 additions and 12 deletions
modules/ags/gtk4/widgets/astalify
179
modules/ags/gtk4/widgets/astalify/astalify.ts
Normal file
179
modules/ags/gtk4/widgets/astalify/astalify.ts
Normal file
|
@ -0,0 +1,179 @@
|
|||
import { property, register } from 'astal';
|
||||
import { Gtk, hook } from 'astal/gtk4';
|
||||
import { type Connectable, type Subscribable } from 'astal/binding';
|
||||
|
||||
import construct from './construct';
|
||||
import setupControllers from './controller';
|
||||
|
||||
import {
|
||||
type BindableProps,
|
||||
childType,
|
||||
type Cursor,
|
||||
dummyBuilder,
|
||||
type MixinParams,
|
||||
noImplicitDestroy,
|
||||
setChildren,
|
||||
} from './generics';
|
||||
|
||||
|
||||
export default <
|
||||
C extends new (...props: MixinParams) => Gtk.Widget,
|
||||
ConstructorProps,
|
||||
>(
|
||||
cls: C,
|
||||
clsName = cls.name,
|
||||
) => {
|
||||
@register({ GTypeName: `RealClass_${clsName}` })
|
||||
class Widget extends cls {
|
||||
declare private _css: string | undefined;
|
||||
declare private _provider: Gtk.CssProvider | undefined;
|
||||
|
||||
@property(String)
|
||||
get css(): string | undefined {
|
||||
return this._css;
|
||||
}
|
||||
|
||||
set css(value: string) {
|
||||
if (!this._provider) {
|
||||
this._provider = new Gtk.CssProvider();
|
||||
|
||||
this.get_style_context().add_provider(
|
||||
this._provider,
|
||||
Gtk.STYLE_PROVIDER_PRIORITY_USER,
|
||||
);
|
||||
}
|
||||
|
||||
this._css = value;
|
||||
this._provider.load_from_string(value);
|
||||
}
|
||||
|
||||
|
||||
declare private [childType]: string;
|
||||
|
||||
@property(String)
|
||||
get type(): string { return this[childType]; }
|
||||
|
||||
set type(value: string) { this[childType] = value; }
|
||||
|
||||
|
||||
@property(Object)
|
||||
get children(): Gtk.Widget[] { return this.getChildren(this); }
|
||||
|
||||
set children(value: Gtk.Widget[]) { this.setChildren(this, value); }
|
||||
|
||||
|
||||
declare private [noImplicitDestroy]: boolean;
|
||||
|
||||
@property(String)
|
||||
get noImplicitDestroy(): boolean { return this[noImplicitDestroy]; }
|
||||
|
||||
set noImplicitDestroy(value: boolean) { this[noImplicitDestroy] = value; }
|
||||
|
||||
|
||||
protected getChildren(widget: Gtk.Widget): Gtk.Widget[] {
|
||||
if ('get_child' in widget && typeof widget.get_child == 'function') {
|
||||
return widget.get_child() ? [widget.get_child()] : [];
|
||||
}
|
||||
|
||||
const children: Gtk.Widget[] = [];
|
||||
let ch = widget.get_first_child();
|
||||
|
||||
while (ch !== null) {
|
||||
children.push(ch);
|
||||
ch = ch.get_next_sibling();
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
protected setChildren(widget: Gtk.Widget, children: Gtk.Widget[]) {
|
||||
for (const child of children) {
|
||||
widget.vfunc_add_child(
|
||||
dummyBuilder,
|
||||
child,
|
||||
childType in widget ? widget[childType] as string : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
[setChildren](children: Gtk.Widget[]) {
|
||||
for (const child of (this.getChildren(this))) {
|
||||
child?.unparent();
|
||||
|
||||
if (!children.includes(child) && noImplicitDestroy in this) {
|
||||
child.run_dispose();
|
||||
}
|
||||
}
|
||||
|
||||
this.setChildren(this, children);
|
||||
}
|
||||
|
||||
|
||||
private _cursorName: Cursor = 'default';
|
||||
|
||||
@property(String)
|
||||
get cursorName(): Cursor {
|
||||
return this._cursorName;
|
||||
}
|
||||
|
||||
set cursorName(val: Cursor) {
|
||||
this._cursorName = val;
|
||||
this.set_cursor_from_name(val);
|
||||
}
|
||||
|
||||
|
||||
hook(
|
||||
object: Connectable,
|
||||
signal: string,
|
||||
callback: (self: this, ...args: unknown[]) => void,
|
||||
): this;
|
||||
|
||||
hook(
|
||||
object: Subscribable,
|
||||
callback: (self: this, ...args: unknown[]) => void,
|
||||
): this;
|
||||
|
||||
hook(
|
||||
object: Connectable | Subscribable,
|
||||
signalOrCallback: string | ((self: this, ...args: unknown[]) => void),
|
||||
callback?: (self: this, ...args: unknown[]) => void,
|
||||
) {
|
||||
hook(this, object, signalOrCallback, callback);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
constructor(...params: MixinParams) {
|
||||
const props = params[0] || {};
|
||||
|
||||
super('cssName' in props ? { cssName: props.cssName } : {});
|
||||
|
||||
if ('cssName' in props) {
|
||||
delete props.cssName;
|
||||
}
|
||||
|
||||
if (props.noImplicitDestroy) {
|
||||
this.noImplicitDestroy = true;
|
||||
delete props.noImplicitDestroy;
|
||||
}
|
||||
|
||||
if (props.type) {
|
||||
this.type = props.type;
|
||||
delete props.type;
|
||||
}
|
||||
|
||||
construct(this, setupControllers(this, props));
|
||||
}
|
||||
}
|
||||
|
||||
type Constructor<Instance, Props> = new (...args: Props[]) => Instance;
|
||||
|
||||
type WidgetClass = Constructor<
|
||||
Widget & Gtk.Widget & InstanceType<C>,
|
||||
Partial<BindableProps<ConstructorProps>>
|
||||
>;
|
||||
|
||||
// override the parameters of the `super` constructor
|
||||
return Widget as unknown as WidgetClass;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue