layout fixes

This commit is contained in:
Matthew 2025-12-29 15:32:26 +11:00
parent e6024b0ff4
commit 07f72ac41e
9 changed files with 218 additions and 204 deletions

Binary file not shown.

Binary file not shown.

@ -1 +1 @@
Subproject commit c00c404006147838fb8af3259cf214396da31c99
Subproject commit e77c1790f7eb5d18d8d84596025c53b2caaca18c

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;