Adding Clip ui primitive. text boxes looking... well, still awful but getting there

master
Dustin Swan 3 days ago
parent 4626616b14
commit 787e071fbd
Signed by: dustinswan
GPG Key ID: 30D46587E2100467

@ -55,6 +55,7 @@ export type UIValue =
| { kind: 'padding', child: UIValue, amount: number } | { kind: 'padding', child: UIValue, amount: number }
| { kind: 'positioned', x: number, y: number, child: UIValue } | { kind: 'positioned', x: number, y: number, child: UIValue }
| { kind: 'opacity', child: UIValue, opacity: number } | { kind: 'opacity', child: UIValue, opacity: number }
| { kind: 'clip', child: UIValue, w: number, h: number }
| { kind: 'stack', children: UIValue[] } | { kind: 'stack', children: UIValue[] }
| { kind: 'text-input', value: string, placeholder: string, x: number, y: number, w: number, h: number, focused: boolean, onInput: Value, onSubmit: Value } | { kind: 'text-input', value: string, placeholder: string, x: number, y: number, w: number, h: number, focused: boolean, onInput: Value, onSubmit: Value }

@ -72,7 +72,10 @@ textInput2 = {
cursorX = measureText textBeforeCursor; cursorX = measureText textBeforeCursor;
padding = 8; padding = 8;
Clickable { Clip {
w = config.w,
h = config.h,
child = Clickable {
event = config.onFocus, event = config.onFocus,
child = child =
Stack { Stack {
@ -95,4 +98,5 @@ textInput2 = {
] ]
} }
} }
}
}; };

@ -110,6 +110,16 @@ function renderUI(ui: UIValue, ctx: CanvasRenderingContext2D, x: number, y: numb
break; break;
} }
case 'clip': {
ctx.save();
ctx.beginPath();
ctx.rect(x, y, ui.w, ui.h);
ctx.clip();
renderUI(ui.child, ctx, x, y);
ctx.restore();
break;
}
case 'stack': { case 'stack': {
for (const child of ui.children) { for (const child of ui.children) {
renderUI(child, ctx, x, y); renderUI(child, ctx, x, y);
@ -184,6 +194,12 @@ function measure(ui: UIValue): { width: number, height: number } {
case 'clickable': case 'clickable':
return measure(ui.child); return measure(ui.child);
case 'opacity':
return measure(ui.child);
case 'clip':
return { width: ui.w, height: ui.h };
case 'padding': { case 'padding': {
const childSize = measure(ui.child); const childSize = measure(ui.child);
return { return {

@ -95,6 +95,15 @@ export function valueToUI(value: Value): UIValue {
return { kind: 'opacity', opacity: opacity.value, child: valueToUI(child) }; return { kind: 'opacity', opacity: opacity.value, child: valueToUI(child) };
} }
case 'Clip': {
const { child, w, h } = fields;
if (w.kind !== 'int' || h.kind !== 'int')
throw new Error('Invalid Clip fields');
return { kind: 'clip', w: w.value, h: h.value, child: valueToUI(child) };
}
case 'Stack': { case 'Stack': {
const children = fields.children; const children = fields.children;

Loading…
Cancel
Save