code cleanup

This commit is contained in:
Matthew 2025-09-23 06:21:44 +10:00
parent f15eda312a
commit 8b71f1239c
3 changed files with 262 additions and 272 deletions

View File

@ -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))

View File

@ -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);
}

View File

@ -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();
@ -159,27 +162,25 @@ LineCounter(u8[] parent_id, FlatBuffer* buf, f32 offset, i64 start_row, i64 end_
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;
}