diff --git a/src/editor/ui.d b/src/editor/ui.d index d89b967..e10f9c1 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -29,14 +29,23 @@ alias A2D = Axis2D; enum UIFlags { - None, - DrawBackground, - DragX, - DragY, + None = 0x00, + DrawBackground = 0x01, + Clickable = 0x02, + Draggable = 0x04, } alias UIF = UIFlags; +enum UISignal +{ + None = 0x00, + Clicked = 0x01, + Dragged = 0x02, +} + +alias UIS = UISignal; + enum SizeType { Pixels, @@ -58,6 +67,7 @@ struct UIContext UIItemNode* top_parent; UIItemNode* prev_sibling; u32 panel_level; + UIItem* drag_item; UIItemStackList stack_free_list; @@ -66,6 +76,7 @@ struct UIContext Vec4[4] border_color; Vec4 text_color; Axis2D layout_axis; + Vec2 adjustment; } struct UIItemStackList @@ -84,6 +95,7 @@ struct UIItem { UIFlags flags; UIKey key; + UISignal signal; UIItem* next; UIItem* prev; @@ -96,6 +108,7 @@ struct UIItem // Build Parameters Axis2D layout_axis; UISize[2] size_info; + Vec2 adjustment; // Calculated Parameters Vec2 size; @@ -113,9 +126,9 @@ struct UIBuffer { MappedBuffer!(Vertex) mapped_vtx; MappedBuffer!(u32) mapped_idx; - Vertex[] vtx; - u32[] idx; - u32 count; + Vertex[] vtx; + u32[] idx; + u32 count; } union Rect @@ -164,6 +177,7 @@ InitUICtx(Renderer* rd, FontAtlas atlas) root: g_UI_NIL, top_parent: g_UI_NIL_NODE, prev_sibling: g_UI_NIL_NODE, + drag_item: g_UI_NIL, buffer: { mapped_vtx: m_vtx, mapped_idx: m_idx, @@ -315,6 +329,12 @@ PushParent(UIItem* parent) ctx.panel_level += 1; } +void +SetAdjustment(Vec2 adj) +{ + g_ui_ctx.adjustment = adj; +} + void SetColor(Vec4 col) { @@ -383,7 +403,7 @@ CalcFixedSizes(UIItem* item) { if (item.size_info[axis].type == ST.Pixels) { - item.size.v[axis] = item.size_info[axis].value; + item.size.v[axis] = item.size_info[axis].value + item.adjustment.v[axis]; } } @@ -401,7 +421,7 @@ CalcPercentageSizes(UIItem* item) { if (item.size_info[axis].type == ST.Percentage) { - item.size.v[axis] = item.parent.size.v[axis] * item.size_info[axis].value; + item.size.v[axis] = (item.parent.size.v[axis]*item.size_info[axis].value) + item.adjustment.v[axis]; } } @@ -438,29 +458,20 @@ DrawUI(UIContext* ctx, UIItem* item) } } -UIItem* -BuildItem(string id, UISize size_x, UISize size_y, UIFlags properties) -{ - u8[] u8_id = CastStr!(u8)(id); - return BuildItem(u8_id, size_x, size_y, properties); -} - -UIItem* -BuildItem(u8[] id, UISize size_x, UISize size_y, UIFlags properties) +void +BuildItem(UIItem* item, UISize size_x, UISize size_y, UIFlags properties) { UIContext* ctx = GetCtx(); - UIKey key = MakeKey(id); - UIItem* item = Get(key); item.first = item.last = item.next = item.prev = g_UI_NIL; - item.key = key; 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.parent = ctx.top_parent == g_UI_NIL_NODE ? g_UI_NIL : ctx.top_parent.item; if (!Nil(item.parent)) @@ -468,7 +479,32 @@ BuildItem(u8[] id, UISize size_x, UISize size_y, UIFlags properties) DLLPush(item.parent, item, g_UI_NIL); } - return item; + // Reset any once off values here + ctx.adjustment = Vec2(0.0); +} + +void +Signal(UIItem* item) +{ + UIContext* ctx = GetCtx(); + + item.signal = UIS.None; + + for(DNode!(InputEvent)* n = ctx.inputs.list.first; !CheckNil(null, n); n = n.next) + { + + if (item.flags & UIF.Clickable && Clicked(item, n)) + { + Logf("Clicked"); + DLLRemove(&ctx.inputs.list, n, null); + } + + if (item.flags & UIF.Draggable && Clicked(item, n)) + { + Logf("Dragged"); + DLLRemove(&ctx.inputs.list, n, null); + } + } } UIContext* @@ -534,13 +570,23 @@ MakeKey(u8[] id) } UIItem* -Get(UIKey key) +Get(string id) { + u8[] u8_id = CastStr!(u8)(id); + return Get(u8_id); +} + +UIItem* +Get(u8[] id) +{ + UIKey key = MakeKey(id); + Result!(UIItem*) result = g_ui_ctx.items[key.hash]; if (!result.ok) { result.value = Alloc!(UIItem)(&g_ui_ctx.arena); Push(&g_ui_ctx.items, key.hash, result.value); + result.value.key = key; } return result.value; @@ -641,66 +687,27 @@ Nil(UIItem* item) return item == null || item == g_UI_NIL; } -/* -// Setter function in case I need to change to using a mutex -pragma(inline) void -SetProp(alias P, T)(T value) +bool +Clicked(UIItem* item, DNode!(InputEvent)* n) { - static if (is(T: Axis2D)) + bool result = false; + InputEvent* ev = &n.value; + + if ( + ev.key == Input.LeftClick && + ev.x >= item.rect.x0 && + ev.x <= item.rect.x1 && + ev.y >= item.rect.y0 && + ev.y <= item.rect.y1 && + ev.pressed + ) { - static if (P == CtxP.LayoutAxis) g_ui_ctx.layout_axis = value; - else static assert(false, "Unknown property for type Axis2D"); + result = true; } - else static if (is(T: Vec2)) - { - static if (P == CtxP.Position) g_ui_ctx.position = value; - else static assert(false, "Unknown property for type Vec2"); - } - 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 (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]"); - } - else static if (is(T: SizeKind) && P == CtxP.SizeKind) - { - g_ui_ctx.size_kind = value; - } - else static if (is(T: UISize)) - { - 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 (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 (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 (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 (P == CtxP.TabWidth) g_ui_ctx.tab_width = value; - else static assert(false, "Unknown property for type u32"); - } - else static assert(false, "Unknown Type"); + + return result; } -*/ + unittest { diff --git a/src/editor/widgets.d b/src/editor/widgets.d index 2c7e1b1..f561429 100644 --- a/src/editor/widgets.d +++ b/src/editor/widgets.d @@ -8,7 +8,8 @@ Root() { Vec2 d = RootSize(); SetLayoutAxis(A2D.Y); - UIItem* root = BuildItem("##root_item", UISize(ST.Pixels, d.x), UISize(ST.Pixels, d.y), UIF.DrawBackground); + UIItem* root = Get("##root_item"); + BuildItem(root, UISize(ST.Pixels, d.x), UISize(ST.Pixels, d.y), UIF.DrawBackground); return root; } @@ -16,32 +17,43 @@ Root() UIItem* Panel(string id, f32 x_pct, f32 y_pct, Axis2D layout_axis, Vec4 color) { + UIItem* item = Get(id); + UIItem* separator = g_UI_NIL; + UIItem* prev_panel = PeekSiblingPanel(); UIItem* parent = PeekParent(); + Signal(item); + + f32 adj_x = 0.0, adj_y = 0.0; if (!Nil(prev_panel) && parent != prev_panel) { f32 sep_y = 1.0, sep_x = 1.0; if (parent.layout_axis == A2D.X) { - sep_x = 0.005; - //x_pct -= 0.005; + sep_x = 5.0; + adj_x = -5.0; } else { - sep_y = 0.005; - //y_pct -= 0.005; + sep_y = 5.0; + adj_y = -5.0; } - u8[128] buf; + u8[128] buf = 0; (cast(char[])buf).sformat("sep_%s", id); - Separator(buf, sep_x, sep_y); + separator = Get(buf); + + Separator(separator, sep_x, sep_y, parent.layout_axis); + + Signal(separator); } SetColor(color); SetLayoutAxis(layout_axis); - UIItem* item = BuildItem(id, UISize(ST.Percentage, x_pct), UISize(ST.Percentage, y_pct), UIF.DrawBackground); + + BuildItem(item, UISize(ST.Percentage, x_pct), UISize(ST.Percentage, y_pct), UIF.DrawBackground); UIItem* sibling = PrevSiblingPanel(item); @@ -51,14 +63,15 @@ Panel(string id, f32 x_pct, f32 y_pct, Axis2D layout_axis, Vec4 color) return item; } -UIItem* -Separator(u8[] id, f32 x_pct, f32 y_pct) +void +Separator(UIItem* item, f32 x_size, f32 y_size, Axis2D axis) { SetColor(Vec4(0.0, 0.0, 0.0, 1.0)); - UIItem* item = BuildItem(id, UISize(ST.Percentage, x_pct), UISize(ST.Percentage, y_pct), UIF.DrawBackground); + SizeType x_t = axis == A2D.X ? ST.Pixels : ST.Percentage; + SizeType y_t = axis == A2D.Y ? ST.Pixels : ST.Percentage; - return item; + BuildItem(item, UISize(x_t, x_size), UISize(y_t, y_size), UIF.DrawBackground|UIF.Draggable); } void