text input now passes actual constructors instead of strings
This commit is contained in:
parent
223eea72e3
commit
645de97db2
6 changed files with 46 additions and 38 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
10
src/ui-components.cg
Normal file
10
src/ui-components.cg
Normal file
|
|
@ -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}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
51
src/ui.ts
51
src/ui.ts
|
|
@ -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…
Add table
Add a link
Reference in a new issue