ags.Variable and Widget.binds (#76)

This commit is contained in:
Aylur
2023-09-04 20:08:35 +02:00
committed by GitHub
parent 7add863d58
commit 6b043b37af
11 changed files with 111 additions and 20 deletions
+5 -4
View File
@@ -1,13 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/com/github/Aylur/ags">
<file>main.js</file>
<file>app.js</file>
<file>client.js</file>
<file>utils.js</file>
<file>widget.js</file>
<file>main.js</file>
<file>service.js</file>
<file>utils.js</file>
<file>variable.js</file>
<file>widget.js</file>
<file>widgets/constructor.js</file>
<file>widgets/overrides.js</file>
<file>widgets/box.js</file>
<file>widgets/button.js</file>
@@ -21,7 +23,6 @@
<file>widgets/progressbar.js</file>
<file>widgets/revealer.js</file>
<file>widgets/scrollable.js</file>
<file>widgets/shared.js</file>
<file>widgets/slider.js</file>
<file>widgets/stack.js</file>
<file>widgets/window.js</file>
+2
View File
@@ -4,6 +4,7 @@ import * as Utils from './utils.js';
import App from './app.js';
import client from './client.js';
import Service from './service.js';
import Variable from './variable.js';
import Widget from './widget.js';
const APP_BUS = (name: string) => 'com.github.Aylur.ags.' + name;
@@ -130,6 +131,7 @@ export function main(args: string[]) {
Utils,
Widget,
Service,
Variable,
};
const bus = APP_BUS(flags.busName);
+10 -4
View File
@@ -2,7 +2,7 @@ import Gtk from 'gi://Gtk?version=3.0';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import { Command } from './widgets/shared.js';
import { Command } from './widgets/constructor.js';
export const USER = GLib.get_user_name();
export const CACHE_DIR = `${GLib.get_user_cache_dir()}/${pkg.name}`;
@@ -113,15 +113,16 @@ export function connect(
export function interval(
interval: number,
callback: () => void, widget: Gtk.Widget,
callback: () => void,
bind?: Gtk.Widget,
) {
callback();
const id = GLib.timeout_add(GLib.PRIORITY_DEFAULT, interval, () => {
callback();
return true;
});
if (widget)
widget.connect('destroy', () => GLib.source_remove(id));
if (bind)
bind.connect('destroy', () => GLib.source_remove(id));
return id;
}
@@ -211,6 +212,7 @@ export function subprocess(
cmd: string | string[],
callback: (out: string) => void,
onError = logError,
bind?: Gtk.Widget,
) {
try {
const read = (stdout: Gio.DataInputStream) => {
@@ -245,6 +247,10 @@ export function subprocess(
});
read(stdout);
if (bind)
bind.connect('destroy', () => proc.force_exit());
return proc;
} catch (e) {
onError(e as Error);
+62
View File
@@ -0,0 +1,62 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import GObject from 'gi://GObject';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import { execAsync, interval, subprocess } from './utils.js';
interface Options {
poll?: [interval: number, cmd: string[] | string | (() => unknown)],
listen?: string[] | string,
}
class AgsVariable extends GObject.Object {
static {
GObject.registerClass({
GTypeName: 'AgsVariable',
Signals: { 'changed': {} },
}, this);
}
_inerval?: number;
_subprocess?: Gio.Subprocess | null;
constructor(value: any, option: Options) {
super();
this.value = value;
if (option.poll) {
const [time, cmd] = option.poll;
if (Array.isArray(cmd) || typeof cmd === 'string') {
this._inerval = interval(time, () => execAsync(cmd)
.catch(logError)
.then(this.setValue.bind(this)));
}
if (typeof cmd === 'function')
this._inerval = interval(time, () => this.setValue(cmd()));
}
if (option.listen)
this._subprocess = subprocess(option.listen, this.setValue.bind(this), logError);
}
dispose() {
if (this._inerval)
GLib.source_remove(this._inerval);
this._subprocess?.force_exit();
this.run_dispose();
}
private _value: any;
getValue() { return this._value; }
setValue(value: any) {
this._value = value;
this.emit('changed');
}
get value() { return this._value; }
set value(value: any) { this.setValue(value); }
}
export default (value: any, options: Options) => new AgsVariable(value, options);
+1 -2
View File
@@ -14,8 +14,7 @@ import AgsProgressBar from './widgets/progressbar.js';
import AgsEntry from './widgets/entry.js';
import { AgsMenu, AgsMenuItem } from './widgets/menu.js';
import AgsWindow from './widgets/window.js';
import constructor from './widgets/shared.js';
import { ctor } from './widgets/shared.js';
import { constructor, type ctor } from './widgets/constructor.js';
export default function Widget({ type, ...params }: { type: ctor }) {
return constructor(type, params);
+1 -1
View File
@@ -2,7 +2,7 @@ import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=3.0';
import Gdk from 'gi://Gdk?version=3.0';
import { runCmd } from '../utils.js';
import { Command } from './shared.js';
import { Command } from './constructor.js';
export default class AgsButton extends Gtk.Button {
static {
@@ -25,16 +25,17 @@ interface CommonParams {
[number, (...args: unknown[]) => unknown] |
[Connectable, (...args: unknown[]) => unknown, string]
)[]
properties?: [string, unknown][]
properties?: [prop: string, value: unknown][]
binds?: [prop: string, obj: Connectable, objProp?: string, signal?: string][],
setup?: (widget: Gtk.Widget) => void
}
function separateCommon({
className, style, halign, valign, connections, properties, setup,
className, style, halign, valign, connections, properties, binds, setup,
...rest
}: CommonParams) {
return [
{ className, style, halign, valign, connections, properties, setup },
{ className, style, halign, valign, connections, properties, binds, setup },
rest,
];
}
@@ -42,7 +43,7 @@ function separateCommon({
function parseCommon(widget: Gtk.Widget, {
className, style,
halign, valign,
connections, properties, setup,
connections = [], properties, binds, setup,
}: CommonParams) {
if (className !== undefined)
// @ts-expect-error
@@ -84,8 +85,28 @@ function parseCommon(widget: Gtk.Widget, {
});
}
if (binds) {
binds.forEach(([prop, obj, value = 'value', signal = 'changed']) => {
if (!prop || !obj) {
logError(new Error('missing arguments to connections'));
return;
}
const callback = () => {
// @ts-expect-error
widget[prop] = obj[value];
};
connections.push([obj, callback, signal]);
});
}
if (connections) {
connections.forEach(([s, callback, event]) => {
if (!s || !callback) {
logError(new Error('missing arguments to connections'));
return;
}
if (typeof s === 'string')
widget.connect(s, callback);
@@ -112,7 +133,7 @@ function parseCommon(widget: Gtk.Widget, {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ctor = { new(...args: any[]): Gtk.Widget }
export default function constructor(
export function constructor(
ctor: ctor,
params: CommonParams | string = {},
) {
+1 -1
View File
@@ -1,7 +1,7 @@
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=3.0';
import { runCmd } from '../utils.js';
import { Command } from './shared.js';
import { Command } from './constructor.js';
export default class AgsEntry extends Gtk.Entry {
static {
+1 -1
View File
@@ -2,7 +2,7 @@ import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=3.0';
import Gdk from 'gi://Gdk?version=3.0';
import { runCmd } from '../utils.js';
import { Command } from './shared.js';
import { Command } from './constructor.js';
export default class AgsEventBox extends Gtk.EventBox {
static {
+1 -1
View File
@@ -1,7 +1,7 @@
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=3.0';
import { runCmd } from '../utils.js';
import { Command } from './shared.js';
import { Command } from './constructor.js';
interface Params {
children?: Gtk.Widget[]
+1 -1
View File
@@ -2,7 +2,7 @@ import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=3.0';
import { runCmd } from '../utils.js';
import { EventButton, EventScroll, EventKey } from 'gi-types/gdk3';
import { Command } from './shared.js';
import { Command } from './constructor.js';
interface Params {
onChange?: Command