border radius on rect

master
Dustin Swan 3 days ago
parent 58715f42bf
commit 441957185e
Signed by: dustinswan
GPG Key ID: 30D46587E2100467

@ -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 }

@ -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 }

@ -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';

@ -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': {

Loading…
Cancel
Save