From 3feb5041bd9a943318de4f2da2eb00e24953a25b Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 10 Oct 2025 19:02:34 +1100 Subject: [PATCH] start rework of UI --- src/editor/editor.d | 31 ++++++++++- src/editor/ui.d | 121 +++++++++++++++++++++++++++++++++++++++++++ src/editor/widgets.d | 93 +++++++++++++++++++++++++++++++++ 3 files changed, 243 insertions(+), 2 deletions(-) diff --git a/src/editor/editor.d b/src/editor/editor.d index 2da9614..b9f27a4 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -142,8 +142,32 @@ Cycle(EditorCtx* ctx, Inputs* inputs) g_input_mode = ctx.state == ES.InputMode; // UI Functions After This Point - BeginBuild(inputs); + //BeginBuild(inputs); + UICtx* uictx = GetCtx(); + uictx.inputs = inputs; + + PrepRendering(uictx); + + SetPanelSizes(ctx.base_panel); + + for(auto p = ctx.base_panel; !Nil(p); p = Recurse(p)) + { + Panel2(p); + } + + with(uictx) + { + BindBuffers(&rd, &buffers[f_idx].m_idx, &buffers[f_idx].m_vtx); + DrawIndexed(&rd, 6, buffers[f_idx].count, 0); + } + + + CompleteRendering(uictx); + + uictx.frame += 1; + + /* if(ctx.state == ES.CmdOpen) { if(ctx.cmd.commands.length == 0 && ctx.cmd.icount == 0) @@ -155,11 +179,14 @@ Cycle(EditorCtx* ctx, Inputs* inputs) } DrawPanels(ctx.base_panel); + */ + + //EndBuild(); - EndBuild(); // UI Functions Before This Point } + EditorCtx InitEditorCtx(PlatformWindow* window) { diff --git a/src/editor/ui.d b/src/editor/ui.d index af6d959..edfacf3 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -136,6 +136,8 @@ struct UICtx debug u32 item_count; debug u32 final_count; debug bool dbg; + + } struct UIStack(T) @@ -1518,6 +1520,58 @@ DrawGlyph(UIItem* item, Glyph* glyph, f32 scale, f32* x_pos, f32 y, bool highlig *x_pos += glyph.advance * scale; } +pragma(inline) Vertex* +GetVertex(UICtx* ctx) +{ + return ctx.buffers[ctx.f_idx].vtx.ptr + ctx.buffers[ctx.f_idx].count; +} + +pragma(inline) void +DrawBorderedRect(Vec2 pos, Vec2 size, f32 border, f32 radius, f32 softness, Vec4[4] cols, Vec4[4] border_col) +{ + DrawRect(pos, size, radius, border, cols); + DrawBorder(pos, size, border, radius, softness, border_col); +} + +void +DrawRect(Vec2 pos, Vec2 size, f32 corner_radius, f32 border, Vec4[4] cols) +{ + UICtx* ctx = GetCtx(); + + Vertex* v = GetVertex(ctx); + v.dst_start = pos; + v.dst_end = pos + size; + v.cols = cols; + v.corner_radius = corner_radius; + + v.border_thickness = v.edge_softness = v.raised = 0.0; + + if(border > 0.0) + { + v.dst_start += border; + v.dst_end -= border; + } + + AddUIIndices(ctx); +} + +void +DrawBorder(Vec2 pos, Vec2 size, f32 border, f32 radius, f32 softness, Vec4[4] cols) +{ + UICtx* ctx = GetCtx(); + + Vertex* v = GetVertex(ctx); + v.dst_start = pos; + v.dst_end = pos + size; + v.cols = cols; + v.corner_radius = radius; + v.border_thickness = border; + v.edge_softness = softness; + v.raised = 0.0; + + AddUIIndices(ctx); +} + pragma(inline) void DrawRect(UICtx* ctx, UIItem* item) { @@ -1597,6 +1651,73 @@ ClickedCharIndex(UIItem* item) } } +pragma(inline) bool +InBounds(InputEvent* ev, Vec2 p0, Vec2 p1) +{ + return ev.x >= p0.x && ev.x <= p1.x && ev.y >= p0.y && ev.y <= p1.y; +} + +bool +Clicked(UIItem* item, Vec2 p0, Vec2 p1) +{ + bool result; + UICtx* ctx = GetCtx(); + + for(auto n = ctx.inputs.list.first; !CheckNil(null, n) && Nil(ctx.drag_item); n = n.next) + { + InputEvent* ev = &n.value; + + if(ev.key == Input.LeftClick && ev.pressed && InBounds(ev, p1, p1)) + { + result = true; + DLLRemove(&ctx.inputs.list, n, null); + break; + } + } + + return result; +} + +bool +Dragged(UIItem* item, Vec2 p0, Vec2 p1) +{ + bool result; + UICtx* ctx = GetCtx(); + + item.dragged = 0.0; + + if(Nil(ctx.drag_item) && Clicked(item, p0, p1)) + { + ctx.drag_item = item; + } + + for(auto n = ctx.inputs.list.first; !CheckNil(null, n) && ctx.drag_item == item; n = n.next) + { + InputEvent* ev = &n.value; + bool taken; + + if(ev.key == Input.MouseMotion) + { + item.dragged.x += cast(f32)ev.rel_x; + item.dragged.y += cast(f32)ev.rel_y; + result = true; + taken = true; + } + else if(ev.key == Input.LeftClick && !ev.pressed) + { + ctx.drag_item = g_UI_NIL; + taken = true; + } + + if(taken) + { + DLLRemove(&ctx.inputs.list, n, null); + } + } + + return result; +} + bool Clicked(UIItem* item, DNode!(InputEvent)* n) { diff --git a/src/editor/widgets.d b/src/editor/widgets.d index 96cac71..f9e1c5a 100644 --- a/src/editor/widgets.d +++ b/src/editor/widgets.d @@ -72,6 +72,9 @@ struct UIPanel i64 prev_offset; i64 start_row; i64 end_row; + + Vec2 pos; + Vec2 size; } struct AnimState @@ -110,6 +113,96 @@ Root() return root; } +void +SetPanelSizes(UIPanel* panel) +{ + UICtx* ctx = GetCtx(); + + panel.size.x = ctx.res.x; + panel.size.y = ctx.res.y; + panel.pos = 0.0; + + u32 count = 0; + static foreach(axis; A2D.min .. A2D.max) + { + for(UIPanel* p = panel; !Nil(p); p = Recurse(p)) + { + f32 pos = p.pos.v[axis]; + for(UIPanel* c = p.first; !Nil(c); c = c.next) + { + c.pos.v[axis] = pos; + c.size.v[axis] = p.axis == axis ? c.pct * p.size.v[axis] : p.size.v[axis]; + + if(axis == p.axis) + { + pos += c.size.v[axis]; + } + + count += 1; + } + } + } + + static u32 prev = 0; + if(prev != count) + { + Logf("start"); + for(auto p = panel; !Nil(p); p = Recurse(p)) + { + Logf("axis %s pos %s size %s ed %s child %s", p.axis, p.pos.v, p.size.v, p.ed != null, !Nil(p.first)); + } + + prev = count; + } +} + +void +Panel2(UIPanel* panel) +{ + if(panel.ed == null) return; + + UICtx* ctx = GetCtx(); + UIItem* item = Get(panel.id); + + UIPanel* parent = panel.parent; + UIPanel* prev = panel.prev; + + if(!Nil(prev)) + { + Vec2 p0, p1; + p0.x = parent.axis == A2D.X ? panel.pos.x - 10 : panel.pos.x; + p0.y = parent.axis == A2D.Y ? panel.pos.y - 10 : panel.pos.y; + p1.x = parent.axis == A2D.X ? panel.pos.x + 10 : panel.pos.x + panel.size.x; + p1.y = parent.axis == A2D.Y ? panel.pos.y + 10 : panel.pos.y + panel.size.y; + + if(Dragged(item, p0, p1)) + { + A2D axis = parent.axis; + f32 p_start = parent.pos.v[axis]; + f32 p_end = p_start + parent.size.v[axis]; + f32 drag = item.dragged.v[axis]; + + if(drag != 0.0) + { + f32 pct = Remap(drag, 0.0, p_start-p_end, 0.0, 1.0); + if(CheckPanelBounds(panel.pct - pct) && CheckPanelBounds(panel.prev.pct + pct)) + { + panel.pct -= pct; + panel.prev.pct += pct; + } + } + } + } + + DrawBorderedRect(panel.pos, panel.size, 2.0, 2.0, 0.1, DEFAULT_COL, DEFAULT_BORDER_COL); +} + +void +LineCounter2(UIPanel* panel) +{ + +} + UIItem* Panel(UIPanel* panel, UIFlags flags = UIF.None) {