text input now passes actual constructors instead of strings

master
Dustin Swan 4 days ago
parent 223eea72e3
commit 645de97db2
Signed by: dustinswan
GPG Key ID: 30D46587E2100467

@ -64,17 +64,10 @@ export function runApp(app: App, canvas: HTMLCanvasElement) {
}); });
window.addEventListener('keydown', (e) => { window.addEventListener('keydown', (e) => {
const result = handleKeyboard(e.key); const event = handleKeyboard(e.key);
if (result) {
const event: Value = {
kind: 'constructor',
name: result.event,
args: [{ kind: 'string', value: result.value }]
}
if (event) {
handleEvent(event); handleEvent(event);
e.preventDefault(); e.preventDefault();
} }
}) })

@ -20,8 +20,8 @@ view = state \
w = 290, w = 290,
h = 30, h = 30,
focused = True, focused = True,
onInput = "UpdateText", onInput = UpdateText,
onSubmit = "Submit" onSubmit = Submit
} }
] ]
} }

@ -54,6 +54,6 @@ export type UIValue =
| { kind: 'clickable', child: UIValue, event: string } | { kind: 'clickable', child: UIValue, event: string }
| { kind: 'padding', child: UIValue, amount: number } | { kind: 'padding', child: UIValue, amount: 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: string, onSubmit: string } | { kind: 'text-input', value: string, placeholder: string, x: number, y: number, w: number, h: number, focused: boolean, onInput: Value, onSubmit: Value }
export type Value = IntValue | FloatValue | StringValue | Closure | ListValue | RecordValue | ConstructorValue | NativeFunction; export type Value = IntValue | FloatValue | StringValue | Closure | ListValue | RecordValue | ConstructorValue | NativeFunction;

@ -0,0 +1,10 @@
button = config \
Clickable {
event = config.event,
child = Stack {
children = [
Rect { w = 100, h = 40, color = "blue" },
Text { content = config.label, x = 10, y = 25}
]
}
};

@ -1,4 +1,4 @@
import type { UIValue } from './types'; import type { UIValue, Value } from './types';
type ClickRegion = { type ClickRegion = {
x: number; x: number;
@ -13,14 +13,14 @@ type TextInputRegion = {
y: number; y: number;
width: number; width: number;
height: number; height: number;
inputId: string; inputConstructor: Value;
submitId: string; submitConstructor: Value;
} }
let clickRegions: ClickRegion[] = []; let clickRegions: ClickRegion[] = [];
let textInputRegions: TextInputRegion[] = []; let textInputRegions: TextInputRegion[] = [];
let focusedInput: string | null = null; let focusedInput: Value | null = null;
let focusedInputSubmit: string | null = null; let focusedInputSubmit: Value | null = null;
export function render(ui: UIValue, canvas: HTMLCanvasElement) { export function render(ui: UIValue, canvas: HTMLCanvasElement) {
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
@ -102,11 +102,11 @@ function renderUI(ui: UIValue, ctx: CanvasRenderingContext2D, x: number, y: numb
y: y + ui.y, y: y + ui.y,
width: ui.w, width: ui.w,
height: ui.h, height: ui.h,
inputId: ui.onInput, inputConstructor: ui.onInput,
submitId: ui.onSubmit submitConstructor: ui.onSubmit
}); });
if (ui.focused && ui.onInput === focusedInput) { if (ui.focused && focusedInput && (ui.onInput as any).name === (focusedInput as any).name) {
currentInputValue = ui.value; currentInputValue = ui.value;
} }
@ -191,8 +191,8 @@ export function hitTestTextInput(x: number, y: number): boolean {
for (const region of textInputRegions) { for (const region of textInputRegions) {
if (x >= region.x && x < region.x + region.width && if (x >= region.x && x < region.x + region.width &&
y >= region.y && y < region.y + region.height) { y >= region.y && y < region.y + region.height) {
focusedInput = region.inputId; focusedInput = region.inputConstructor;
focusedInputSubmit = region.submitId; focusedInputSubmit = region.submitConstructor;
return true; return true;
} }
} }
@ -202,36 +202,41 @@ export function hitTestTextInput(x: number, y: number): boolean {
return false; return false;
} }
export function getFocusedInput(): string | null { export function getFocusedInput(): Value | null {
return focusedInput; return focusedInput;
} }
export function storeInputValue(inputId: string, value: string) { export function handleKeyboard(key: string): Value | null {
if (inputId === focusedInput) {
currentInputValue = value;
}
}
export function handleKeyboard(key: string): { event: string, value: string } | null {
if (!focusedInput) return null; if (!focusedInput) return null;
if (key === 'Enter') { if (key === 'Enter') {
return focusedInputSubmit if (!focusedInputSubmit) return null;
? { event: focusedInputSubmit, value: currentInputValue } return {
: null; kind: 'constructor',
name: (focusedInputSubmit as any).name,
args: [{ kind: 'string', value: currentInputValue }]
};
} }
if (key === 'Backspace') { if (key === 'Backspace') {
const newValue = currentInputValue.slice(0, -1); const newValue = currentInputValue.slice(0, -1);
currentInputValue = newValue; currentInputValue = newValue;
return { event: focusedInput, value: newValue }; return {
kind: 'constructor',
name: (focusedInput as any).name,
args: [{ kind: 'string', value: newValue }]
};
} }
// Character // Character
if (key.length === 1) { if (key.length === 1) {
const newValue = currentInputValue + key; const newValue = currentInputValue + key;
currentInputValue = newValue; currentInputValue = newValue;
return { event: focusedInput, value: newValue }; return {
kind: 'constructor',
name: (focusedInput as any).name,
args: [{ kind: 'string', value: newValue }]
};
} }
return null; return null;

@ -87,7 +87,7 @@ export function valueToUI(value: Value): UIValue {
if (value.kind !== 'string' || placeholder.kind !== 'string' || if (value.kind !== 'string' || placeholder.kind !== 'string' ||
x.kind !== 'int' || y.kind !== 'int' || w.kind !== 'int' || h.kind !== 'int' || x.kind !== 'int' || y.kind !== 'int' || w.kind !== 'int' || h.kind !== 'int' ||
onInput.kind !== 'string' || onSubmit.kind !== 'string') onInput.kind !== 'constructor' || onSubmit.kind !== 'constructor')
throw new Error('Invalid TextInput fields'); throw new Error('Invalid TextInput fields');
const isFocused = focused.kind === 'constructor' && focused.name === 'True'; const isFocused = focused.kind === 'constructor' && focused.name === 'True';
@ -101,8 +101,8 @@ export function valueToUI(value: Value): UIValue {
w: w.value, w: w.value,
h: h.value, h: h.value,
focused: isFocused, focused: isFocused,
onInput: onInput.value, onInput: onInput,
onSubmit: onSubmit.value onSubmit: onSubmit
}; };
} }

Loading…
Cancel
Save