From 80b454914ab77cd31098f3d91da59920db39b488 Mon Sep 17 00:00:00 2001 From: Matthew Date: Tue, 30 Dec 2025 17:29:51 +1100 Subject: [PATCH] fixes & improvements --- src/dlib | 2 +- src/editor/editor.d | 13 ++- src/editor/ui.d | 232 +++++++++++++++++++++++++------------------- src/editor/views.d | 95 +++++++++++++++--- 4 files changed, 225 insertions(+), 117 deletions(-) diff --git a/src/dlib b/src/dlib index e77c179..1160d74 160000 --- a/src/dlib +++ b/src/dlib @@ -1 +1 @@ -Subproject commit e77c1790f7eb5d18d8d84596025c53b2caaca18c +Subproject commit 1160d747ccb550b72a60cd68aa22a14f6dcb1ab1 diff --git a/src/editor/editor.d b/src/editor/editor.d index 1bd1858..bc04dd8 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -161,7 +161,18 @@ Cycle(Inputs* inputs) } } + UIItem* container = Container(A2D.Y, UIS2()); + Push!("parent")(container); + + UIItem* ed_container = Container(A2D.X, UISY(ST.Percentage, 0.98)); + + Push!("parent")(ed_container); EditorView(g_ed_ctx.base_panel); + Pop!("parent"); + + assert(ui_ctx.parent.top.value == container); + + StatusBar(&g_ed_ctx); if(g_ed_ctx.state == ES.CmdOpen) { @@ -283,7 +294,7 @@ ToAbsolutePath(u8[] file_name) version(Windows) { - name_buf.sformat("%s/%s", wd, cast(char[])file_name); +name_buf.sformat("%s/%s", wd, cast(char[])file_name); } char[] path_buf = ScratchAlloc!(char)(strlen(name_buf.ptr)+1); diff --git a/src/editor/ui.d b/src/editor/ui.d index ebe1915..028fc2f 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -102,36 +102,37 @@ alias A2D = Axis2D; enum UIFlags { - None = 0, - DrawBackground = 1<<0, - DrawText = 1<<1, - DrawBorder = 1<<2, - Clickable = 1<<3, - Draggable = 1<<4, - ScrollX = 1<<5, - ScrollY = 1<<6, - ClampX = 1<<7, - ClampY = 1<<8, - Resizeable = 1<<9, - ResizeAdjacent = 1<<10, - FloatingWindow = 1<<11, // todo - Window = 1<<12, - TextInput = 1<<13, // todo - RightAlignText = 1<<14, - CenterAlignText = 1<<15, // todo - TextWrap = 1<<16, - PortalViewX = 1<<17, - PortalViewY = 1<<18, - FixedPosition = 1<<19, - FixedPosAnimated = 1<<20, // todo: add fixed_pos_target then interpolate position every frame - OverflowX = 1<<21, - OverflowY = 1<<22, - Gradient = 1<<23, + None = 0, + DrawBackground = 1<<0, + DrawText = 1<<1, + DrawBorder = 1<<2, + Clickable = 1<<3, + Draggable = 1<<4, + ScrollX = 1<<5, + ScrollY = 1<<6, + ClampX = 1<<7, + ClampY = 1<<8, + Resizeable = 1<<9, + ResizeAdjacent = 1<<10, + FloatingWindow = 1<<11, // todo + Window = 1<<12, + TextInput = 1<<13, // todo + RightAlignText = 1<<14, + CenterAlignText = 1<<15, // todo + TextWrap = 1<<16, + PortalViewX = 1<<17, + PortalViewY = 1<<18, + FixedPosition = 1<<19, + FixedPosAnimated = 1<<20, // todo: add fixed_pos_target then interpolate position every frame + OverflowX = 1<<21, + OverflowY = 1<<22, + Gradient = 1<<23, + VerticalAlignText = 1<<24, - Clamp = UIFlags.ClampX | UIFlags.ClampY, - PortalView = UIFlags.PortalViewX | UIFlags.PortalViewY, - Scroll = UIFlags.ScrollX | UIFlags.ScrollY, - Overflow = UIFlags.OverflowX | UIFlags.OverflowY, + Clamp = UIFlags.ClampX | UIFlags.ClampY, + PortalView = UIFlags.PortalViewX | UIFlags.PortalViewY, + Scroll = UIFlags.ScrollX | UIFlags.ScrollY, + Overflow = UIFlags.OverflowX | UIFlags.OverflowY, } alias UIF = UIFlags; @@ -258,7 +259,6 @@ struct UICtx u32 tab_width; Vec4[TS.max][UISH.max] syntax_colors; - UIItem* window_root; UIItem* root; UIItem* drag_item; UIItem* focus_item; @@ -423,6 +423,14 @@ struct Vertex u32 atlas_index; } +enum SettingType +{ + Value, + Slider, + Dropdown, + Toggle, +} + Attribute[15] attributes = [ { binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof }, { binding: 0, location: 1, format: FMT.RGBA_F32, offset: Vertex.cols_end.offsetof }, @@ -638,11 +646,11 @@ MakeItem(Args...)(string str, Args args) UIFlags flags = has_flag ? args[args.length-1] : UIF.None; enum len = has_flag ? Args.length-1 : Args.length; - char[] key = sformat(ScratchAlloc!(char)(cast(u64)(str.length*1.5)), str, args[0 .. len]); + string key = Scratchf(str, args[0 .. len]); } else { - char[] key = CastStr(char)(str); + string key = str; UIFlags flags = UIF.None; } @@ -667,6 +675,7 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(is(T: UIKey) || StringType!T) } next.next = item; + item.prev = next; } else if(!Nil(item.parent)) { @@ -689,8 +698,8 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(is(T: UIKey) || StringType!T) } FontAtlasBuf* abuf = GetFontAtlas(item.text_size); + item.max_text_width = 0.0; string str = item.display_string.length ? item.display_string : item.key.text; - item.max_text_width = cast(f32)(str.length)*abuf.atlas.max_advance; if(item.flags & UIF.TextWrap) { @@ -698,8 +707,6 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(is(T: UIKey) || StringType!T) u32 ch_per_line = cast(u32)floor(width/abuf.atlas.max_advance); u64 lines = (str.length/ch_per_line) + (str.length%ch_per_line ? 1 : 0); - u32 max_chars = str.length > ch_per_line ? ch_per_line : cast(u32)str.length; - item.max_text_width = cast(f32)(max_chars)*abuf.atlas.max_advance; item.text_lines = ScratchAlloc!(string)(lines); u64 start; @@ -707,6 +714,11 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(is(T: UIKey) || StringType!T) { u64 end = str.length-start <= ch_per_line ? str.length : start+ch_per_line; item.text_lines[i] = str[start .. end]; + f32 text_width = CalcTextWidth(item.text_lines[i], abuf); + if(text_width > item.max_text_width) + { + item.max_text_width = text_width; + } } if(item.syntax_tokens.length) @@ -721,8 +733,9 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(is(T: UIKey) || StringType!T) } else { - item.text_lines = ScratchAlloc!(string)(1); - item.text_lines[0] = str; + item.text_lines = ScratchAlloc!(string)(1); + item.text_lines[0] = str; + item.max_text_width = CalcTextWidth(str, abuf); if(item.syntax_tokens.length) { @@ -761,8 +774,6 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(is(T: UIKey) || StringType!T) item.last_frame = ctx.frame; item.rendered = false; - //item.padding[A2D.X] += item.border_thickness; - //item.padding[A2D.Y] += item.border_thickness; return item; } @@ -916,6 +927,7 @@ BeginUI(Inputs* inputs) UIItem* item = items[i].value; if(item.last_frame != ctx.frame) { + Delete(&ctx.items, items[i].key); memset(item, 0, UIItem.sizeof); DLLPush(ctx.free_items, item, g_UI_NIL); } @@ -966,7 +978,6 @@ BeginUI(Inputs* inputs) Push!("size_info")(sizes); ctx.root = MakeItem("###root"); - ctx.window_root = MakeItem("###window_root"); Pop!("size_info"); Push!("parent")(ctx.root); @@ -1023,7 +1034,7 @@ EndUI() } else if(item.size_info[axis].type == ST.TextSize) { - f32 size = axis == A2D.X ? item.max_text_width : GetFontAtlas(item.text_size).atlas.line_height*item.text_lines.length; + f32 size = axis == A2D.X ? item.max_text_width : GetFontAtlas(item.text_size).atlas.line_height*item.text_lines.length; item.size.v[axis] = size + AxisPadding!(axis)(item); } } @@ -1169,8 +1180,8 @@ EndUI() { UIItem* prev = parent.last_relative_item; - item.rect.p0.v[axis] = prev.rect.p1.v[axis] + InnerOffset!(axis, false)(prev) + InnerOffset!(axis, true)(item); - item.rect.p1.v[axis] = item.rect.p0.v[axis] + item.size.v[axis] - InnerOffset!(axis, false)(item); + item.rect.p0.v[axis] = prev.rect.p1.v[axis] + InnerOffset!(axis, false)(prev) + InnerOffset!(axis, true )(item); + item.rect.p1.v[axis] = item.rect.p0.v[axis] + item.size.v[axis] - InnerOffset!(axis, false)(item); } if(axis == parent.layout_axis && !fixed && !Nil(parent)) @@ -1186,7 +1197,6 @@ EndUI() // Render Items RenderItems(ctx.root); - RenderItems(ctx.window_root); version(ENABLE_RENDERER) { @@ -1235,14 +1245,17 @@ RenderItem(UICtx* ctx, UIItem* item) if(item.rendered) return; if(!(item.flags & DRAW_FLAGS)) return; + Vertex* v = null; + if(item.flags & UIF.DrawBackground) { - Vertex* v = GetVertex(ctx); + v = GetVertex(ctx); v.dst_start = item.rect.p0; v.dst_end = item.rect.p1; v.cols = item.bg_col; v.cols_end = item.flags & UIF.Gradient ? item.bg_col_end : item.bg_col; v.corner_radius = item.flags & UIF.DrawBorder ? item.corner_radius*0.5 : item.corner_radius; + v.edge_softness = item.edge_softness; v.bounds = ItemBounds(item.parent); AddVertexCount(ctx); @@ -1250,7 +1263,7 @@ RenderItem(UICtx* ctx, UIItem* item) if(item.flags & UIF.DrawBorder) { - Vertex* v = GetVertex(ctx); + v = GetVertex(ctx); v.dst_start = item.rect.p0 - Vec2(InnerOffset!(A2D.X, true )(item), InnerOffset!(A2D.Y, true )(item)); v.dst_end = item.rect.p1 + Vec2(InnerOffset!(A2D.X, false)(item), InnerOffset!(A2D.Y, false)(item)); v.cols = item.border_col; @@ -1263,49 +1276,65 @@ RenderItem(UICtx* ctx, UIItem* item) AddVertexCount(ctx); } + if(v) + { + v.dst_start = Clamp(v.dst_start, Vec2(0.0), Vec2(ctx.res)); + v.dst_end = Clamp(v.dst_end, Vec2(0.0), Vec2(ctx.res)); + } + if(item.flags & UIF.DrawText || item.display_string) { - if(item.flags & UIF.CenterAlignText) + FontGlyphs* fg = GetFontGlyphs(item.text_size); + f32 y_pos = item.rect.p0.y; + Vec4[] syntax_cols = ctx.syntax_colors[item.syntax_highlight]; + f32 line_height = fg.abuf.atlas.line_height; + + if(item.flags & UIF.VerticalAlignText) { - // TODO + y_pos += (item.rect.p1.y - item.rect.p0.y - line_height) / 2.0; } - else + + foreach(i; 0 .. item.text_lines.length) { - FontGlyphs* fg = GetFontGlyphs(item.text_size); - f32 y_pos = item.rect.p0.y; - Vec4[] syntax_cols = ctx.syntax_colors[item.syntax_highlight]; - f32 line_height = fg.abuf.atlas.line_height; - - foreach(i; 0 .. item.text_lines.length) + string str = item.text_lines[i]; + u8[] tks = item.token_lines.length ? item.token_lines[i] : []; + f32 x_pos = 0.0; + if(item.flags & UIF.RightAlignText) { - string str = item.text_lines[i]; - u8[] tks = item.token_lines.length ? item.token_lines[i] : []; - f32 x_pos = item.flags & UIF.RightAlignText ? item.rect.p1.x - item.padding[A2D.X].x - CalcTextWidth(str, &fg.abuf) : - item.rect.p0.x + item.padding[A2D.X].x; - - x_pos = clamp(x_pos, item.rect.p0.x, item.rect.p1.x); - - if(tks.length) - { - foreach(j; 0 .. str.length) - { - u8 ch = str[j]; - Glyph* g = ch < fg.abuf.atlas.glyphs.length ? fg.abuf.atlas.glyphs.ptr + ch : null; - DrawGlyph(item, g, fg.index, &x_pos, y_pos, line_height, fg.index, syntax_cols[tks[j]]); - } - } - else - { - foreach(j; 0 .. str.length) - { - u8 ch = str[j]; - Glyph* g = ch < fg.abuf.atlas.glyphs.length ? fg.abuf.atlas.glyphs.ptr + ch : null; - DrawGlyph(item, g, fg.index, &x_pos, y_pos, line_height, fg.index, item.text_col); - } - } - - y_pos += line_height; + x_pos = item.rect.p1.x - item.padding[A2D.X].x - CalcTextWidth(str, &fg.abuf); } + else if(item.flags & UIF.CenterAlignText) + { + x_pos = ((item.rect.p1.x-item.rect.p0.x - CalcTextWidth(str, &fg.abuf)) / 2.0) + item.padding[A2D.X].x; + Logf("%f", x_pos); + } + else + { + x_pos = item.rect.p0.x + item.padding[A2D.X].x; + } + + x_pos = clamp(x_pos, item.rect.p0.x, item.rect.p1.x); + + if(tks.length) + { + foreach(j; 0 .. str.length) + { + u8 ch = str[j]; + Glyph* g = ch < fg.abuf.atlas.glyphs.length ? fg.abuf.atlas.glyphs.ptr + ch : null; + DrawGlyph(item, g, fg.index, &x_pos, y_pos, line_height, fg.index, syntax_cols[tks[j]]); + } + } + else + { + foreach(j; 0 .. str.length) + { + u8 ch = str[j]; + Glyph* g = ch < fg.abuf.atlas.glyphs.length ? fg.abuf.atlas.glyphs.ptr + ch : null; + DrawGlyph(item, g, fg.index, &x_pos, y_pos, line_height, fg.index, item.text_col); + } + } + + y_pos += line_height; } } @@ -1732,7 +1761,7 @@ MakeKey(T)(T str) if(StringType!T) } else { - string id = ConvToStr(str); + string id = Str(str); } UIKey key; @@ -1784,7 +1813,18 @@ MakeKey(T)(T str) if(StringType!T) return key; } -UIKey +static Vec4 +HexCol(u64 col) +{ + return Vec4( + cast(f32)((col >> 16) & 0xFF) / 255.0, + cast(f32)((col >> 8 ) & 0xFF) / 255.0, + cast(f32)((col >> 0 ) & 0xFF) / 255.0, + 1.0 + ); +} + +static UIKey ZeroKey() { return UIKey(); @@ -1862,7 +1902,7 @@ Get(T)(T k) if(is(T: UIKey) || StringType!T) } f32 -CalcTextWidth(bool fast = true, T, U)(T text, U param) if((is(T == string) || StringType!T) && (is(U: u32) || is(U == FontAtlasBuf*) )) +CalcTextWidth(T, U)(T text, U param) if((is(T == string) || StringType!T) && (is(U: u32) || is(U == FontAtlasBuf*) )) { static if(is(T == string)) { @@ -1870,7 +1910,7 @@ CalcTextWidth(bool fast = true, T, U)(T text, U param) if((is(T == string) || St } else { - string str = ConvToStr(text); + string str = Str(text); } static if(is(U: u32)) @@ -1884,18 +1924,10 @@ CalcTextWidth(bool fast = true, T, U)(T text, U param) if((is(T == string) || St u32 tab_width = g_ui_ctx.tab_width; - static if(fast) + f32 width = 0.0; + for(u64 i = 0; i < str.length; i += 1) { - f32 width = str.length * abuf.atlas.max_advance; - assert(abuf.atlas.max_advance > 0.0009); - } - else - { - f32 width = 0.0; - for(u64 i = 0; i < str.length; i += 1) - { - width += GlyphWidth(abuf.atlas.glyphs.ptr + str.ptr[i], abuf); - } + width += GlyphWidth(abuf.atlas.glyphs.ptr + str.ptr[i], abuf); } return width; @@ -1992,19 +2024,19 @@ AxisPadding(Axis2D axis)(UIItem* item) pragma(inline) f32 InnerSize(Axis2D axis)(UIItem* item) { - return clamp(item.size[axis] - (item.padding[axis].x + item.padding[axis].y) - item.border_thickness*2.0, 0.0, f32.max); + return clamp(item.size[axis] - item.border_thickness*2.0, 0.0, f32.max); } pragma(inline) f32 InnerSize(UIItem* item, Axis2D axis) { - return clamp(item.size[axis] - (item.padding[axis].x + item.padding[axis].y) - item.border_thickness*2.0, 0.0, f32.max); + return clamp(item.size[axis] - item.border_thickness*2.0, 0.0, f32.max); } pragma(inline) f32 InnerOffset(Axis2D axis, bool start)(UIItem* item) { - return item.padding[axis].v[start] + item.border_thickness; + return item.border_thickness; } pragma(inline) Vertex* diff --git a/src/editor/views.d b/src/editor/views.d index c3e29c6..9c99bf4 100644 --- a/src/editor/views.d +++ b/src/editor/views.d @@ -12,12 +12,16 @@ __gshared const Panel g_nil_panel; __gshared Panel* g_NIL_PANEL; __gshared const Editor g_nil_ed; __gshared Editor* g_NIL_ED; +__gshared const UIKey ZERO = ZeroKey(); -Vec4 BG_COL = Vec4(0.18, 0.18, 0.18, 1.0); +Vec4 BG_COL = Vec4(0.18, 0.18, 0.18, 1.0); Vec4 CMD_COL = Vec4(0.22, 0.22, 0.22, 1.0); Vec4 HL_BG_COL = Vec4(0.160, 0.533, 0.803, 1.0); Vec4 HL_BORDER_COL = Vec4(0.172, 0.643, 0.988, 1.0); +Vec4 BLUE = HexCol(0x4EA9FF); +Vec4 RED = HexCol(0xFF3268); +Vec4 YELLOW = HexCol(0xF7C443); shared static this() { @@ -38,23 +42,22 @@ void LineCounterView(FontAtlasBuf* abuf, u64 max_line, u64 lines, i64 line_offset, f32 view_offset) { UICtx* ctx = GetCtx(); - UIKey zero = ZeroKey(); u64 ch_width = max_line.toChars().length; f32 lc_width = cast(f32)(ch_width+1)*abuf.atlas.max_advance; enum UIPushInfo[] lc_params = [ - { "layout_axis", q{ A2D.Y } }, - { "view_offset", q{ Vec2(0.0, view_offset) } }, - { "padding", q{ Vec2(4.0) } }, - { "size_info", q{ UIS2(ST.Pixels, ST.Percentage, lc_width, 1.0) }}, - { "edge_softness", q{ 0.0 } }, - { "border_thickness", q{ 1.0 } }, + { "layout_axis", q{ A2D.Y } }, + { "view_offset", q{ Vec2(0.0, view_offset) } }, + { "padding", q{ Vec2(4.0) } }, + { "size_info", q{ UIS2(ST.Pixels, ST.Percentage, lc_width, 1.0) } }, + { "edge_softness", q{ 0.0 } }, + { "border_thickness", q{ 1.0 } }, ]; mixin(PushOnce!(lc_params)); - UIItem* line_count = MakeItem("###lc", UIF.DrawBorder|UIF.PortalViewY); + UIItem* line_count = MakeItem(ZERO, UIF.DrawBorder|UIF.PortalViewY); mixin(PushScope!("text_col", q{ Vec4(1.0) } )); mixin(PushScope!("size_info", q{ UISY(ST.Pixels, abuf.atlas.line_height) } )); @@ -64,8 +67,8 @@ LineCounterView(FontAtlasBuf* abuf, u64 max_line, u64 lines, i64 line_offset, f3 for(u64 i = line_offset; i < end_line && i < max_line; i += 1) { char[] buf = ScratchAlloc!(char)(ch_width); - Push!("display_string")(ConvToStr(sformat(ScratchAlloc!(char)(ch_width), "%s", i)), true); - MakeItem(zero, UIF.DrawText); + Push!("display_string")(Scratchf("%s", i), true); + MakeItem(ZERO, UIF.DrawText); } } @@ -106,7 +109,7 @@ EditorTextView(UIItem* editor, Panel* p, FontAtlasBuf* abuf, u64 lines, i64 line u8 ch = lb.text.length > ed.cursor_pos.y ? lb.text[ed.cursor_pos.y] : 0; f32 line_h = abuf.atlas.line_height; - f32 cursor_x = CalcTextWidth!(false)(lb.text[0 .. ed.cursor_pos.x], abuf); + f32 cursor_x = CalcTextWidth(lb.text[0 .. ed.cursor_pos.x], abuf); f32 cursor_y = cast(f32)(ed.cursor_pos.y - line_offset)*line_h; Glyph* g = abuf.atlas.glyphs.length > ch ? abuf.atlas.glyphs.ptr + ch : abuf.atlas.glyphs.ptr + ' '; @@ -129,7 +132,7 @@ EditorTextView(UIItem* editor, Panel* p, FontAtlasBuf* abuf, u64 lines, i64 line for(LineBuffer* lb = GetLine(&ed.buf, i); !CheckNil(g_NIL_LINE_BUF, lb) && i < line_offset+lines; i += 1, lb = GetLine(&ed.buf, i)) { enum UIPushInfo[] lc_info = [ - { "display_string", q{ ConvToStr(lb.text) } }, + { "display_string", q{ Str(lb.text) } }, { "syntax_tokens", q{ cast(u8[])(lb.style) } }, ]; mixin(PushOnce!(lc_info)); @@ -266,7 +269,7 @@ CommandPalette(CmdPalette* cmd) enum UIPushInfo[] cmd_input_params = [ { "bg_col", q{ HL_BG_COL } }, { "size_info", q{ UISY(ST.TextSize) } }, - { "display_string", q{ ConvToStr(cmd.buffer[0 .. cmd.icount]) } }, + { "display_string", q{ Str(cmd.buffer[0 .. cmd.icount]) } }, ]; mixin(PushOnce!(cmd_input_params)); @@ -295,9 +298,71 @@ CommandPalette(CmdPalette* cmd) for(u64 i = 0; i < cmd.opt_strs.length && i < max_opts; i += 1) { - PushDisplayString(ConvToStr(cmd.opt_strs[i]), true); + PushDisplayString(Str(cmd.opt_strs[i]), true); PushBgCol(cmd.selected == i ? HL_BG_COL : opt_cols[i%2], true); MakeItem(zero, UIF.DrawBackground|UIF.DrawText); } } +UIItem* +Container(Axis2D axis, UISize[2] size_info) +{ + enum UIPushInfo[] container_info = [ + { "layout_axis", q{ axis } }, + { "size_info", q{ size_info }}, + ]; + + mixin(PushOnce!(container_info)); + + return MakeItem(ZeroKey()); +} + +void +StatusBar(EditorCtx* ed_ctx) +{ + mixin(PushScope!("edge_softness", q{ 0.6 })); + + enum UIPushInfo[] bar_info = [ + { "size_info", q{ UISY(ST.Percentage, 0.02)} }, + { "layout_axis", q{ A2D.X} }, + ]; + mixin(PushOnce!(bar_info)); + + Vec4 status_col = BLUE; + string status = "Normal"; + if(ed_ctx.state == ES.InputMode) + { + status = "Input"; + status_col = YELLOW; + } + else if(ed_ctx.state == ES.CmdOpen) + { + status = "Command"; + status_col = RED; + } + + UIItem* bar = MakeItem(ZERO); + + mixin(PushScope!("parent", q{ bar })); + + enum UIPushInfo[] status_info = [ + { "bg_col", q{ status_col } }, + { "corner_radius", q{ Vec4(8.0) } }, + { "text_size", q{ 16 }}, + { "padding", q{ Vec2A2(8.0, 8.0, 0.0, 0.0) } }, + { "size_info", q{ UISX(ST.TextSize) } }, + { "display_string", q{ status } }, + ]; + mixin(PushOnce!(status_info)); + + MakeItem(ZERO, UIF.DrawBackground|UIF.DrawText|UIF.VerticalAlignText); + + enum UIPushInfo[] rest_info = [ + { "bg_col", q{ BG_COL }}, + { "corner_radius", q{ Vec4(0.0, 0.0, 0.0, 8.0) }}, + { "size_info", q{ UIS2() }}, + ]; + + MakeItem(ZERO, UIF.DrawBackground); +} +