more ui work

This commit is contained in:
Matthew 2025-12-14 15:22:46 +11:00
parent 8acbeee072
commit f3262c8fb6
6 changed files with 196 additions and 223 deletions

Binary file not shown.

View File

@ -132,7 +132,7 @@ Cycle(EditorCtx* ctx, Inputs* inputs)
assert(Nil(ctx.base_panel.next)); assert(Nil(ctx.base_panel.next));
HandleInputs(ctx, inputs); //HandleInputs(ctx, inputs);
debug if(g_frame_step && !g_frame_continue) return; debug if(g_frame_step && !g_frame_continue) return;
debug g_frame_continue = false; debug g_frame_continue = false;
@ -152,12 +152,15 @@ Cycle(EditorCtx* ctx, Inputs* inputs)
Push!("bg_col", true)(ui_ctx, col0); Push!("bg_col", true)(ui_ctx, col0);
UIItem* p0 = MakeItem("###p0", UIF.DrawBackground|UIF.Resizeable); UIItem* p0 = MakeItem("###p0", UIF.DrawBackground|UIF.Resizeable);
Logf("%s", *ui_ctx.size_info.top); Push!("size_info", true)(ui_ctx, MakeUISize(UISize(ST.Pixels, 200.0), UISize(ST.Pixels, 80.0)));
Push!("parent", true)(ui_ctx, p0);
Push!("bg_col", true)(ui_ctx, col_sep);
Push!("padding", true)(ui_ctx, Vec2(4.0));
UIItem* text = MakeItem("Haha##text", UIF.DrawBackground|UIF.DrawText);
Push!("size_info", true)(ui_ctx, MakeUISizeX(ST.Pixels, 2.0)); Push!("size_info", true)(ui_ctx, MakeUISizeX(ST.Pixels, 2.0));
Logf("%s", *ui_ctx.size_info.top);
Push!("bg_col", true)(ui_ctx, col_sep); Push!("bg_col", true)(ui_ctx, col_sep);
UIItem* sep = MakeItem("###sep", UIF.Draggable|UIF.DrawBackground|UIF.ResizeAdjacent); UIItem* sep = MakeItem("###sep", UIF.Draggable|UIF.DrawBackground|UIF.ResizeAdjacent);
Logf("%s", *ui_ctx.size_info.top);
Push!("bg_col", true)(ui_ctx, col1); Push!("bg_col", true)(ui_ctx, col1);
@ -228,7 +231,7 @@ InitEditorCtx(PlatformWindow* window)
ctx.base_panel = CreatePanel(&ctx); ctx.base_panel = CreatePanel(&ctx);
ctx.base_panel.ed = CreateEditor(&ctx); ctx.base_panel.ed = CreateEditor(&ctx);
ctx.timer = CreateTimer(); ctx.timer = CreateTimer();
SetFocusedPanel(ctx.base_panel); //SetFocusedPanel(ctx.base_panel);
if(getcwd() != "/") if(getcwd() != "/")
{ {
@ -450,10 +453,10 @@ AddEditor(EditorCtx* ctx, UIPanel* target, Axis2D axis)
target.axis = axis; target.axis = axis;
target.ed = null; target.ed = null;
PushPanel(target, first); //PushPanel(target, first);
PushPanel(target, second); //PushPanel(target, second);
SetFocusedPanel(second); //SetFocusedPanel(second);
debug debug
{ {
@ -468,7 +471,7 @@ AddEditor(EditorCtx* ctx, UIPanel* target, Axis2D axis)
UIPanel* panel = CreatePanel(ctx); UIPanel* panel = CreatePanel(ctx);
panel.ed = CreateEditor(ctx); panel.ed = CreateEditor(ctx);
InsertPanel(target.parent, target, panel); //InsertPanel(target.parent, target, panel);
u64 count = 0; u64 count = 0;
for(UIPanel* p = target.parent.first; !Nil(p); p = p.next, count += 1) {} for(UIPanel* p = target.parent.first; !Nil(p); p = p.next, count += 1) {}
@ -479,7 +482,7 @@ AddEditor(EditorCtx* ctx, UIPanel* target, Axis2D axis)
p.pct = pct; p.pct = pct;
} }
SetFocusedPanel(panel); //SetFocusedPanel(panel);
debug debug
{ {
@ -514,12 +517,14 @@ InsertInputToBuf(EditorCtx* ctx)
{ {
if(ctx.icount > 0) if(ctx.icount > 0)
{ {
/*
UIPanel* p = GetFocusedPanel(); UIPanel* p = GetFocusedPanel();
if(!Nil(p)) if(!Nil(p))
{ {
Insert(&p.ed.buf, ctx.input_buf, ctx.icount); Insert(&p.ed.buf, ctx.input_buf, ctx.icount);
ctx.icount = 0; ctx.icount = 0;
} }
*/
} }
} }
@ -551,7 +556,7 @@ MovePanelFocus(A2D axis, bool prev)(UIPanel* panel)
UIPanel* target = prev ? panel.prev : panel.next; UIPanel* target = prev ? panel.prev : panel.next;
if(panel.parent.axis == axis && !Nil(target) && target.ed != null) if(panel.parent.axis == axis && !Nil(target) && target.ed != null)
{ {
SetFocusedPanel(target); //SetFocusedPanel(target);
result = true; result = true;
} }
else for(UIPanel* p = panel.parent; !Nil(p); p = p.parent) else for(UIPanel* p = panel.parent; !Nil(p); p = p.parent)
@ -576,7 +581,7 @@ MovePanelFocus(A2D axis, bool prev)(UIPanel* panel)
if(!Nil(f) && f.ed != null) if(!Nil(f) && f.ed != null)
{ {
SetFocusedPanel(f); //SetFocusedPanel(f);
result = true; result = true;
break; break;
} }
@ -592,7 +597,7 @@ void
HandleInputs(EditorCtx* ctx, Inputs* inputs) HandleInputs(EditorCtx* ctx, Inputs* inputs)
{ {
u8[] cb_text; u8[] cb_text;
UIPanel* panel = GetFocusedPanel(); UIPanel* panel = g_UI_NIL_PANEL;//GetFocusedPanel();
FlatBuffer* fb = !Nil(panel) ? &panel.ed.buf : null; FlatBuffer* fb = !Nil(panel) ? &panel.ed.buf : null;
for(auto node = inputs.first; node != null; node = node.next) for(auto node = inputs.first; node != null; node = node.next)
@ -740,7 +745,7 @@ HandleInputs(EditorCtx* ctx, Inputs* inputs)
void void
MoveCursor(InputEvent* ev) MoveCursor(InputEvent* ev)
{ {
UIPanel* p = GetFocusedPanel(); UIPanel* p = g_UI_NIL_PANEL;//GetFocusedPanel();
if(!Nil(p)) if(!Nil(p))
{ {
@ -787,7 +792,7 @@ HandleInputMode(EditorCtx* ctx, InputEvent* ev)
mixin(CharCases()); mixin(CharCases());
case Input.Backspace: case Input.Backspace:
{ {
UIPanel* p = GetFocusedPanel(); UIPanel* p = g_UI_NIL_PANEL;//GetFocusedPanel();
if(!Nil(p)) if(!Nil(p))
{ {
Backspace(&p.ed.buf); Backspace(&p.ed.buf);
@ -959,7 +964,7 @@ HandleCmdMode(EditorCtx* ctx, InputEvent* ev)
} }
} }
UIPanel* p = GetFocusedPanel(); UIPanel* p = g_UI_NIL_PANEL;//GetFocusedPanel();
switch(cmd.current.type) switch(cmd.current.type)
{ {

View File

@ -43,7 +43,6 @@ void main(string[] argv)
if(g_ui_ctx.rd.res != Vec2(window.w, window.h).v) if(g_ui_ctx.rd.res != Vec2(window.w, window.h).v)
{ {
Logf("resize");
SetExtent(&g_ui_ctx.rd, window.w, window.h); SetExtent(&g_ui_ctx.rd, window.w, window.h);
} }

View File

@ -37,6 +37,7 @@ enum Vec4 TEXT_COL = Vec4(1.0);
enum Vec4 TEXT_HL_COL = Vec4(0.0, 0.0, 0.0, 1.0); enum Vec4 TEXT_HL_COL = Vec4(0.0, 0.0, 0.0, 1.0);
const u64 VERTEX_MAX_COUNT = 10000; const u64 VERTEX_MAX_COUNT = 10000;
const Vec2 CLICK_BUFFER = Vec2(3.0, 3.0);
// TODO: add setting // TODO: add setting
const f32 TEXT_SIZE = 16.0; const f32 TEXT_SIZE = 16.0;
@ -62,6 +63,8 @@ Vec4 g_text_hl_col_default = TEXT_HL_COL;
UISize[2] g_size_info_default = [UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0)]; UISize[2] g_size_info_default = [UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0)];
Axis2D g_layout_axis_default = A2D.X; Axis2D g_layout_axis_default = A2D.X;
Vec2 g_padding_default = Vec2(0.0); Vec2 g_padding_default = Vec2(0.0);
f32 g_text_scale_default = 1.0;
alias g_parent_default = g_UI_NIL;
const UI_COUNT = 5000; const UI_COUNT = 5000;
@ -80,7 +83,6 @@ __gshared Stack!Vec4* g_NIL_VEC4_STACK;
__gshared const Stack!u32 g_nil_u32_stack; __gshared const Stack!u32 g_nil_u32_stack;
__gshared Stack!u32* g_NIL_U32_STACK; __gshared Stack!u32* g_NIL_U32_STACK;
alias g_parent_default = g_UI_NIL;
enum Axis2D enum Axis2D
{ {
@ -223,19 +225,20 @@ struct UICtx
UIPanel* parent_panel; UIPanel* parent_panel;
UIPanel* focused_panel; UIPanel* focused_panel;
mixin UICtxParameter!(UIItem*, "parent");
mixin UICtxParameter!(f32, "corner_radius");
mixin UICtxParameter!(f32, "border_thickness");
mixin UICtxParameter!(f32, "edge_softness");
mixin UICtxParameter!(Vec4[4], "bg_col"); mixin UICtxParameter!(Vec4[4], "bg_col");
mixin UICtxParameter!(Vec4[4], "bg_hl_col"); mixin UICtxParameter!(Vec4[4], "bg_hl_col");
mixin UICtxParameter!(Vec4[4], "border_col"); mixin UICtxParameter!(Vec4[4], "border_col");
mixin UICtxParameter!(Vec4[4], "border_hl_col"); mixin UICtxParameter!(Vec4[4], "border_hl_col");
mixin UICtxParameter!(UISize[2], "size_info");
mixin UICtxParameter!(Vec4, "text_col"); mixin UICtxParameter!(Vec4, "text_col");
mixin UICtxParameter!(Vec4, "text_hl_col"); mixin UICtxParameter!(Vec4, "text_hl_col");
mixin UICtxParameter!(UISize[2], "size_info");
mixin UICtxParameter!(Axis2D, "layout_axis");
mixin UICtxParameter!(Vec2, "padding"); mixin UICtxParameter!(Vec2, "padding");
mixin UICtxParameter!(UIItem*, "parent");
mixin UICtxParameter!(Axis2D, "layout_axis");
mixin UICtxParameter!(f32, "corner_radius");
mixin UICtxParameter!(f32, "border_thickness");
mixin UICtxParameter!(f32, "edge_softness");
mixin UICtxParameter!(f32, "text_scale");
debug bool dbg; debug bool dbg;
} }
@ -560,12 +563,11 @@ void
Signal(UIItem* item) Signal(UIItem* item)
{ {
UICtx* ctx = GetCtx(); UICtx* ctx = GetCtx();
i32 x = ctx.mouse_pos.x;
i32 y = ctx.mouse_pos.y;
item.signal = UIS.None; item.signal = UIS.None;
bool mouse_over = InBounds(ctx.mouse_pos, &item.rect);
if(x >= item.rect.p0.x && x <= item.rect.p1.x && y >= item.rect.p0.y && y <= item.rect.p1.y) if(mouse_over)
{ {
item.signal |= UIS.Hovered; item.signal |= UIS.Hovered;
} }
@ -576,18 +578,14 @@ Signal(UIItem* item)
{ {
bool taken; bool taken;
Logf("%s", i.type);
if(item.flags & UIF.Clickable && i.type == UIE.Click && InBounds(ctx.mouse_pos, &item.rect)) if(item.flags & UIF.Clickable && i.type == UIE.Click && InBounds(ctx.mouse_pos, &item.rect))
{ {
Logf("clicked");
item.signal |= UIS.Clicked; item.signal |= UIS.Clicked;
taken = true; taken = true;
} }
if(Nil(ctx.drag_item) && item.flags & UIF.Draggable && i.type == UIE.DragStart && InBounds(i.pos, &item.rect)) if(Nil(ctx.drag_item) && item.flags & UIF.Draggable && i.type == UIE.DragStart && InBounds(i.pos, &item.rect))
{ {
Logf("dragged");
item.signal |= UIS.Dragged; item.signal |= UIS.Dragged;
ctx.drag_item = item; ctx.drag_item = item;
taken = true; taken = true;
@ -595,7 +593,6 @@ Signal(UIItem* item)
if(ctx.drag_item == item && i.type == UIE.Drag) if(ctx.drag_item == item && i.type == UIE.Drag)
{ {
Logf("dragged");
item.signal |= UIS.Dragged; item.signal |= UIS.Dragged;
item.dragged += i.rel; item.dragged += i.rel;
taken = true; taken = true;
@ -726,34 +723,34 @@ EndUI()
UICtx* ctx = GetCtx(); UICtx* ctx = GetCtx();
// Automatic signals // Automatic signals
for(UIItem* item = ctx.root; !Nil(item); item = Recurse!(true)(item, g_UI_NIL)) for(UIItem* item = ctx.root; !Nil(item); item = Recurse!(false)(item, g_UI_NIL))
{ {
if(item.flags & AUTO_FLAGS) if(item.flags & AUTO_FLAGS)
{ {
Signal(item); Signal(item);
if(item.signal & UIS.Dragged)
{
Logf("1");
}
if(item.flags & UIF.ResizeAdjacent && item.dragged != IVec2(0)) if(item.flags & UIF.ResizeAdjacent && item.dragged != IVec2(0))
{ {
UIItem* prev = !Nil(item.prev) ? item.prev : g_UI_NIL; UIItem* prev = !Nil(item.prev) ? item.prev : g_UI_NIL;
UIItem* next = !Nil(item.next) ? item.next : g_UI_NIL; UIItem* next = !Nil(item.next) ? item.next : g_UI_NIL;
if(prev.flags & UIF.Resizeable && next.flags & UIF.Resizeable)
{
Axis2D axis = item.parent.layout_axis; Axis2D axis = item.parent.layout_axis;
f32 mov_pct = Remap(item.dragged.v[axis], 0.0, item.parent.size.v[axis], 0.0, 1.0); f32 mov_pct = Remap(item.dragged.v[axis], 0.0, item.parent.size.v[axis], 0.0, 1.0);
if(prev.resize_pct > 0.0 && prev.resize_pct < 1.0 && next.resize_pct > 0.0 && next.resize_pct < 1.0)
debug if(!(prev.flags & UIF.Resizeable) && !(next.flags & UIF.Resizeable))
{
Logf("Warning: ResizeAdjacent flag set with no adjacent items having Resizeable flag");
}
if(prev.flags & UIF.Resizeable)
{ {
prev.resize_pct -= mov_pct; prev.resize_pct -= mov_pct;
next.resize_pct += mov_pct;
prev.resize_pct = clamp(prev.resize_pct, 0.0, 1.0); prev.resize_pct = clamp(prev.resize_pct, 0.0, 1.0);
next.resize_pct = clamp(next.resize_pct, 0.0, 1.0);
} }
if(next.flags & UIF.Resizeable)
{
next.resize_pct += mov_pct;
next.resize_pct = clamp(next.resize_pct, 0.0, 1.0);
} }
} }
} }
@ -785,7 +782,7 @@ EndUI()
{ {
if(p.size_info[axis].type == ST.Pixels) if(p.size_info[axis].type == ST.Pixels)
{ {
item.size.v[axis] = floor(item.size_info[axis].value * item.parent.size[axis]); item.size.v[axis] = floor(item.size_info[axis].value * InnerSize!(axis)(item.parent));
break; break;
} }
} }
@ -808,6 +805,9 @@ EndUI()
// Violations // Violations
for(UIItem* item = ctx.root; !Nil(item); item = Recurse!(true)(item, g_UI_NIL)) for(UIItem* item = ctx.root; !Nil(item); item = Recurse!(true)(item, g_UI_NIL))
{ {
Logf("ccc %s", cast(char[])item.key.hash_text);
f32 size = item.size[axis]; // InnerSize!(axis)(item);
if(axis == item.layout_axis) if(axis == item.layout_axis)
{ {
f32 children_size = 0.0; f32 children_size = 0.0;
@ -816,34 +816,41 @@ EndUI()
children_size += c.size.v[axis]; children_size += c.size.v[axis];
} }
if(children_size > item.size[axis]) Logf("%s %s %s", cast(char[])item.key.hash_text, size, children_size);
{ if(children_size > size)
u64 child_count;
for(UIItem* c = item.first; !Nil(c); c = c.next)
{
f32 reduced = c.size.v[axis] - c.size.v[axis]*c.size_info[axis].strictness;
children_size -= reduced;
c.size.v[axis] -= reduced;
child_count += 1;
}
if(children_size > 0.0)
{ {
f32 excess = children_size - size;
for(UIItem* c = item.last; !Nil(c); c = c.prev) for(UIItem* c = item.last; !Nil(c); c = c.prev)
{ {
f32 reduced = Min(children_size, c.size[axis]); f32 leniency = c.size.v[axis] - c.size.v[axis]*c.size_info[axis].strictness;
children_size -= reduced; f32 reduced = Min(excess, leniency);
excess -= reduced;
c.size.v[axis] -= reduced; c.size.v[axis] -= reduced;
if(children_size < 0.0009) if(excess <= 0.0009)
{ {
break; break;
} }
} }
assert(children_size < 0.0009); if(excess > 0.0009)
{
for(UIItem* c = item.last; !Nil(c); c = c.prev)
{
f32 reduced = Min(excess, c.size[axis]);
Logf("r %s", reduced);
excess -= reduced;
c.size.v[axis] -= reduced;
if(excess < 0.0009)
{
break;
}
}
Logf("%s %s", excess, cast(char[])item.key.hash_text);
assert(excess < 0.0009);
} }
} }
} }
@ -851,9 +858,9 @@ EndUI()
{ {
for(UIItem* c = item.first; !Nil(c); c = c.next) for(UIItem* c = item.first; !Nil(c); c = c.next)
{ {
if(c.size.v[axis] > item.size.v[axis]) if(c.size.v[axis] > size)
{ {
c.size.v[axis] = item.size.v[axis]; c.size.v[axis] = size;
} }
} }
} }
@ -864,10 +871,16 @@ EndUI()
f32 pos = 0.0; f32 pos = 0.0;
for(UIItem* item = ctx.root; !Nil(item);) for(UIItem* item = ctx.root; !Nil(item);)
{ {
// This padding idea is FUCKED
f32 padding = !Nil(item.parent) ? item.parent.border_thickness : 0.0;
f32 next_pos = 0.0; f32 next_pos = 0.0;
f32 end_pos = pos + item.size.v[axis]; f32 end_pos = pos + item.size.v[axis];
item.rect.p0.v[axis] = pos; item.rect.p0.v[axis] = pos + padding;
if(axis == A2D.Y)
{
Logf("padding %s %s", pos, padding);
}
item.rect.p1.v[axis] = end_pos; item.rect.p1.v[axis] = end_pos;
assert(!isNaN(item.rect.p0.v[axis])); assert(!isNaN(item.rect.p0.v[axis]));
@ -922,7 +935,7 @@ void
RenderItems(UIItem* root) RenderItems(UIItem* root)
{ {
UICtx* ctx = GetCtx(); UICtx* ctx = GetCtx();
for(UIItem* item = ctx.root; !Nil(item); item = Recurse!(true)(item, g_UI_NIL)) for(UIItem* item = root; !Nil(item); item = Recurse!(true)(item, g_UI_NIL))
{ {
if(item.flags & UIF.DrawBackground) if(item.flags & UIF.DrawBackground)
{ {
@ -948,6 +961,19 @@ RenderItems(UIItem* root)
AddVertexCount(ctx); AddVertexCount(ctx);
} }
if(item.flags & UIF.DrawText)
{
FontAtlas* atl = &ctx.atlas_buf.atlas;
f32 x_pos = item.rect.p0.x + item.border_thickness + item.padding.x;
f32 y_pos = item.rect.p0.y + item.border_thickness + item.padding.y;
foreach(i; 0 .. item.key.text.length)
{
u8 ch = item.key.text[i];
Glyph* g = ch < atl.glyphs.length ? atl.glyphs.ptr + ch : null;
DrawGlyph(item, g, &x_pos, y_pos);
}
}
} }
} }
@ -987,7 +1013,11 @@ Push(string stack_str, bool auto_pop = false, T)(UICtx* ctx, T value)
auto top = mixin(ids.stack_top_node); auto top = mixin(ids.stack_top_node);
Stack!(T)* node = stack.free; Stack!(T)* node = stack.free;
if(!node) if(node)
{
stack.free = node.next;
}
else
{ {
node = Alloc!(Stack!(T))(&ctx.temp_arena); node = Alloc!(Stack!(T))(&ctx.temp_arena);
} }
@ -1009,7 +1039,6 @@ Pop(string stack_str)(UICtx* ctx)
auto stack = &mixin(ids.stack); auto stack = &mixin(ids.stack);
auto top = mixin(ids.stack_top_node); auto top = mixin(ids.stack_top_node);
auto pop = stack.top; auto pop = stack.top;
if(pop != top) if(pop != top)
{ {
@ -1092,7 +1121,6 @@ T*
Recurse(bool pre = true, T)(T* node, T* nil) Recurse(bool pre = true, T)(T* node, T* nil)
{ {
T* child = pre ? node.first : node.last; T* child = pre ? node.first : node.last;
T* sibling = pre ? node.next : node.prev;
T* result = nil; T* result = nil;
if(!Nil(child)) if(!Nil(child))
@ -1101,6 +1129,7 @@ Recurse(bool pre = true, T)(T* node, T* nil)
} }
else for(T* p = node; !Nil(p); p = p.parent) else for(T* p = node; !Nil(p); p = p.parent)
{ {
T* sibling = pre ? p.next : p.prev;
if(!Nil(sibling)) if(!Nil(sibling))
{ {
result = sibling; result = sibling;
@ -1120,14 +1149,7 @@ LineCounterWidth(u32 char_width)
Vec2 Vec2
InnerSize(UIPanel* panel) InnerSize(UIPanel* panel)
{ {
return panel.size - Vec2(g_ui_ctx.border_thickness_top.value*2.0);; return panel.size - Vec2(g_ui_ctx.border_thickness_top.value*2.0);
}
pragma(inline) void
DrawChar(u8 ch, f32* x_pos, f32 y, Vec4 col = Vec4(1.0))
{
Glyph* g = GetGlyph(ch);
DrawGlyph(g, 1.0, x_pos, y, col);
} }
void void
@ -1300,97 +1322,24 @@ struct TextBuffer
TextBuffer* next; TextBuffer* next;
} }
/*
pragma(inline) bool
CullText(UIItem* item, GlyphBounds* gb)
{
bool skip = false;
if(item.culling.x0 != 0.0 || item.culling.x1 != 0.0)
{
if(gb.w <= item.culling.x0+item.culling.x1)
{
skip = true;
}
else
{
f32 start_pct = 1.0-((gb.w-item.culling.x0)/gb.w);
f32 end_pct = 1.0-((gb.w-item.culling.x1)/gb.w);
f32 atlas_len = gb.atlas_r - gb.atlas_l;
gb.atlas_l += atlas_len * start_pct;
gb.atlas_r -= atlas_len * end_pct;
gb.l += item.culling.x0;
gb.r -= item.culling.x1;
gb.w = gb.r-gb.l;
}
}
if(!skip && (item.culling.y0 != 0.0 || item.culling.y1 != 0.0))
{
if(gb.h <= item.culling.y0+item.culling.y1)
{
skip = true;
}
else
{
f32 start_pct = 1.0-((gb.h-item.culling.y0)/gb.h);
f32 end_pct = 1.0-((gb.h-item.culling.y1)/gb.h);
f32 atlas_len = gb.atlas_b-gb.atlas_t;
gb.atlas_t += atlas_len * start_pct;
gb.atlas_b -= atlas_len * end_pct;
gb.t += item.culling.y0;
gb.b -= item.culling.y1;
gb.h = gb.b-gb.t;
}
}
return skip;
}
*/
void void
DrawGlyph(Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col) DrawGlyph(UIItem* item, Glyph* glyph, f32* x_pos, f32 y)
{ {
Vertex* v = DrawGlyph(glyph, scale, x_pos, y); if(glyph)
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(); UICtx* ctx = GetCtx();
Vertex* v = null; Vertex* v = null;
f32 advance = glyph.advance * item.text_scale;
if(glyph.ch == '\t') if(glyph.ch == '\t')
{ {
*x_pos += glyph.advance * (GetCtx().tab_width - 1); *x_pos += advance * (GetCtx().tab_width - 1);
} }
f32 r = glyph.plane_right * scale; f32 r = glyph.plane_right * item.text_scale;
f32 l = glyph.plane_left * scale; f32 l = glyph.plane_left * item.text_scale;
f32 t = glyph.plane_top * scale; f32 t = glyph.plane_top * item.text_scale;
f32 b = glyph.plane_bottom * scale; f32 b = glyph.plane_bottom * item.text_scale;
GlyphBounds gb = { GlyphBounds gb = {
r: r, r: r,
@ -1405,31 +1354,49 @@ DrawGlyph(Glyph* glyph, f32 scale, f32* x_pos, f32 y)
atlas_b: glyph.atlas_bottom, atlas_b: glyph.atlas_bottom,
}; };
// TODO: readd culling
//bool skip = CullText(item, &gb);
f32 y_pos = t; f32 y_pos = t;
v = ctx.buffers[ctx.f_idx].vtx.ptr + ctx.buffers[ctx.f_idx].count; 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 = Vec2(*x_pos+gb.l, y);
v.dst_start.y = y - y_pos; v.dst_end = Vec2(*x_pos+gb.w+gb.l, y+gb.h);
v.dst_end.x = *x_pos + gb.w + gb.l; v.cols = item.text_col;
v.dst_end.y = y + gb.h - y_pos; v.texture = true;
if(glyph.ch != '\t' && glyph.ch != '\n') if(glyph.ch != '\t' && glyph.ch != '\n')
{ {
v.src_start.x = gb.atlas_l; v.src_start = Vec2(gb.atlas_l, gb.atlas_t);
v.src_start.y = gb.atlas_t; v.src_end = Vec2(gb.atlas_r, gb.atlas_b);
v.src_end.x = gb.atlas_r; }
v.src_end.y = gb.atlas_b;
f32 end_x = *x_pos + advance;
f32 width = end_x - *x_pos;
if(end_x > item.rect.p1.x)
{
f32 cull_pct = (end_x - item.rect.p1.x) / width;
v.dst_end.x -= (v.dst_end.x - v.dst_start.x) * cull_pct;
v.src_end.x -= (v.src_end.x - v.src_start.x) * cull_pct;
}
f32 end_y = y_pos + TEXT_SIZE;
f32 height = end_y - y_pos;
if(end_y > item.rect.p1.y)
{
f32 cull_pct = (end_y - item.rect.p1.y) / height;
v.dst_end.y -= (v.dst_end.y - v.dst_start.y) * cull_pct;
v.src_end.y -= (v.src_end.y - v.src_start.y) * cull_pct;
} }
AddVertexCount(ctx); AddVertexCount(ctx);
*x_pos += glyph.advance * scale; *x_pos += advance;
}
}
return v; pragma(inline) f32
InnerSize(Axis2D axis)(UIItem* item)
{
return clamp(item.size[axis] - item.border_thickness*2.0, 0.0, f32.max);
} }
pragma(inline) Vertex* pragma(inline) Vertex*

View File

@ -7,6 +7,13 @@ import buffer;
import std.format; import std.format;
import std.conv; import std.conv;
bool
Nil(UIPanel* panel)
{
return panel == null || panel == g_UI_NIL_PANEL;
}
/*
void void
Panel(UIPanel* panel) Panel(UIPanel* panel)
{ {
@ -198,12 +205,6 @@ GetFocusedPanel()
return Nil(g_ui_ctx.focused_panel) ? g_UI_NIL_PANEL : g_ui_ctx.focused_panel; return Nil(g_ui_ctx.focused_panel) ? g_UI_NIL_PANEL : g_ui_ctx.focused_panel;
} }
bool
Nil(UIPanel* panel)
{
return panel == null || panel == g_UI_NIL_PANEL;
}
TextBuffer* TextBuffer*
MakeMultiline(u8[] text, f32 width, TS[] style = []) MakeMultiline(u8[] text, f32 width, TS[] style = [])
{ {
@ -306,3 +307,4 @@ DrawLineCount(char[] fmt, f32* x_pos, f32 y, u64 line)
*x_pos += LINE_COUNT_PADDING; *x_pos += LINE_COUNT_PADDING;
} }
*/