changes to how styling is done (about to rework again)

This commit is contained in:
Matthew 2026-01-10 13:10:40 +11:00
parent 57c56ce650
commit 6e3dde1cad
3 changed files with 328 additions and 131 deletions

@ -1 +1 @@
Subproject commit 9f70b8982c71d6d24031a08c6f2780be2dd402e0
Subproject commit 246e7006f535f65e0d045c644bfa8d645c86f5f7

View File

@ -30,12 +30,23 @@ import core.stdc.stdio : sprintf;
*********************************/
enum Vec4 BG_COL = SRGBVec4(0.13, 0.13, 0.13, 1.0);
enum Vec4 BG_HL_COL = SRGBVec4(0.12, 0.30, 0.63, 1.0);
enum Vec4 BORDER_COL = SRGBVec4(0.254, 0.254, 0.266, 1.0);
enum Vec4 BORDER_HL_COL = SRGBVec4(0.035, 0.549, 0.824, 1.0);
enum Vec4 TEXT_COL = SRGBVec4(1.0);
enum Vec4 TEXT_HL_COL = SRGBVec4(0.0, 0.0, 0.0, 1.0);
enum Vec4 BG_COL = Vec4(0.18, 0.18, 0.18, 1.0);
enum Vec4 BG_HL_COL = Vec4(0.160, 0.533, 0.803, 1.0);
enum Vec4 HL_BORDER_COL = Vec4(0.172, 0.643, 0.988, 1.0);
enum Vec4 CMD_COL = Vec4(0.22, 0.22, 0.22, 1.0);
enum Vec4 CMD_BORDER_COL = Vec4(0.48, 0.48, 0.48, 1.0);
enum Vec4 CMD_INPUT_COL = Vec4(0.130, 0.420, 0.640, 1.0);
enum Vec4 GREY = Vec4(0.80, 0.80, 0.80, 1.0);
enum Vec4 WHITE = HexCol(0xFFFFFF);
enum Vec4 BLUE = HexCol(0x4EA9FF);
enum Vec4 RED = HexCol(0xFF3268);
enum Vec4 YELLOW = HexCol(0xF7C443);
enum Vec4 OPT_COL = Vec4(0.22, 0.22, 0.22, 1.0);
enum Vec4 OPT_ALT_COL = Vec4(0.31, 0.31, 0.31, 1.0);
const u64 VERTEX_MAX_COUNT = 10000;
const Vec2 CLICK_BUFFER = Vec2(3.0, 3.0);
@ -57,9 +68,6 @@ u8[] FRAGMENT_BYTES = cast(u8[])import("gui.frag.spv");
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;
Vec4 g_text_col_default = TEXT_COL;
@ -70,7 +78,6 @@ Vec2 g_padding_default = Vec2(0.0);
u32 g_text_size_default = 18;
Vec2 g_scroll_target_default = Vec2(0.0);
Vec2 g_scroll_clamp_default = Vec2(0.0);
Vec2 g_view_offset_default = Vec2(0.0);
string g_display_string_default = null;
UISH g_syntax_highlight_default = UISH.None;
u8[] g_syntax_tokens_default = [];
@ -252,7 +259,7 @@ struct UICtx
Inputs* inputs;
u64 frame;
u64 f_idx;
u64 f_idx;
LinkedList!(UIInput) events;
IVec2 mouse_pos;
@ -293,33 +300,97 @@ struct UICtx
Stack!(UIItem*)* key_item_stack;
ItemStyle[UIElem.max] item_styles;
UIElement next_element;
mixin UICtxParameter!(UISize[2], "size_info");
mixin UICtxParameter!(u8[], "syntax_tokens");
mixin UICtxParameter!(string, "display_string");
mixin UICtxParameter!(UISyntaxHighlight, "syntax_highlight");
mixin UICtxParameter!(Vec2[2], "scroll_clamp");
mixin UICtxParameter!(Vec2, "scroll_target");
mixin UICtxParameter!(Vec2, "fixed_pos");
mixin UICtxParameter!(UIItem*, "parent");
mixin UICtxParameter!(Axis2D, "layout_axis");
mixin UICtxParameter!(u32, "text_size");
/*
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");
mixin UICtxParameter!(UISize[2], "size_info");
mixin UICtxParameter!(Vec4, "text_col");
mixin UICtxParameter!(Vec4, "text_hl_col");
mixin UICtxParameter!(Vec2[2], "scroll_clamp");
mixin UICtxParameter!(Vec2, "scroll_target");
mixin UICtxParameter!(Vec2[2], "padding");
mixin UICtxParameter!(Vec2, "view_offset");
mixin UICtxParameter!(Vec2, "fixed_pos");
mixin UICtxParameter!(UIItem*, "parent");
mixin UICtxParameter!(string, "display_string");
mixin UICtxParameter!(u8[], "syntax_tokens");
mixin UICtxParameter!(Axis2D, "layout_axis");
mixin UICtxParameter!(Vec4, "corner_radius");
mixin UICtxParameter!(f32, "border_thickness");
mixin UICtxParameter!(f32, "edge_softness");
mixin UICtxParameter!(u32, "text_size");
mixin UICtxParameter!(UISyntaxHighlight, "syntax_highlight");
*/
debug bool dbg;
debug u64 item_count;
}
enum UIElement
{
Default,
LineCount,
LineCountText,
EditorPanel,
EditorTextView,
EditorTextCursor,
EditorText,
CmdWindow,
CmdOptWindow,
CmdOpt,
CmdOptAlt,
CmdTitleText,
CmdSubtitleText,
CmdInput,
CmdInputEmpty,
StatusInfo,
StatusMessage,
Max,
}
alias UIElem = UIElement;
struct ItemStyle
{
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;
Vec4 corner_radius;
f32 border_thickness;
f32 edge_softness;
}
ItemStyle
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,
text_col: TEXT_COL,
text_hl_col: TEXT_HL_COL,
padding: Vec2A2(0.0, 0.0, 0.0, 0.0),
corner_radius: 0.0,
border_thickness: 0.0,
edge_softness: 0.8,
};
return style;
}
struct FontGlyphs
{
FontAtlasBuf abuf;
@ -378,6 +449,7 @@ struct UIItem
u64 last_frame;
UISignal signal;
UIFlags flags;
UIElem element;
UIItem* next, prev, first, last; // parent in mixin
UIItem* transient_next;
@ -616,6 +688,129 @@ InitUICtx(PlatformWindow* window)
SetClearColors(&ctx.rd, [0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 0.0]);
}
foreach(i; 0 .. ctx.item_styles.length)
{
ctx.item_styles[i] = DefaultItemStyle();
}
with(UIElem)
{
with(ctx.item_styles[LineCount])
{
padding = Vec2(4.0);
edge_softness = 0.0;
border_thickness = 1.0;
}
with(ctx.item_styles[LineCountText])
{
// None
}
with(ctx.item_styles[EditorPanel])
{
// None
}
with(ctx.item_styles[EditorTextView])
{
padding = Vec2(4.0);
edge_softness = 0.0;
border_thickness = 1.0;
}
with(ctx.item_styles[EditorTextCursor])
{
bg_col = Vec4(1.0);
}
with(ctx.item_styles[EditorText])
{
border_col = HL_BORDER_COL;
border_thickness = 4.0;
corner_radius = Vec4(8.0);
}
with(ctx.item_styles[EditorText])
{
}
with(ctx.item_styles[CmdWindow])
{
corner_radius = Vec4(8.0);
}
with(ctx.item_styles[CmdOptWindow])
{
border_col = CMD_BORDER_COL;
border_thickness = 1.0;
corner_radius = Vec4(0.0, 0.0, 12.0, 12.0);
edge_softness = 1.0;
}
with(ctx.item_styles[CmdOpt])
{
bg_col = OPT_COL;
padding[A2D.X] = Vec2(8.0);
padding[A2D.Y] = Vec2(4.0);
}
ctx.item_styles[CmdOptAlt] = ctx.item_styles[CmdOpt];
with(ctx.item_styles[CmdOptAlt])
{
bg_col = OPT_ALT_COL;
}
with(ctx.item_styles[CmdTitleText])
{
padding[0] = Vec2(8.0);
padding[1] = Vec2(4.0, 2.0);
}
with(ctx.item_styles[CmdSubtitleText])
{
padding[0] = Vec2(8.0);
padding[1] = Vec2(0.0);
text_col = GREY;
}
with(ctx.item_styles[CmdInput])
{
bg_col = CMD_COL;
border_col = CMD_BORDER_COL;
border_thickness = 1.0;
corner_radius = Vec4(12.0, 12.0, 0.0, 0.0);
edge_softness = 1.0;
padding = Vec2(6.0);
Logf("corner radius %s", corner_radius.v);
}
ctx.item_styles[CmdInputEmpty] = ctx.item_styles[CmdInput];
with(ctx.item_styles[CmdInputEmpty])
{
text_col = GREY;
}
with(ctx.item_styles[StatusInfo])
{
bg_col = BLUE;
corner_radius = Vec4(8.0);
padding = Vec2A2(8.0, 8.0, 0.0, 0.0);
edge_softness = 0.6;
}
with(ctx.item_styles[StatusMessage])
{
bg_col = BG_COL;
corner_radius = Vec4(0.0, 0.0, 0.0, 8.0);
edge_softness = 0.6;
}
}
InitStacks(ctx);
}
@ -704,6 +899,18 @@ Set(UIItem* item, UICtx* ctx)
}
}
void
SetElement(UIElement element)
{
g_ui_ctx.next_element = element;
}
ItemStyle*
GetElementStyle(UIElement elem)
{
return &g_ui_ctx.item_styles[elem];
}
UIItem*
MakeItem(Args...)(string str, Args args)
{
@ -733,6 +940,7 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(KeyType!(T))
item.flags = flags;
item.signal = UIS.None;
item.element = ctx.next_element;
Set(item, ctx);
if(Nil(ctx.root_first))
@ -818,23 +1026,10 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(KeyType!(T))
{
}
if(item.flags & UIF.AnimateHot)
{
bool is_hot = cast(bool)(item.flags & UIF.SetHot) || Hovered!(true)(item);
item.hot_t += ctx.animation_rate * (cast(f32)(is_hot) - item.hot_t);
item.bg_col = Mix(item.bg_col, BG_HL_COL, item.hot_t);
}
if(item.flags & UIF.AnimateReady)
{
bool is_ready = cast(bool)(item.flags & UIF.SetReady);
item.ready_t += ctx.fade_rate * (cast(f32)(is_ready) - item.ready_t);
SetColorTransparency(item, item.ready_t);
}
if(item.flags & UIF.DrawBorder && item.border_thickness < 0.0009)
{
item.border_thickness = 1.0;
}
item.last_frame = ctx.frame;
@ -843,15 +1038,6 @@ MakeItem(T)(T k, UIFlags flags = UIF.None) if(KeyType!(T))
return item;
}
void
SetColorTransparency(UIItem* item, f32 v)
{
item.bg_col.a *= v;
item.bg_col_end.a *= v;
item.text_col.a *= v;
item.border_col.a *= v;
}
static string
AssignItem(T, alias p)()
{
@ -1433,18 +1619,18 @@ EndUI()
UIItem* parent = item.parent;
if(fixed)
{
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.p0.v[axis] = parent.rect.p0.v[axis] + item.fixed_pos.v[axis] + InnerOffset!(axis, true)(item);
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.p0.v[axis] = parent.rect.p0.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] + 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);
item.rect.p0.v[axis] = parent.rect.p0.v[axis] + InnerOffset!(axis, true)(item);
item.rect.p1.v[axis] = item.rect.p0.v[axis] + item.size.v[axis] - InnerOffset!(axis, false)(item);
}
else
{
@ -1484,7 +1670,7 @@ EndUI()
// Render Items
for(UIItem* item = ctx.root_first; !Nil(item); item = Recurse!(true)(item, g_UI_NIL))
{
if(item.flags & UIF.AnimateReady && item.ready_t < 1.0)
if(item.flags & UIF.AnimateReady && fabsf(item.ready_t-1.0) > 0.00009)
{
UIItem* first = item.first, last = item.last;
@ -1501,10 +1687,13 @@ EndUI()
{
c.flags |= UIF.AnimateReady;
c.ready_t = item.ready_t;
SetColorTransparency(c, item.ready_t);
}
}
}
else
{
item.ready_t = 1.0;
}
if(!ZeroKey(item.key))
{
@ -1571,11 +1760,46 @@ FocusItem(T)(T focus) if(ItemAndKeyType!(T))
}
pragma(inline) void
AnimateHot(Args...)(UIItem* item, Vec4 hl_col, Args cols) // Args == Vec4*[]
{
if(item.flags & UIF.AnimateHot)
{
bool is_hot = cast(bool)(item.flags & UIF.SetHot) || Hovered!(true)(item);
item.hot_t += g_ui_ctx.animation_rate * (cast(f32)(is_hot) - item.hot_t);
static foreach(i; 0 .. Args.length)
{
*(cols[i]) = Mix(*(cols[i]), hl_col, item.hot_t);
}
}
}
pragma(inline) void
AnimateReady(Args...)(UIItem* item, Args cols)
{
if(item.flags & UIF.AnimateReady)
{
static foreach(i; 0 .. Args.length)
{
static if(is(typeof(Args[i]) == f32*))
{
*(cols[i]) *= item.ready_t;
}
else static if(is(typeof(Args[i]) == Vec4*))
{
cols[i].a *= item.ready_t;
}
}
}
}
void
RenderItem(UICtx* ctx, UIItem* item)
{
if(item.processed) return;
if(!(item.flags & DRAW_FLAGS)) return;
ItemStyle* style = GetElementStyle(item.element);
Vec2 border_p0 = item.rect.p0 - Vec2(InnerOffset!(A2D.X, true )(item), InnerOffset!(A2D.Y, true )(item));
Vec2 border_p1 = item.rect.p1 + Vec2(InnerOffset!(A2D.X, false)(item), InnerOffset!(A2D.Y, false)(item));
@ -1586,10 +1810,7 @@ RenderItem(UICtx* ctx, UIItem* item)
{
f32 px = clamp(((item.size.x+item.size.y)/2.0)*0.004, 1.0, f32.max);
f32 alpha = 0.1;
if(item.flags & UIF.AnimateReady)
{
alpha *= item.ready_t;
}
AnimateReady(item, &alpha);
Vertex* v = GetVertex(ctx);
v.dst_start = border_p0 - Vec2(px);
@ -1604,27 +1825,36 @@ 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);
Vertex* v = GetVertex(ctx);
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.edge_softness = item.edge_softness;
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;
Clamp(ctx, v);
}
if(item.flags & UIF.DrawBorder)
{
Vec4 col = style.border_col;
AnimateHot(item, BORDER_HL_COL, &col);
AnimateReady(item, &col);
Vertex* v = GetVertex(ctx);
v.dst_start = border_p0;
v.dst_end = border_p1;
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 = item.border_thickness;
v.edge_softness = item.edge_softness;
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;
Clamp(ctx, v);
}
@ -1645,7 +1875,7 @@ RenderItem(UICtx* ctx, UIItem* item)
}
else
{
y_pos += item.padding[A2D.Y].x;
y_pos += style.padding[A2D.Y].x;
}
foreach(i; 0 .. item.text_lines.length)
@ -1655,15 +1885,15 @@ RenderItem(UICtx* ctx, UIItem* item)
f32 x_pos = 0.0;
if(item.flags & UIF.RightAlignText)
{
x_pos = item.rect.p1.x - item.padding[A2D.X].x - CalcTextWidth(str, &fg.abuf);
x_pos = item.rect.p1.x - style.padding[A2D.X].x - CalcTextWidth(str, &fg.abuf);
}
else if(item.flags & UIF.CenterAlignText)
{
x_pos = ((item.rect.p1.x-item.rect.p0.x - CalcTextWidth(str, &fg.abuf)) / 2.0) + item.padding[A2D.X].x;
x_pos = ((item.rect.p1.x-item.rect.p0.x - CalcTextWidth(str, &fg.abuf)) / 2.0) + style.padding[A2D.X].x;
}
else
{
x_pos = item.rect.p0.x + item.padding[A2D.X].x;
x_pos = item.rect.p0.x + style.padding[A2D.X].x;
}
x_pos = clamp(x_pos, item.rect.p0.x, item.rect.p1.x);
@ -1674,16 +1904,23 @@ 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, &x_pos, y_pos, line_height, syntax_cols[tks[j]]);
Vec4 col = syntax_cols[tks[j]];
AnimateReady(item, &col);
DrawGlyph(item, g, &x_pos, y_pos, line_height, col);
}
}
else
{
Vec4 text_col = style.text_col;
AnimateReady(item, &text_col);
foreach(j; 0 .. str.length)
{
u8 ch = str[j];
Glyph* g = ch < fg.abuf.atlas.glyphs.length ? fg.abuf.atlas.glyphs.ptr + ch : null;
DrawGlyph(item, g, &x_pos, y_pos, line_height, item.text_col);
DrawGlyph(item, g, &x_pos, y_pos, line_height, text_col);
}
}
@ -2312,25 +2549,26 @@ DrawGlyph(UIItem* item, Glyph* glyph, f32* x_pos, f32 y, f32 line_height, Vec4 c
pragma(inline) f32
AxisPadding(Axis2D axis)(UIItem* item)
{
return item.padding[axis].x + item.padding[axis].y;
ItemStyle* s = GetElementStyle(item.element);
return s.padding[axis].x + s.padding[axis].y;
}
pragma(inline) f32
InnerSize(Axis2D axis)(UIItem* item)
{
return clamp(item.size[axis] - item.border_thickness*2.0, 0.0, f32.max);
return clamp(item.size[axis] - g_ui_ctx.item_styles[item.element].border_thickness*2.0, 0.0, f32.max);
}
pragma(inline) f32
InnerSize(UIItem* item, Axis2D axis)
{
return clamp(item.size[axis] - item.border_thickness*2.0, 0.0, f32.max);
return clamp(item.size[axis] - g_ui_ctx.item_styles[item.element].border_thickness*2.0, 0.0, f32.max);
}
pragma(inline) f32
InnerOffset(Axis2D axis, bool start)(UIItem* item)
{
return item.border_thickness;
return g_ui_ctx.item_styles[item.element].border_thickness;
}
pragma(inline) Vertex*

View File

@ -1,5 +1,6 @@
import dlib;
import ui;
import ui : YELLOW, BLUE, RED;
import editor;
import parsing;
import buffer;
@ -19,18 +20,6 @@ __gshared const UIKey ZERO = ZeroKey();
- Move scrolling behaviour into ui.d and externally be oblivious to it, e.g. just feed it all lines of text in a text buffer, will have to specifically handle extreme cases later but initially i think it should be fine
******/
Vec4 BG_COL = Vec4(0.18, 0.18, 0.18, 1.0);
Vec4 HL_BG_COL = Vec4(0.160, 0.533, 0.803, 1.0);
Vec4 HL_BORDER_COL = Vec4(0.172, 0.643, 0.988, 1.0);
Vec4 CMD_COL = Vec4(0.22, 0.22, 0.22, 1.0);
Vec4 CMD_BORDER_COL = Vec4(0.48, 0.48, 0.48, 1.0);
Vec4 CMD_INPUT_COL = Vec4(0.130, 0.420, 0.640, 1.0);
Vec4 GREY = Vec4(0.80, 0.80, 0.80, 1.0);
Vec4 WHITE = HexCol(0xFFFFFF);
Vec4 BLUE = HexCol(0x4EA9FF);
Vec4 RED = HexCol(0xFF3268);
Vec4 YELLOW = HexCol(0xF7C443);
const f32 CMD_X_PAD = 8.0;
const f32 CMD_Y_PAD = 4.0;
const u32 CMD_TITLE_PX = 14;
@ -61,21 +50,17 @@ 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(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.ScissorY);
mixin(PushScope!("text_col", q{ Vec4(1.0) } ));
mixin(PushScope!("size_info", q{ UISY(ST.Pixels, abuf.atlas.line_height) } ));
mixin(PushScope!("parent", q{ line_count } ));
SetElement(UIElem.LineCountText);
u64 end_line = lines+line_offset;
for(u64 i = line_offset; i < end_line && i < max_line; i += 1)
{
@ -97,9 +82,9 @@ EditorTextView(UIItem* editor, Panel* p, FontAtlasBuf* abuf, u64 lines, i64 line
f32 scroll_pos = cast(f32)(ed.line_offset)*text_size;
f32 padding = 8.0;
f32 scroll_target = 0.0;
f32 scroll_target = 0.0;
static bool toggled = true;
static f32 t = 0.0;
static f32 t = 0.0;
if(toggled)
{
scroll_target = 0.0;
@ -121,17 +106,13 @@ EditorTextView(UIItem* editor, Panel* p, FontAtlasBuf* abuf, u64 lines, i64 line
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_target) } },
//{ "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));
SetElement(UIElem.EditorTextView);
editor = MakeItem(editor.key, UIF.DrawBorder|UIF.ScrollY|UIF.ClampY|UIF.ScissorY|UIF.ScrollFitChildren);
mixin(PushScope!("parent", q{ editor }));
@ -151,16 +132,17 @@ EditorTextView(UIItem* editor, Panel* p, FontAtlasBuf* abuf, u64 lines, i64 line
enum UIPushInfo[] cursor_info = [
{ "size_info", q{ UIS2(ST.Pixels, ST.Pixels, g.advance, line_h) } },
{ "fixed_pos", q{ Vec2(cursor_x, cursor_y) } },
{ "bg_col", q{ Vec4(1.0) } },
];
mixin(PushOnce!(cursor_info));
SetElement(UIElem.EditorTextCursor);
UIItem* cursor = MakeItem("###cursor", UIF.DrawBackground|UIF.FixedPosition);
}
mixin(PushScope!("size_info", q{ UISY(ST.TextSize) } ));
mixin(PushScope!("syntax_highlight", q{ UISH.D } ));
SetElement(UIElem.EditorText);
for(u64 i = 0; i < 200; i += 1)
{
MakeItem("%s", i, UIF.DrawText);
@ -209,7 +191,6 @@ EditorView(Panel* p)
f32 frame_view_offset = -(editor.scroll_offset.y%text_size);
enum UIPushInfo[] c_info = [
{ "bg_col", q{ BG_COL } },
{ "size_info", q{ UIS2() } },
];
mixin(PushOnce!(c_info));
@ -217,7 +198,6 @@ EditorView(Panel* p)
UIItem* container = MakeItem(zero, UIF.DrawBackground);
mixin(PushScope!("parent", q{ container } ));
mixin(PushScope!("border_col", q{ Vec4(1.0) } ));
u64 view_lines;
if(editor.size.y > 0.0)
@ -287,10 +267,6 @@ CommandWindow(f32 w, f32 h, f32 x, f32 y, bool active)
enum UIPushInfo[] cmd_params = [
{ "layout_axis", q{ A2D.Y } },
{ "fixed_pos", q{ Vec2(x, y) } },
{ "bg_col", q{ BG_COL } },
{ "border_col", q{ HL_BORDER_COL } },
{ "border_thickness", q{ 4.0 } },
{ "corner_radius", q{ Vec4(8.0) } },
{ "size_info", q{ UIS2(ST.Pixels, ST.Pixels, w, h) } },
];
mixin(PushOnce!(cmd_params));
@ -301,6 +277,7 @@ CommandWindow(f32 w, f32 h, f32 x, f32 y, bool active)
cmd_flags |= UIF.SetReady;
}
SetElement(UIElem.CmdWindow);
UIItem* window = MakeItem("###cmd_palette", cmd_flags);
Push!("parent")(window, false);
@ -311,36 +288,25 @@ UIItem*
CommandInput(CmdPalette* cmd, string placeholder = "")
{
string input_str = cmd.icount ? Str(cmd.buffer[0 .. cmd.icount]) : "Search...";
Vec4 input_text_col = cmd.icount ? WHITE : GREY;
enum UIPushInfo[] cmd_input_params = [
{ "bg_col", q{ CMD_COL } },
{ "border_col", q{ CMD_BORDER_COL } },
{ "border_thickness", q{ 1.0 }},
{ "text_size", q{ 14 }},
{ "corner_radius", q{ Vec4(12.0, 12.0, 0.0, 0.0) } },
{ "edge_softness", q{ 1.0 } },
{ "size_info", q{ UISY(ST.TextSize) } },
{ "padding", q{ Vec2A2(6.0, 6.0, 6.0, 6.0)} },
{ "display_string", q{ input_str } },
{ "text_col", q{ input_text_col } },
];
mixin(PushOnce!(cmd_input_params));
SetElement(cmd.icount ? UIElem.CmdInput : UIElem.CmdInputEmpty);
return MakeItem("###cmd_input", UIF.DrawBorder|UIF.DrawBackground|UIF.DrawText|UIF.Overflow);
}
UIItem*
CommandOpt(T)(CmdPalette* cmd, T opt, u64 i)
{
Vec4[2] opt_cols = [
Vec4(0.22, 0.22, 0.22, 1.0),
Vec4(0.31, 0.31, 0.31, 1.0),
];
UIFlags flags = UIF.DrawBackground|UIF.AnimateHot|UIF.Clickable;
PushBgCol(opt_cols[i%2]);
SetElement(i%2 ? UIElem.CmdOpt : UIElem.CmdOptAlt);
PushLayoutAxis(A2D.Y);
static if(is(T == string))
@ -369,16 +335,15 @@ CommandOpt(T)(CmdPalette* cmd, T opt, u64 i)
PushSizeInfo(UISY(ST.TextSize), false);
PushTextSize(CMD_TITLE_PX);
PushPadding(Vec2A2(CMD_X_PAD, CMD_X_PAD, CMD_Y_PAD, 2.0));
PushDisplayStringCopy(cmd.commands[i].name);
SetElement(UIElem.CmdTitleText);
MakeItem(ZERO, UIF.DrawText);
PushTextSize(CMD_SUB_PX);
PushTextCol(GREY);
PushPadding(Vec2A2(CMD_X_PAD, CMD_X_PAD, 0.0, 0.0));
PushDisplayStringCopy(cmd.commands[i].desc);
SetElement(UIElem.CmdSubtitleText);
MakeItem(ZERO, UIF.DrawText);
Pop!("parent", "size_info");
@ -413,15 +378,12 @@ CommandPalette(CmdPalette* cmd, bool active)
enum UIPushInfo[] cmd_opts_box_params = [
{ "layout_axis", q{ A2D.Y }},
{ "border_col", q{ CMD_BORDER_COL } },
{ "border_thickness", q{ 1.0 } },
{ "corner_radius", q{ Vec4(0.0, 0.0, 12.0, 12.0) } },
{ "edge_softness", q{ 1.0 }},
{ "size_info", q{ UISY(ST.Pixels, h-opt_height) } },
];
mixin(PushOnce!(cmd_opts_box_params));
SetElement(UIElem.CmdOptWindow);
UIItem* opt_box = MakeItem(ZERO, UIF.DrawBorder);
mixin(PushScope!("parent", q{ opt_box }));
@ -432,8 +394,6 @@ CommandPalette(CmdPalette* cmd, bool active)
bool opts = cast(bool)cmd.opt_strs.length;
if(opts)
{
mixin(PushScope!("padding", q{ Vec2A2(CMD_X_PAD, CMD_X_PAD, CMD_Y_PAD, CMD_Y_PAD) } ));
for(u64 i = 0; i < cmd.opt_strs.length && i < max_opts; i += 1)
{
UIItem* opt = CommandOpt(cmd, cmd.opt_strs[i], i);
@ -499,14 +459,14 @@ Container(bool push = true)(Axis2D axis, UISize[2] size_info)
void
StatusBar(EditorCtx* ed_ctx)
{
mixin(PushScope!("edge_softness", q{ 0.6 }));
enum UIPushInfo[] bar_info = [
{ "size_info", q{ UISY(ST.Percentage, 0.02)} },
{ "layout_axis", q{ A2D.X} },
];
mixin(PushOnce!(bar_info));
ItemStyle* info_style = GetElementStyle(UIElem.StatusInfo);
Vec4 status_col = BLUE;
string status = "Normal";
if(ed_ctx.state == ES.InputMode)
@ -520,28 +480,27 @@ StatusBar(EditorCtx* ed_ctx)
status_col = RED;
}
info_style.bg_col = status_col;
UIItem* bar = MakeItem(ZERO);
mixin(PushScope!("parent", q{ bar }));
enum UIPushInfo[] status_info = [
{ "bg_col", q{ status_col } },
{ "corner_radius", q{ Vec4(8.0) } },
{ "text_size", q{ 16 }},
{ "padding", q{ Vec2A2(8.0, 8.0, 0.0, 0.0) } },
{ "size_info", q{ UISX(ST.TextSize) } },
{ "display_string", q{ status } },
];
mixin(PushOnce!(status_info));
SetElement(UIElem.StatusInfo);
MakeItem(ZERO, UIF.DrawBackground|UIF.DrawText|UIF.VerticalAlignText);
enum UIPushInfo[] rest_info = [
{ "bg_col", q{ BG_COL }},
{ "corner_radius", q{ Vec4(0.0, 0.0, 0.0, 8.0) }},
{ "size_info", q{ UIS2() }},
];
SetElement(UIElem.StatusMessage);
MakeItem(ZERO, UIF.DrawBackground);
}