2023-01-16 22:11:17 +00:00
|
|
|
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
|
|
|
2023-05-21 21:20:41 +00:00
|
|
|
type ExtractIds<T extends Layout.Hierarchy, Depth extends Prev[number] = 9> =
|
2023-02-19 18:01:08 +00:00
|
|
|
[Depth] extends [never]
|
|
|
|
? never
|
|
|
|
: (T extends { id: infer Id extends string }
|
|
|
|
? { [k in Id]: T }
|
|
|
|
: never)
|
|
|
|
|
|
|
|
|
(
|
2023-05-21 21:20:41 +00:00
|
|
|
T extends { c: Array<infer Sub extends Layout.Hierarchy> }
|
2023-02-19 18:01:08 +00:00
|
|
|
? ExtractIds<Sub, Prev[Depth]>
|
|
|
|
: never
|
|
|
|
);
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-05-21 21:20:41 +00:00
|
|
|
declare module Layout {
|
2023-02-19 18:01:08 +00:00
|
|
|
type Layouter<T extends Hierarchy> =
|
|
|
|
ExtractIds<T>
|
|
|
|
&
|
|
|
|
{
|
|
|
|
// these actually change T
|
2023-05-18 21:39:44 +00:00
|
|
|
render(l?: Hierarchy): void;
|
|
|
|
layout(l: Hierarchy): void;
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-05-18 21:39:44 +00:00
|
|
|
debug(l?: Hierarchy, c?: ColorResolvable): void;
|
2023-02-19 18:01:08 +00:00
|
|
|
update(): void; // changes layoutObject into a RenderedHierarchy
|
2023-05-18 21:39:44 +00:00
|
|
|
clear(obj?: Hierarchy): void;
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-02-19 18:01:08 +00:00
|
|
|
forgetLazyState(): void;
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-02-19 18:01:08 +00:00
|
|
|
setUI(): void;
|
|
|
|
};
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-02-19 18:01:08 +00:00
|
|
|
var Layout: {
|
|
|
|
new <T extends Hierarchy>(
|
|
|
|
hier: T,
|
|
|
|
options?: {
|
|
|
|
lazy: boolean,
|
|
|
|
btns?: {
|
|
|
|
label: string,
|
|
|
|
cb: () => void,
|
|
|
|
cbl: () => void,
|
|
|
|
}[],
|
|
|
|
back?: () => void,
|
|
|
|
remove?: () => void,
|
|
|
|
},
|
|
|
|
): Layouter<T>;
|
|
|
|
};
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-02-19 18:01:08 +00:00
|
|
|
export type Layout = typeof Layout;
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-02-19 18:01:08 +00:00
|
|
|
type Image = string;
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-05-18 21:40:01 +00:00
|
|
|
type Fill = number; // fill a proportion of space, relative to sibling `filly`s
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-02-19 18:01:08 +00:00
|
|
|
type RenderedHierarchy =
|
|
|
|
Hierarchy & {
|
|
|
|
// top left position
|
|
|
|
x: number,
|
|
|
|
y: number,
|
|
|
|
// width and height
|
|
|
|
w: number,
|
|
|
|
h: number,
|
|
|
|
// minimum width and height
|
|
|
|
_w: number,
|
|
|
|
_h: number,
|
|
|
|
};
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-02-19 18:01:08 +00:00
|
|
|
type Hierarchy =
|
|
|
|
HierarchyParts & {
|
|
|
|
id?: string,
|
|
|
|
font?: FontNameWithScaleFactor,
|
|
|
|
scale?: number,
|
|
|
|
col?: ColorResolvable,
|
|
|
|
bgCol?: ColorResolvable,
|
|
|
|
pad?: number,
|
|
|
|
fillx?: Fill,
|
|
|
|
filly?: Fill,
|
|
|
|
width?: number,
|
|
|
|
height?: number,
|
2023-05-20 07:52:55 +00:00
|
|
|
|
|
|
|
// technically only on children of a h/v
|
|
|
|
halign?: Align, // children of a v
|
|
|
|
valign?: Align, // children of a h
|
2023-02-19 18:01:08 +00:00
|
|
|
} & (
|
|
|
|
{
|
|
|
|
r?: number, // 0: 0°, 1: 90°, 2: 180°, 3: 270°.
|
|
|
|
} | {
|
|
|
|
wrap?: boolean,
|
|
|
|
}
|
|
|
|
);
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-05-20 07:52:55 +00:00
|
|
|
const enum Align {
|
|
|
|
Left = -1,
|
|
|
|
Top = -1,
|
|
|
|
Center = 0,
|
|
|
|
Right = 1,
|
|
|
|
Bottom = -1,
|
|
|
|
}
|
2023-01-16 22:11:17 +00:00
|
|
|
|
2023-05-25 22:21:19 +00:00
|
|
|
const enum Rotation {
|
|
|
|
None = 0,
|
|
|
|
Deg90 = 1,
|
|
|
|
Deg180 = 2,
|
|
|
|
Deg270 = 3,
|
|
|
|
}
|
|
|
|
|
2023-02-19 18:01:08 +00:00
|
|
|
type HierarchyParts =
|
|
|
|
{
|
|
|
|
type: "v",
|
|
|
|
c: Hierarchy[],
|
|
|
|
} | {
|
|
|
|
type: "h"
|
|
|
|
c: Hierarchy[],
|
|
|
|
} | {
|
|
|
|
type: "txt",
|
|
|
|
label: string,
|
|
|
|
font: FontNameWithScaleFactor,
|
|
|
|
} | {
|
|
|
|
type: undefined, // blank, for padding
|
|
|
|
} | (
|
|
|
|
{
|
|
|
|
type: "btn",
|
|
|
|
src: Image,
|
|
|
|
cb: () => void,
|
2023-05-25 22:21:19 +00:00
|
|
|
r?: Rotation,
|
2023-06-18 21:38:54 +00:00
|
|
|
btnBorder?: ColorResolvable,
|
2023-02-19 18:01:08 +00:00
|
|
|
} | {
|
|
|
|
type: "btn",
|
|
|
|
cb: () => void,
|
|
|
|
label: string,
|
|
|
|
font?: FontNameWithScaleFactor,
|
|
|
|
scale?: number,
|
2023-05-25 22:21:19 +00:00
|
|
|
r?: Rotation,
|
2023-06-18 21:38:54 +00:00
|
|
|
btnBorder?: ColorResolvable,
|
2023-02-19 18:01:08 +00:00
|
|
|
}
|
|
|
|
) | {
|
|
|
|
type: "img",
|
|
|
|
src: Image | (() => Image),
|
2023-05-25 22:21:19 +00:00
|
|
|
r?: Rotation,
|
2023-02-19 18:01:08 +00:00
|
|
|
} | {
|
|
|
|
type: "custom",
|
2023-06-29 20:17:18 +00:00
|
|
|
render: (h: RenderedHierarchy) => void,
|
2023-02-19 18:01:08 +00:00
|
|
|
};
|
2023-01-16 22:11:17 +00:00
|
|
|
}
|