diff --git a/assets/gui.frag.spv b/assets/gui.frag.spv index 89ae57e..8794c32 100644 Binary files a/assets/gui.frag.spv and b/assets/gui.frag.spv differ diff --git a/assets/gui.vert.spv b/assets/gui.vert.spv index f6bf6e3..26ecb60 100644 Binary files a/assets/gui.vert.spv and b/assets/gui.vert.spv differ diff --git a/src/dlib b/src/dlib index c00c404..e77c179 160000 --- a/src/dlib +++ b/src/dlib @@ -1 +1 @@ -Subproject commit c00c404006147838fb8af3259cf214396da31c99 +Subproject commit e77c1790f7eb5d18d8d84596025c53b2caaca18c diff --git a/src/editor/editor.d b/src/editor/editor.d index ae248ff..1bd1858 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -135,6 +135,7 @@ Cycle(Inputs* inputs) g_delta = 0.01; } + //HandleInputs(ctx, inputs); debug if(g_frame_step && !g_frame_continue) return; @@ -146,6 +147,20 @@ Cycle(Inputs* inputs) UICtx* ui_ctx = GetCtx(); + debug + { + ui_ctx.dbg = false; + + for(InputEvent* ev = inputs.first; ev; ev = ev.next) + { + if(ev.key == Input.g && ev.md & MD.LeftCtrl) + { + ui_ctx.dbg = true; + break; + } + } + } + EditorView(g_ed_ctx.base_panel); if(g_ed_ctx.state == ES.CmdOpen) @@ -221,7 +236,7 @@ CreatePanel(EditorCtx* ctx, Editor* ed = null) p.layout_axis = A2D.Y; p.ed = ed; p.id = ctx.panel_id++; - p.text_size = 18; + p.text_size = 14; p.parent = p.first = p.last = p.next = p.prev = g_NIL_PANEL; return p; diff --git a/src/editor/ui.d b/src/editor/ui.d index b1f308b..ebe1915 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -25,6 +25,7 @@ import core.stdc.stdio : sprintf; - Display string should be separate from key string - If key is 0 then its transient and will be discarded next frame - Events should be created then processed instead of directly from inputs +// Little mode ui thing in the corner thats colored and it slides the colour out (left to right) when mode is changed *********************************/ @@ -56,6 +57,7 @@ Vec4 g_corner_radius_default = 0.0; f32 g_edge_softness_default = 0.8; f32 g_border_thickness_default = 0.0; Vec4 g_bg_col_default = BG_COL; +Vec4 g_bg_col_end_default = BG_COL; Vec4 g_bg_hl_col_default = BG_HL_COL; Vec4 g_border_col_default = BORDER_COL; Vec4 g_border_hl_col_default = BORDER_HL_COL; @@ -124,6 +126,7 @@ enum UIFlags FixedPosAnimated = 1<<20, // todo: add fixed_pos_target then interpolate position every frame OverflowX = 1<<21, OverflowY = 1<<22, + Gradient = 1<<23, Clamp = UIFlags.ClampX | UIFlags.ClampY, PortalView = UIFlags.PortalViewX | UIFlags.PortalViewY, @@ -261,6 +264,7 @@ struct UICtx UIItem* focus_item; mixin UICtxParameter!(Vec4, "bg_col"); + mixin UICtxParameter!(Vec4, "bg_col_end"); mixin UICtxParameter!(Vec4, "bg_hl_col"); mixin UICtxParameter!(Vec4, "border_col"); mixin UICtxParameter!(Vec4, "border_hl_col"); @@ -269,7 +273,7 @@ struct UICtx mixin UICtxParameter!(Vec4, "text_hl_col"); mixin UICtxParameter!(Vec2[2], "scroll_clamp"); mixin UICtxParameter!(Vec2, "scroll_target"); - mixin UICtxParameter!(Vec2, "padding"); + mixin UICtxParameter!(Vec2[2], "padding"); mixin UICtxParameter!(Vec2, "view_offset"); mixin UICtxParameter!(Vec2, "fixed_pos"); mixin UICtxParameter!(UIItem*, "parent"); @@ -354,7 +358,6 @@ struct UIItem string[] text_lines; u8[][] token_lines; Vec2 scroll_offset; - Vec2 pos_offset; u8[] text_buffer; f32 max_text_width; f32 resize_pct; @@ -390,12 +393,6 @@ struct UIBuffer u32 vtx_offset; } -struct GlyphBounds -{ - f32 r = 0.0, l = 0.0, t = 0.0, b = 0.0, w = 0.0, h = 0.0; - f32 atlas_r = 0.0, atlas_l = 0.0, atlas_t = 0.0, atlas_b = 0.0; -} - struct VPos { Vec2 start; @@ -405,6 +402,7 @@ struct VPos struct Vertex { Vec4 cols; + Vec4 cols_end; Vec4 corner_radius; Vec2[2] bounds; union @@ -425,6 +423,24 @@ struct Vertex u32 atlas_index; } +Attribute[15] attributes = [ + { binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof }, + { binding: 0, location: 1, format: FMT.RGBA_F32, offset: Vertex.cols_end.offsetof }, + { binding: 0, location: 2, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof + f32.sizeof*0 }, + { binding: 0, location: 3, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof + f32.sizeof*1 }, + { binding: 0, location: 4, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof + f32.sizeof*2 }, + { binding: 0, location: 5, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof + f32.sizeof*3 }, + { binding: 0, location: 6, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof }, + { binding: 0, location: 7, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof }, + { binding: 0, location: 8, format: FMT.RG_F32, offset: Vertex.src_start.offsetof }, + { binding: 0, location: 9, format: FMT.RG_F32, offset: Vertex.src_end.offsetof }, + { binding: 0, location: 10, format: FMT.R_F32, offset: Vertex.border_thickness.offsetof }, + { binding: 0, location: 11, format: FMT.R_F32, offset: Vertex.edge_softness.offsetof }, + { binding: 0, location: 12, format: FMT.R_F32, offset: Vertex.raised.offsetof }, + { binding: 0, location: 13, format: FMT.R_U32, offset: Vertex.texture.offsetof }, + { binding: 0, location: 14, format: FMT.R_U32, offset: Vertex.atlas_index.offsetof }, +]; + union Rect { Vec2[2] v; @@ -512,22 +528,6 @@ InitUICtx(PlatformWindow* window) ctx.desc_set = AllocDescSet(&ctx.rd, ctx.desc_set_layout); ctx.pipeline_layout = CreatePipelineLayout(&ctx.rd, ctx.desc_set_layout, Mat4.sizeof); - Attribute[] attributes = [ - { binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof }, - { binding: 0, location: 1, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof + f32.sizeof*0 }, - { binding: 0, location: 2, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof + f32.sizeof*1 }, - { binding: 0, location: 3, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof + f32.sizeof*2 }, - { binding: 0, location: 4, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof + f32.sizeof*3 }, - { binding: 0, location: 5, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof }, - { binding: 0, location: 6, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof }, - { binding: 0, location: 7, format: FMT.RG_F32, offset: Vertex.src_start.offsetof }, - { binding: 0, location: 8, format: FMT.RG_F32, offset: Vertex.src_end.offsetof }, - { binding: 0, location: 9, format: FMT.R_F32, offset: Vertex.border_thickness.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 }, - { binding: 0, location: 13, format: FMT.R_U32, offset: Vertex.atlas_index.offsetof }, - ]; GfxPipelineInfo ui_info = { vertex_shader: cast(u8[])VERTEX_BYTES, @@ -754,9 +754,15 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(is(T: UIKey) || StringType!T) } } - item.last_frame = ctx.frame; - item.padding += item.border_thickness; - item.rendered = false; + if(item.flags & UIF.DrawBorder && item.border_thickness < 0.0009) + { + item.border_thickness = 1.0; + } + + item.last_frame = ctx.frame; + item.rendered = false; + //item.padding[A2D.X] += item.border_thickness; + //item.padding[A2D.Y] += item.border_thickness; return item; } @@ -1013,18 +1019,12 @@ EndUI() { if(item.size_info[axis].type == ST.Pixels) { - item.size.v[axis] = item.padding.v[axis] + item.size_info[axis].value; + item.size.v[axis] = AxisPadding!(axis)(item) + item.size_info[axis].value; } else if(item.size_info[axis].type == ST.TextSize) { - static if(axis == A2D.X) - { - item.size.v[axis] = item.max_text_width + item.padding.x*2.0; - } - else - { - item.size.v[axis] = item.padding.y*2.0 + GetFontAtlas(item.text_size).atlas.line_height*item.text_lines.length; - } + f32 size = axis == A2D.X ? item.max_text_width : GetFontAtlas(item.text_size).atlas.line_height*item.text_lines.length; + item.size.v[axis] = size + AxisPadding!(axis)(item); } } @@ -1086,6 +1086,7 @@ EndUI() f32 children_size = 0.0; for(UIItem* c = item.first; !Nil(c); c = c.next) { + if(c.flags & UIF.FixedPosition) continue; children_size += c.size.v[axis]; } @@ -1151,28 +1152,28 @@ EndUI() UIItem* parent = item.parent; if(fixed) { - item.rect.p0.v[axis] = parent.rect.p0.v[axis] + item.fixed_pos.v[axis] + item.padding.v[axis] + parent.view_offset.v[axis]; - item.rect.p1.v[axis] = item.rect.p0.v[axis] + item.size.v[axis] - item.padding.v[axis]; + item.rect.p0.v[axis] = parent.rect.p0.v[axis] + item.fixed_pos.v[axis] + InnerOffset!(axis, true)(item) + parent.view_offset.v[axis]; + item.rect.p1.v[axis] = item.rect.p0.v[axis] + item.size.v[axis] - InnerOffset!(axis, false)(item); + } + else if(axis != parent.layout_axis) + { + item.rect.p0.v[axis] = parent.rect.p0.v[axis] + parent.view_offset.v[axis] + InnerOffset!(axis, true )(item); + item.rect.p1.v[axis] = parent.rect.p0.v[axis] + item.size.v[axis] - InnerOffset!(axis, false)(item); } else if(Nil(item.parent.last_relative_item)) { - item.rect.p0.v[axis] = parent.rect.p0.v[axis] + item.padding.v[axis] + parent.view_offset.v[axis]; - item.rect.p1.v[axis] = item.rect.p0.v[axis] + item.size.v[axis] - item.padding.v[axis]; - } - else if(axis != item.parent.layout_axis) - { - item.rect.p0.v[axis] = parent.rect.p0.v[axis] + parent.view_offset.v[axis] + item.padding.v[axis]; - item.rect.p1.v[axis] = parent.rect.p0.v[axis] + item.size.v[axis] - item.padding.v[axis]; + item.rect.p0.v[axis] = parent.rect.p0.v[axis] + InnerOffset!(axis, true)(item) + parent.view_offset.v[axis]; + item.rect.p1.v[axis] = item.rect.p0.v[axis] + item.size.v[axis] - InnerOffset!(axis, false)(item); } else { UIItem* prev = parent.last_relative_item; - item.rect.p0.v[axis] = prev.rect.p1.v[axis] + prev.padding.v[axis] + item.padding.v[axis]; - item.rect.p1.v[axis] = item.rect.p0.v[axis] + item.size.v[axis] - item.padding.v[axis]; + item.rect.p0.v[axis] = prev.rect.p1.v[axis] + InnerOffset!(axis, false)(prev) + InnerOffset!(axis, true)(item); + item.rect.p1.v[axis] = item.rect.p0.v[axis] + item.size.v[axis] - InnerOffset!(axis, false)(item); } - if(!fixed && !Nil(parent)) + if(axis == parent.layout_axis && !fixed && !Nil(parent)) { parent.last_relative_item = item; } @@ -1228,35 +1229,19 @@ FocusItem(T)(T focus) if(is(T == UIKey) || StringType!T || is(T == UIItem*)) } } -void +pragma(inline) void RenderItem(UICtx* ctx, UIItem* item) { if(item.rendered) return; if(!(item.flags & DRAW_FLAGS)) return; - Vec2 p0 = item.rect.p0 - item.padding; - Vec2 p1 = item.rect.p1 + item.padding; - - // Doesn't really support nesting scissors, will maybe change this later. - bool scissor_x = cast(bool)(item.flags & UIF.PortalViewX); - bool scissor_y = cast(bool)(item.flags & UIF.PortalViewY); - if(scissor_x || scissor_y) - { - DrawUI(ctx); - - u32 x = cast(u32)(scissor_x ? floor(p0.x) : 0); - u32 y = cast(u32)(scissor_y ? floor(p0.y) : 0); - u32 w = cast(u32)(scissor_x ? floor(p1.x) - x : ctx.res.x); - u32 h = cast(u32)(scissor_y ? floor(p1.y) - y : ctx.res.y); - SetScissor(&ctx.rd, x, y, w, h); - } - if(item.flags & UIF.DrawBackground) { Vertex* v = GetVertex(ctx); - v.dst_start = p0 + item.border_thickness; - v.dst_end = p1 - item.border_thickness; + v.dst_start = item.rect.p0; + v.dst_end = item.rect.p1; v.cols = item.bg_col; + v.cols_end = item.flags & UIF.Gradient ? item.bg_col_end : item.bg_col; v.corner_radius = item.flags & UIF.DrawBorder ? item.corner_radius*0.5 : item.corner_radius; v.bounds = ItemBounds(item.parent); @@ -1266,11 +1251,12 @@ RenderItem(UICtx* ctx, UIItem* item) if(item.flags & UIF.DrawBorder) { Vertex* v = GetVertex(ctx); - v.dst_start = p0; - v.dst_end = p1; + v.dst_start = item.rect.p0 - Vec2(InnerOffset!(A2D.X, true )(item), InnerOffset!(A2D.Y, true )(item)); + v.dst_end = item.rect.p1 + Vec2(InnerOffset!(A2D.X, false)(item), InnerOffset!(A2D.Y, false)(item)); v.cols = item.border_col; + v.cols_end = item.flags & UIF.Gradient ? item.bg_col_end : item.bg_col; v.corner_radius = item.corner_radius; - v.border_thickness = clamp(item.border_thickness, 1.0, f32.max); + v.border_thickness = item.border_thickness; v.edge_softness = item.edge_softness; v.bounds = ItemBounds(item.parent); @@ -1286,16 +1272,18 @@ RenderItem(UICtx* ctx, UIItem* item) else { FontGlyphs* fg = GetFontGlyphs(item.text_size); - f32 y_pos = p0.y + fg.abuf.atlas.line_height; + f32 y_pos = item.rect.p0.y; Vec4[] syntax_cols = ctx.syntax_colors[item.syntax_highlight]; - + f32 line_height = fg.abuf.atlas.line_height; + foreach(i; 0 .. item.text_lines.length) { string str = item.text_lines[i]; u8[] tks = item.token_lines.length ? item.token_lines[i] : []; - f32 x_pos = item.flags & UIF.RightAlignText ? p1.x - item.padding.x - CalcTextWidth(str, &fg.abuf) : p0.x + item.padding.x; + f32 x_pos = item.flags & UIF.RightAlignText ? item.rect.p1.x - item.padding[A2D.X].x - CalcTextWidth(str, &fg.abuf) : + item.rect.p0.x + item.padding[A2D.X].x; - x_pos = clamp(x_pos, p0.x, p1.x); + x_pos = clamp(x_pos, item.rect.p0.x, item.rect.p1.x); if(tks.length) { @@ -1303,7 +1291,7 @@ RenderItem(UICtx* ctx, UIItem* item) { u8 ch = str[j]; Glyph* g = ch < fg.abuf.atlas.glyphs.length ? fg.abuf.atlas.glyphs.ptr + ch : null; - DrawGlyph(item, g, fg.index, &x_pos, y_pos, syntax_cols[tks[j]]); + DrawGlyph(item, g, fg.index, &x_pos, y_pos, line_height, fg.index, syntax_cols[tks[j]]); } } else @@ -1312,17 +1300,32 @@ RenderItem(UICtx* ctx, UIItem* item) { u8 ch = str[j]; Glyph* g = ch < fg.abuf.atlas.glyphs.length ? fg.abuf.atlas.glyphs.ptr + ch : null; - DrawGlyph(item, g, fg.index, &x_pos, y_pos, item.text_col); + DrawGlyph(item, g, fg.index, &x_pos, y_pos, line_height, fg.index, item.text_col); } } - y_pos += fg.abuf.atlas.line_height; + y_pos += line_height; } } } + // Doesn't really support nesting scissors, will maybe change this later. + bool scissor_x = cast(bool)(item.flags & UIF.PortalViewX); + bool scissor_y = cast(bool)(item.flags & UIF.PortalViewY); if(scissor_x || scissor_y) { + DrawUI(ctx); + + Vec2 p0 = Clamp(item.rect.p0 - item.padding[A2D.X], Vec2(0.0), Vec2(ctx.res.x, ctx.res.y)); + Vec2 p1 = Clamp(item.rect.p1 + item.padding[A2D.Y], Vec2(0.0), Vec2(ctx.res.x, ctx.res.y)); + + u32 x = cast(u32)(scissor_x ? floor(p0.x) : 0); + u32 y = cast(u32)(scissor_y ? floor(p0.y) : 0); + u32 w = cast(u32)(scissor_x ? floor(p1.x) - x : ctx.res.x); + u32 h = cast(u32)(scissor_y ? floor(p1.y) - y : ctx.res.y); + + SetScissor(&ctx.rd, x, y, w, h); + UIItem* first = item.first; UIItem* last = item.last; @@ -1852,7 +1855,7 @@ Get(T)(T k) if(is(T: UIKey) || StringType!T) } } - item.key = key; + item.key = key; item.next = item.prev = item.first = item.last = item.parent = g_UI_NIL; return item; @@ -1879,7 +1882,7 @@ CalcTextWidth(bool fast = true, T, U)(T text, U param) if((is(T == string) || St FontAtlasBuf* abuf = param; } - u32 tab_width = g_ui_ctx.tab_width; + u32 tab_width = g_ui_ctx.tab_width; static if(fast) { @@ -1904,8 +1907,8 @@ GlyphWidth(Glyph* g, FontAtlasBuf* abuf) return g.ch == '\t' ? (abuf.atlas.glyphs[' '].advance*cast(f32)(g_ui_ctx.tab_width)) : g.advance; } -void -DrawGlyph(UIItem* item, Glyph* glyph, u32 atlas_index, f32* x_pos, f32 y, Vec4 col = Vec4(1.0)) +pragma(inline) void +DrawGlyph(UIItem* item, Glyph* glyph, u32 atlas_index, f32* x_pos, f32 y, f32 line_height, u32 index, Vec4 col = Vec4(1.0)) { if(glyph) { @@ -1923,40 +1926,22 @@ DrawGlyph(UIItem* item, Glyph* glyph, u32 atlas_index, f32* x_pos, f32 y, Vec4 c } else { - f32 r = glyph.plane_right; - f32 l = glyph.plane_left; - f32 t = glyph.plane_top; - f32 b = glyph.plane_bottom; - - GlyphBounds gb = { - r: r, - l: l, - t: t, - b: b, - w: r - l, - h: b - t, - atlas_r: glyph.atlas_right, - atlas_l: glyph.atlas_left, - atlas_t: glyph.atlas_top, - atlas_b: glyph.atlas_bottom, - }; + f32 w = glyph.plane_right-glyph.plane_left; + f32 h = glyph.plane_bottom-glyph.plane_top; v = ctx.buffers[ctx.f_idx].vtx.ptr + ctx.buffers[ctx.f_idx].count; - f32 y_pos = y + gb.t; + f32 y_pos = y + glyph.plane_top; - v.dst_start = Vec2(*x_pos+gb.l, y_pos); - v.dst_end = Vec2(*x_pos+gb.w+gb.l, y_pos+gb.h); + v.dst_start = Vec2(*x_pos+glyph.plane_left, y_pos); + v.dst_end = Vec2(*x_pos+glyph.plane_left+w, y_pos+h); v.cols = col; + v.cols_end = col; v.texture = true; v.bounds = ItemBounds(item); - v.atlas_index = atlas_index; - - if(glyph.ch != '\t' && glyph.ch != '\n') - { - v.src_start = Vec2(gb.atlas_l, gb.atlas_t); - v.src_end = Vec2(gb.atlas_r, gb.atlas_b); - } + v.atlas_index = index; + v.src_start = Vec2(glyph.atlas_left, glyph.atlas_top); + v.src_end = Vec2(glyph.atlas_right, glyph.atlas_bottom); f32 end_x = *x_pos + advance; f32 width = end_x - *x_pos; @@ -1968,8 +1953,7 @@ DrawGlyph(UIItem* item, Glyph* glyph, u32 atlas_index, f32* x_pos, f32 y, Vec4 c v.src_end.x -= (v.src_end.x - v.src_start.x) * cull_pct; } - /* - f32 end_y = y; + f32 end_y = y + line_height; f32 height = end_y - y; if(end_y > item.rect.p1.y) { @@ -1977,7 +1961,6 @@ DrawGlyph(UIItem* item, Glyph* glyph, u32 atlas_index, f32* x_pos, f32 y, Vec4 c v.dst_end.y -= (v.dst_end.y - v.dst_start.y) * cull_pct; v.src_end.y -= (v.src_end.y - v.src_start.y) * cull_pct; } - */ static foreach(axis; A2D.min .. A2D.max) { @@ -2000,10 +1983,28 @@ ItemBounds(UIItem* item) return [item.rect.p0, item.rect.p1]; } +pragma(inline) f32 +AxisPadding(Axis2D axis)(UIItem* item) +{ + return item.padding[axis].x + item.padding[axis].y; +} + pragma(inline) f32 InnerSize(Axis2D axis)(UIItem* item) { - return clamp(item.size[axis] - item.padding.v[axis]*2.0, 0.0, f32.max); + return clamp(item.size[axis] - (item.padding[axis].x + item.padding[axis].y) - item.border_thickness*2.0, 0.0, f32.max); +} + +pragma(inline) f32 +InnerSize(UIItem* item, Axis2D axis) +{ + return clamp(item.size[axis] - (item.padding[axis].x + item.padding[axis].y) - item.border_thickness*2.0, 0.0, f32.max); +} + +pragma(inline) f32 +InnerOffset(Axis2D axis, bool start)(UIItem* item) +{ + return item.padding[axis].v[start] + item.border_thickness; } pragma(inline) Vertex* @@ -2049,22 +2050,10 @@ InBounds(T)(T pos, Rect* rect) return pos.x >= rect.p0.x && pos.x <= rect.p1.x && pos.y >= rect.p0.y && pos.y <= rect.p1.y; } -static Vec4[4] -Vec4Arr(Vec4 vec) -{ - return [vec, vec, vec, vec]; -} - static Vec2[2] -Vec2ArrX(alias Vec2 vec)() +Vec2A2(f32 x0, f32 y0, f32 x1, f32 y1) { - return [vec, Vec2(0.0)]; -} - -static Vec2[2] -Vec2ArrY(alias Vec2 vec)() -{ - return [Vec2(0.0), vec]; + return [Vec2(x0, y0), Vec2(x1, y1)]; } unittest diff --git a/src/editor/views.d b/src/editor/views.d index d958927..c3e29c6 100644 --- a/src/editor/views.d +++ b/src/editor/views.d @@ -46,13 +46,15 @@ LineCounterView(FontAtlasBuf* abuf, u64 max_line, u64 lines, i64 line_offset, f3 enum UIPushInfo[] lc_params = [ { "layout_axis", q{ A2D.Y } }, { "view_offset", q{ Vec2(0.0, view_offset) } }, - { "padding", q{ Vec2(8.0) } }, - { "size_info", q{ UISX(ST.Pixels, lc_width) }}, + { "padding", q{ Vec2(4.0) } }, + { "size_info", q{ UIS2(ST.Pixels, ST.Percentage, lc_width, 1.0) }}, + { "edge_softness", q{ 0.0 } }, + { "border_thickness", q{ 1.0 } }, ]; mixin(PushOnce!(lc_params)); - UIItem* line_count = MakeItem(zero, UIF.DrawBorder|UIF.PortalViewY); + UIItem* line_count = MakeItem("###lc", UIF.DrawBorder|UIF.PortalViewY); mixin(PushScope!("text_col", q{ Vec4(1.0) } )); mixin(PushScope!("size_info", q{ UISY(ST.Pixels, abuf.atlas.line_height) } )); @@ -80,17 +82,19 @@ EditorTextView(UIItem* editor, Panel* p, FontAtlasBuf* abuf, u64 lines, i64 line f32 padding = 8.0; enum UIPushInfo[] text_view_params = [ - { "layout_axis", q{ A2D.Y } }, - { "border_col", q{ Vec4(1.0) } }, - { "size_info", q{ UIS2() } }, - { "scroll_target", q{ Vec2(0.0, scroll_pos) } }, - { "scroll_clamp", q{ Vec2(0.0, clamp_y) } }, - { "view_offset", q{ Vec2(0.0, view_offset) } }, - { "padding", q{ Vec2(padding) } }, + { "layout_axis", q{ A2D.Y } }, + { "border_col", q{ Vec4(1.0) } }, + { "size_info", q{ UIS2() } }, + { "scroll_target", q{ Vec2(0.0, scroll_pos) } }, + { "scroll_clamp", q{ Vec2(0.0, clamp_y) } }, + { "view_offset", q{ Vec2(0.0, view_offset) } }, + { "padding", q{ Vec2(4.0) } }, + { "edge_softness", q{ 0.0 } }, + { "border_thickness", q{ 1.0 } }, ]; mixin(PushOnce!(text_view_params)); - editor = MakeItem(editor.key, UIF.DrawBorder|UIF.ScrollY|UIF.ClampY); + editor = MakeItem(editor.key, UIF.DrawBorder|UIF.ScrollY|UIF.ClampY|UIF.PortalViewY); mixin(PushScope!("parent", q{ editor })); @@ -113,13 +117,13 @@ EditorTextView(UIItem* editor, Panel* p, FontAtlasBuf* abuf, u64 lines, i64 line ]; mixin(PushOnce!(cursor_info)); - MakeItem(zero, UIF.DrawBackground|UIF.FixedPosition); + UIItem* cursor = MakeItem("###cursor", UIF.DrawBackground|UIF.FixedPosition); } mixin(PushScope!("size_info", q{ UISY(ST.TextSize) } )); mixin(PushScope!("syntax_highlight", q{ UISH.D } )); - // NEED TO FIX LINES BEING OFFSET FOR WHATEVER REASON + // Do a thing like the bottom 3 colours on lost trail (arknights) on highlighting but make it slide to the right one colour every time you scroll down u64 i = line_offset; for(LineBuffer* lb = GetLine(&ed.buf, i); !CheckNil(g_NIL_LINE_BUF, lb) && i < line_offset+lines; i += 1, lb = GetLine(&ed.buf, i)) @@ -142,6 +146,8 @@ EditorView(Panel* p) UIKey zero = ZeroKey(); FontAtlasBuf* abuf = GetFontAtlas(p.text_size); + mixin(PushScope!("text_size", q{ p.text_size })); + if(CheckNil(g_NIL_ED, ed)) { for(Panel* c = p.first; !CheckNil(g_NIL_PANEL, c); c = c.next) @@ -173,11 +179,11 @@ EditorView(Panel* p) u64 view_lines; if(editor.size.y > 0.0) { - view_lines = cast(u64)floor(editor.size.y/text_size); + view_lines = cast(u64)floor(editor.size.y/text_size)+1; const u64 SCROLL_BUFFER = 4; - u64 start = ed.line_offset; - u64 end = start+view_lines; + i64 start = ed.line_offset; + i64 end = start+view_lines; if(ed.cursor_pos.y < start) { @@ -190,10 +196,6 @@ EditorView(Panel* p) } } - u64 start = cast(u64)floor(editor.scroll_offset.y/text_size); - LineCounterView(abuf, ed.buf.line_count, view_lines, start, frame_view_offset); - EditorTextView(editor, p, abuf, view_lines, start, frame_view_offset); - for(UIInput* i = ctx.events.first; !CheckNil(g_UI_NIL_INPUT, i) && g_ed_ctx.focused_editor == p.ed; i = i.next) { bool taken; @@ -224,6 +226,10 @@ EditorView(Panel* p) } ed.cursor_pos = VecPos(&ed.buf); + + u64 start = cast(u64)floor(editor.scroll_offset.y/text_size); + LineCounterView(abuf, ed.buf.line_count, view_lines, start, frame_view_offset); + EditorTextView(editor, p, abuf, view_lines, start, frame_view_offset); } ResetBuffer(&ed.buf); diff --git a/src/shaders/gui.frag.glsl b/src/shaders/gui.frag.glsl index 67442a5..eb51179 100644 --- a/src/shaders/gui.frag.glsl +++ b/src/shaders/gui.frag.glsl @@ -3,28 +3,10 @@ #extension GL_GOOGLE_include_directive : require #extension GL_EXT_debug_printf : require +#define FRAG_SHADER + #include "gui.layout" -layout (location = 0) flat in struct FragDataFlatIn -{ - uint texture; - uint atlas_index; -} FDF; - -layout (location = 2) in struct FragDataIn -{ - vec4 color; - vec2 uv; - vec2 dst_pos; - vec2 dst_center; - vec2 dst_half_size; - vec2 sdf_sample_pos; - float corner_radius; - float softness; - float raised; - float border_thickness; -} FD; - layout (location = 0) out vec4 FragColor; float RectSDF(vec2 pos, vec2 half_size, float radius) @@ -47,6 +29,11 @@ vec4 ToLinear(vec4 col) return pow(col, vec4(vec3(2.2), 1.0)); } +float GradientNoise(vec2 uv) +{ + return fract(52.9829189 * fract(dot(uv, vec2(0.06711056, 0.00583715)))); +} + void main() { float softness = FD.softness; @@ -90,5 +77,7 @@ void main() out_color.a *= corner_factor; out_color.a *= border_factor; + out_color += (1.0 / 255.0) * GradientNoise(gl_FragCoord.xy); + FragColor = out_color; } diff --git a/src/shaders/gui.layout b/src/shaders/gui.layout index e27d573..4c1c269 100644 --- a/src/shaders/gui.layout +++ b/src/shaders/gui.layout @@ -9,3 +9,34 @@ layout (push_constant) uniform Constants { } PC; #define SpriteAtlas SpriteAtlasArray[FDF.atlas_index] + +#ifdef VERT_SHADER +# define FragData out struct FragDataOut +# define FragDataFlat flat out struct FragDataFlatOut +#endif + +#ifdef FRAG_SHADER +# define FragData in struct FragDataIn +# define FragDataFlat flat in struct FragDataFlatIn +#endif + +layout (location = 0) FragDataFlat +{ + uint texture; + uint atlas_index; +} FDF; + +layout (location = 2) FragData +{ + vec4 color; + vec4 color_end; + vec2 uv; + vec2 dst_pos; + vec2 dst_center; + vec2 dst_half_size; + vec2 sdf_sample_pos; + float corner_radius; + float softness; + float raised; + float border_thickness; +} FD; diff --git a/src/shaders/gui.vert.glsl b/src/shaders/gui.vert.glsl index 99dfa3d..62813b7 100644 --- a/src/shaders/gui.vert.glsl +++ b/src/shaders/gui.vert.glsl @@ -2,42 +2,25 @@ #extension GL_GOOGLE_include_directive : require +#define VERT_SHADER + #include "gui.layout" -layout (location = 0) in vec4 in_col; -layout (location = 1) in float in_corner_radius_x0y0; -layout (location = 2) in float in_corner_radius_x1y0; -layout (location = 3) in float in_corner_radius_x0y1; -layout (location = 4) in float in_corner_radius_x1y1; -layout (location = 5) in vec2 in_dst_start; -layout (location = 6) in vec2 in_dst_end; -layout (location = 7) in vec2 in_src_start; -layout (location = 8) in vec2 in_src_end; -layout (location = 9) in float border_thickness; -layout (location = 10) in float edge_softness; -layout (location = 11) in float raised; -layout (location = 12) in uint in_has_texture; -layout (location = 13) in uint in_atlas_index; - -layout (location = 0) flat out struct FragDataFlatOut -{ - uint texture; - uint atlas_index; -} FDF; - -layout (location = 2) out struct FragDataOut -{ - vec4 color; - vec2 uv; - vec2 dst_pos; - vec2 dst_center; - vec2 dst_half_size; - vec2 sdf_sample_pos; - float corner_radius; - float softness; - float raised; - float border_thickness; -} FD; +layout (location = 0) in vec4 in_col_start; +layout (location = 1) in vec4 in_col_end; +layout (location = 2) in float in_corner_radius_x0y0; +layout (location = 3) in float in_corner_radius_x1y0; +layout (location = 4) in float in_corner_radius_x0y1; +layout (location = 5) in float in_corner_radius_x1y1; +layout (location = 6) in vec2 in_dst_start; +layout (location = 7) in vec2 in_dst_end; +layout (location = 8) in vec2 in_src_start; +layout (location = 9) in vec2 in_src_end; +layout (location = 10) in float border_thickness; +layout (location = 11) in float edge_softness; +layout (location = 12) in float raised; +layout (location = 13) in uint in_has_texture; +layout (location = 14) in uint in_atlas_index; vec2 Vertices[4] = vec2[4]( vec2(-1.0, -1.0), @@ -83,7 +66,8 @@ void main() vec2 dst_verts_pct = vec2(bool(gl_VertexIndex >> 1) ? 1.0f : 0.0f, bool(gl_VertexIndex & 1) ? 0.0f : 1.0f); - FD.color = in_col; + FD.color = in_col_start; + FD.color_end = in_col_end; FD.uv = uvs[gl_VertexIndex] / tex_size; FD.dst_pos = pos; FD.dst_center = center;