layout fixes
This commit is contained in:
parent
e6024b0ff4
commit
07f72ac41e
Binary file not shown.
Binary file not shown.
2
src/dlib
2
src/dlib
@ -1 +1 @@
|
||||
Subproject commit c00c404006147838fb8af3259cf214396da31c99
|
||||
Subproject commit e77c1790f7eb5d18d8d84596025c53b2caaca18c
|
||||
@ -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;
|
||||
|
||||
243
src/editor/ui.d
243
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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user