fixes & improvements

This commit is contained in:
Matthew 2025-12-30 17:29:51 +11:00
parent 07f72ac41e
commit 80b454914a
4 changed files with 225 additions and 117 deletions

@ -1 +1 @@
Subproject commit e77c1790f7eb5d18d8d84596025c53b2caaca18c Subproject commit 1160d747ccb550b72a60cd68aa22a14f6dcb1ab1

View File

@ -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); 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) if(g_ed_ctx.state == ES.CmdOpen)
{ {
@ -283,7 +294,7 @@ ToAbsolutePath(u8[] file_name)
version(Windows) 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); char[] path_buf = ScratchAlloc!(char)(strlen(name_buf.ptr)+1);

View File

@ -102,36 +102,37 @@ alias A2D = Axis2D;
enum UIFlags enum UIFlags
{ {
None = 0, None = 0,
DrawBackground = 1<<0, DrawBackground = 1<<0,
DrawText = 1<<1, DrawText = 1<<1,
DrawBorder = 1<<2, DrawBorder = 1<<2,
Clickable = 1<<3, Clickable = 1<<3,
Draggable = 1<<4, Draggable = 1<<4,
ScrollX = 1<<5, ScrollX = 1<<5,
ScrollY = 1<<6, ScrollY = 1<<6,
ClampX = 1<<7, ClampX = 1<<7,
ClampY = 1<<8, ClampY = 1<<8,
Resizeable = 1<<9, Resizeable = 1<<9,
ResizeAdjacent = 1<<10, ResizeAdjacent = 1<<10,
FloatingWindow = 1<<11, // todo FloatingWindow = 1<<11, // todo
Window = 1<<12, Window = 1<<12,
TextInput = 1<<13, // todo TextInput = 1<<13, // todo
RightAlignText = 1<<14, RightAlignText = 1<<14,
CenterAlignText = 1<<15, // todo CenterAlignText = 1<<15, // todo
TextWrap = 1<<16, TextWrap = 1<<16,
PortalViewX = 1<<17, PortalViewX = 1<<17,
PortalViewY = 1<<18, PortalViewY = 1<<18,
FixedPosition = 1<<19, FixedPosition = 1<<19,
FixedPosAnimated = 1<<20, // todo: add fixed_pos_target then interpolate position every frame FixedPosAnimated = 1<<20, // todo: add fixed_pos_target then interpolate position every frame
OverflowX = 1<<21, OverflowX = 1<<21,
OverflowY = 1<<22, OverflowY = 1<<22,
Gradient = 1<<23, Gradient = 1<<23,
VerticalAlignText = 1<<24,
Clamp = UIFlags.ClampX | UIFlags.ClampY, Clamp = UIFlags.ClampX | UIFlags.ClampY,
PortalView = UIFlags.PortalViewX | UIFlags.PortalViewY, PortalView = UIFlags.PortalViewX | UIFlags.PortalViewY,
Scroll = UIFlags.ScrollX | UIFlags.ScrollY, Scroll = UIFlags.ScrollX | UIFlags.ScrollY,
Overflow = UIFlags.OverflowX | UIFlags.OverflowY, Overflow = UIFlags.OverflowX | UIFlags.OverflowY,
} }
alias UIF = UIFlags; alias UIF = UIFlags;
@ -258,7 +259,6 @@ struct UICtx
u32 tab_width; u32 tab_width;
Vec4[TS.max][UISH.max] syntax_colors; Vec4[TS.max][UISH.max] syntax_colors;
UIItem* window_root;
UIItem* root; UIItem* root;
UIItem* drag_item; UIItem* drag_item;
UIItem* focus_item; UIItem* focus_item;
@ -423,6 +423,14 @@ struct Vertex
u32 atlas_index; u32 atlas_index;
} }
enum SettingType
{
Value,
Slider,
Dropdown,
Toggle,
}
Attribute[15] attributes = [ Attribute[15] attributes = [
{ binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof }, { 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 }, { 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; UIFlags flags = has_flag ? args[args.length-1] : UIF.None;
enum len = has_flag ? Args.length-1 : Args.length; 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 else
{ {
char[] key = CastStr(char)(str); string key = str;
UIFlags flags = UIF.None; 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; next.next = item;
item.prev = next;
} }
else if(!Nil(item.parent)) 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); FontAtlasBuf* abuf = GetFontAtlas(item.text_size);
item.max_text_width = 0.0;
string str = item.display_string.length ? item.display_string : item.key.text; 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) 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); 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); 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); item.text_lines = ScratchAlloc!(string)(lines);
u64 start; 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; u64 end = str.length-start <= ch_per_line ? str.length : start+ch_per_line;
item.text_lines[i] = str[start .. end]; 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) if(item.syntax_tokens.length)
@ -721,8 +733,9 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(is(T: UIKey) || StringType!T)
} }
else else
{ {
item.text_lines = ScratchAlloc!(string)(1); item.text_lines = ScratchAlloc!(string)(1);
item.text_lines[0] = str; item.text_lines[0] = str;
item.max_text_width = CalcTextWidth(str, abuf);
if(item.syntax_tokens.length) 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.last_frame = ctx.frame;
item.rendered = false; item.rendered = false;
//item.padding[A2D.X] += item.border_thickness;
//item.padding[A2D.Y] += item.border_thickness;
return item; return item;
} }
@ -916,6 +927,7 @@ BeginUI(Inputs* inputs)
UIItem* item = items[i].value; UIItem* item = items[i].value;
if(item.last_frame != ctx.frame) if(item.last_frame != ctx.frame)
{ {
Delete(&ctx.items, items[i].key);
memset(item, 0, UIItem.sizeof); memset(item, 0, UIItem.sizeof);
DLLPush(ctx.free_items, item, g_UI_NIL); DLLPush(ctx.free_items, item, g_UI_NIL);
} }
@ -966,7 +978,6 @@ BeginUI(Inputs* inputs)
Push!("size_info")(sizes); Push!("size_info")(sizes);
ctx.root = MakeItem("###root"); ctx.root = MakeItem("###root");
ctx.window_root = MakeItem("###window_root");
Pop!("size_info"); Pop!("size_info");
Push!("parent")(ctx.root); Push!("parent")(ctx.root);
@ -1023,7 +1034,7 @@ EndUI()
} }
else if(item.size_info[axis].type == ST.TextSize) 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); item.size.v[axis] = size + AxisPadding!(axis)(item);
} }
} }
@ -1169,8 +1180,8 @@ EndUI()
{ {
UIItem* prev = parent.last_relative_item; 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.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.p1.v[axis] = item.rect.p0.v[axis] + item.size.v[axis] - InnerOffset!(axis, false)(item);
} }
if(axis == parent.layout_axis && !fixed && !Nil(parent)) if(axis == parent.layout_axis && !fixed && !Nil(parent))
@ -1186,7 +1197,6 @@ EndUI()
// Render Items // Render Items
RenderItems(ctx.root); RenderItems(ctx.root);
RenderItems(ctx.window_root);
version(ENABLE_RENDERER) version(ENABLE_RENDERER)
{ {
@ -1235,14 +1245,17 @@ RenderItem(UICtx* ctx, UIItem* item)
if(item.rendered) return; if(item.rendered) return;
if(!(item.flags & DRAW_FLAGS)) return; if(!(item.flags & DRAW_FLAGS)) return;
Vertex* v = null;
if(item.flags & UIF.DrawBackground) if(item.flags & UIF.DrawBackground)
{ {
Vertex* v = GetVertex(ctx); v = GetVertex(ctx);
v.dst_start = item.rect.p0; v.dst_start = item.rect.p0;
v.dst_end = item.rect.p1; v.dst_end = item.rect.p1;
v.cols = item.bg_col; v.cols = item.bg_col;
v.cols_end = item.flags & UIF.Gradient ? item.bg_col_end : 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.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); v.bounds = ItemBounds(item.parent);
AddVertexCount(ctx); AddVertexCount(ctx);
@ -1250,7 +1263,7 @@ RenderItem(UICtx* ctx, UIItem* item)
if(item.flags & UIF.DrawBorder) 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_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.dst_end = item.rect.p1 + Vec2(InnerOffset!(A2D.X, false)(item), InnerOffset!(A2D.Y, false)(item));
v.cols = item.border_col; v.cols = item.border_col;
@ -1263,49 +1276,65 @@ RenderItem(UICtx* ctx, UIItem* item)
AddVertexCount(ctx); 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.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); string str = item.text_lines[i];
f32 y_pos = item.rect.p0.y; u8[] tks = item.token_lines.length ? item.token_lines[i] : [];
Vec4[] syntax_cols = ctx.syntax_colors[item.syntax_highlight]; f32 x_pos = 0.0;
f32 line_height = fg.abuf.atlas.line_height; if(item.flags & UIF.RightAlignText)
foreach(i; 0 .. item.text_lines.length)
{ {
string str = item.text_lines[i]; x_pos = item.rect.p1.x - item.padding[A2D.X].x - CalcTextWidth(str, &fg.abuf);
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;
} }
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 else
{ {
string id = ConvToStr(str); string id = Str(str);
} }
UIKey key; UIKey key;
@ -1784,7 +1813,18 @@ MakeKey(T)(T str) if(StringType!T)
return key; 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() ZeroKey()
{ {
return UIKey(); return UIKey();
@ -1862,7 +1902,7 @@ Get(T)(T k) if(is(T: UIKey) || StringType!T)
} }
f32 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)) 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 else
{ {
string str = ConvToStr(text); string str = Str(text);
} }
static if(is(U: u32)) 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; 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; width += GlyphWidth(abuf.atlas.glyphs.ptr + str.ptr[i], abuf);
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);
}
} }
return width; return width;
@ -1992,19 +2024,19 @@ AxisPadding(Axis2D axis)(UIItem* item)
pragma(inline) f32 pragma(inline) f32
InnerSize(Axis2D axis)(UIItem* item) 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 pragma(inline) f32
InnerSize(UIItem* item, Axis2D axis) 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 pragma(inline) f32
InnerOffset(Axis2D axis, bool start)(UIItem* item) InnerOffset(Axis2D axis, bool start)(UIItem* item)
{ {
return item.padding[axis].v[start] + item.border_thickness; return item.border_thickness;
} }
pragma(inline) Vertex* pragma(inline) Vertex*

