start work on ui views

This commit is contained in:
Matthew 2025-12-22 20:36:38 +11:00
parent bf1e8aaac2
commit 39ab34ebeb
3 changed files with 101 additions and 116 deletions

View File

@ -147,91 +147,15 @@ Cycle(EditorCtx* ctx, Inputs* inputs)
UICtx* ui_ctx = GetCtx();
Vec4[4] col0 = Vec4(0.2, 0.4, 0.8, 1.0);
Vec4[4] col1 = Vec4(0.8, 0.4, 0.2, 1.0);
Vec4[4] blue = Vec4(0.1, 0.3, 0.9, 1.0);
Vec4[4] black = Vec4(0.0, 0.0, 0.0, 1.0);
Vec4[4] green = Vec4(0.2, 0.8, 0.1, 1.0);
Vec4[4] white = Vec4(1.0);
static Editor* ed;
Push!("border_thickness", true)(ui_ctx, 10.0f);
Push!("size_info")(ui_ctx, MakeUISizeX(ST.Percentage, 0.5));
Push!("bg_col", true)(ui_ctx, col0);
UIItem* p0 = MakeItem("###p0", UIF.DrawBackground|UIF.Resizeable|UIF.DrawBorder);
Push!("layout_axis", true)(ui_ctx, A2D.Y);
Push!("parent")(ui_ctx, p0);
Push!("size_info", true)(ui_ctx, MakeUISize(UISize(ST.ChildrenSum, 1.0), UISize(ST.Percentage, 1.0)));
Push!("bg_col", true)(ui_ctx, blue);
UIItem* ln = MakeItem("###ln", UIF.DrawBackground);
Push!("parent")(ui_ctx, ln);
Push!("bg_col")(ui_ctx, white);
Push!("padding")(ui_ctx, Vec2(4.0, 0.0));
Push!("size_info")(ui_ctx, MakeUISize(UISize(ST.TextSize, 1.0), UISize(ST.Pixels, ui_ctx.char_height)));
foreach(i; 0 .. 99)
if(!ed)
{
MakeItem("%s##ln", i, UIF.DrawText);
ed = CreateEditor(ctx);
OpenFile(ed, CastStr!(u8)("src/editor/ui.d"));
}
Pop!("padding", "size_info", "parent", "bg_col")(ui_ctx);
Push!("size_info", true)(ui_ctx, MakeUISizeX(ST.Percentage, 1.0));
Push!("layout_axis", true)(ui_ctx, A2D.Y);
UIItem* t_box = MakeItem("###t_box");
Push!("parent")(ui_ctx, t_box);
Push!("size_info", true)(ui_ctx, MakeUISize(UISize(ST.Pixels, 350.0, 1.0), UISize(ST.TextSize, 1.0, 1.0)));
Push!("bg_col", true)(ui_ctx, green);
Push!("padding", true)(ui_ctx, Vec2(4.0));
UIItem* text = MakeItem("Test line of text##text", UIF.DrawBackground|UIF.DrawText|UIF.RightAlignText|UIF.TextWrap);
Push!("size_info", true)(ui_ctx, MakeUISize(UISize(ST.Percentage, 1.0, 1.0), UISize(ST.TextSize, 1.0, 1.0)));
Push!("bg_col", true)(ui_ctx, white);
Push!("text_col", true)(ui_ctx, black[0]);
Push!("padding", true)(ui_ctx, Vec2(8.0));
UIItem* text2 = MakeItem("A different line of text for testing purposes##text2", UIF.DrawBackground|UIF.DrawText|UIF.TextWrap);
Pop!("parent")(ui_ctx);
Pop!("parent")(ui_ctx);
Push!("size_info", true)(ui_ctx, MakeUISizeX(ST.Pixels, 100.0));
Push!("bg_col", true)(ui_ctx, black);
UIItem* sep = MakeItem("###sep", UIF.Draggable|UIF.DrawBackground|UIF.ResizeAdjacent);
Push!("layout_axis", true)(ui_ctx, A2D.Y);
Push!("bg_col", true)(ui_ctx, col1);
UIItem* p1 = MakeItem("###p1", UIF.DrawBackground|UIF.Resizeable);
Push!("parent")(ui_ctx, p1);
Vec4[4] c0 = Vec4(Vec3(0.2), 1.0);
Vec4[4] c1 = Vec4(Vec3(0.4), 1.0);
Vec4[4] c2 = Vec4(Vec3(0.6), 1.0);
Vec4[4] c3 = Vec4(Vec3(0.8), 1.0);
Vec4[4] c4 = Vec4(1.0);
Push!("bg_col", true)(ui_ctx, c0);
Push!("size_info", true)(ui_ctx, MakeUISizeY(ST.Percentage, 0.1));
MakeItem("###c0", UIF.DrawBackground);
Push!("bg_col", true)(ui_ctx, c1);
Push!("size_info", true)(ui_ctx, MakeUISizeY(ST.Percentage, 0.13));
MakeItem("###c1", UIF.DrawBackground);
Push!("bg_col", true)(ui_ctx, c2);
Push!("size_info", true)(ui_ctx, MakeUISizeY(ST.Percentage, 0.17));
MakeItem("###c2", UIF.DrawBackground);
Push!("bg_col", true)(ui_ctx, c3);
Push!("size_info", true)(ui_ctx, MakeUISizeY(ST.Percentage, 0.25));
MakeItem("###c3", UIF.DrawBackground);
Push!("bg_col", true)(ui_ctx, c4);
Push!("size_info", true)(ui_ctx, MakeUISizeY(ST.Percentage, 0.35));
MakeItem("###c4", UIF.DrawBackground);
EditorView(ed);
/*
UIPanel* root = ctx.base_panel;

View File

@ -67,6 +67,7 @@ f32 g_text_scale_default = 1.0;
Vec2 g_scroll_target_default = Vec2(0.0);
Vec2 g_scroll_clamp_default = Vec2(0.0);
Vec2 g_view_offset_default = Vec2(0.0);
string g_display_string_default = null;
alias g_parent_default = g_UI_NIL;
const UI_COUNT = 5000;
@ -198,6 +199,7 @@ struct UICtx
{
HashTable!(UIHash, UIItem*) items;
UIItem* free_items;
UIItem* transient_items;
Arena arena;
Arena temp_arena;
@ -249,6 +251,7 @@ struct UICtx
mixin UICtxParameter!(Vec2, "padding");
mixin UICtxParameter!(Vec2, "view_offset");
mixin UICtxParameter!(UIItem*, "parent");
mixin UICtxParameter!(string, "display_string");
mixin UICtxParameter!(Axis2D, "layout_axis");
mixin UICtxParameter!(f32, "corner_radius");
mixin UICtxParameter!(f32, "border_thickness");
@ -309,11 +312,11 @@ struct UIItem
UIFlags flags;
UIItem* next, prev, first, last; // parent in mixin
UIItem* transient_next;
Rect rect;
Vec2 size;
string display_string;
string[] text_lines;
f32 max_text_width;
f32 resize_pct;
@ -466,6 +469,7 @@ InitUICtx(PlatformWindow* window)
arena: arena,
temp_arena: CreateArena(MB(1)),
drag_item: g_UI_NIL,
transient_items: g_UI_NIL,
font: OpenFont(cast(u8[])FONT_BYTES),
font_data: cast(u8[])FONT_BYTES,
text_size: 16.0,
@ -473,7 +477,7 @@ InitUICtx(PlatformWindow* window)
};
UIItem* fi = ctx.free_items;
fi.first = fi.last = fi.next = fi.prev = fi.parent = g_UI_NIL;
fi.transient_next = fi.first = fi.last = fi.next = fi.prev = fi.parent = g_UI_NIL;
ctx.atlas_buf = CreateAtlas(&arena, ctx.font, 16.0, 256);
ctx.char_height = cast(f32)((ctx.font.size.metrics.ascender - ctx.font.size.metrics.descender) >> 6);
@ -828,15 +832,21 @@ BeginUI(Inputs* inputs)
foreach(i; 0 .. items.length)
{
UIItem* item = items[i].value;
if(item.last_frame != ctx.frame || ZeroKey(item.key))
if(item.last_frame != ctx.frame)
{
Logf("discarding %s", cast(char[])item.key.hash_text);
item.first = item.last = item.parent = item.prev = item.next = g_UI_NIL;
memset(item, 0, UIItem.sizeof);
DLLPush(ctx.free_items, item, g_UI_NIL);
}
}
for(UIItem* item = ctx.transient_items; !Nil(item); item = item.transient_next)
{
memset(item, 0, UIItem.sizeof);
DLLPush(ctx.free_items, item, g_UI_NIL);
}
ctx.frame += 1;
ctx.transient_items = g_UI_NIL;
// Ctx state
ctx.f_idx = ctx.frame%FRAME_OVERLAP;
@ -989,6 +999,11 @@ EndUI()
{
f32 size = InnerSize!(axis)(item);
if(item.flags & (UIF.PortalX << axis))
{
continue;
}
if(axis == item.layout_axis)
{
f32 children_size = 0.0;
@ -1062,6 +1077,8 @@ EndUI()
item.rect.p0.v[axis] = inner_pos;
item.rect.p1.v[axis] = end_pos;
next_pos = item.parent.layout_axis == axis ? end_pos : pos;
assert(!isNaN(item.rect.p0.v[axis]));
assert(!isNaN(item.rect.p1.v[axis]));
@ -1087,8 +1104,6 @@ EndUI()
}
}
next_pos = item.parent.layout_axis == axis ? end_pos : pos;
if(!Nil(item.first))
{
item = item.first;
@ -1181,7 +1196,7 @@ RenderItem(UICtx* ctx, UIItem* item)
v.dst_end = item.rect.p1;
v.cols = item.border_col;
v.corner_radius = item.corner_radius;
v.border_thickness = item.border_thickness;
v.border_thickness = clamp(item.border_thickness, 1.0, f32.max);
v.edge_softness = item.edge_softness;
v.bounds = ItemBounds(item.parent);
@ -1566,6 +1581,25 @@ ZeroKey(UIKey key)
return key.hash == 0 && key.hash_text.length == 0;
}
UIItem*
NewItem(UICtx* ctx)
{
UIItem* item = g_UI_NIL;
if(!Nil(ctx.free_items.first))
{
item = DLLPop(ctx.free_items, g_UI_NIL);
}
else
{
item = Alloc!(UIItem)(&ctx.arena);
}
item.last_frame = ctx.frame-2;
return item;
}
UIItem*
Get(Args...)(string str, Args args)
{
@ -1585,26 +1619,33 @@ Get(T)(T k) if(is(T: UIKey) || StringType!T)
UIKey key = MakeKey(k);
}
Result!(UIItem*) res = g_ui_ctx.items[key.hash];
if(!res.ok)
UIItem* item;
UICtx* ctx = GetCtx();
if(ZeroKey(key))
{
if(!Nil(g_ui_ctx.free_items.first))
{
res.value = DLLPop(g_ui_ctx.free_items, g_UI_NIL);
item = NewItem(ctx);
item.transient_next = ctx.transient_items;
ctx.transient_items = item;
}
else
{
res.value = Alloc!(UIItem)(&g_ui_ctx.arena);
HTPush(&g_ui_ctx.items, key.hash, res.value);
Result!(UIItem*) res = ctx.items[key.hash];
if(res.ok)
{
item = res.value;
}
else
{
item = NewItem(ctx);
HTPush(&ctx.items, key.hash, item);
}
}
res.value.last_frame = g_ui_ctx.frame-2;
}
item.key = key;
item.next = item.prev = item.first = item.last = item.parent = g_UI_NIL;
res.value.key = key;
res.value.next = res.value.prev = res.value.first = res.value.last = res.value.parent = g_UI_NIL;
return res.value;
return item;
}
f32

View File

@ -25,11 +25,18 @@ EditorView(Editor* ed)
u64 frame_line_offset = ed.line_offset;
f32 frame_view_offset = editor.scroll_offset.y%TEXT_SIZE;
Push!("border_col" )(ctx, Vec4Arr(Vec4(1.0)));
Push!("bg_col", true)(ctx, Vec4Arr(Vec4(0.2, 0.3, 0.8, 1.0)));
Push!("size_info", true)(ctx, MakeUISizeX(ST.Percentage, 1.0));
UIItem* container = MakeItem(zero, UIF.DrawBackground);
Push!("parent")(ctx, container);
Push!("border_col")(ctx, Vec4Arr(Vec4(1.0)));
// Line Counter
f32 lc_width = ed.buf.line_count.toChars().length*ctx.char_width;
Push!("layout_axis", true)(ctx, A2D.Y);
Push!("view_offset" )(ctx, Vec2(0.0, frame_view_offset));
Push!("padding", true)(ctx, Vec2(4.0, 0.0));
Push!("size_info", true)(ctx, MakeUISizeX(ST.Pixels, lc_width));
@ -39,6 +46,7 @@ EditorView(Editor* ed)
// Editor
f32 scroll_pos = cast(f32)(ed.line_offset)*TEXT_SIZE;
Push!("layout_axis", true)(ctx, A2D.Y);
Push!("scroll_clamp", true)(ctx, cast(Vec2[2])[Vec2(0.0), Vec2(0.0, cast(f32)(ed.buf.line_count)*TEXT_SIZE)]);
Push!("size_info", true)(ctx, MakeUISize(UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0)));
Push!("border_col", true)(ctx, Vec4Arr(Vec4(1.0)));
@ -72,14 +80,26 @@ EditorView(Editor* ed)
Push!("parent" )(ctx, line_count);
Push!("text_col" )(ctx, Vec4(1.0));
u64 i = frame_line_offset;
for(LineBuffer* lb = GetLine(&ed.buf, i); i < frame_line_offset+view_lines; i += 1)
{
u64 end_line = frame_line_offset+view_lines;
for(u64 i = frame_line_offset; i < end_line; i += 1)
{
MakeItem("%s##ed_%s", i, ed.editor_id, UIF.DrawText);
}
Pop!("parent")(ctx);
Pop!("parent", "size_info")(ctx);
Push!("size_info")(ctx, MakeUISizeY(ST.TextSize, 1.0));
Push!("parent")(ctx, editor);
u64 i = frame_line_offset;
for(LineBuffer* lb = GetLine(&ed.buf, i); !CheckNil(g_NIL_LINE_BUF, lb) && i < end_line; i += 1, lb = GetLine(&ed.buf, i))
{
Push!("display_string", true)(ctx, ConvToStr(lb.text));
UIItem* line = MakeItem(zero, UIF.DrawText);
}
Pop!("parent", "parent", "text_col")(ctx);
}
/*