ui animations
This commit is contained in:
parent
7c6b6b73a0
commit
211a6e641d
@ -28,7 +28,7 @@ u64 GC_HashFromGlyphDesc(GC_GlyphDesc desc)
|
|||||||
//~ Run
|
//~ Run
|
||||||
|
|
||||||
// TODO: Thread-local cache
|
// TODO: Thread-local cache
|
||||||
GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size)
|
GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size, f32 scale)
|
||||||
{
|
{
|
||||||
GC_Run result = Zi;
|
GC_Run result = Zi;
|
||||||
if (str.len > 0)
|
if (str.len > 0)
|
||||||
@ -179,14 +179,20 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
|
|||||||
GC_Glyph *glyph = ready_glyphs[glyph_idx];
|
GC_Glyph *glyph = ready_glyphs[glyph_idx];
|
||||||
GC_RunRect *rect = &result.rects[glyph_idx];
|
GC_RunRect *rect = &result.rects[glyph_idx];
|
||||||
|
|
||||||
|
f32 advance = RoundF32(glyph->advance * scale);
|
||||||
|
|
||||||
|
Rng2 bounds = Zi;
|
||||||
|
bounds.p0 = MulVec2(glyph->bounds.p0, scale);
|
||||||
|
bounds.p1 = MulVec2(glyph->bounds.p1, scale);
|
||||||
|
|
||||||
rect->tex = glyph->atlas->tex_ref;
|
rect->tex = glyph->atlas->tex_ref;
|
||||||
rect->tex_slice = glyph->tex_slice;
|
rect->tex_slice = glyph->tex_slice;
|
||||||
rect->tex_slice_uv = glyph->tex_slice_uv;
|
rect->tex_slice_uv = glyph->tex_slice_uv;
|
||||||
|
|
||||||
rect->baseline_pos = baseline_pos;
|
rect->baseline_pos = baseline_pos;
|
||||||
rect->advance = glyph->advance;
|
rect->advance = advance;
|
||||||
|
|
||||||
rect->bounds = glyph->bounds;
|
rect->bounds = bounds;
|
||||||
|
|
||||||
if (glyph_idx == 0)
|
if (glyph_idx == 0)
|
||||||
{
|
{
|
||||||
@ -204,10 +210,10 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
|
|||||||
if (ready_glyphs_count > 0)
|
if (ready_glyphs_count > 0)
|
||||||
{
|
{
|
||||||
GC_Glyph *glyph = ready_glyphs[0];
|
GC_Glyph *glyph = ready_glyphs[0];
|
||||||
result.font_size = glyph->font_size;
|
result.font_size = glyph->font_size * scale;
|
||||||
result.font_ascent = glyph->font_ascent;
|
result.font_ascent = glyph->font_ascent * scale;
|
||||||
result.font_descent = glyph->font_descent;
|
result.font_descent = glyph->font_descent * scale;
|
||||||
result.font_cap = glyph->font_cap;
|
result.font_cap = glyph->font_cap * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
EndScratch(scratch);
|
EndScratch(scratch);
|
||||||
|
|||||||
@ -155,7 +155,7 @@ u64 GC_HashFromGlyphDesc(GC_GlyphDesc desc);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Run
|
//~ Run
|
||||||
|
|
||||||
GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size);
|
GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size, f32 scale);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Async
|
//~ Async
|
||||||
|
|||||||
@ -138,6 +138,10 @@ void V_EndCommandsWidget(V_CommandsWidget *widget)
|
|||||||
Vec2 cursor_pos = UI_CursorPos();
|
Vec2 cursor_pos = UI_CursorPos();
|
||||||
|
|
||||||
UI_Key titlebar_key = UI_KeyF("title bar");
|
UI_Key titlebar_key = UI_KeyF("title bar");
|
||||||
|
UI_Report titlebar_rep = UI_ReportFromKey(titlebar_key);
|
||||||
|
|
||||||
|
UI_Push(Scale, titlebar_rep.exists);
|
||||||
|
UI_Push(Tint, VEC4(1, 1, 1, titlebar_rep.exists));
|
||||||
|
|
||||||
Vec4 window_background_color = theme.window_background_color;
|
Vec4 window_background_color = theme.window_background_color;
|
||||||
// Vec4 window_background_color = VEC4(0, 0, 0, 0);
|
// Vec4 window_background_color = VEC4(0, 0, 0, 0);
|
||||||
@ -145,15 +149,12 @@ void V_EndCommandsWidget(V_CommandsWidget *widget)
|
|||||||
Vec4 titlebar_color = Zi;
|
Vec4 titlebar_color = Zi;
|
||||||
Vec4 titlebar_border_color = Zi;
|
Vec4 titlebar_border_color = Zi;
|
||||||
Vec4 divider_color = theme.divider_color;
|
Vec4 divider_color = theme.divider_color;
|
||||||
|
if (titlebar_rep.m1.held)
|
||||||
{
|
{
|
||||||
UI_Report rep = UI_ReportFromKey(titlebar_key);
|
widget->pos = SubVec2(cursor_pos, titlebar_rep.last_down_mouse_offset);
|
||||||
if (rep.m1.held)
|
|
||||||
{
|
|
||||||
widget->pos = SubVec2(cursor_pos, rep.last_down_mouse_offset);
|
|
||||||
}
|
|
||||||
// window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), rep.hot);
|
|
||||||
window_border_color = BlendSrgb(window_border_color, Rgb32(0x0078a6), rep.hot);
|
|
||||||
}
|
}
|
||||||
|
// window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), titlebar_rep.hot);
|
||||||
|
window_border_color = BlendSrgb(window_border_color, Rgb32(0x0078a6), titlebar_rep.hot);
|
||||||
|
|
||||||
UI_Push(BackgroundColor, window_background_color);
|
UI_Push(BackgroundColor, window_background_color);
|
||||||
UI_Push(BorderColor, window_border_color);
|
UI_Push(BorderColor, window_border_color);
|
||||||
@ -243,7 +244,8 @@ void V_EndCommandsWidget(V_CommandsWidget *widget)
|
|||||||
UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
|
UI_BuildSpacer(UI_PIX(20, 1), Axis_X);
|
||||||
|
|
||||||
// Command label
|
// Command label
|
||||||
UI_SetNext(ChildAlignment, UI_Alignment_Center);
|
// UI_SetNext(ChildAlignment, UI_Alignment_Center);
|
||||||
|
UI_SetNext(ChildAlignment, UI_Alignment_Left);
|
||||||
UI_BuildLabel(item->desc.display_name);
|
UI_BuildLabel(item->desc.display_name);
|
||||||
|
|
||||||
// Middle spacer
|
// Middle spacer
|
||||||
@ -1055,7 +1057,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
i64 new_active_window_idx = panel->active_window_idx;
|
i64 new_active_window_idx = panel->active_window_idx;
|
||||||
UI_PushCP(UI_BuildColumn());
|
UI_PushCP(UI_BuildColumn());
|
||||||
{
|
{
|
||||||
UI_Push(Tint, VEC4(1, 1, 1, 0.90));
|
UI_Push(Tint, VEC4(1, 1, 1, 0.90 * panel_rep.exists));
|
||||||
|
|
||||||
i64 active_window_idx = ClampI64(panel->active_window_idx, 0, MaxI64(panel->windows_count - 1, 0));
|
i64 active_window_idx = ClampI64(panel->active_window_idx, 0, MaxI64(panel->windows_count - 1, 0));
|
||||||
//- Build tab row
|
//- Build tab row
|
||||||
|
|||||||
@ -246,7 +246,6 @@ TTF_GlyphResult TTF_RasterizeGlyphFromCodepoint(Arena *arena, u32 codepoint, Res
|
|||||||
hr = IDWriteFontFace_GetDesignGlyphMetrics(font->face, &glyph_idx, 1, &m, 0);
|
hr = IDWriteFontFace_GetDesignGlyphMetrics(font->face, &glyph_idx, 1, &m, 0);
|
||||||
}
|
}
|
||||||
f32 advance = (f32)m.advanceWidth * pixels_per_design_unit;
|
f32 advance = (f32)m.advanceWidth * pixels_per_design_unit;
|
||||||
advance = RoundF32(advance);
|
|
||||||
|
|
||||||
// Best-guess a position in the middle of the render target based on metrics
|
// Best-guess a position in the middle of the render target based on metrics
|
||||||
Vec2I32 rt_baseline = Zi;
|
Vec2I32 rt_baseline = Zi;
|
||||||
|
|||||||
132
src/ui/ui_core.c
132
src/ui/ui_core.c
@ -253,6 +253,7 @@ void UI_PushDefaults(void)
|
|||||||
case UI_StyleKind_Parent: { desc.style.Parent = UI_RootKey; } break;
|
case UI_StyleKind_Parent: { desc.style.Parent = UI_RootKey; } break;
|
||||||
case UI_StyleKind_Width: { desc.style.Width = UI_GROW(1, 0); } break;
|
case UI_StyleKind_Width: { desc.style.Width = UI_GROW(1, 0); } break;
|
||||||
case UI_StyleKind_Height: { desc.style.Height = UI_GROW(1, 0); }
|
case UI_StyleKind_Height: { desc.style.Height = UI_GROW(1, 0); }
|
||||||
|
case UI_StyleKind_Scale: { desc.style.Scale = 1; } break;
|
||||||
case UI_StyleKind_Font: { desc.style.Font = UI_GetDefaultFont(); } break;
|
case UI_StyleKind_Font: { desc.style.Font = UI_GetDefaultFont(); } break;
|
||||||
|
|
||||||
u8 prefetch[127] = Zi;
|
u8 prefetch[127] = Zi;
|
||||||
@ -506,6 +507,7 @@ UI_Key UI_BuildBoxEx(UI_Key semantic_key)
|
|||||||
n->cmd.box.flags = UI_UseTop(Flags);
|
n->cmd.box.flags = UI_UseTop(Flags);
|
||||||
n->cmd.box.pref_semantic_dims[Axis_X] = UI_UseTop(Width);
|
n->cmd.box.pref_semantic_dims[Axis_X] = UI_UseTop(Width);
|
||||||
n->cmd.box.pref_semantic_dims[Axis_Y] = UI_UseTop(Height);
|
n->cmd.box.pref_semantic_dims[Axis_Y] = UI_UseTop(Height);
|
||||||
|
n->cmd.box.scale = UI_UseTop(Scale);
|
||||||
n->cmd.box.child_alignment[Axis_X] = UI_UseTop(ChildAlignmentX);
|
n->cmd.box.child_alignment[Axis_X] = UI_UseTop(ChildAlignmentX);
|
||||||
n->cmd.box.child_alignment[Axis_Y] = UI_UseTop(ChildAlignmentY);
|
n->cmd.box.child_alignment[Axis_Y] = UI_UseTop(ChildAlignmentY);
|
||||||
n->cmd.box.child_layout_axis = UI_UseTop(ChildLayoutAxis);
|
n->cmd.box.child_layout_axis = UI_UseTop(ChildLayoutAxis);
|
||||||
@ -778,29 +780,35 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update box hot & active states
|
|
||||||
UI_Box *hot_box = active_box;
|
UI_Box *hot_box = active_box;
|
||||||
if (hovered_box && !active_box)
|
if (hovered_box && !active_box)
|
||||||
{
|
{
|
||||||
hot_box = hovered_box;
|
hot_box = hovered_box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update box reports
|
||||||
for (u64 pre_index = 0; pre_index < UI.boxes_count; ++pre_index)
|
for (u64 pre_index = 0; pre_index < UI.boxes_count; ++pre_index)
|
||||||
{
|
{
|
||||||
UI_Box *box = last_frame->boxes_pre[pre_index];
|
UI_Box *box = last_frame->boxes_pre[pre_index];
|
||||||
UI_Report *report = &box->report;
|
UI_Report *report = &box->report;
|
||||||
report->is_hovered = box == hovered_box;
|
report->is_hovered = box == hovered_box;
|
||||||
report->is_hot = box == hot_box;
|
report->is_hot = box == hot_box;
|
||||||
f32 target_hovered = report->is_hovered;
|
|
||||||
f32 target_hot = report->is_hot;
|
f32 target_exists = box->last_build_tick >= (frame->tick - 1);
|
||||||
f32 target_active = box == active_box;
|
f32 target_hovered = report->is_hovered;
|
||||||
|
f32 target_hot = report->is_hot;
|
||||||
|
f32 target_active = box == active_box;
|
||||||
f32 target_selected = !!(box->desc.flags & UI_BoxFlag_Selected);
|
f32 target_selected = !!(box->desc.flags & UI_BoxFlag_Selected);
|
||||||
f32 hot_blend_rate = target_hot == 1 ? 1 : (15 * frame->dt);
|
|
||||||
f32 active_blend_rate = target_active == 1 ? 1 : (15 * frame->dt);
|
f32 exists_blend_rate = (30 * frame->dt);
|
||||||
f32 hovered_blend_rate = target_hovered == 1 ? 1 : (15 * frame->dt);
|
f32 hot_blend_rate = target_hot == 1 ? 1 : (15 * frame->dt);
|
||||||
f32 selected_blend_rate = target_selected == 1 ? 1 : (15 * frame->dt);
|
f32 active_blend_rate = target_active == 1 ? 1 : (15 * frame->dt);
|
||||||
report->hot = LerpF32(report->hot, target_hot, hot_blend_rate);
|
f32 hovered_blend_rate = target_hovered == 1 ? 1 : (15 * frame->dt);
|
||||||
report->active = LerpF32(report->active, target_active, active_blend_rate);
|
f32 selected_blend_rate = target_selected == 1 ? 1 : (15 * frame->dt);
|
||||||
|
|
||||||
|
report->exists = LerpF32(report->exists, target_exists, exists_blend_rate);
|
||||||
|
report->hot = LerpF32(report->hot, target_hot, hot_blend_rate);
|
||||||
|
report->active = LerpF32(report->active, target_active, active_blend_rate);
|
||||||
report->hovered = LerpF32(report->hovered, target_hovered, hovered_blend_rate);
|
report->hovered = LerpF32(report->hovered, target_hovered, hovered_blend_rate);
|
||||||
report->selected = LerpF32(report->selected, target_selected, selected_blend_rate);
|
report->selected = LerpF32(report->selected, target_selected, selected_blend_rate);
|
||||||
report->screen_rect = box->rect;
|
report->screen_rect = box->rect;
|
||||||
@ -954,7 +962,8 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
// Update box from cmd
|
// Update box from cmd
|
||||||
{
|
{
|
||||||
box->desc = cmd.box;
|
box->desc = cmd.box;
|
||||||
box->glyph_run = GC_RunFromString(frame->arena, box->desc.text, box->desc.font, box->desc.font_size);
|
|
||||||
|
box->glyph_run = GC_RunFromString(frame->arena, box->desc.text, box->desc.font, box->desc.font_size, box->desc.scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
box->last_build_tick = frame->tick;
|
box->last_build_tick = frame->tick;
|
||||||
@ -975,46 +984,6 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
//- Interpolate box sizes
|
|
||||||
|
|
||||||
for (UI_BoxIterResult ir = UI_FirstBox(scratch.arena, &box_iter, UI_RootKey); ir.box; ir = UI_NextBox(scratch.arena, &box_iter))
|
|
||||||
{
|
|
||||||
if (ir.pre)
|
|
||||||
{
|
|
||||||
UI_Box *box = ir.box;
|
|
||||||
|
|
||||||
for (Axis axis = 0; axis < countof(box->semantic_dims); ++axis)
|
|
||||||
{
|
|
||||||
UI_Size *dst_sem_size = &box->semantic_dims[axis];
|
|
||||||
UI_Size *pref_sem_size = &box->desc.pref_semantic_dims[axis];
|
|
||||||
b32 was_built = box->last_build_tick >= frame->tick;
|
|
||||||
b32 is_new = box->gen != box->old_gen;
|
|
||||||
if (!was_built)
|
|
||||||
{
|
|
||||||
*pref_sem_size = UI_PIX(0, 0);
|
|
||||||
}
|
|
||||||
else if (is_new)
|
|
||||||
{
|
|
||||||
dst_sem_size->v = 0;
|
|
||||||
dst_sem_size->strictness = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
f32 lerp_rate = 20.0 * frame->dt;
|
|
||||||
// f32 lerp_rate = 1;
|
|
||||||
if (box->desc.is_transient || dst_sem_size->kind != pref_sem_size->kind)
|
|
||||||
{
|
|
||||||
lerp_rate = 1;
|
|
||||||
}
|
|
||||||
lerp_rate = ClampF32(lerp_rate, 0, 1);
|
|
||||||
|
|
||||||
dst_sem_size->kind = pref_sem_size->kind;
|
|
||||||
dst_sem_size->v = LerpF32(dst_sem_size->v, pref_sem_size->v, lerp_rate);
|
|
||||||
dst_sem_size->strictness = LerpF32(dst_sem_size->strictness, pref_sem_size->strictness, lerp_rate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Prune cached boxes
|
//- Prune cached boxes
|
||||||
|
|
||||||
@ -1026,29 +995,15 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (ir.pre)
|
if (ir.pre)
|
||||||
{
|
{
|
||||||
UI_Box *box = ir.box;
|
UI_Box *box = ir.box;
|
||||||
// if (box->last_build_tick < frame->tick)
|
if (box->last_build_tick < frame->tick)
|
||||||
{
|
{
|
||||||
b32 should_prune = 0;
|
// Cause children to prune
|
||||||
for (Axis axis = 0; axis < countof(box->semantic_dims); ++axis)
|
for (UI_Box *child = box->first; child; child = child->next)
|
||||||
{
|
{
|
||||||
UI_Size sem_size = box->semantic_dims[axis];
|
child->last_build_tick = box->last_build_tick;
|
||||||
if (sem_size.kind != UI_SizeKind_Shrink && sem_size.v <= 0)
|
|
||||||
{
|
|
||||||
should_prune = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (should_prune)
|
|
||||||
{
|
|
||||||
// Cause children to prune
|
|
||||||
for (UI_Box *child = box->first; child; child = child->next)
|
|
||||||
{
|
|
||||||
child->semantic_dims[Axis_X] = UI_PIX(0, 0);
|
|
||||||
child->semantic_dims[Axis_Y] = UI_PIX(0, 0);
|
|
||||||
}
|
|
||||||
// Push box to prunes array
|
|
||||||
prunes[prunes_count++] = box;
|
|
||||||
}
|
}
|
||||||
|
// Push box to prunes array
|
||||||
|
prunes[prunes_count++] = box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1124,13 +1079,24 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
Assert(post_index == boxes_count);
|
Assert(post_index == boxes_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply scales
|
||||||
|
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
|
||||||
|
{
|
||||||
|
UI_Box *box = boxes_pre[pre_index];
|
||||||
|
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
|
||||||
|
{
|
||||||
|
UI_Size *sem_dims = &box->desc.pref_semantic_dims[axis];
|
||||||
|
sem_dims->v *= box->desc.scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Compute independent sizes
|
// Compute independent sizes
|
||||||
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
|
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
|
||||||
{
|
{
|
||||||
UI_Box *box = boxes_pre[pre_index];
|
UI_Box *box = boxes_pre[pre_index];
|
||||||
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
|
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
|
||||||
{
|
{
|
||||||
UI_Size sem_dims = box->semantic_dims[axis];
|
UI_Size sem_dims = box->desc.pref_semantic_dims[axis];
|
||||||
if (sem_dims.kind == UI_SizeKind_Pixel)
|
if (sem_dims.kind == UI_SizeKind_Pixel)
|
||||||
{
|
{
|
||||||
box->solved_dims[axis] = sem_dims.v;
|
box->solved_dims[axis] = sem_dims.v;
|
||||||
@ -1141,7 +1107,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
f32 text_size = 0;
|
f32 text_size = 0;
|
||||||
if (axis == Axis_X)
|
if (axis == Axis_X)
|
||||||
{
|
{
|
||||||
text_size = box->glyph_run.baseline_length;
|
text_size = CeilF32(box->glyph_run.baseline_length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1159,14 +1125,14 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (box->parent)
|
if (box->parent)
|
||||||
{
|
{
|
||||||
Axis axis = box->parent->desc.child_layout_axis;
|
Axis axis = box->parent->desc.child_layout_axis;
|
||||||
UI_Size sem_dims = box->semantic_dims[axis];
|
UI_Size sem_dims = box->desc.pref_semantic_dims[axis];
|
||||||
if (sem_dims.kind == UI_SizeKind_Grow)
|
if (sem_dims.kind == UI_SizeKind_Grow)
|
||||||
{
|
{
|
||||||
f32 match_size = 0;
|
f32 match_size = 0;
|
||||||
b32 found_match = 0;
|
b32 found_match = 0;
|
||||||
for (UI_Box *ancestor = box->parent; ancestor != 0 && !found_match; ancestor = ancestor->parent)
|
for (UI_Box *ancestor = box->parent; ancestor != 0 && !found_match; ancestor = ancestor->parent)
|
||||||
{
|
{
|
||||||
UI_Size ancestor_size = ancestor->semantic_dims[axis];
|
UI_Size ancestor_size = ancestor->desc.pref_semantic_dims[axis];
|
||||||
if (ancestor_size.kind == UI_SizeKind_Pixel || (ancestor_size.kind == UI_SizeKind_Shrink && AnyBit(box->desc.flags, UI_BoxFlag_DrawText)))
|
if (ancestor_size.kind == UI_SizeKind_Pixel || (ancestor_size.kind == UI_SizeKind_Shrink && AnyBit(box->desc.flags, UI_BoxFlag_DrawText)))
|
||||||
{
|
{
|
||||||
// Match independent ancestor
|
// Match independent ancestor
|
||||||
@ -1185,7 +1151,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
UI_Box *box = boxes_post[post_index];
|
UI_Box *box = boxes_post[post_index];
|
||||||
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
|
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
|
||||||
{
|
{
|
||||||
UI_Size sem_dims = box->semantic_dims[axis];
|
UI_Size sem_dims = box->desc.pref_semantic_dims[axis];
|
||||||
if (sem_dims.kind == UI_SizeKind_Shrink && !AnyBit(box->desc.flags, UI_BoxFlag_DrawText))
|
if (sem_dims.kind == UI_SizeKind_Shrink && !AnyBit(box->desc.flags, UI_BoxFlag_DrawText))
|
||||||
{
|
{
|
||||||
f32 accum = 0;
|
f32 accum = 0;
|
||||||
@ -1215,7 +1181,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (box->parent)
|
if (box->parent)
|
||||||
{
|
{
|
||||||
Axis axis = !box->parent->desc.child_layout_axis;
|
Axis axis = !box->parent->desc.child_layout_axis;
|
||||||
UI_Size sem_dims = box->semantic_dims[axis];
|
UI_Size sem_dims = box->desc.pref_semantic_dims[axis];
|
||||||
if (sem_dims.kind == UI_SizeKind_Grow)
|
if (sem_dims.kind == UI_SizeKind_Grow)
|
||||||
{
|
{
|
||||||
box->solved_dims[axis] = box->parent->solved_dims[axis] * sem_dims.v;
|
box->solved_dims[axis] = box->parent->solved_dims[axis] * sem_dims.v;
|
||||||
@ -1239,7 +1205,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (!AnyBit(child->desc.flags, UI_BoxFlag_Floating))
|
if (!AnyBit(child->desc.flags, UI_BoxFlag_Floating))
|
||||||
{
|
{
|
||||||
f32 size = child->solved_dims[axis];
|
f32 size = child->solved_dims[axis];
|
||||||
f32 strictness = child->semantic_dims[axis].strictness;
|
f32 strictness = child->desc.pref_semantic_dims[axis].strictness;
|
||||||
f32 flex = size * (1.0 - strictness);
|
f32 flex = size * (1.0 - strictness);
|
||||||
if (axis == box->desc.child_layout_axis)
|
if (axis == box->desc.child_layout_axis)
|
||||||
{
|
{
|
||||||
@ -1262,7 +1228,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (!AnyBit(child->desc.flags, UI_BoxFlag_Floating))
|
if (!AnyBit(child->desc.flags, UI_BoxFlag_Floating))
|
||||||
{
|
{
|
||||||
f32 size = child->solved_dims[axis];
|
f32 size = child->solved_dims[axis];
|
||||||
f32 strictness = child->semantic_dims[axis].strictness;
|
f32 strictness = child->desc.pref_semantic_dims[axis].strictness;
|
||||||
f32 flex = size * (1.0 - strictness);
|
f32 flex = size * (1.0 - strictness);
|
||||||
f32 new_size = size;
|
f32 new_size = size;
|
||||||
if (axis == box->desc.child_layout_axis)
|
if (axis == box->desc.child_layout_axis)
|
||||||
@ -1293,7 +1259,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
f32 size = child->solved_dims[axis];
|
f32 size = child->solved_dims[axis];
|
||||||
if (size > box_size)
|
if (size > box_size)
|
||||||
{
|
{
|
||||||
f32 strictness = child->semantic_dims[axis].strictness;
|
f32 strictness = child->desc.pref_semantic_dims[axis].strictness;
|
||||||
f32 flex = size * (1.0 - strictness);
|
f32 flex = size * (1.0 - strictness);
|
||||||
child->solved_dims[axis] = MaxF32(size - flex, box_size);
|
child->solved_dims[axis] = MaxF32(size - flex, box_size);
|
||||||
}
|
}
|
||||||
@ -1495,7 +1461,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (should_truncate)
|
if (should_truncate)
|
||||||
{
|
{
|
||||||
// Get elipses run
|
// Get elipses run
|
||||||
GC_Run elipses_run = GC_RunFromString(scratch.arena, Lit("..."), box->desc.font, box->desc.font_size);
|
GC_Run elipses_run = GC_RunFromString(scratch.arena, Lit("..."), box->desc.font, box->desc.font_size, box->desc.scale);
|
||||||
f32 truncation_offset = max_baseline - elipses_run.baseline_length;
|
f32 truncation_offset = max_baseline - elipses_run.baseline_length;
|
||||||
|
|
||||||
// Append non-overflowed rects
|
// Append non-overflowed rects
|
||||||
|
|||||||
@ -100,6 +100,7 @@ Enum(UI_BoxFlag)
|
|||||||
X(ChildAlignmentY, UI_AxisAlignment) \
|
X(ChildAlignmentY, UI_AxisAlignment) \
|
||||||
X(Width, UI_Size) \
|
X(Width, UI_Size) \
|
||||||
X(Height, UI_Size) \
|
X(Height, UI_Size) \
|
||||||
|
X(Scale, f32) \
|
||||||
X(BackgroundColor, Vec4) \
|
X(BackgroundColor, Vec4) \
|
||||||
X(BorderColor, Vec4) \
|
X(BorderColor, Vec4) \
|
||||||
X(DebugColor, Vec4) \
|
X(DebugColor, Vec4) \
|
||||||
@ -186,6 +187,7 @@ Struct(UI_Report)
|
|||||||
b32 is_hovered;
|
b32 is_hovered;
|
||||||
b32 is_hot;
|
b32 is_hot;
|
||||||
|
|
||||||
|
f32 exists;
|
||||||
f32 hovered;
|
f32 hovered;
|
||||||
f32 hot;
|
f32 hot;
|
||||||
f32 active;
|
f32 active;
|
||||||
@ -227,6 +229,7 @@ Struct(UI_BoxDesc)
|
|||||||
Vec4 debug_color;
|
Vec4 debug_color;
|
||||||
Vec4 tint;
|
Vec4 tint;
|
||||||
f32 border;
|
f32 border;
|
||||||
|
f32 scale;
|
||||||
Vec2 floating_pos;
|
Vec2 floating_pos;
|
||||||
String text;
|
String text;
|
||||||
GC_FontKey font;
|
GC_FontKey font;
|
||||||
@ -287,7 +290,6 @@ Struct(UI_Box)
|
|||||||
GC_Run glyph_run;
|
GC_Run glyph_run;
|
||||||
|
|
||||||
//- Pre-layout data
|
//- Pre-layout data
|
||||||
UI_Size semantic_dims[Axis_COUNTXY];
|
|
||||||
u64 pre_index;
|
u64 pre_index;
|
||||||
u64 post_index;
|
u64 post_index;
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ UI_Key UI_BuildLabel(String text)
|
|||||||
UI_Key parent = UI_UseTop(Parent);
|
UI_Key parent = UI_UseTop(Parent);
|
||||||
GC_FontKey font = UI_UseTop(Font);
|
GC_FontKey font = UI_UseTop(Font);
|
||||||
f32 font_size = UI_UseTop(FontSize);
|
f32 font_size = UI_UseTop(FontSize);
|
||||||
|
f32 scale = UI_UseTop(Scale);
|
||||||
Vec4 tint = UI_UseTop(Tint);
|
Vec4 tint = UI_UseTop(Tint);
|
||||||
UI_Alignment alignment = UI_UseTop(ChildAlignment);
|
UI_Alignment alignment = UI_UseTop(ChildAlignment);
|
||||||
|
|
||||||
@ -14,14 +15,15 @@ UI_Key UI_BuildLabel(String text)
|
|||||||
{
|
{
|
||||||
UI_PushDefaults();
|
UI_PushDefaults();
|
||||||
UI_Push(Parent, parent);
|
UI_Push(Parent, parent);
|
||||||
UI_SetNext(Tint, tint);
|
UI_Push(Scale, scale);
|
||||||
UI_SetNext(Font, font);
|
UI_Push(Tint, tint);
|
||||||
UI_SetNext(FontSize, font_size);
|
UI_Push(Font, font);
|
||||||
UI_SetNext(Width, UI_SHRINK(0, 1));
|
UI_Push(FontSize, font_size);
|
||||||
UI_SetNext(Height, UI_SHRINK(0, 1));
|
UI_Push(Width, UI_SHRINK(0, 1));
|
||||||
UI_SetNext(Text, text);
|
UI_Push(Height, UI_SHRINK(0, 1));
|
||||||
UI_SetNext(ChildAlignment, alignment);
|
UI_Push(Text, text);
|
||||||
UI_SetNext(Flags, UI_BoxFlag_DrawText);
|
UI_Push(ChildAlignment, alignment);
|
||||||
|
UI_Push(Flags, UI_BoxFlag_DrawText);
|
||||||
key = UI_BuildBox();
|
key = UI_BuildBox();
|
||||||
}
|
}
|
||||||
UI_PopCP(UI_TopCP());
|
UI_PopCP(UI_TopCP());
|
||||||
@ -50,10 +52,12 @@ UI_Key UI_BuildSpacer(UI_Size size, Axis axis)
|
|||||||
{
|
{
|
||||||
UI_Key parent = UI_UseTop(Parent);
|
UI_Key parent = UI_UseTop(Parent);
|
||||||
UI_Key key = Zi;
|
UI_Key key = Zi;
|
||||||
|
f32 scale = UI_UseTop(Scale);
|
||||||
UI_PushCP(UI_NilKey);
|
UI_PushCP(UI_NilKey);
|
||||||
{
|
{
|
||||||
UI_PushDefaults();
|
UI_PushDefaults();
|
||||||
UI_Push(Parent, parent);
|
UI_Push(Parent, parent);
|
||||||
|
UI_Push(Scale, scale);
|
||||||
UI_Push(Tint, 0);
|
UI_Push(Tint, 0);
|
||||||
UI_Push(AxisSize, UI_GROW(1, 0), .axis = !axis);
|
UI_Push(AxisSize, UI_GROW(1, 0), .axis = !axis);
|
||||||
UI_Push(AxisSize, size, .axis = axis);
|
UI_Push(AxisSize, size, .axis = axis);
|
||||||
@ -67,11 +71,13 @@ UI_Key UI_BuildDivider(UI_Size size, Vec4 color, Axis axis)
|
|||||||
{
|
{
|
||||||
UI_Key key = Zi;
|
UI_Key key = Zi;
|
||||||
UI_Key parent = UI_UseTop(Parent);
|
UI_Key parent = UI_UseTop(Parent);
|
||||||
|
f32 scale = UI_UseTop(Scale);
|
||||||
Vec4 tint = UI_UseTop(Tint);
|
Vec4 tint = UI_UseTop(Tint);
|
||||||
UI_PushCP(UI_NilKey);
|
UI_PushCP(UI_NilKey);
|
||||||
{
|
{
|
||||||
UI_PushDefaults();
|
UI_PushDefaults();
|
||||||
UI_Push(Parent, parent);
|
UI_Push(Parent, parent);
|
||||||
|
UI_Push(Scale, scale);
|
||||||
UI_Push(Tint, tint);
|
UI_Push(Tint, tint);
|
||||||
UI_Push(BackgroundColor, color);
|
UI_Push(BackgroundColor, color);
|
||||||
UI_Push(AxisSize, UI_GROW(1, 0), .axis = !axis);
|
UI_Push(AxisSize, UI_GROW(1, 0), .axis = !axis);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user