From 00949428b8c3a96bfff81e36f79db7368eca70d2 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sat, 11 Oct 2025 16:29:02 +1100 Subject: [PATCH] replace editor UI code (about to delete a lot of code) --- src/editor/buffer.d | 8 ++- src/editor/editor.d | 18 +----- src/editor/ui.d | 87 ++++++++++++++++++++++++++--- src/editor/widgets.d | 130 +++++++++++++++++++++++++++++++++++++------ 4 files changed, 199 insertions(+), 44 deletions(-) diff --git a/src/editor/buffer.d b/src/editor/buffer.d index e2be6e2..5688e62 100644 --- a/src/editor/buffer.d +++ b/src/editor/buffer.d @@ -409,7 +409,7 @@ pragma(inline) void SliceLineBuffer(FlatBuffer* fb, LineBuffers* lbufs, LineBuffer* lbuf, u64 start, u64 len) { lbuf.text = fb.data[start .. start+len]; - lbuf.style = !Nil(fb.tk.first) ? fb.tk.buffer[start .. start+len] : []; + lbuf.style = fb.tk.buffer[start .. start+len]; lbufs.count += 1; } @@ -429,7 +429,8 @@ GetLines(FlatBuffer* fb, LineBuffers* linebufs, u64 start_line, u64 length) if(fb.length == 0) { - linebufs.first.text = AllocArray!(u8)(&linebufs.arena, 1); + linebufs.first.text = Alloc!(u8)(&linebufs.arena, 1); + linebufs.first.style = Alloc!(TS)(&linebufs.arena, 1); } else if(start_line == end_line) with(fb) { @@ -452,7 +453,8 @@ GetLines(FlatBuffer* fb, LineBuffers* linebufs, u64 start_line, u64 length) if(i == fb.lf_count && fb.data[fb.length-1] == '\n') { - current.text = AllocArray!(u8)(&arena, 1); + current.text = Alloc!(u8)(&arena, 1); + current.style = Alloc!(TS)(&arena, 1); count += 1; current.next = Alloc!(LineBuffer)(&arena); diff --git a/src/editor/editor.d b/src/editor/editor.d index b9f27a4..56b02ec 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -144,28 +144,14 @@ Cycle(EditorCtx* ctx, Inputs* inputs) // UI Functions After This Point //BeginBuild(inputs); - UICtx* uictx = GetCtx(); - uictx.inputs = inputs; - - PrepRendering(uictx); - - SetPanelSizes(ctx.base_panel); + BeginUI(ctx, inputs); 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; + EndUI(); /* if(ctx.state == ES.CmdOpen) diff --git a/src/editor/ui.d b/src/editor/ui.d index edfacf3..74a234e 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -707,11 +707,6 @@ EndBuild() debug assert(ctx.item_count == ctx.final_count); - BindBuffers(&ctx.rd, &ctx.buffers[ctx.f_idx].m_idx, &ctx.buffers[ctx.f_idx].m_vtx); - DrawIndexed(&ctx.rd, 6, ctx.buffers[ctx.f_idx].count, 0); - - CompleteRendering(ctx); - ctx.frame += 1; debug @@ -1450,11 +1445,89 @@ CullText(UIItem* item, GlyphBounds* gb) return skip; } +void +DrawGlyph(Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col) +{ + Vertex* v = DrawGlyph(glyph, scale, x_pos, y); + if(v) + { + v.cols = col; + v.texture = 1; + } +} + +void +DrawGlyph(Glyph* glyph, f32 scale, f32* x_pos, f32 y, TokenStyle ts) +{ + Vertex* v = DrawGlyph(glyph, scale, x_pos, y); + if(v) + { + v.cols = SYNTAX_COLORS[ts]; + v.texture = 1; + } +} + +Vertex* +DrawGlyph(Glyph* glyph, f32 scale, f32* x_pos, f32 y) +{ + UICtx* ctx = GetCtx(); + Vertex* v = null; + + if(glyph.ch == '\t') + { + *x_pos += glyph.advance * (GetCtx().tab_width - 1); + } + + f32 r = glyph.plane_right * scale; + f32 l = glyph.plane_left * scale; + f32 t = glyph.plane_top * scale; + f32 b = glyph.plane_bottom * scale; + + GlyphBounds gb = { + r: r, + l: l, + t: t, + b: b, + w: r - l, + h: b - t, + atlas_r: glyph.atlas_right, + atlas_l: glyph.atlas_left, + atlas_t: glyph.atlas_top, + atlas_b: glyph.atlas_bottom, + }; + + // TODO: readd culling + //bool skip = CullText(item, &gb); + + f32 y_pos = t; + + v = ctx.buffers[ctx.f_idx].vtx.ptr + ctx.buffers[ctx.f_idx].count; + + v.dst_start.x = *x_pos + gb.l; + v.dst_start.y = y - y_pos; + v.dst_end.x = *x_pos + gb.w + gb.l; + v.dst_end.y = y + gb.h - y_pos; + + if(glyph.ch != '\t' && glyph.ch != '\n') + { + v.src_start.x = gb.atlas_l; + v.src_start.y = gb.atlas_t; + v.src_end.x = gb.atlas_r; + v.src_end.y = gb.atlas_b; + } + + AddUIIndices(ctx); + + *x_pos += glyph.advance * scale; + + return v; +} + pragma(inline) void DrawGlyph(UIItem* item, Glyph* glyph, f32 scale, f32* x_pos, f32 y, bool highlight = false, TokenStyle ts = TS.None, Vec4 col = Vec4(1.0)) { UICtx* ctx = GetCtx(); - Vertex* bg_v = null, v = null; + Vertex* v = null; if(glyph.ch == '\t') { @@ -1667,7 +1740,7 @@ Clicked(UIItem* item, Vec2 p0, Vec2 p1) { InputEvent* ev = &n.value; - if(ev.key == Input.LeftClick && ev.pressed && InBounds(ev, p1, p1)) + if(ev.key == Input.LeftClick && ev.pressed && InBounds(ev, p0, p1)) { result = true; DLLRemove(&ctx.inputs.list, n, null); diff --git a/src/editor/widgets.d b/src/editor/widgets.d index f9e1c5a..3243ad3 100644 --- a/src/editor/widgets.d +++ b/src/editor/widgets.d @@ -1,5 +1,6 @@ import dlib; +import vulkan; import buffer; import ui : Nil; import ui; @@ -37,6 +38,9 @@ const Vec4[4] CMD_PALETTE_INPUT_COL = [ Vec4(0.17, 0.17, 0.17, 1.0), ]; +// TODO: add setting +const f32 TEXT_SIZE = 16.0; + const UIPanel g_ui_nil_panel; UIPanel* g_UI_NIL_PANEL; @@ -113,6 +117,37 @@ Root() return root; } +void +BeginUI(EditorCtx* edctx, Inputs* inputs) +{ + UICtx* ctx = GetCtx(); + + Reset(&ctx.temp_arena); + + ctx.f_idx = ctx.frame%FRAME_OVERLAP; + ctx.inputs = inputs; + + PrepRendering(ctx); + + SetPanelSizes(edctx.base_panel); +} + +void +EndUI() +{ + UICtx* ctx = GetCtx(); + + with(ctx) + { + BindBuffers(&rd, &buffers[f_idx].m_idx, &buffers[f_idx].m_vtx); + DrawIndexed(&rd, 6, buffers[f_idx].count, 0); + } + + CompleteRendering(ctx); + + ctx.frame += 1; +} + void SetPanelSizes(UIPanel* panel) { @@ -122,7 +157,6 @@ SetPanelSizes(UIPanel* panel) 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)) @@ -137,23 +171,9 @@ SetPanelSizes(UIPanel* panel) { 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 @@ -161,8 +181,9 @@ Panel2(UIPanel* panel) { if(panel.ed == null) return; - UICtx* ctx = GetCtx(); + UICtx* ctx = GetCtx(); UIItem* item = Get(panel.id); + Editor* ed = panel.ed; UIPanel* parent = panel.parent; UIPanel* prev = panel.prev; @@ -195,12 +216,85 @@ Panel2(UIPanel* panel) } DrawBorderedRect(panel.pos, panel.size, 2.0, 2.0, 0.1, DEFAULT_COL, DEFAULT_BORDER_COL); + + i64 rows = cast(i64)ceil(panel.size.y/TEXT_SIZE); + + f32 lcw = LineCounter2(panel, 0, rows); + + GetLines(&ed.buf, &ed.linebufs, rows); + + f32 x = panel.pos.x + lcw; + f32 y = panel.pos.y + TEXT_SIZE; + + for(auto buf = ed.linebufs.first; buf != null; buf = buf.next) + { + f32 x_pos = x; + + foreach(i; 0 .. buf.text.length) + { + if(buf.text[i] < ctx.atlas_buf.atlas.glyphs.length) + { + Glyph* g = ctx.atlas_buf.atlas.glyphs.ptr + buf.text[i]; + DrawGlyph(g, 1.0, &x_pos, y, buf.style[i]); + } + } + + y += TEXT_SIZE; + } } -void -LineCounter2(UIPanel* panel) +f32 +LineCounter2(UIPanel* panel, i64 start_row, i64 end_row) { + UICtx* ctx = GetCtx(); + + f32 lc_width = 0.0; + f32 padding = 4.0; + + UIItem* item = Get(ScratchName(panel.id, "linec")); + u8[] max_line_text; + u8[][] line_counts = ScratchAlloc!(u8[])(end_row-start_row); + + u64 width = u64(end_row.toChars().length); + + char[32] buf = '\0'; + char[] fmt = buf.sformat("%%0%sllu", width); + + if(line_counts.length > 0) + { + for(u64 i = 0; start_row+i < end_row; i += 1) + { + line_counts[i] = ScratchAlloc!(u8)(width); + sprintf(cast(char*)line_counts[i].ptr, fmt.ptr, start_row+i); + } + + max_line_text = ScratchAlloc!(u8)(width); + max_line_text[] = cast(u8)'0'; + } + + lc_width = CalcTextWidth(max_line_text) + padding*2.0; + + f32 x = panel.pos.x + padding; + f32 y = panel.pos.y + TEXT_SIZE; + + foreach(i; 0 .. line_counts.length) + { + f32 x_pos = x; + + foreach(j; 0 .. line_counts[i].length) + { + if(line_counts[i][j] < ctx.atlas_buf.atlas.glyphs.length) + { + Glyph* g = ctx.atlas_buf.atlas.glyphs.ptr + line_counts[i][j]; + DrawGlyph(g, 1.0, &x_pos, y, Vec4(1.0)); + } + } + + y += TEXT_SIZE; + } + + return lc_width; } UIItem*