From 8b71f1239c3f0d885dc0b0e298056d8e94e41e0d Mon Sep 17 00:00:00 2001 From: Matthew Date: Tue, 23 Sep 2025 06:21:44 +1000 Subject: [PATCH] code cleanup --- src/editor/editor.d | 20 +-- src/editor/ui.d | 284 +++++++++++++++++++++---------------------- src/editor/widgets.d | 230 ++++++++++++++++++----------------- 3 files changed, 262 insertions(+), 272 deletions(-) diff --git a/src/editor/editor.d b/src/editor/editor.d index c12935c..535bd2b 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -247,14 +247,14 @@ HandleInputs(EditorCtx* ctx, Inputs* inputs) } else { - switch(key) + switch(key) with(Input) { - case Input.i: + case i: { ctx.state = ES.InputMode; taken = true; } break; - case Input.Semicolon: + case Semicolon: { if(node.value.md & (MD.LeftShift | MD.RightShift)) { @@ -262,23 +262,23 @@ HandleInputs(EditorCtx* ctx, Inputs* inputs) taken = true; } } break; - case Input.v: + case v: { AddEditor(ctx, GetFocusedPanel(), A2D.X); taken = true; } break; - case Input.c: + case c: { //AddEditor(ctx, GetFocusedPanel(), A2D.Y); //taken = true; } break; - case Input.d: + case d: { } break; - case Input.Up: - case Input.Down: - case Input.Left: - case Input.Right: + case Up: + case Down: + case Left: + case Right: { UIPanel* p = GetFocusedPanel(); if(!Nil(p)) diff --git a/src/editor/ui.d b/src/editor/ui.d index 6a76b9c..15dcb90 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -1,9 +1,6 @@ -import dlib.aliases; -import dlib.platform; -import dlib.math; -import dlib.util; -import dlib.alloc; -import dlib.fonts; +import dlib; +import dlib.util : HTPush = Push; + import vulkan; import widgets; import std.stdio; @@ -103,26 +100,34 @@ struct UICtx UIItemStackList stack_free_list; - Vec4[4] color; - Vec4[4] border_color; - Vec4 text_color; - Axis2D layout_axis; - Vec2 adjustment; - Vec2 offset; - Vec2 padding; + UIStack!(Vec4[4])* color; + UIStack!(Vec4[4])* border_color; + UIStack!(Vec4)* text_color; + UIStack!(Axis2D)* layout_axis; + UIStack!(Vec2)* adjustment; + UIStack!(Vec2)* offset; + UIStack!(Vec2)* padding; + UIStack!(f32)* border_thickness; + UIStack!(f32)* corner_radius; + UIStack!(f32)* edge_softness; + i64 highlighted_char; u32 tab_width; f32 text_size; - f32 border_thickness; - f32 corner_radius; - f32 edge_softness; - f32 z_index; debug u32 item_count; debug u32 final_count; debug bool dbg; } +struct UIStack(T) +{ + + + UIStack!(T)* next; + T value; +} + struct UIItemStackList { UIItemNode* first; @@ -168,7 +173,6 @@ struct UIItem f32 border_thickness; f32 corner_radius; f32 edge_softness; - f32 z_index; Rect culling; } @@ -272,20 +276,12 @@ InitUICtx(PlatformWindow* window) prev_sibling: g_UI_NIL_NODE, drag_item: g_UI_NIL, focused: g_UI_NIL, - text_size: 16.0, - tab_width: 2, - border_thickness: 0.0, - corner_radius: 0.0, - edge_softness: 0.0, - color: [b, b, b, b], - border_color: [b, b, b, b], atlas_buf: atlas_buf, font: font, font_data: cast(u8[])FONT_BYTES, - adjustment: 0.0, - padding: Vec2(0.0), - offset: 0.0, - z_index: 0.0, + text_size: 16.0, + tab_width: 2, + highlighted_char: -1, }; u64 vertex_size = 10000; @@ -351,6 +347,101 @@ InitUICtx(PlatformWindow* window) InitWidgets(); } +void +ClearStacks(UICtx* ctx) +{ + import std.traits; + + static foreach(i; 0 .. ctx.tupleof.length) + { + static if( + isPointer!(typeof(ctx.tupleof[i])) && + hasMember!(typeof(ctx.tupleof[i]), "value") && + is(typeof(*ctx.tupleof[i]): UIStack!(typeof(ctx.tupleof[i].value))) + ) + { + ctx.tupleof[i] = null; + ctx.tupleof[i] = Alloc!(UIStack!(typeof(ctx.tupleof[i].value)))(&ctx.temp_arena); + } + } +} + +void +Push(string id, T)(T value) +{ + import std.string; + import std.traits; + + enum string s = "g_ui_ctx.@".replace("@", id); + + static if(isPointer!(typeof(mixin(s))) && hasMember!(typeof(*mixin(s)), "next")) + { + enum stack = true; + alias U = typeof(mixin(s~".value")); + } + else + { + enum stack = false; + alias U = typeof(mixin(s)); + } + + static if(!stack) + { + mixin(s) = value; + } + else static if(stack) + { + static if(is(U: Vec4[4]) && is(T: Vec4)) + { + UIStack!(U)* node = Alloc!(UIStack!(U))(&g_ui_ctx.temp_arena); + node.value[] = value; + } + else + { + UIStack!(U)* node = Alloc!(UIStack!(U))(&g_ui_ctx.temp_arena); + node.value = value; + } + + node.next = mixin(s); + mixin(s) = node; + } +} + +auto +Pop(string stack)() +{ + import std.string; + import std.traits; + + enum string s = "g_ui_ctx.@".replace("@", stack); + + static assert(isPointer!(typeof(mixin(s))) && hasMember!(typeof(*mixin(s)), "next")); + + assert(mixin(s) != null); + auto value = mixin(s~".value"); + mixin(s) = mixin(s~".next"); + return value; +} + +auto +Get(string id)() +{ + import std.string; + import std.traits; + + enum string s = "g_ui_ctx.@".replace("@", id); + + static if(isPointer!(typeof(mixin(s))) && hasMember!(typeof(*mixin(s)), "next")) + { + assert(mixin(s) != null); + return mixin(s~".value"); + } + else + { + return mixin(s); + } +} + UIItemNode* PopItemNode() { @@ -491,36 +582,6 @@ PushParent(UIItem* parent) ctx.panel_level += 1; } -void -SetAdjustment(Vec2 adj) -{ - g_ui_ctx.adjustment = adj; -} - -void -SetZIndex(f32 z_index) -{ - g_ui_ctx.z_index = z_index; -} - -f32 -GetZIndex() -{ - return g_ui_ctx.z_index; -} - -void -SetOffset(Vec2 offset) -{ - g_ui_ctx.offset = offset; -} - -void -SetHighlightedChar(i64 pos) -{ - g_ui_ctx.highlighted_char = pos; -} - void SetDebug(bool dbg) { @@ -530,75 +591,6 @@ SetDebug(bool dbg) } } -void -SetBorderThickness(f32 value) -{ - g_ui_ctx.border_thickness = value; -} - -void -SetCornerRadius(f32 value) -{ - g_ui_ctx.corner_radius = value; -} - -void -SetEdgeSoftness(f32 value) -{ - g_ui_ctx.edge_softness = value; -} - -void -SetColor(Vec4 col) -{ - SetColor(col, col, col, col); -} - -void -SetPadding(Vec2 padding) -{ - g_ui_ctx.padding = padding; -} - -void -SetColor(Vec4 col0, Vec4 col1, Vec4 col2, Vec4 col3) -{ - UICtx* ctx = GetCtx(); - ctx.color[0] = col0; - ctx.color[1] = col1; - ctx.color[2] = col2; - ctx.color[3] = col3; -} - -void -SetBorderColor(Vec4 col) -{ - SetBorderColor(col, col, col, col); -} - -void -SetBorderColor(Vec4 col0, Vec4 col1, Vec4 col2, Vec4 col3) -{ - UICtx* ctx = GetCtx(); - ctx.border_color[0] = col0; - ctx.border_color[1] = col1; - ctx.border_color[2] = col2; - ctx.border_color[3] = col3; -} - -void -SetLayoutAxis(Axis2D axis) -{ - UICtx* ctx = GetCtx(); - ctx.layout_axis = axis; -} - -void -SetTextSize(f32 size) -{ - g_ui_ctx.text_size = size; -} - void BeginBuild(Inputs* inputs) { @@ -608,6 +600,9 @@ BeginBuild(Inputs* inputs) debug ctx.final_count = 0; Reset(&ctx.temp_arena); + ClearStacks(ctx); + Push!("text_size")(16.0); + Push!("tab_width")(2); KVPair!(u64, UIItem*)*[] items = GetAllNodes(&ctx.temp_arena, &ctx.items); for(u64 i = 0; i < items.length; i += 1) @@ -914,21 +909,20 @@ BuildItem(UIItem* item, UISize size_x, UISize size_y, UIFlags properties) item.flags = properties; item.size_info[A2D.X] = size_x; item.size_info[A2D.Y] = size_y; - item.color = ctx.color; - item.layout_axis = ctx.layout_axis; item.level = ctx.panel_level; - item.adjustment = ctx.adjustment; - item.border_color = ctx.border_color; - item.border_thickness = ctx.border_thickness; - item.corner_radius = ctx.corner_radius; - item.edge_softness = ctx.edge_softness; item.last_frame = ctx.frame; - item.highlighted_char = ctx.highlighted_char; - item.offset = ctx.offset; - item.padding = ctx.padding; + item.color = Get!("color")(); + item.layout_axis = Get!("layout_axis")(); + item.adjustment = Get!("adjustment")(); + item.border_color = Get!("border_color")(); + item.border_thickness = Get!("border_thickness")(); + item.corner_radius = Get!("corner_radius")(); + item.edge_softness = Get!("edge_softness")(); + item.highlighted_char = Get!("highlighted_char")(); + item.offset = Get!("offset")(); + item.padding = Get!("padding")(); item.culling.vec0 = Vec2(0.0); item.culling.vec1 = Vec2(0.0); - item.z_index = ctx.z_index; item.parent = ctx.top_parent == g_UI_NIL_NODE ? g_UI_NIL : ctx.top_parent.item; if(!Nil(item.parent)) @@ -936,9 +930,6 @@ BuildItem(UIItem* item, UISize size_x, UISize size_y, UIFlags properties) DLLPush(item.parent, item, g_UI_NIL); } - // Reset any once off values here - ctx.adjustment = Vec2(0.0); - debug ctx.item_count += 1; } @@ -1076,7 +1067,7 @@ Get(UIKey key) if(!result.ok) { result.value = Alloc!(UIItem)(&g_ui_ctx.arena); - Push(&g_ui_ctx.items, key.hash, result.value); + HTPush(&g_ui_ctx.items, key.hash, result.value); } result.value.key = key; @@ -1223,7 +1214,8 @@ void DrawLine(UIItem* item) { UICtx* ctx = GetCtx(); - f32 y = item.rect.y0 + ctx.text_size + item.padding.v[A2D.Y]; + f32 text_size = Get!("text_size")(); + f32 y = item.rect.y0 + text_size + item.padding.v[A2D.Y]; f32 x = item.rect.x0 + item.padding.v[A2D.X]; FontAtlas* atlas = &ctx.atlas_buf.atlas; @@ -1357,8 +1349,6 @@ DrawGlyph(UIItem* item, Glyph* glyph, f32 scale, f32* x_pos, f32 y, bool highlig v.dst_end.x = *x_pos + w + l; v.dst_end.y = y + h - y_pos; - v.z_index = item.z_index; - if(glyph.ch != '\t' && glyph.ch != '\n') { v.src_start.x = glyph.atlas_left; @@ -1394,7 +1384,6 @@ DrawRect(UICtx* ctx, UIItem* item) v.corner_radius = 0.0; v.edge_softness = 0.0; v.raised = 0.0; - v.z_index = item.z_index; AddUIIndices(ctx); } @@ -1410,7 +1399,6 @@ DrawBorder(UICtx* ctx, UIItem* item) v.corner_radius = item.corner_radius; v.edge_softness = item.edge_softness; v.raised = 0.0; - v.z_index = item.z_index; AddUIIndices(ctx); } diff --git a/src/editor/widgets.d b/src/editor/widgets.d index 0f803ce..001120b 100644 --- a/src/editor/widgets.d +++ b/src/editor/widgets.d @@ -11,6 +11,13 @@ import core.stdc.math : fabsf; import std.conv; import core.stdc.stdio : sprintf; +const Vec4[4] DEFAULT_COL = [ + Vec4(0.3, 0.65, 0.86, 1.0), + Vec4(0.25, 0.60, 0.81, 1.0), + Vec4(0.25, 0.60, 0.81, 1.0), + Vec4(0.3, 0.65, 0.86, 1.0), +]; + const UIPanel g_ui_nil_panel; UIPanel* g_UI_NIL_PANEL; @@ -68,13 +75,8 @@ Root() { Vec2 d = RootSize(); - SetColor( - Vec4(0.3, 0.65, 0.86, 1.0), - Vec4(0.25, 0.60, 0.81, 1.0), - Vec4(0.25, 0.60, 0.81, 1.0), - Vec4(0.3, 0.65, 0.86, 1.0), - ); - SetLayoutAxis(A2D.Y); + Push!("color")(DEFAULT_COL); + Push!("layout_axis")(A2D.Y); UIItem* root = Get("##root_item"); BuildItem(root, UISize(ST.Pixels, d.x), UISize(ST.Pixels, d.y), UIF.DrawBackground); @@ -92,6 +94,9 @@ Root() UIItem* Panel(UIPanel* panel, UIFlags flags = UIF.None) { + Push!("color")(DEFAULT_COL); + Push!("layout_axis")(panel.axis); + UIItem* item = Get(panel.id); UIItem* separator = g_UI_NIL; @@ -109,7 +114,6 @@ Panel(UIPanel* panel, UIFlags flags = UIF.None) if(item.signal & UIS.Clicked) { - Logf("%s clicked", cast(char[])panel.id); SetFocusedPanel(panel); } @@ -119,24 +123,23 @@ Panel(UIPanel* panel, UIFlags flags = UIF.None) Separator(panel, parent, &adj_x, &adj_y); } - SetColor( - Vec4(0.3, 0.65, 0.86, 1.0), - Vec4(0.25, 0.60, 0.81, 1.0), - Vec4(0.25, 0.60, 0.81, 1.0), - Vec4(0.3, 0.65, 0.86, 1.0), - ); - SetLayoutAxis(panel.axis); - BuildItem(item, UISize(ST.Percentage, x_pct), UISize(ST.Percentage, y_pct), UIF.DrawBackground|flags); PushParent(item); + Pop!("color")(); + Pop!("layout_axis")(); + return item; } UIItem* LineCounter(u8[] parent_id, FlatBuffer* buf, f32 offset, i64 start_row, i64 end_row) { + Push!("padding")(Vec2(4.0, 0.0)); + Push!("offset")(Vec2(0.0, offset)); + Push!("color")(Vec4(0.2, 0.5, 0.65, 1.0)); + u8[] id = ScratchName(parent_id, "linec"); auto end_chars = end_row.toChars(); @@ -158,28 +161,26 @@ LineCounter(u8[] parent_id, FlatBuffer* buf, f32 offset, i64 start_row, i64 end_ max_row_text = ScratchAlloc!(u8)(width); max_row_text[] = cast(u8)'0'; } - - SetPadding(Vec2(4.0, 0.0)); - scope(exit) SetPadding(Vec2(0.0)); - - SetColor(Vec4(0.2, 0.5, 0.65, 1.0)); UISize s_x = UISize(ST.Pixels, CalcTextWidth(max_row_text)); UISize s_y = UISize(ST.Percentage, 1.0); UIItem* item = Container(ScratchName(parent_id, "linec"), s_x, s_y, A2D.Y, UIF.DrawBackground); - scope(exit) EndContainer(); - - SetOffset(Vec2(0.0, offset)); - scope(exit) SetOffset(Vec2(0.0)); - - UIItem* inner = Container(ScratchName(parent_id, "lcinner"), s_x, s_y, A2D.Y, UIF.None); - scope(exit) EndContainer(); - - for(u64 i = 0; i < line_counts.length; i += 1) { - UIItem* line = Text(line_counts[i]); + UIItem* inner = Container(ScratchName(parent_id, "lcinner"), s_x, s_y, A2D.Y, UIF.None); + { + for(u64 i = 0; i < line_counts.length; i += 1) + { + UIItem* line = Text(line_counts[i]); + } + } + EndContainer(); } + EndContainer(); + + Pop!("padding")(); + Pop!("offset")(); + Pop!("color")(); return item; } @@ -187,14 +188,14 @@ LineCounter(u8[] parent_id, FlatBuffer* buf, f32 offset, i64 start_row, i64 end_ UIItem* Container(u8[] text, UISize size_x, UISize size_y, Axis2D axis, UIF flags = UIF.None) { + Push!("layout_axis")(axis); + UIItem* item = Get(text); - - SetLayoutAxis(axis); - BuildItem(item, size_x, size_y, flags); - PushParent(item); + Pop!("layout_axis")(); + return item; } @@ -216,6 +217,8 @@ Text(u8[] text) void Separator(UIPanel* panel, UIItem* parent, f32* adj_x, f32* adj_y) { + Push!("color")(Vec4(0.1, 0.2, 0.6, 1.0)); + Axis2D axis = parent.layout_axis; f32 sep_y = 1.0, sep_x = 1.0, parent_start = 0.0, parent_end = 0.0; @@ -237,16 +240,11 @@ Separator(UIPanel* panel, UIItem* parent, f32* adj_x, f32* adj_y) u8[] buf = ScratchAlloc!(u8)(panel.id.length + 5); (cast(char[])buf).sformat("%s_sep", cast(char[])panel.id); - SetColor(Vec4(0.1, 0.2, 0.6, 1.0)); - SizeType x_t = axis == A2D.X ? ST.Pixels : ST.Percentage; SizeType y_t = axis == A2D.Y ? ST.Pixels : ST.Percentage; UIItem* item = Get(buf); - - f32 prev_z = GetZIndex(); BuildItem(item, UISize(x_t, sep_x), UISize(y_t, sep_y), UIF.DrawBackground|UIF.Draggable); - Signal(item); f32 pos = item.dragged.v[parent.layout_axis]; @@ -259,6 +257,8 @@ Separator(UIPanel* panel, UIItem* parent, f32* adj_x, f32* adj_y) panel.prev.pct += pct; } } + + Pop!("color"); } void @@ -313,84 +313,90 @@ EditorView(UIPanel* panel) { bool focused = panel == GetFocusedPanel(); - f32 prev_z = GetZIndex(); - UICtx* ctx = GetCtx(); - UIItem* item = Panel(panel, UIF.Clickable); Editor* ed = panel.ed; - Container(ScratchName(panel.id, "cntr"), UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0), A2D.X); - - f32 text_size = 16.0; - f32 height = 0.0; - - i64 rows = cast(i64)ceil(item.size.y/text_size); - if(ed.buf.rows != rows) + UIItem* item = Panel(panel, UIF.Clickable); { - ed.buf.rows = rows; - } - - if(panel.prev_offset != ed.buf.offset) - { - SetPanelScroll(panel, rows, text_size); - } - - f32 offset = 0.0; - i64 line_offset = ed.buf.offset; - i64 line_rows = rows; - if(panel.anim.remaining_time > 0.0) with(panel.anim) - { - remaining_time -= g_delta; - if(remaining_time < 0.0) + Container(ScratchName(panel.id, "cntr"), UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0), A2D.X); { - remaining_time = 0.0; - } + f32 text_size = 16.0; + f32 height = 0.0; - offset = Remap(remaining_time, 0.0, start_time, 0.0, 1.0); - offset = Remap(EaseOutExp(offset), 0.0, 1.0, start_value, end_value); - - if(remaining_time == 0.0) - { - start_value = end_value = start_time = 0.0; - } - - line_offset = panel.start_row; - line_rows = panel.end_row-panel.start_row; - GetLines(&ed.buf, &ed.linebufs, panel.start_row, panel.end_row-panel.start_row); - } - else - { - GetLines(&ed.buf, &ed.linebufs, rows); - } - - LineCounter(panel.id, &panel.ed.buf, offset, line_offset, line_offset+line_rows); - - SetOffset(Vec2(0.0, offset)); - Container(ScratchName(panel.id, "lines"), UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0), A2D.Y); - - U64Vec2 pos = VecPos(&ed.buf); - u64 i = 0; - for(LineBuffer* buf = ed.linebufs.first; buf != null; buf = buf.next, i += 1) - { - if(buf.text.length > 0) - { - i64 line_no = i+line_offset; - if(pos.y == line_no && focused) + i64 rows = cast(i64)ceil(item.size.y/text_size); + if(ed.buf.rows != rows) { - SetHighlightedChar(pos.x); + ed.buf.rows = rows; } - TextPart* tp = WrappedTextLine(buf.text, panel.id, text_size, line_no); - height += (text_size * tp.count); - if(TextClicked(tp)) + if(panel.prev_offset != ed.buf.offset) { - SetFocusedPanel(panel); + SetPanelScroll(panel, rows, text_size); } - } - SetHighlightedChar(-1); + f32 offset = 0.0; + i64 line_offset = ed.buf.offset; + i64 line_rows = rows; + if(panel.anim.remaining_time > 0.0) with(panel.anim) + { + remaining_time -= g_delta; + if(remaining_time < 0.0) + { + remaining_time = 0.0; + } + + offset = Remap(remaining_time, 0.0, start_time, 0.0, 1.0); + offset = Remap(EaseOutExp(offset), 0.0, 1.0, start_value, end_value); + + if(remaining_time == 0.0) + { + start_value = end_value = start_time = 0.0; + } + + line_offset = panel.start_row; + line_rows = panel.end_row-panel.start_row; + GetLines(&ed.buf, &ed.linebufs, panel.start_row, panel.end_row-panel.start_row); + } + else + { + GetLines(&ed.buf, &ed.linebufs, rows); + } + + LineCounter(panel.id, &panel.ed.buf, offset, line_offset, line_offset+line_rows); + + Push!("offset")(Vec2(0.0, offset)); + scope(exit) Pop!("offset")(); + + Container(ScratchName(panel.id, "lines"), UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0), A2D.Y); + { + U64Vec2 pos = VecPos(&ed.buf); + u64 i = 0; + for(LineBuffer* buf = ed.linebufs.first; buf != null; buf = buf.next, i += 1) + { + if(buf.text.length > 0) + { + i64 line_no = i+line_offset; + if(pos.y == line_no && focused) + { + Push!("highlighted_char")(pos.x); + } + + TextPart* tp = WrappedTextLine(buf.text, panel.id, text_size, line_no); + height += (text_size * tp.count); + if(TextClicked(tp)) + { + SetFocusedPanel(panel); + } + } + + Push!("highlighted_char")(-1); + } + } + EndContainer(); + } + EndContainer(); } - SetOffset(Vec2(0.0)); + EndPanel(); Signal(item); @@ -398,12 +404,6 @@ EditorView(UIPanel* panel) { SetFocusedPanel(panel); } - - EndContainer(); - - EndContainer(); - - EndPanel(); } bool @@ -426,13 +426,13 @@ TextClicked(TextPart* text_part) TextPart* WrappedTextLine(u8[] text, u8[] parent_id, f32 text_size, u64 line_no) { + Push!("color")(Vec4(1.0)); + Push!("text_size")(text_size); + UIItem* parent = PeekParent(); TextPart* part = ScratchAlloc!(TextPart)(); part.item = g_UI_NIL; - SetColor(Vec4(1.0)); - SetTextSize(text_size); - TextPart* tp = part; Node!(u8[])* lines = MakeMultiline(text, parent.size.x, parent_id, line_no); for(Node!(u8[])* line = lines; line != null; line = line.next, tp = tp.next) @@ -453,6 +453,8 @@ WrappedTextLine(u8[] text, u8[] parent_id, f32 text_size, u64 line_no) BuildItem(tp.item, UISize(ST.Percentage, 1.0), UISize(ST.Pixels, text_size), UIF.DrawText|UIF.Clickable|UIF.Draggable); } + Pop!("color")(); + return part; }