diff --git a/src/runtime.ts b/src/runtime.ts index cfde57d..acf596a 100644 --- a/src/runtime.ts +++ b/src/runtime.ts @@ -64,17 +64,10 @@ export function runApp(app: App, canvas: HTMLCanvasElement) { }); window.addEventListener('keydown', (e) => { - const result = handleKeyboard(e.key); - - if (result) { - const event: Value = { - kind: 'constructor', - name: result.event, - args: [{ kind: 'string', value: result.value }] - } + const event = handleKeyboard(e.key); + if (event) { handleEvent(event); - e.preventDefault(); } }) diff --git a/src/textinput-test.cg b/src/textinput-test.cg index 8cec12a..60d2b61 100644 --- a/src/textinput-test.cg +++ b/src/textinput-test.cg @@ -20,8 +20,8 @@ view = state \ w = 290, h = 30, focused = True, - onInput = "UpdateText", - onSubmit = "Submit" + onInput = UpdateText, + onSubmit = Submit } ] } diff --git a/src/types.ts b/src/types.ts index cb8d465..d622b97 100644 --- a/src/types.ts +++ b/src/types.ts @@ -54,6 +54,6 @@ export type UIValue = | { kind: 'clickable', child: UIValue, event: string } | { kind: 'padding', child: UIValue, amount: number } | { 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; diff --git a/src/ui-components.cg b/src/ui-components.cg new file mode 100644 index 0000000..1874853 --- /dev/null +++ b/src/ui-components.cg @@ -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} + ] + } + }; diff --git a/src/ui.ts b/src/ui.ts index 41c189c..114ba66 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -1,4 +1,4 @@ -import type { UIValue } from './types'; +import type { UIValue, Value } from './types'; type ClickRegion = { x: number; @@ -13,14 +13,14 @@ type TextInputRegion = { y: number; width: number; height: number; - inputId: string; - submitId: string; + inputConstructor: Value; + submitConstructor: Value; } let clickRegions: ClickRegion[] = []; let textInputRegions: TextInputRegion[] = []; -let focusedInput: string | null = null; -let focusedInputSubmit: string | null = null; +let focusedInput: Value | null = null; +let focusedInputSubmit: Value | null = null; export function render(ui: UIValue, canvas: HTMLCanvasElement) { const ctx = canvas.getContext('2d'); @@ -102,11 +102,11 @@ function renderUI(ui: UIValue, ctx: CanvasRenderingContext2D, x: number, y: numb y: y + ui.y, width: ui.w, height: ui.h, - inputId: ui.onInput, - submitId: ui.onSubmit + inputConstructor: ui.onInput, + 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; } @@ -191,8 +191,8 @@ export function hitTestTextInput(x: number, y: number): boolean { for (const region of textInputRegions) { if (x >= region.x && x < region.x + region.width && y >= region.y && y < region.y + region.height) { - focusedInput = region.inputId; - focusedInputSubmit = region.submitId; + focusedInput = region.inputConstructor; + focusedInputSubmit = region.submitConstructor; return true; } } @@ -202,36 +202,41 @@ export function hitTestTextInput(x: number, y: number): boolean { return false; } -export function getFocusedInput(): string | null { +export function getFocusedInput(): Value | null { return focusedInput; } -export function storeInputValue(inputId: string, value: string) { - if (inputId === focusedInput) { - currentInputValue = value; - } -} - -export function handleKeyboard(key: string): { event: string, value: string } | null { +export function handleKeyboard(key: string): Value | null { if (!focusedInput) return null; if (key === 'Enter') { - return focusedInputSubmit - ? { event: focusedInputSubmit, value: currentInputValue } - : null; + if (!focusedInputSubmit) return null; + return { + kind: 'constructor', + name: (focusedInputSubmit as any).name, + args: [{ kind: 'string', value: currentInputValue }] + }; } if (key === 'Backspace') { const newValue = currentInputValue.slice(0, -1); currentInputValue = newValue; - return { event: focusedInput, value: newValue }; + return { + kind: 'constructor', + name: (focusedInput as any).name, + args: [{ kind: 'string', value: newValue }] + }; } // Character if (key.length === 1) { const newValue = currentInputValue + key; currentInputValue = newValue; - return { event: focusedInput, value: newValue }; + return { + kind: 'constructor', + name: (focusedInput as any).name, + args: [{ kind: 'string', value: newValue }] + }; } return null; diff --git a/src/valueToUI.ts b/src/valueToUI.ts index 8ea799a..24e7b13 100644 --- a/src/valueToUI.ts +++ b/src/valueToUI.ts @@ -87,7 +87,7 @@ export function valueToUI(value: Value): UIValue { if (value.kind !== 'string' || placeholder.kind !== 'string' || 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'); const isFocused = focused.kind === 'constructor' && focused.name === 'True'; @@ -101,8 +101,8 @@ export function valueToUI(value: Value): UIValue { w: w.value, h: h.value, focused: isFocused, - onInput: onInput.value, - onSubmit: onSubmit.value + onInput: onInput, + onSubmit: onSubmit }; }