diff --git a/src/dlib b/src/dlib index ff94c5c..85177ac 160000 --- a/src/dlib +++ b/src/dlib @@ -1 +1 @@ -Subproject commit ff94c5cb5e4b3c581521452a2a50b363a09cd8d6 +Subproject commit 85177acdd04a21d0248051f718ef1e57e12f090e diff --git a/src/editor/buffer.d b/src/editor/buffer.d index 4e5c934..1081f4f 100644 --- a/src/editor/buffer.d +++ b/src/editor/buffer.d @@ -395,7 +395,7 @@ AdjustOffset(FlatBuffer* fb) { i64 screen_pos = CurrentLine(fb) - offset; i64 start = 1; - i64 end = rows-1; + i64 end = rows-2; if(offset > 0 && screen_pos < start) { offset += screen_pos - start; diff --git a/src/editor/editor.d b/src/editor/editor.d index 9968f40..fc09c4d 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -97,7 +97,7 @@ InitEditorCtx(PlatformWindow* window) } UIPanel* -CreatePanel(EditorCtx* ctx) +CreatePanel(EditorCtx* ctx, SizeType size_type = ST.Percentage) { UIPanel* p = Alloc!(UIPanel)(&ctx.arena); p.axis = A2D.Y; diff --git a/src/editor/ui.d b/src/editor/ui.d index df61b26..dff8bf3 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -11,6 +11,7 @@ import std.math.traits : isNaN; import std.math.rounding : ceil; import std.format : sformat; import core.stdc.string : memset; +import core.stdc.math : fabsf; import editor; @@ -63,6 +64,7 @@ enum SizeType { Pixels, Percentage, + FitChild, } alias ST = SizeType; @@ -107,6 +109,7 @@ struct UICtx Axis2D layout_axis; Vec2 adjustment; Vec2 offset; + Vec2 padding; u32 tab_width; f32 text_size; f32 border_thickness; @@ -154,15 +157,16 @@ struct UIItem i64 highlighted_char; // Calculated Parameters - Vec2 size; - Rect rect; Vec4[4] color; Vec4[4] border_color; + Rect rect; + Vec2 size; + Vec2 last_click_pos; + Vec2 offset; + Vec2 padding; f32 border_thickness; f32 corner_radius; f32 edge_softness; - Vec2 last_click_pos; - Vec2 offset; } struct UISize @@ -275,6 +279,8 @@ InitUICtx(PlatformWindow* window) font: font, font_data: cast(u8[])FONT_BYTES, adjustment: 0.0, + padding: Vec2(0.0), + offset: 0.0, }; u64 vertex_size = 10000; @@ -530,6 +536,12 @@ 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) { @@ -696,7 +708,7 @@ CalcFixedSizes(UIItem* item) { if(i.size_info[axis].type == ST.Pixels) { - i.size.v[axis] = i.size_info[axis].value + i.adjustment.v[axis]; + i.size.v[axis] = i.size_info[axis].value + i.adjustment.v[axis] + fabsf(i.offset.v[axis]) + (i.padding.v[axis] * 2.0); assert(!isNaN(i.size.v[axis])); } } @@ -712,7 +724,7 @@ CalcPercentageSizes(UIItem* item) { if(i.size_info[axis].type == ST.Percentage) { - i.size.v[axis] = (i.parent.size.v[axis]*i.size_info[axis].value) + i.adjustment.v[axis]; + i.size.v[axis] = (i.parent.size.v[axis]*i.size_info[axis].value) + fabsf(i.adjustment.v[axis]) + i.offset.v[axis]; assert(!isNaN(i.size.v[axis])); } } @@ -725,10 +737,20 @@ CalcPositions(alias axis)(UIItem* item) f32 pos = 0.0; for(UIItem* i = item; !Nil(i);) { - f32 end_pos = pos + i.size.v[axis]; + f32 end_pos = pos + i.size.v[axis] + i.offset.v[axis]; i.rect.vec0.v[axis] = pos + i.offset.v[axis]; i.rect.vec1.v[axis] = end_pos; + if(i.parent.offset.v[axis] != 0.0) + { + Logf("parent %s %s %s %s", cast(char[])i.parent.key.text, end_pos, i.parent.rect.vec0.v[axis], i.parent.offset.v[axis]); + } + + if(i.offset.v[axis] != 0.0) + { + Logf("%s %s %s %s", cast(char[])i.key.text, end_pos, i.rect.vec0.v[axis], i.offset.v[axis]); + } + assert(!isNaN(i.rect.vec0.v[axis])); assert(!isNaN(i.rect.vec1.v[axis])); @@ -842,6 +864,7 @@ BuildItem(UIItem* item, UISize size_x, UISize size_y, UIFlags properties) item.last_frame = ctx.frame; item.highlighted_char = ctx.highlighted_char; item.offset = ctx.offset; + item.padding = ctx.padding; item.parent = ctx.top_parent == g_UI_NIL_NODE ? g_UI_NIL : ctx.top_parent.item; if(!Nil(item.parent)) @@ -1136,16 +1159,14 @@ void DrawLine(UIItem* item) { UICtx* ctx = GetCtx(); - f32 y = item.rect.y0 + ctx.text_size; - f32 x = item.rect.x0; + f32 y = item.rect.y0 + ctx.text_size + item.padding.v[A2D.Y]; + f32 x = item.rect.x0 + item.padding.v[A2D.X]; FontAtlas* atlas = &ctx.atlas_buf.atlas; - UIPanel* panel = GetFocusedPanel(); - bool active = panel.id == item.parent.key.text; bool edit_mode = EditModeActive(); Vertex* v; - if(item.highlighted_char >= 0 && active) + if(item.highlighted_char >= 0) { v = ctx.buffers[ctx.f_idx].vtx.ptr + ctx.buffers[ctx.f_idx].count; AddUIIndices(ctx); @@ -1333,6 +1354,18 @@ Clicked(UIItem* item, DNode!(InputEvent)* n) return result; } +u8[] +ScratchName(u8[] base, string append) +{ + u8[] u8_append = CastStr!(u8)(append); + + u8[] id = ScratchAlloc!(u8)(base.length+append.length); + id[0 .. base.length] = base[0 .. $]; + id[base.length .. $] = u8_append[0 .. $]; + + return id; +} + void SetFocus(UIItem* item) { diff --git a/src/editor/widgets.d b/src/editor/widgets.d index 078bb08..4f7d971 100644 --- a/src/editor/widgets.d +++ b/src/editor/widgets.d @@ -8,6 +8,8 @@ import std.format : sformat; import std.math.rounding : ceil, floor; import std.math.exponential : pow; import core.stdc.math : fabsf; +import std.conv; +import core.stdc.stdio : sprintf; const UIPanel g_ui_nil_panel; UIPanel* g_UI_NIL_PANEL; @@ -28,17 +30,18 @@ struct UIPanel u8[] id; Editor* ed; - UIPanel* parent; - UIPanel* next; - UIPanel* prev; - UIPanel* first; - UIPanel* last; + UIPanel* parent; + UIPanel* next; + UIPanel* prev; + UIPanel* first; + UIPanel* last; - UIPanel* list_next; + UIPanel* list_next; - Axis2D axis; - f32 pct; - Vec4 color; + Axis2D axis; + SizeType size_type; + f32 pct; + Vec4 color; i64 prev_offset; i64 start_row; @@ -131,6 +134,85 @@ Panel(UIPanel* panel, UIFlags flags = UIF.None) return item; } +UIItem* +LineCounter(u8[] parent_id, FlatBuffer* buf, f32 offset, i64 start_row, i64 end_row) +{ + u8[] id = ScratchName(parent_id, "linec"); + + auto end_chars = end_row.toChars(); + u64 width = cast(u64)(end_chars.length); + + char[20] ch_buf; + ch_buf.sformat("%%0%sllu%%s", width); + + u8[] max_row_text; + u8[][] line_counts = ScratchAlloc!(u8[])(end_row-start_row); + if(line_counts.length > 0) + { + for(u64 i = 0; start_row+i < end_row; i += 1) + { + line_counts[i] = ScratchAlloc!(u8)(width+parent_id.length); + sprintf(cast(char*)line_counts[i].ptr, ch_buf.ptr, start_row+i, cast(char*)parent_id.ptr); + } + + max_row_text = ScratchAlloc!(u8)(width); + max_row_text[] = cast(u8)'0'; + } + + SetPadding(Vec2(4.0, 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); + + SetOffset(Vec2(0.0, offset)); + 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]); + } + SetOffset(Vec2(0.0)); + + SetPadding(Vec2(0.0)); + EndContainer(); + EndContainer(); + + return item; +} + +UIItem* +Container(u8[] text, UISize size_x, UISize size_y, Axis2D axis, UIF flags = UIF.None) +{ + UIItem* item = Get(text); + + SetLayoutAxis(axis); + + BuildItem(item, size_x, size_y, flags); + + PushParent(item); + + return item; +} + +void +EndContainer() +{ + PopParent(); +} + +UIItem* +Text(u8[] text) +{ + UIItem* item = Get(text); + f32 width = CalcTextWidth(item.key.text); + BuildItem(item, UISize(ST.Pixels, width), UISize(ST.Pixels, 16.0), UIF.DrawText); + return item; +} + void Separator(UIPanel* panel, UIItem* parent, f32* adj_x, f32* adj_y) { @@ -234,6 +316,8 @@ EditorView(UIPanel* panel) bool focused = panel == GetFocusedPanel(); + 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; @@ -248,7 +332,9 @@ EditorView(UIPanel* panel) 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; @@ -257,9 +343,8 @@ EditorView(UIPanel* panel) remaining_time = 0.0; } - f32 offset = Remap(remaining_time, 0.0, start_time, 0.0, 1.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); - SetOffset(Vec2(0.0, offset)); if(remaining_time == 0.0) { @@ -267,6 +352,7 @@ EditorView(UIPanel* panel) } 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 @@ -274,6 +360,11 @@ EditorView(UIPanel* panel) 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) @@ -296,7 +387,7 @@ EditorView(UIPanel* panel) SetHighlightedChar(-1); } - + SetOffset(Vec2(0.0)); Signal(item); @@ -305,7 +396,9 @@ EditorView(UIPanel* panel) SetFocusedPanel(panel); } - SetOffset(Vec2(0.0)); + EndContainer(); + + EndContainer(); EndPanel(); }