New dialogs

master
Kuba Orlik 4 years ago
parent d4c15f44ac
commit 8e962c3f52

@ -9,17 +9,24 @@ export type DialogOptions = Record<
true | string | undefined | string[]
>; // array value means use this flag this many times
type Geometry = { x: number; y: number; width: number; height: number };
let last_position: { x: number; y: number } | null = null;
async function get_geometry() {
async function get_geometry(): Promise<Geometry | null> {
const result = (await simpleSpawn("bash", [
"-c",
'wmctrl -l -x node-zenity -G | grep node-zenity | awk \'{print $3 " " $4 " " $5 " " $6}\'',
])) as string;
console.log(result);
const [x, y, width, height] = result
.split("\n")[0]
.split(" ")
.map((s) => parseInt(s));
console.log("getgeometry", result, { x, y, width, height });
if (!height) {
return null;
}
return { x, y, width, height };
}
@ -40,7 +47,7 @@ async function set_geometry({
if (height === undefined) {
height = -1;
}
await simpleSpawn("wmctrl", [
const args = [
"-x",
"-a",
"node-zenity",
@ -48,15 +55,28 @@ async function set_geometry({
`0,${Math.round(x)},${Math.round(y)},${Math.round(width)},${Math.round(
height
)}`,
]);
];
console.log(args);
await simpleSpawn("wmctrl", args);
}
type DialogResponse = {
export type DialogResponse = {
code: number;
output: string;
error: string;
};
setInterval(async () => {
const geometry = await get_geometry();
if (!geometry) {
return;
}
last_position = {
x: Math.round(geometry.x + geometry.width / 2),
y: Math.round(geometry.y + geometry.height / 2),
};
}, 2000);
export default class Dialog extends EventEmitter {
shown = false;
process: ChildProcessWithoutNullStreams;
@ -83,7 +103,6 @@ export default class Dialog extends EventEmitter {
} else if (value === undefined) {
//void
} else {
console.log("unknown value:", value);
throw new Error("uknown arg value type");
}
}
@ -98,17 +117,6 @@ export default class Dialog extends EventEmitter {
];
console.log("spawning process!", args.join(" "));
this.process = spawn("zenity", args);
let position_listener_interval = setInterval(async () => {
const { x, y, width, height } = await get_geometry();
console.log(
{ x, y, width, height },
{ x: Math.round(x + width / 2), y: Math.round(y + height / 2) }
);
last_position = {
x: Math.round(x + width / 2),
y: Math.round(y + height / 2),
};
}, 2000);
let spawned = false;
return new Promise((resolve, reject) => {
@ -135,13 +143,13 @@ export default class Dialog extends EventEmitter {
]); // to activate it
if (last_position) {
const { width, height } = await get_geometry();
console.log(last_position, width, height);
await set_geometry({
x: last_position.x - width / 2 - 11,
y: last_position.y - height / 2 - 82,
}); // to put it where it last was
}
succeded = true;
console.log("WMCTRL SUCCEEDED!");
} catch (e) {
console.error(e);
continue;
@ -155,7 +163,6 @@ export default class Dialog extends EventEmitter {
this.error += chunk;
});
this.process.on("close", (code) => {
clearInterval(position_listener_interval);
console.log("process closed. output:", this.output);
if (code !== 0) {
if (!spawned) {

@ -17,6 +17,7 @@ export default class Entry {
height: ((options?.height as unknown) as string)?.toString(),
});
await dialog.show();
return dialog.output.split("\n")[0];
const answer = await dialog.getAnswer();
return answer.output.split("\n")[0];
}
}

@ -6,3 +6,4 @@ export {
ItemsSelectedResponse,
} from "./list";
export { default as Entry } from "./entry";
export { default as TextInfo } from "./text-info";

@ -1,4 +1,4 @@
import Dialog from "./dialog";
import Dialog, { DialogResponse } from "./dialog";
export default class Info {
static async show(
@ -10,9 +10,9 @@ export default class Info {
ellipsize: true;
title: string;
}>
): Promise<void> {
): Promise<DialogResponse> {
const dialog = new Dialog("info", { ...options, text });
await dialog.show();
await dialog.getAnswer();
return dialog.getAnswer();
}
}

@ -8,7 +8,7 @@ export type ListOptions = {
title: string;
text: string;
rows: string[][];
multiple: true;
multiple: boolean;
separator: string;
editable: true;
"print-column": number;
@ -77,7 +77,9 @@ export default class List {
if (options.columns) {
ret.column = options.columns;
}
ret.multiple = options.multiple;
ret.multiple = (options.multiple ? true : undefined) as
| true
| undefined;
ret.separator = options.separator;
ret.editable = options.editable;
ret["print-column"] = options["print-column"]?.toString();

@ -0,0 +1,29 @@
import Dialog from "./dialog";
export default class TextInfo {
static async show(
options: Partial<{
text: string;
editable: true;
title: string;
width: number;
height: number;
}>
): Promise<string | null> {
const dialog = new Dialog("text-info", {
...options,
editable: options.editable ? true : undefined,
text: undefined,
width: ((options?.width as unknown) as string)?.toString(),
height: ((options?.height as unknown) as string)?.toString(),
});
await dialog.show();
dialog.process.stdin.write(options.text || "");
const answer = await dialog.getAnswer();
if (answer.code === 0) {
return answer.output;
} else {
return null;
}
}
}
Loading…
Cancel
Save