diff --git a/assets/gui.frag.spv b/assets/gui.frag.spv index bd666ad..fb06257 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 25c67fb..3955c64 100644 Binary files a/assets/gui.vert.spv and b/assets/gui.vert.spv differ diff --git a/src/VulkanRenderer b/src/VulkanRenderer index c2b7544..3390ee9 160000 --- a/src/VulkanRenderer +++ b/src/VulkanRenderer @@ -1 +1 @@ -Subproject commit c2b7544979b16e1f27f419475b866a2903bd9c0a +Subproject commit 3390ee9742fbce758941a0dd216ebec5c75876e5 diff --git a/src/editor/ui.d b/src/editor/ui.d index 66ed5ee..5b36c80 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -332,6 +332,20 @@ struct UICtx debug u64 item_count; } +struct ItemStyle +{ + Vec4 bg_col; + Vec4 bg_hl_col; + Vec4 border_col; + Vec4 border_hl_col; + Vec4 text_col; + Vec4 text_hl_col; + Vec2[2] padding; + Vec4 corner_radius; + f32 border_thickness; + f32 edge_softness; +} + enum UIElement { Default, @@ -353,20 +367,31 @@ enum UIElement StatusMessage, Max, } - alias UIElem = UIElement; -struct ItemStyle +enum Element { - Vec4 bg_col; - Vec4 bg_col_end; - Vec4 bg_hl_col; - Vec4 border_col; - Vec4 border_hl_col; - Vec4 text_col; - Vec4 text_hl_col; - Vec2[2] padding; + Panel, + PanelFocus, + Window, + WindowFocus, + Border, + BorderFocus, + Text, + Button, + ButtonAlt, // Alternating option colours + ButtonFocus, + Max, +} alias Elem = Element; + +struct UIStyle +{ + enum N = Elem.max; + + Vec4[N] cols; Vec4 corner_radius; + Vec2[2] text_box_padding; + Vec2[2] button_padding; f32 border_thickness; f32 edge_softness; } @@ -376,7 +401,6 @@ DefaultItemStyle() { ItemStyle style = { bg_col: BG_COL, - bg_col_end: BG_COL, bg_hl_col: BG_HL_COL, border_col: BORDER_COL, border_hl_col: BORDER_HL_COL, @@ -480,6 +504,8 @@ enum SizeType Percentage, ChildrenSum, TextSize, + Pct = ST.Percentage, + Px = ST.Pixels, } alias ST = SizeType; @@ -488,7 +514,6 @@ struct UISize { SizeType type; f32 value; - f32 strictness = 1.0; } struct UIBuffer @@ -510,7 +535,6 @@ struct VPos struct Vertex { Vec4 cols; - Vec4 cols_end; Vec4 corner_radius; union { @@ -537,18 +561,17 @@ enum SettingType Toggle, } -Attribute[11] 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.RGBA_F32, offset: Vertex.corner_radius.offsetof }, - { binding: 0, location: 3, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof }, - { binding: 0, location: 4, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof }, - { binding: 0, location: 5, format: FMT.RG_F32, offset: Vertex.src_start.offsetof }, - { binding: 0, location: 6, format: FMT.RG_F32, offset: Vertex.src_end.offsetof }, - { binding: 0, location: 7, format: FMT.R_F32, offset: Vertex.border_thickness.offsetof }, - { binding: 0, location: 8, format: FMT.R_F32, offset: Vertex.edge_softness.offsetof }, - { binding: 0, location: 9, format: FMT.R_F32, offset: Vertex.raised.offsetof }, - { binding: 0, location: 10, format: FMT.R_U32, offset: Vertex.has_texture.offsetof }, +Attribute[10] attributes = [ + { binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof }, + { binding: 0, location: 1, format: FMT.RGBA_F32, offset: Vertex.corner_radius.offsetof }, + { binding: 0, location: 2, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof }, + { binding: 0, location: 3, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof }, + { binding: 0, location: 4, format: FMT.RG_F32, offset: Vertex.src_start.offsetof }, + { binding: 0, location: 5, format: FMT.RG_F32, offset: Vertex.src_end.offsetof }, + { binding: 0, location: 6, format: FMT.R_F32, offset: Vertex.border_thickness.offsetof }, + { binding: 0, location: 7, format: FMT.R_F32, offset: Vertex.edge_softness.offsetof }, + { binding: 0, location: 8, format: FMT.R_F32, offset: Vertex.raised.offsetof }, + { binding: 0, location: 9, format: FMT.R_U32, offset: Vertex.has_texture.offsetof }, ]; union Rect @@ -568,7 +591,103 @@ struct UIKey } enum bool KeyType(T) = (StringType!(T) || is(T == UIKey) || is(T == const(UIKey))); -enum bool ItemAndKeyType(T) = (KeyType!(T) || is(T == UIItem*)); +enum bool ItemAndKeyType(T) = (KeyType!(T) || is(T == UIItem*)); + +// ****** +// Public +// ****** + +void +BeginContainer(ST x_t = ST.Pct, ST y_t = ST.Pct)(Axis2D axis, f32 w, f32 h) +{ + PushSizeInfo(UIS2(x_t, y_t, w, h)); + PushAxisLayout(axis); + UIItem* item = MakeItem(ZeroKey()); + PushParent(item); +} + +alias EndContainer = Pop!("parent"); + +enum WindowFlags +{ + None = 0<<0, + NoBorder = 1<<0, + NoBackground = 1<<1, + NoDropShadow = 1<<2, + Draggable = 1<<3, + NoTitleBar = 1<<4, +} alias WinF = WindowFlags; + +UIFlags +GetFlags(WinF flags)() +{ + UIFlags flags = UIF.DrawBackground|UIF.DrawBorder|UIF.DrawDropShadow|UIF.AnimateReady|UIF.Window; + static if(flags & WinF.NoBorder) + { + flags &= ~UIF.DrawBorder; + } + static if(flags & WinF.NoBackground) + { + flags &= ~UIF.DrawBackground; + } + static if(flags & WinF.NoDropShadow) + { + flags &= ~UIF.DrawDropShadow; + } + static if(flags & WinF.Draggable) + { + flags &= ~UIF.Window; + flags |= UIF.FloatingWindow; + } + + return flags; +} + +// Converts to parameters (string label, Args args, Axis2D axis, f32 x, f32 y, f32 w, f32 h) +void +BeginWindow(WinF flags = WinF.None, ST x_t = ST.Px, ST x_y = ST.Px, Args...)(string label, Args args) +{ + enum len = Args.length; + + static assert(is(typeof(Args[len-1]) == f32)); + static assert(is(typeof(Args[len-2]) == f32)); + static assert(is(typeof(Args[len-3]) == f32)); + static assert(is(typeof(Args[len-4]) == f32)); + static assert(is(typeof(Args[len-5]) == Axis2D)); + + string scratch = Scratchf!(Args[0 .. len-5])(label, args[0 .. len-5]); + + BeginWindow!(flags, x_t, x_y)(scratch, args[len-5], args[len-4], args[len-3], args[len-2], args[len-1]); +} + +void +BeginWindow(WinF flags = WinF.None, ST x_t = ST.Px, ST x_y = ST.Px)(string label, Axis2D axis, f32 x, f32 y, f32 w, f32 h) +{ + PushFixedPos(Vec2(x, y)); + PushSizeInfo(UIS2(x_t, y_t, w, h)); + PushAxisLayout(axis); + UIFlags flags = GetFlags!(flags); + + static assert((flags & WinF.Draggable) == 0 || (flags & ~WinF.NoTitleBar) == flags, "Unable to use NoTitleBar flag with the Draggable flag"); + + UIItem* window = MakeItem("###window_%s", label, flags); + + static if(flags & WinF.Draggable) + { + //UIItem* header + } +} + +void +EndWindow() +{ + UIItem* window = Pop!("parent"); + +} + +// ******** +// Internal +// ******** void InitUICtx(PlatformWindow* window) @@ -1382,6 +1501,8 @@ EndUI() BeginRendering(&ctx.rd); + SetStencilTest(&ctx.rd, false); + Vec2 ext = GetExtent(); if(ext != ctx.res) { @@ -1521,22 +1642,6 @@ EndUI() if(children_size > size) { f32 excess = children_size - size; - for(UIItem* c = item.last; !Nil(c); c = c.prev) - { - if(c.flags & (UIF.FixedPosition | (UIF.OverflowX< 0.0009) { for(UIItem* c = item.last; !Nil(c); c = c.prev) @@ -1816,7 +1921,6 @@ RenderItem(UICtx* ctx, UIItem* item) v.dst_start = border_p0 - Vec2(px); v.dst_end = border_p1 + Vec2(px); v.cols = Vec4(0.0, 0.0, 0.0, alpha); - v.cols_end = Vec4(0.0, 0.0, 0.0, alpha); v.corner_radius = 0.8f; v.edge_softness = 8.0f; @@ -1826,15 +1930,13 @@ RenderItem(UICtx* ctx, UIItem* item) if(item.flags & UIF.DrawBackground) { Vec4 bg_col = style.bg_col; - Vec4 bg_col_end = style.bg_col_end; - AnimateHot(item, BG_HL_COL, &bg_col, &bg_col_end); - AnimateReady(item, &bg_col, &bg_col_end); + AnimateHot(item, BG_HL_COL, &bg_col); + AnimateReady(item, &bg_col); Vertex* v = GetVertex(ctx); v.dst_start = item.rect.p0; v.dst_end = item.rect.p1; v.cols = bg_col; - v.cols_end = item.flags & UIF.Gradient ? bg_col_end : bg_col; v.corner_radius = item.flags & UIF.DrawBorder ? style.corner_radius*0.5 : style.corner_radius; v.edge_softness = style.edge_softness; @@ -1851,7 +1953,6 @@ RenderItem(UICtx* ctx, UIItem* item) v.dst_start = border_p0; v.dst_end = border_p1; v.cols = style.border_col; - v.cols_end = style.border_col; v.corner_radius = style.corner_radius; v.border_thickness = style.border_thickness; v.edge_softness = style.edge_softness; @@ -2509,7 +2610,6 @@ DrawGlyph(UIItem* item, Glyph* glyph, f32* x_pos, f32 y, f32 line_height, Vec4 c 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.src_start = Vec2(glyph.atlas_left, glyph.atlas_top); v.src_end = Vec2(glyph.atlas_right, glyph.atlas_bottom); v.has_texture = true; @@ -2579,21 +2679,21 @@ GetVertex(UICtx* ctx) } static UISize[2] -UIS2(SizeType t0 = ST.Percentage, SizeType t1 = ST.Percentage, f32 v0 = 1.0, f32 v1 = 1.0, f32 s0 = 1.0, f32 s1 = 1.0) +UIS2(SizeType t0 = ST.Percentage, SizeType t1 = ST.Percentage, f32 v0 = 1.0, f32 v1 = 1.0) { - return [UISize(t0, v0, s0), UISize(t1, v1, s1)]; + return [UISize(t0, v0), UISize(t1, v1)]; } static UISize[2] -UISX(SizeType type, f32 value = 1.0, f32 strictness = 1.0) +UISX(SizeType type, f32 value = 1.0) { - return [UISize(type, value, strictness), UISize(ST.Percentage, 1.0)]; + return [UISize(type, value), UISize(ST.Percentage, 1.0)]; } static UISize[2] -UISY(SizeType type, f32 value = 1.0, f32 strictness = 1.0) +UISY(SizeType type, f32 value = 1.0) { - return [UISize(ST.Percentage, 1.0), UISize(type, value, strictness)]; + return [UISize(ST.Percentage, 1.0), UISize(type, value)]; } bool diff --git a/src/shaders/gui.layout b/src/shaders/gui.layout index 6e464eb..1691df7 100644 --- a/src/shaders/gui.layout +++ b/src/shaders/gui.layout @@ -29,7 +29,6 @@ layout (location = 0) FragDataFlat layout (location = 1) FragData { vec4 color; - vec4 color_end; vec2 uv; vec2 dst_pos; vec2 dst_center; diff --git a/src/shaders/gui.vert.glsl b/src/shaders/gui.vert.glsl index 9911138..87f37ab 100644 --- a/src/shaders/gui.vert.glsl +++ b/src/shaders/gui.vert.glsl @@ -6,17 +6,16 @@ #include "gui.layout" -layout (location = 0) in vec4 in_col_start; -layout (location = 1) in vec4 in_col_end; -layout (location = 2) in vec4 in_corner_radius; -layout (location = 3) in vec2 in_dst_start; -layout (location = 4) in vec2 in_dst_end; -layout (location = 5) in vec2 in_src_start; -layout (location = 6) in vec2 in_src_end; -layout (location = 7) in float border_thickness; -layout (location = 8) in float edge_softness; -layout (location = 9) in float raised; -layout (location = 10) in uint has_texture; +layout (location = 0) in vec4 in_col; +layout (location = 1) in vec4 in_corner_radius; +layout (location = 2) in vec2 in_dst_start; +layout (location = 3) in vec2 in_dst_end; +layout (location = 4) in vec2 in_src_start; +layout (location = 5) in vec2 in_src_end; +layout (location = 6) in float border_thickness; +layout (location = 7) in float edge_softness; +layout (location = 8) in float raised; +layout (location = 9) in uint has_texture; vec2 Vertices[4] = vec2[4]( vec2(-1.0, -1.0), @@ -62,8 +61,7 @@ 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_start; - FD.color_end = in_col_end; + FD.color = in_col; FD.uv = uvs[gl_VertexIndex] / tex_size; FD.dst_pos = pos; FD.dst_center = center;