diff --git a/src/dlib b/src/dlib index a7d571b..ad1b167 160000 --- a/src/dlib +++ b/src/dlib @@ -1 +1 @@ -Subproject commit a7d571bd5a1bdbe7aa15e5cacfba8795f2e5979b +Subproject commit ad1b167e2b527a2386f7a42e6f908a0f667b5089 diff --git a/src/editor/editor.d b/src/editor/editor.d index 21b04c9..b651eb4 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -4,9 +4,11 @@ import dlib.platform; import dlib.fonts; import vulkan; import dlib.math; +import std.format : sformat; import dlib.alloc; import buffer; import ui; +import widgets; import std.stdio; import std.exception; @@ -174,12 +176,10 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name) } void -Cycle(Editor* ed) +Cycle(Editor* ed, Inputs* inputs) { Reset(&ed.temp_arena); - Logf("begin"); UIBeginBuild(); - Logf("end"); /* f32 pos = 0.0; @@ -187,6 +187,36 @@ Cycle(Editor* ed) DrawBuffer(ed, 0.0, 0.0, h, ed.active_buffer); */ + u32 count = 0; + static u32 box_count = 1; + for(auto ev = inputs.list.first; ev != null; ev = ev.next) + { + count += 1; + Logf("%s", ev.value.key); + switch(ev.value.key) + { + case KBI.One: box_count = 1; break; + case KBI.Two: box_count = 2; break; + case KBI.Three: box_count = 3; break; + case KBI.Four: box_count = 4; break; + case KBI.Five: box_count = 5; break; + case KBI.Six: box_count = 6; break; + case KBI.Seven: box_count = 7; break; + case KBI.Eight: box_count = 8; break; + case KBI.Nine: box_count = 9; break; + default: break; + } + } + + char[128] buf = 0; + f32 x_pct = 1.0/box_count; + foreach(i; 0 .. box_count) + { + buf.sformat("##%s", i); + Logf("%r %s %s %f", buf, i, box_count, x_pct); + WindowItem(cast(u8[])buf, x_pct, 1.0, Vec4(Vec3(x_pct * i), 1.0)); + } + BeginFrame(&ed.rd); UVec2 ext = UVec2(GetExtent(&ed.rd)); diff --git a/src/editor/main.d b/src/editor/main.d index 37cc9e7..9e7028c 100644 --- a/src/editor/main.d +++ b/src/editor/main.d @@ -30,6 +30,6 @@ void main(string[] argv) break; } - Cycle(&editor); + Cycle(&editor, &window.inputs); } } diff --git a/src/editor/ui.d b/src/editor/ui.d index 08a0c81..65dbb5e 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -31,6 +31,7 @@ struct UIContext u32 tab_width; f32 text_scale; Stack!(UIItem) parent_stack; + Axis2D layout_axis; } struct Stack(T) @@ -61,6 +62,7 @@ enum CtxProperty Padding, TextScale, TabWidth, + LayoutAxis, } alias CtxP = CtxProperty; @@ -108,6 +110,7 @@ alias SK = SizeKind; union Rect { + Vec2[2] v; struct { Vec2 vec0; @@ -133,6 +136,13 @@ struct UISize f32 strictness; } +struct UIItemRec +{ + UIItem* next; + i32 push_count; + i32 pop_count; +} + struct UIItem { UIProperties flags; @@ -153,6 +163,7 @@ struct UIItem f32[A2D.max] fixed_position; Rect rect; f32 text_scale; + Axis2D layout_axis; } struct UIKey @@ -194,7 +205,7 @@ UIFinishBuild() // 1. Pixel/Text sizes (any order) - for(UIItem* item = ui.root; !Nil(item); item = Recurse!(UIR.PreOrder)(item, ui.root)) + for(UIItem* item = ui.root; !Nil(item); item = Recurse!(UIR.PreOrder)(item, ui.root).next) { foreach(i, ref s; item.size) { @@ -202,34 +213,87 @@ UIFinishBuild() { item.computed_size[i] = s.value; } + else if (s.kind == SK.TextContent) + { + // Text size + padding + } } } // 2. PercentOfParent (Upward dependant) size (pre-order) (Ignore downward dependant sizes) - // 3. ChildrenSum (Downward dependant) (post-order) - // 4. Solve violations e.g. extending past boundaries of parent (pre-order) - - // 5. Compute relative positions of each widgets (pre-order) - for(UIItem* item = ui.root; !Nil(item); item = Recurse!(UIR.PreOrder)(item, ui.root)) + u32 count = 0; + for(UIItem* item = ui.root; !Nil(item); item = Recurse!(UIR.PreOrder)(item, ui.root).next) { - if (Nil(item.parent)) + for(UIItem* child = item.first; !Nil(child); child = child.next) { - item.computed_rel_pos = item.fixed_position; + foreach(i, ref s; child.size) + { + if (s.kind == SK.PercentOfParent) + { + UIItem* fixed_parent = g_UI_NIL; + for(UIItem* p = child.parent; !Nil(p); p = p.parent) + { + if (p.size[i].kind == SK.Pixels || p.size[i].kind == SK.TextContent) + { + fixed_parent = p; + break; + } + } - item.rect.x0 = item.computed_rel_pos[A2D.X]; - item.rect.y0 = item.computed_rel_pos[A2D.Y]; - item.rect.x1 = item.computed_size[A2D.X]; - item.rect.y1 = item.computed_size[A2D.Y]; + child.computed_size[i] = fixed_parent.computed_size[i] * s.value; + } + } } } - for(UIItem* item = ui.root; !Nil(item); item = Recurse!(UIR.PreOrder)(item, ui.root)) + // 3. ChildrenSum (Downward dependant) (post-order) { - if (!Nil(item)) + UIItemRec rec; + foreach(axis; A2D.min .. A2D.max) { - if (item.flags & UIP.DrawBackground) + for(UIItem* item = ui.root; !Nil(item); item = rec.next) { - DrawRect(ui, item); + rec = Recurse!(UIR.PreOrder)(item, ui.root); + i32 pop_index = 0; + for(UIItem* i = item; !Nil(item) && pop_index <= rec.pop_count; i = i.parent, pop_index += 1) + { + } + } + } + } + // 4. Solve violations e.g. extending past boundaries of parent (pre-order) + + // 5. Compute relative positions of each widgets (pre-order) + foreach(axis; A2D.min .. A2D.max) + { + for(UIItem* item = ui.root; !Nil(item); item = Recurse!(UIR.PreOrder)(item, ui.root).next) + { + f32 layout_position = 0.0; + + for(UIItem* child = item.first; !Nil(child); child = child.next) + { + child.computed_rel_pos[axis] = layout_position; + child.rect.vec0.v[axis] = layout_position; + child.rect.vec1.v[axis] = layout_position + child.computed_size[axis]; + + if (axis == item.layout_axis) + { + layout_position += child.computed_size[axis]; + } + } + } + } + + for(UIItem* item = ui.root; !Nil(item); item = Recurse!(UIR.PreOrder)(item, ui.root).next) + { + for(UIItem* child = item.first; !Nil(child); child = child.next) + { + if (!Nil(child)) + { + if (child.flags & UIP.DrawBackground) + { + DrawRect(ui, child); + } } } } @@ -244,10 +308,10 @@ BuildItem(UIKey key, UIProperties flags) item.first = item.last = item.next = item.prev = item.parent = g_UI_NIL; item.computed_rel_pos = item.computed_size = 0; - item.flags = flags; item.size = ui.size_axes; item.padding = ui.padding; + item.layout_axis = ui.layout_axis; if (item.flags & UIP.DrawBackground) { @@ -262,6 +326,12 @@ BuildItem(UIKey key, UIProperties flags) item.text_scale = ui.text_scale; } + item.parent = ui.parent_stack.first; + if (!Nil(item.parent)) + { + DLLPush(item.parent, item, g_UI_NIL); + } + return item; } @@ -473,17 +543,19 @@ Nil(UIItem* item) return item == null || item == g_UI_NIL; } -UIItem* +UIItemRec Recurse(alias mode)(UIItem* item, UIItem* root) { - UIItem* sibling, child, result = g_UI_NIL; + UIItem* sibling, child; + UIItemRec result = UIItemRec(next: g_UI_NIL); static if (mode == UIR.PostOrder) sibling = item.next; else sibling = item.prev; static if (mode == UIR.PostOrder) child = item.prev; else child = item.last; if (!Nil(child)) { - result = sibling; + result.next = child; + result.push_count = 1; } else for(UIItem* i = sibling; !Nil(i) && i != root; i = i.parent) { @@ -491,9 +563,11 @@ Recurse(alias mode)(UIItem* item, UIItem* root) if (!Nil(sibling)) { - result = sibling; + result.next = sibling; break; } + + result.pop_count += 1; } return result; @@ -503,17 +577,20 @@ Recurse(alias mode)(UIItem* item, UIItem* root) pragma(inline) void SetProp(alias P, T)(T value) { - static if (is(T: Vec4)) + static if (is(T: Axis2D)) { - static if (0) {} - else static if (P == CtxP.BGColor) g_ui_ctx.bg_cols = [value, value, value, value]; + static if (P == CtxP.LayoutAxis) g_ui_ctx.layout_axis = value; + else static assert(false, "Unknown property for type Axis2D"); + } + else static if (is(T: Vec4)) + { + static if (P == CtxP.BGColor) g_ui_ctx.bg_cols = [value, value, value, value]; else static if (P == CtxP.BorderColor) g_ui_ctx.border_cols = [value, value, value, value]; else static assert(false, "Unknown Property for type Vec4"); } else static if (is(T: Vec4[4])) { - static if (0) {} - else static if (P == CtxP.BGColor) g_ui_ctx.bg_cols = value; + static if (P == CtxP.BGColor) g_ui_ctx.bg_cols = value; else static if (P == CtxP.BorderColor) g_ui_ctx.border_cols = value; else static assert(false, "Unknown Property for type Vec4[4]"); } @@ -523,32 +600,28 @@ SetProp(alias P, T)(T value) } else static if (is(T: UISize)) { - static if (0) {} - else static if (P == CtxP.AxisX) g_ui_ctx.size_axes[A2D.X] = value; + static if (P == CtxP.AxisX) g_ui_ctx.size_axes[A2D.X] = value; else static if (P == CtxP.AxisY) g_ui_ctx.size_axes[A2D.Y] = value; else static assert(false, "Unknown Property for type UISize"); } else static if (is(T: FontAtlas)) { - static if (0) {} - else static if (P == CtxP.FontAtlas) g_ui_ctx.atlas = value; + static if (P == CtxP.FontAtlas) g_ui_ctx.atlas = value; else static assert(false, "Unknown Property for type FontAtlas"); } else static if (is(T: Rect)) { - static if (0) {} - else static if (P == CtxP.Padding) g_ui_ctx.padding = value; + static if (P == CtxP.Padding) g_ui_ctx.padding = value; + else static assert(false, "Unknown property for type Rect"); } else static if (is(T: f32)) { - static if (0) {} - else static if (P == CtxP.TextScale) g_ui_ctx.text_scale = value; + static if (P == CtxP.TextScale) g_ui_ctx.text_scale = value; else static assert(false, "Unknown property for type f32"); } else static if (is(T: u32)) { - static if (0) {} - else static if (P == CtxP.TabWidth) g_ui_ctx.tab_width = value; + static if (P == CtxP.TabWidth) g_ui_ctx.tab_width = value; else static assert(false, "Unknown property for type u32"); } else static assert(false, "Unknown Type"); diff --git a/src/editor/widgets.d b/src/editor/widgets.d index 4355731..17397fa 100644 --- a/src/editor/widgets.d +++ b/src/editor/widgets.d @@ -2,6 +2,11 @@ import dlib; import ui; +struct Window +{ + +} + UIItem* RootItem() { @@ -12,8 +17,23 @@ RootItem() SetProp!(CtxP.AxisX)(UISize(SK.Pixels, size.x, 1.0)); SetProp!(CtxP.AxisY)(UISize(SK.Pixels, size.y, 1.0)); SetProp!(CtxP.BGColor)(Vec4(0.2, 0.5, 0.85, 1.0)); + SetProp!(CtxP.LayoutAxis)(A2D.X); UIItem* item = BuildItem(key, UIP.DrawBackground); - return item; + return item; +} + +UIItem* +WindowItem(u8[] str, f32 x_pct, f32 y_pct, Vec4 col) +{ + UIKey key = MakeKey(str); + + SetProp!(CtxP.AxisX)(UISize(SK.PercentOfParent, x_pct)); + SetProp!(CtxP.AxisY)(UISize(SK.PercentOfParent, y_pct)); + SetProp!(CtxP.BGColor)(col); + + UIItem* item = BuildItem(key, UIP.DrawBackground); + + return item; }