diff --git a/src/textinput-test.cg b/src/textinput-test.cg index ddb268e..4072616 100644 --- a/src/textinput-test.cg +++ b/src/textinput-test.cg @@ -6,33 +6,36 @@ update = state event \ event | Go \ state.{ text = "" }; view = state viewport \ - Column { - gap = 20, - children = [ - Text { - content = "window: " & str(viewport.width) & " x " & str(viewport.height), - x = 0, - y = 20 - }, - Text { content = "You typed: " & state.text, x = 0, y = 20 }, - Stack { + Padding { + amount = 20, + child = Column { + gap = 20, children = [ - Rect { w = viewport.width, h = 40, color = "blue" }, - TextInput { - value = state.text, - placeholder = "Type something...", - x = 5, - y = 5, - w = 290, - h = 30, - focused = True, - onInput = UpdateText, - onSubmit = Submit - } + Text { + content = "window: " & str(viewport.width) & " x " & str(viewport.height), + x = 0, + y = 20 + }, + Text { content = "You typed: " & state.text, x = 0, y = 20 }, + Stack { + children = [ + Rect { w = 300, h = 40, color = "blue", radius = 2 }, + TextInput { + value = state.text, + placeholder = "Type something...", + x = 5, + y = 5, + w = 290, + h = 30, + focused = True, + onInput = UpdateText, + onSubmit = Submit + } + ] + }, + button { label = "Go", event = Go, theme = theme } ] - }, - button { label = "Go", event = Go, theme = theme } - ] + } }; { init = init, update = update, view = view } diff --git a/src/types.ts b/src/types.ts index 3b467c6..c4aa396 100644 --- a/src/types.ts +++ b/src/types.ts @@ -47,7 +47,7 @@ export type NativeFunction = { } export type UIValue = - | { kind: 'rect', w: number, h: number, color: string } + | { kind: 'rect', w: number, h: number, color: string, radius?: number } | { kind: 'text', content: string, x: number, y: number } | { kind: 'row', children: UIValue[], gap: number } | { kind: 'column', children: UIValue[], gap: number } diff --git a/src/ui.ts b/src/ui.ts index 6a24587..eec323b 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -39,10 +39,29 @@ export function render(ui: UIValue, canvas: HTMLCanvasElement) { function renderUI(ui: UIValue, ctx: CanvasRenderingContext2D, x: number, y: number) { switch (ui.kind) { - case 'rect': + case 'rect': { ctx.fillStyle = ui.color; - ctx.fillRect(x, y, ui.w, ui.h); + + if (ui.radius && ui.radius > 0) { + const r = Math.min(ui.radius, ui.w / 2, ui.h / 2); + ctx.beginPath(); + ctx.moveTo(x + r, y); + ctx.lineTo(x + ui.w - r, y); + ctx.arcTo(x + ui.w, y, x + ui.w, y + r, r); + ctx.lineTo(x + ui.w, y + ui.h - r); + ctx.arcTo(x + ui.w, y + ui.h, x + ui.w - r, y + ui.h, r); + ctx.lineTo(x + r, y + ui.h); + ctx.arcTo(x, y + ui.h, x, y + ui.h - r, r); + ctx.lineTo(x, y + r); + ctx.arcTo(x, y, x + r, y, r); + ctx.closePath(); + ctx.fill(); + } else { + ctx.fillRect(x, y, ui.w, ui.h); + } + break; + } case 'text': ctx.fillStyle = 'black'; diff --git a/src/valueToUI.ts b/src/valueToUI.ts index cfc2ef4..2be6c4a 100644 --- a/src/valueToUI.ts +++ b/src/valueToUI.ts @@ -12,14 +12,18 @@ export function valueToUI(value: Value): UIValue { switch (value.name) { case 'Rect': { - const w = fields.w; - const h = fields.h; - const color = fields.color; + const { w, h, color, radius } = fields; if (w.kind !== 'int' || h.kind !== 'int' || color.kind !== 'string') throw new Error('Invalid Rect fields'); - return { kind: 'rect', w: w.value, h: h.value, color: color.value }; + return { + kind: 'rect', + w: w.value, + h: h.value, + color: color.value, + radius: radius && radius.kind === 'int' ? radius.value : 0 + }; } case 'Text': {