View File

@ -12,12 +12,16 @@ __gshared const Panel g_nil_panel;
__gshared Panel* g_NIL_PANEL; __gshared Panel* g_NIL_PANEL;
__gshared const Editor g_nil_ed; __gshared const Editor g_nil_ed;
__gshared 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 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_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 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() shared static this()
{ {
@ -38,23 +42,22 @@ void
LineCounterView(FontAtlasBuf* abuf, u64 max_line, u64 lines, i64 line_offset, f32 view_offset) LineCounterView(FontAtlasBuf* abuf, u64 max_line, u64 lines, i64 line_offset, f32 view_offset)
{ {
UICtx* ctx = GetCtx(); UICtx* ctx = GetCtx();
UIKey zero = ZeroKey();
u64 ch_width = max_line.toChars().length; u64 ch_width = max_line.toChars().length;
f32 lc_width = cast(f32)(ch_width+1)*abuf.atlas.max_advance; f32 lc_width = cast(f32)(ch_width+1)*abuf.atlas.max_advance;
enum UIPushInfo[] lc_params = [ enum UIPushInfo[] lc_params = [
{ "layout_axis", q{ A2D.Y } }, { "layout_axis", q{ A2D.Y } },
{ "view_offset", q{ Vec2(0.0, view_offset) } }, { "view_offset", q{ Vec2(0.0, view_offset) } },
{ "padding", q{ Vec2(4.0) } }, { "padding", q{ Vec2(4.0) } },
{ "size_info", q{ UIS2(ST.Pixels, ST.Percentage, lc_width, 1.0) }}, { "size_info", q{ UIS2(ST.Pixels, ST.Percentage, lc_width, 1.0) } },
{ "edge_softness", q{ 0.0 } }, { "edge_softness", q{ 0.0 } },
{ "border_thickness", q{ 1.0 } }, { "border_thickness", q{ 1.0 } },
]; ];
mixin(PushOnce!(lc_params)); 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!("text_col", q{ Vec4(1.0) } ));
mixin(PushScope!("size_info", q{ UISY(ST.Pixels, abuf.atlas.line_height) } )); 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) for(u64 i = line_offset; i < end_line && i < max_line; i += 1)
{ {
char[] buf = ScratchAlloc!(char)(ch_width); char[] buf = ScratchAlloc!(char)(ch_width);
Push!("display_string")(ConvToStr(sformat(ScratchAlloc!(char)(ch_width), "%s", i)), true); Push!("display_string")(Scratchf("%s", i), true);
MakeItem(zero, UIF.DrawText); 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; u8 ch = lb.text.length > ed.cursor_pos.y ? lb.text[ed.cursor_pos.y] : 0;
f32 line_h = abuf.atlas.line_height; 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; 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 + ' '; 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)) 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 = [ enum UIPushInfo[] lc_info = [
{ "display_string", q{ ConvToStr(lb.text) } }, { "display_string", q{ Str(lb.text) } },
{ "syntax_tokens", q{ cast(u8[])(lb.style) } }, { "syntax_tokens", q{ cast(u8[])(lb.style) } },
]; ];
mixin(PushOnce!(lc_info)); mixin(PushOnce!(lc_info));
@ -266,7 +269,7 @@ CommandPalette(CmdPalette* cmd)
enum UIPushInfo[] cmd_input_params = [ enum UIPushInfo[] cmd_input_params = [
{ "bg_col", q{ HL_BG_COL } }, { "bg_col", q{ HL_BG_COL } },
{ "size_info", q{ UISY(ST.TextSize) } }, { "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)); 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) 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); PushBgCol(cmd.selected == i ? HL_BG_COL : opt_cols[i%2], true);
MakeItem(zero, UIF.DrawBackground|UIF.DrawText); 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);
}