fix: fix types

This commit is contained in:
Aylur
2023-10-18 00:32:27 +02:00
parent 24cc942076
commit 57f9ba2a2d
5 changed files with 224 additions and 191 deletions
+6 -3
View File
@@ -14,7 +14,10 @@ const StatusNotifierItemIFace = loadInterfaceXML('org.kde.StatusNotifierItem')!;
const StatusNotifierItemProxy =
Gio.DBusProxy.makeProxyWrapper(StatusNotifierItemIFace) as unknown as StatusNotifierItemProxy;
const DbusMenu = mkCtor < DbusmenuGtk3.Menu.ConstructorProperties > (DbusmenuGtk3.Menu, 'DbusMenu');
const DbusMenu = mkCtor<
typeof DbusmenuGtk3.Menu,
DbusmenuGtk3.Menu.ConstructorProperties
>(DbusmenuGtk3.Menu, 'DbusMenu');
export class TrayItem extends Service {
static {
@@ -122,7 +125,7 @@ export class TrayItem extends Service {
dbus_name: proxy.g_name_owner,
dbus_object: proxy.Menu,
});
this.menu = menu as unknown as DbusmenuGtk3.Menu;
this.menu = (menu as unknown) as DbusmenuGtk3.Menu;
}
if (this._proxy.IconThemePath) {
@@ -169,7 +172,7 @@ export class TrayItem extends Service {
const variant = proxy?.call_finish(result) as GLib.Variant;
if (!variant)
return;
const [properties] = variant.deepUnpack < Record < string, GLib.Variant> [] > ();
const [properties] = variant.deepUnpack < Record < string, GLib.Variant> [] >();
Object.entries(properties).map(([propertyName, value]) => {
this._proxy.set_cached_property(propertyName, value);
});
+24 -22
View File
@@ -16,41 +16,43 @@ import AgsEntry, { type EntryProps } from './widgets/entry.js';
import { AgsMenu, AgsMenuItem, type MenuProps, type MenuItemProps } from './widgets/menu.js';
import AgsWindow, { type WindowProps } from './widgets/window.js';
import AgsCircularProgress, { type CircularProgressProps } from './widgets/circularprogress.js';
import Gtk from 'gi://Gtk?version=3.0';
export function mkCtor<Props>(w: new (...args: Props[]) => any, name?: string) {
const Ctor = AgsWidget(w, name);
return (props: Props & BaseProps<Props>) => new Ctor(props);
export function mkCtor<W extends typeof Gtk.Widget, Props>(w: W, name?: string) {
const Ctor = AgsWidget<W, Props>(w, name);
return (props: Props & BaseProps<typeof w>) => new Ctor(props);
}
export const Box = mkCtor<BoxProps>(AgsBox, 'AgsBox');
export const Button = mkCtor<ButtonProps>(AgsButton, 'AgsButton');
export const CenterBox = mkCtor<CenterBoxProps>(AgsCenterBox, 'AgsCenterBox');
export const CircularProgress = mkCtor<CircularProgressProps>(AgsCircularProgress, 'AgsCircularProgress');
export const Entry = mkCtor<EntryProps>(AgsEntry, 'AgsEntry');
export const EventBox = mkCtor<EventBoxProps>(AgsEventBox, 'AgsEventBox');
export const Icon = mkCtor<IconProps>(AgsIcon, 'AgsIcon');
export const Label = mkCtor<LabelProps>(AgsLabel, 'AgsLabel');
export const Menu = mkCtor<MenuProps>(AgsMenu, 'AgsMenu');
export const MenuItem = mkCtor<MenuItemProps>(AgsMenuItem, 'AgsMenuItem');
export const Overlay = mkCtor<OverlayProps>(AgsOverlay, 'AgsOverlay');
export const ProgressBar = mkCtor<ProgressBarProps>(AgsProgressBar, 'AgsProgressBar');
export const Revealer = mkCtor<RevealerProps>(AgsRevealer, 'AgsRevealer');
export const Scrollable = mkCtor<ScrollableProps>(AgsScrollable, 'AgsScrollable');
export const Slider = mkCtor<SliderProps>(AgsSlider, 'AgsSlider');
export const Stack = mkCtor<StackProps>(AgsStack, 'AgsStack');
export const Window = mkCtor<WindowProps>(AgsWindow, 'AgsWindow');
// @ts-ignore
export const Window = mkCtor<typeof AgsWindow, WindowProps>(AgsWindow, 'AgsWindow');
export const Box = mkCtor<typeof AgsBox, BoxProps>(AgsBox, 'AgsBox');
export const Button = mkCtor<typeof AgsButton, ButtonProps>(AgsButton, 'AgsButton');
export const CenterBox = mkCtor<typeof AgsCenterBox, CenterBoxProps>(AgsCenterBox, 'AgsCenterBox');
export const CircularProgress = mkCtor<typeof AgsCircularProgress, CircularProgressProps>(AgsCircularProgress, 'AgsCircularProgress');
export const Entry = mkCtor<typeof AgsEntry, EntryProps>(AgsEntry, 'AgsEntry');
export const EventBox = mkCtor<typeof AgsEventBox, EventBoxProps>(AgsEventBox, 'AgsEventBox');
export const Icon = mkCtor<typeof AgsIcon, IconProps>(AgsIcon, 'AgsIcon');
export const Label = mkCtor<typeof AgsLabel, LabelProps>(AgsLabel, 'AgsLabel');
export const Menu = mkCtor<typeof AgsMenu, MenuProps>(AgsMenu, 'AgsMenu');
export const MenuItem = mkCtor<typeof AgsMenuItem, MenuItemProps>(AgsMenuItem, 'AgsMenuItem');
export const Overlay = mkCtor<typeof AgsOverlay, OverlayProps>(AgsOverlay, 'AgsOverlay');
export const ProgressBar = mkCtor<typeof AgsProgressBar, ProgressBarProps>(AgsProgressBar, 'AgsProgressBar');
export const Revealer = mkCtor<typeof AgsRevealer, RevealerProps>(AgsRevealer, 'AgsRevealer');
export const Scrollable = mkCtor<typeof AgsScrollable, ScrollableProps>(AgsScrollable, 'AgsScrollable');
export const Slider = mkCtor<typeof AgsSlider, SliderProps>(AgsSlider, 'AgsSlider');
export const Stack = mkCtor<typeof AgsStack, StackProps>(AgsStack, 'AgsStack');
const ctors = new Map();
// TODO: figure out how to type this
export function Widget<Props>({ type, ...props }: {
type: new (props: Props) => any,
type: any
}) {
let Ctor;
if (ctors.has(type)) {
Ctor = ctors.get(type);
} else {
Ctor = mkCtor<Props>(type);
Ctor = mkCtor<typeof type, Props>(type);
ctors.set(type, Ctor);
}
+3 -1
View File
@@ -6,11 +6,13 @@ import Gdk from 'gi://Gdk?version=3.0';
import Service from '../service.js';
import cairo from '@girs/cairo-1.0';
export interface IconProps extends Gtk.Image.ConstructorProperties {
interface Props extends Gtk.Image.ConstructorProperties {
icon?: string | GdkPixbuf.Pixbuf
size?: number
}
export type IconProps = Props | string | GdkPixbuf.Pixbuf | undefined
export default class AgsIcon extends Gtk.Image {
static {
GObject.registerClass({
+4 -2
View File
@@ -7,11 +7,13 @@ import Service from '../service.js';
const justifications = ['left', 'center', 'right', 'fill'];
const truncates = ['none', 'start', 'middle', 'end'];
export interface LabelProps extends Gtk.Label.ConstructorProperties {
interface Props extends Gtk.Label.ConstructorProperties {
justification?: string
truncate?: string
}
export type LabelProps = Props | string | undefined
export default class AgsLabel extends Gtk.Label {
static {
GObject.registerClass({
@@ -22,7 +24,7 @@ export default class AgsLabel extends Gtk.Label {
}, this);
}
constructor(params: LabelProps | string) {
constructor(params: LabelProps) {
super(typeof params === 'string' ? { label: params } : params);
}
+187 -163
View File
@@ -31,184 +31,208 @@ export interface BaseProps<Self> {
setup?: (self: Self) => void
}
export default (W: new (...args: any[]) => any, GTypeName?: string) => class extends W {
static {
GObject.registerClass({
...(GTypeName ? { GTypeName } : {}),
Properties: {
'class-name': Service.pspec('class-name', 'string', 'rw'),
'class-names': Service.pspec('class-names', 'jsobject', 'rw'),
'css': Service.pspec('css', 'string', 'rw'),
},
}, this);
}
export default function <T extends typeof Gtk.Widget, Props>(W: T, GTypeName?: string) {
// @ts-expect-error mixin constructor
return class AgsWidget extends W {
static {
GObject.registerClass({
GTypeName: GTypeName || `${W.name}`,
Properties: {
'class-name': Service.pspec('class-name', 'string', 'rw'),
'class-names': Service.pspec('class-names', 'jsobject', 'rw'),
'css': Service.pspec('css', 'string', 'rw'),
},
}, this);
}
constructor(params: BaseProps<InstanceType<typeof W>> | unknown) {
const {
connections = [],
properties = [],
binds = [],
style,
halign,
valign,
setup,
...rest
} = params as BaseProps<InstanceType<typeof W>>;
super(typeof params === 'string' ? params : rest);
constructor(params: BaseProps<T> & Props | any) {
const {
connections = [],
properties = [],
binds = [],
style,
halign,
valign,
setup,
...rest
} = params as BaseProps<T> & Props;
super(typeof params === 'object' ? rest : params);
this.style = style!;
this.halign = halign!;
this.valign = valign!;
this.style = style!;
this.halign = halign!;
this.valign = valign!;
properties.forEach(([key, value]) => {
this[`_${key}`] = value;
});
properties.forEach(([key, value]) => {
(this as unknown as { [key: string]: unknown })[`_${key}`] = value;
});
binds.forEach(([prop, obj, objProp = 'value', transform = out => out]) => {
if (!prop || !obj) {
console.error(Error('missing arguments to binds'));
binds.forEach(([prop, obj, objProp = 'value', transform = out => out]) => {
if (!prop || !obj) {
console.error(Error('missing arguments to binds'));
return;
}
// @ts-expect-error
const callback = () => this[prop] = transform(obj[objProp]);
connections.push([obj, callback, `notify::${objProp}`]);
});
connections.forEach(([s, callback, event]) => {
if (!s || !callback) {
console.error(Error('missing arguments to connections'));
return;
}
if (typeof s === 'string')
this.connect(s, callback);
else if (typeof s === 'number')
interval(s, () => callback(this as any), this as unknown as Gtk.Widget);
else if (s instanceof GObject.Object)
connect(s, this as unknown as Gtk.Widget, callback as any, event);
else
console.error(Error(`${s} is not a GObject nor a string nor a number`));
});
if (typeof setup === 'function')
setup(this as any);
}
toggleClassName(className: string, condition = true) {
condition
? this.get_style_context().add_class(className)
: this.get_style_context().remove_class(className);
}
// @ts-expect-error prop override
get halign() { return aligns[super.halign]; }
// @ts-expect-error prop override
set halign(align: string) {
if (!align)
return;
if (!aligns.includes(align)) {
console.error(new Error(`halign has to be on of ${aligns}`));
return;
}
super.halign = aligns.findIndex(a => a === align);
}
// @ts-expect-error prop override
get valign() { return aligns[super.valign]; }
// @ts-expect-error prop override
set valign(align: string) {
if (!align)
return;
if (!aligns.includes(align)) {
console.error(new Error(`valign has to be on of ${aligns}`));
return;
}
super.valign = aligns.findIndex(a => a === align);
}
get class_name() {
// @ts-expect-error
return this._className || '';
}
set class_name(names: string) {
// @ts-expect-error
this._className = names;
this.class_names = names.split(/\s+/);
this.notify('class-name');
}
get class_names() {
// @ts-expect-error
return this._classNames || [];
}
set class_names(names: string[]) {
this.class_names.forEach((cn: string) => this.toggleClassName(cn, false));
// @ts-expect-error
const callback = () => this[prop] = transform(obj[objProp]);
connections.push([obj, callback, `notify::${objProp}`]);
});
this._classNames = names.map(cn => {
this.toggleClassName(cn);
return cn;
});
connections.forEach(([s, callback, event]) => {
if (!s || !callback) {
console.error(Error('missing arguments to connections'));
this.notify('class-names');
}
setCss(css: string) {
const previous = widgetProviders.get(this);
if (previous)
this.get_style_context().remove_provider(previous);
const provider = new Gtk.CssProvider();
widgetProviders.set(this, provider);
provider.load_from_data(new TextEncoder().encode(css));
this.get_style_context()
.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_USER);
this.notify('css');
}
setStyle(css: string) {
this.setCss(`* { ${css} }`);
this.notify('style');
}
// @ts-expect-error prop override
get style() { return this._style || ''; }
// @ts-expect-error prop override
set style(css: string) {
if (!css)
return;
}
if (typeof s === 'string')
this.connect(s, callback);
// @ts-expect-error
this._style = css;
this.setCss(`* { ${css} }`);
this.notify('style');
}
else if (typeof s === 'number')
interval(s, () => callback(this), this as unknown as Gtk.Widget);
// @ts-expect-error
get css() { return this._css || ''; }
set css(css: string) {
if (!css)
return;
else if (s instanceof GObject.Object)
connect(s, this as unknown as Gtk.Widget, callback, event);
// @ts-expect-error
this._css = css;
this.setCss(css);
this.notify('css');
}
get child(): Gtk.Widget | null {
// @ts-expect-error
if (typeof this.get_child === 'function')
// @ts-expect-error
return this.get_child();
return null;
}
set child(child: Gtk.Widget) {
// @ts-expect-error
if (typeof this.set_child === 'function')
// @ts-expect-error
this.set_child(child);
else
console.error(Error(`${s} is not a GObject nor a string nor a number`));
});
if (typeof setup === 'function')
setup(this);
}
toggleClassName(className: string, condition = true) {
condition
? this.get_style_context().add_class(className)
: this.get_style_context().remove_class(className);
}
get halign() { return aligns[super.halign]; }
set halign(align: string) {
if (!align)
return;
if (!aligns.includes(align)) {
console.error(new Error(`halign has to be on of ${aligns}`));
return;
console.error(new Error(`can't set child on ${this}`));
}
super.halign = aligns.findIndex(a => a === align);
}
get valign() { return aligns[super.valign]; }
set valign(align: string) {
if (!align)
return;
if (!aligns.includes(align)) {
console.error(new Error(`valign has to be on of ${aligns}`));
return;
// @ts-expect-error prop override
get parent(): Gtk.Container | null {
return this.get_parent() as Gtk.Container || null;
}
super.valign = aligns.findIndex(a => a === align);
}
get class_name() {
return this._className || '';
}
set class_name(names: string) {
this._className = names;
this.class_names = names.split(/\s+/);
this.notify('class-name');
}
get class_names() {
return this._classNames || [];
}
set class_names(names: string[]) {
this.class_names.forEach((cn: string) => this.toggleClassName(cn, false));
this._classNames = names.map(cn => {
this.toggleClassName(cn);
return cn;
});
this.notify('class-names');
}
setCss(css: string) {
const previous = widgetProviders.get(this);
if (previous)
this.get_style_context().remove_provider(previous);
const provider = new Gtk.CssProvider();
widgetProviders.set(this, provider);
provider.load_from_data(new TextEncoder().encode(css));
this.get_style_context()
.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_USER);
this.notify('css');
}
setStyle(css: string) {
this.setCss(`* { ${css} }`);
this.notify('style');
}
get style() { return this._style || ''; }
set style(css: string) {
if (!css)
return;
this.setCss(`* { ${css} }`);
this._style = css;
this.notify('style');
}
get css() { return this._css || ''; }
set css(css: string) {
if (!css)
return;
this.setCss(css);
this._css = css;
this.notify('css');
}
get child(): Gtk.Widget | null {
if (typeof this.get_child === 'function')
return this.get_child();
return null;
}
set child(child: Gtk.Widget) {
if (typeof this.set_child === 'function')
this.set_child(child);
else
console.error(new Error(`can't set child on ${this}`));
}
get parent() {
return this.get_parent();
}
};
};
}