90 lines
2.5 KiB
Plaintext
Raw Normal View History

2024-12-11 01:14:14 +01:00
module ugui;
import std::io;
2024-12-11 22:25:53 +01:00
2024-12-20 19:50:58 +01:00
struct ElemText {
2025-07-10 11:05:39 +02:00
Id hash;
2025-09-09 19:10:04 +02:00
TextSize size;
TextEdit* te;
2024-12-20 19:50:58 +01:00
}
2025-09-09 19:10:04 +02:00
macro Ctx.text(&ctx, String text, ...)
=> ctx.text_id(@compute_id($vasplat), text);
fn void? Ctx.text_id(&ctx, Id id, String text)
2024-12-11 01:14:14 +01:00
{
id = ctx.gen_id(id)!;
2024-12-11 01:14:14 +01:00
Elem *parent = ctx.get_parent()!;
Elem *elem = ctx.get_elem(id, ETYPE_TEXT)!;
2025-07-06 23:13:16 +02:00
Style* style = ctx.styles.get_style(@str_hash("text"));
2024-12-11 01:14:14 +01:00
2025-07-10 11:05:39 +02:00
Id text_hash = text.hash();
if (elem.flags.is_new || elem.text.hash != text_hash) {
2025-09-09 19:10:04 +02:00
elem.text.size = ctx.measure_string(text)!;
2025-07-10 11:05:39 +02:00
}
elem.text.hash = text_hash;
2024-12-11 01:14:14 +01:00
2025-09-09 19:10:04 +02:00
elem.layout.w = @fit(style.size);
elem.layout.h = @fit(style.size);
elem.layout.text = elem.text.size;
elem.layout.content_offset = style.margin + style.border + style.padding;
update_parent_grow(elem, parent);
update_parent_size(elem, parent);
2024-12-11 01:14:14 +01:00
2025-09-09 19:10:04 +02:00
ctx.layout_string(text, elem.bounds.pad(elem.layout.content_offset), TOP_LEFT, parent.div.z_index, style.fg)!;
2024-12-11 01:14:14 +01:00
}
2025-06-30 13:10:00 +02:00
macro Ctx.text_box(&ctx, Size w, Size h, TextEdit* te, ...)
=> ctx.text_box_id(@compute_id($vasplat), w, h, te);
fn ElemEvents? Ctx.text_box_id(&ctx, Id id, Size w, Size h, TextEdit* te)
2025-06-30 13:10:00 +02:00
{
id = ctx.gen_id(id)!;
2025-06-30 13:10:00 +02:00
Elem *parent = ctx.get_parent()!;
Elem *elem = ctx.get_elem(id, ETYPE_TEXT)!;
2025-07-06 23:13:16 +02:00
Style* style = ctx.styles.get_style(@str_hash("text-box"));
2025-07-05 16:37:08 +02:00
elem.text.te = te;
2025-06-30 13:10:00 +02:00
Id text_hash = te.to_string().hash();
if (elem.flags.is_new || elem.text.hash != text_hash) {
elem.text.size = ctx.measure_string(te.to_string())!;
}
elem.text.hash = text_hash;
elem.layout.w = w;
elem.layout.h = h;
elem.layout.text = elem.text.size;
elem.layout.content_offset = style.margin + style.border + style.padding;
update_parent_grow(elem, parent);
update_parent_size(elem, parent);
2025-06-30 13:10:00 +02:00
// check input and update the text
elem.events = ctx.get_elem_events(elem);
if (elem.events.text_input || elem.events.key_press) {
ctx.text_edit(elem.text.te);
2025-06-30 13:10:00 +02:00
}
// draw the box
Rect bg_bounds = elem.bounds.pad(style.margin);
Rect text_bounds = elem.bounds.pad(elem.layout.content_offset);
ctx.push_rect(bg_bounds, parent.div.z_index, style)!;
Rect cur;
cur = ctx.layout_string(elem.text.te.to_string(), text_bounds, TOP_LEFT, parent.div.z_index, style.fg, elem.text.te.cursor)!;
2025-06-30 13:10:00 +02:00
// draw the cursor if the element has focus
if (elem.events.has_focus) {
cur.w = 2;
// FIXME: gross hack for when text is empty
if (cur.x == 0 && cur.y == 0) {
cur.x = text_bounds.x;
cur.y = text_bounds.y;
}
ctx.push_rect(cur, parent.div.z_index, &&(Style){.bg = style.fg})!;
}
2025-06-30 13:10:00 +02:00
return elem.events;
}