diff --git a/assets/gui.vert.spv b/assets/gui.vert.spv index 8e72338..01eb875 100644 Binary files a/assets/gui.vert.spv and b/assets/gui.vert.spv differ diff --git a/src/editor/ui.d b/src/editor/ui.d index dff8bf3..8ccdbd1 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -110,12 +110,13 @@ struct UICtx Vec2 adjustment; Vec2 offset; Vec2 padding; + i64 highlighted_char; u32 tab_width; f32 text_size; f32 border_thickness; f32 corner_radius; f32 edge_softness; - i64 highlighted_char; + f32 z_index; debug u32 item_count; debug u32 final_count; @@ -167,6 +168,8 @@ struct UIItem f32 border_thickness; f32 corner_radius; f32 edge_softness; + f32 z_index; + Rect culling; } struct UISize @@ -200,6 +203,7 @@ struct Vertex f32 corner_radius; f32 edge_softness; f32 raised; + f32 z_index; u32 texture; } @@ -281,6 +285,7 @@ InitUICtx(PlatformWindow* window) adjustment: 0.0, padding: Vec2(0.0), offset: 0.0, + z_index: 0.0, }; u64 vertex_size = 10000; @@ -301,20 +306,21 @@ InitUICtx(PlatformWindow* window) ctx.desc_set = AllocDescSet(&ctx.rd, ctx.desc_set_layout); ctx.pipeline_layout = CreatePipelineLayout(&ctx.rd, ctx.desc_set_layout, PushConst.sizeof); - Attribute[13] attributes = [ - { binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 0}, - { binding: 0, location: 1, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 1}, - { binding: 0, location: 2, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 2}, - { binding: 0, location: 3, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 3}, - { binding: 0, location: 4, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof }, - { binding: 0, location: 5, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof }, - { binding: 0, location: 6, format: FMT.RG_F32, offset: Vertex.src_start.offsetof }, - { binding: 0, location: 7, format: FMT.RG_F32, offset: Vertex.src_end.offsetof }, - { binding: 0, location: 8, format: FMT.R_F32, offset: Vertex.border_thickness.offsetof }, - { binding: 0, location: 9, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof }, - { binding: 0, location: 10, format: FMT.R_F32, offset: Vertex.edge_softness.offsetof }, - { binding: 0, location: 11, format: FMT.R_F32, offset: Vertex.raised.offsetof }, - { binding: 0, location: 12, format: FMT.R_U32, offset: Vertex.texture.offsetof }, + Attribute[14] attributes = [ + { binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 0}, + { binding: 0, location: 1, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 1}, + { binding: 0, location: 2, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 2}, + { binding: 0, location: 3, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 3}, + { binding: 0, location: 4, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof }, + { binding: 0, location: 5, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof }, + { binding: 0, location: 6, format: FMT.RG_F32, offset: Vertex.src_start.offsetof }, + { binding: 0, location: 7, format: FMT.RG_F32, offset: Vertex.src_end.offsetof }, + { binding: 0, location: 8, format: FMT.R_F32, offset: Vertex.border_thickness.offsetof }, + { binding: 0, location: 9, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof }, + { binding: 0, location: 10, format: FMT.R_F32, offset: Vertex.edge_softness.offsetof }, + { binding: 0, location: 11, format: FMT.R_F32, offset: Vertex.raised.offsetof }, + { binding: 0, location: 12, format: FMT.R_F32, offset: Vertex.z_index.offsetof }, + { binding: 0, location: 13, format: FMT.R_U32, offset: Vertex.texture.offsetof }, ]; GfxPipelineInfo ui_info = { @@ -491,6 +497,18 @@ 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) { @@ -668,7 +686,7 @@ PrepRendering(UICtx* ctx) if(ext != ctx.res) { ctx.res = ext; - Ortho(&ctx.pc.projection, 0.0, 0.0, ext.x, ext.y, 1000.0, 0.1); + Ortho(&ctx.pc.projection, 0.0, 0.0, ext.x, ext.y, -10.0, 10.0); } PushConstants(&ctx.rd, ctx.pipeline, &ctx.pc); @@ -741,16 +759,6 @@ CalcPositions(alias axis)(UIItem* item) 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])); @@ -843,6 +851,30 @@ Recurse(UIItem* item) return result; } +UIItem* +RecurseB(UIItem* item) +{ + UIItem* result = g_UI_NIL; + if(!Nil(item.last)) + { + result = item.last; + } + else if(!Nil(item.prev)) + { + result = item.prev; + } + else for(UIItem* i = item.parent; !Nil(i); i = i.parent) + { + if(!Nil(i.prev)) + { + result = i.prev; + break; + } + } + + return result; +} + void BuildItem(UIItem* item, UISize size_x, UISize size_y, UIFlags properties) { @@ -865,6 +897,9 @@ BuildItem(UIItem* item, UISize size_x, UISize size_y, UIFlags properties) item.highlighted_char = ctx.highlighted_char; item.offset = ctx.offset; item.padding = ctx.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)) @@ -1239,6 +1274,8 @@ 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; @@ -1247,6 +1284,27 @@ DrawGlyph(UIItem* item, Glyph* glyph, f32 scale, f32* x_pos, f32 y, bool highlig v.src_end.y = glyph.atlas_bottom; } + /* + static foreach(axis; A2D.min .. A2D.max) + { + if(item.culling.vec0.v[axis] != 0.0 || item.culling.vec1.v[axis] != 0.0) + { + f32 length = v.dst_end.v[axis] - v.dst_start.v[axis]; + f32 start_pct = 1.0-((length-item.culling.vec0.v[axis])/length); + f32 end_pct = 1.0-((length-item.culling.vec1.v[axis])/length); + + f32 atlas_len = v.src_end.v[axis] - v.src_start.v[axis]; + v.src_start.v[axis] -= atlas_len * start_pct; + v.src_end.v[axis] -= atlas_len * end_pct; + + v.dst_start.v[axis] -= item.culling.vec0.v[axis]; + v.dst_end.v[axis] -= item.culling.vec1.v[axis]; + + Logf("culling %s %s %s %s start_pct %s end_pct %s", length, item.culling.vec0.v[axis], item.culling.vec1.v[axis], axis, start_pct, end_pct); + } + } + */ + if(highlight) { col = Vec4(Vec3(1.0)-col.xyz, 1.0); @@ -1273,6 +1331,7 @@ 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); } @@ -1288,6 +1347,7 @@ 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); } diff --git a/src/editor/widgets.d b/src/editor/widgets.d index 4f7d971..ed88f1c 100644 --- a/src/editor/widgets.d +++ b/src/editor/widgets.d @@ -160,26 +160,26 @@ LineCounter(u8[] parent_id, FlatBuffer* buf, f32 offset, i64 start_row, i64 end_ } SetPadding(Vec2(4.0, 0.0)); - SetColor(Vec4(0.2, 0.5, 0.65, 1.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]); } - SetOffset(Vec2(0.0)); - - SetPadding(Vec2(0.0)); - EndContainer(); - EndContainer(); return item; } @@ -244,7 +244,10 @@ Separator(UIPanel* panel, UIItem* parent, f32* adj_x, f32* adj_y) UIItem* item = Get(buf); + f32 prev_z = GetZIndex(); + SetZIndex(-5.0); BuildItem(item, UISize(x_t, sep_x), UISize(y_t, sep_y), UIF.DrawBackground|UIF.Draggable); + SetZIndex(prev_z); Signal(item); @@ -310,11 +313,20 @@ EaseOutExp(f32 v) void EditorView(UIPanel* panel) { + bool focused = panel == GetFocusedPanel(); + + f32 prev_z = GetZIndex(); + if(!focused) + { + SetZIndex(-1.0); + } + UICtx* ctx = GetCtx(); UIItem* item = Panel(panel, UIF.Clickable); Editor* ed = panel.ed; - bool focused = panel == GetFocusedPanel(); + + scope(exit) SetZIndex(prev_z); Container(ScratchName(panel.id, "cntr"), UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0), A2D.X); @@ -490,7 +502,9 @@ DrawPanels(UIPanel* panel) } else { + SetZIndex(1.0); Panel(panel); + SetZIndex(0.0); } DrawPanels(panel.first); diff --git a/src/shaders/gui.vert.glsl b/src/shaders/gui.vert.glsl index 76c9692..db63396 100644 --- a/src/shaders/gui.vert.glsl +++ b/src/shaders/gui.vert.glsl @@ -16,7 +16,8 @@ layout (location = 8) in float border_thickness; layout (location = 9) in float corner_radius; layout (location = 10) in float edge_softness; layout (location = 11) in float raised; -layout (location = 12) in uint in_has_texture; +layout (location = 12) in float z_index; +layout (location = 13) in uint in_has_texture; layout (location = 0) flat out uint out_has_texture; @@ -85,6 +86,6 @@ void main() FragData.border_thickness = border_thickness; out_has_texture = in_has_texture; - vec4 v_pos = PC.projection * vec4(pos.x, pos.y, 0, 1); - gl_Position = vec4(v_pos.x, v_pos.y, 0, 1); + vec4 v_pos = PC.projection * vec4(pos.x, pos.y, z_index, 1); + gl_Position = vec4(v_pos.x, v_pos.y, v_pos.z, 1); }