proper ui scale solve pass & text scaling for animations

This commit is contained in:
jacob 2025-12-30 04:28:43 -06:00
parent db2f5b9bd3
commit b3012c37bd
3 changed files with 91 additions and 16 deletions

View File

@ -82,11 +82,16 @@ V_WidgetTheme V_GetWidgetTheme(void)
// theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf")));
// theme.font_size = 16;
// theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/seguisb.ttf")));
// theme.font_size = 16;
theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/seguisb.ttf")));
theme.font_size = 12;
theme.font_size = 16;
// theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/seguisb.ttf")));
// theme.font_size = 12;
// theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/seguisb.ttf")));
// theme.font_size = 30;
theme.window_background_color = Rgb32(0xff1a1d1e);
theme.window_border_color = Rgb32(0xff343a3b);
@ -1301,8 +1306,8 @@ void V_TickForever(WaveLaneCtx *lane)
}
window_border_color = LerpSrgb(window_border_color, Rgb32(0x0078a6), titlebar_rep.hot);
UI_Push(Scale, LerpF32(0.75, 1, palette->show));
UI_Push(Tint, VEC4(1, 1, 1, palette->show));
UI_SetNext(Scale, LerpF32(0.75, 1, palette->show));
UI_Push(BackgroundColor, window_background_color);
UI_Push(BorderColor, window_border_color);

View File

@ -873,6 +873,36 @@ Vec2 UI_CursorPos(void)
return UI_CurrentFrame()->cursor_pos;
}
////////////////////////////////////////////////////////////
//~ Text layout helpers
GC_Run UI_ScaleRun(Arena *arena, GC_Run unscaled_run, f32 scale)
{
GC_Run result = Zi;
result = unscaled_run;
result.font_size *= scale;
result.font_ascent *= scale;
result.font_descent *= scale;
result.font_cap *= scale;
result.baseline_length *= scale;
result.rects_count = unscaled_run.rects_count;
result.rects = PushStructsNoZero(arena, GC_RunRect, result.rects_count);
for (u64 rect_idx = 0; rect_idx < result.rects_count; ++rect_idx)
{
GC_RunRect *src = &unscaled_run.rects[rect_idx];
GC_RunRect *dst = &result.rects[rect_idx];
*dst = *src;
dst->bounds = MulRng2Vec2(dst->bounds, VEC2(scale, scale));
dst->advance *= scale;
dst->baseline_pos *= scale;
}
return result;
}
////////////////////////////////////////////////////////////
//~ End frame
@ -1103,7 +1133,7 @@ void UI_EndFrame(UI_Frame *frame)
UI_Size sem_dims = box->desc.pref_semantic_dims[axis];
if (sem_dims.kind == UI_SizeKind_Pixel)
{
box->solved_dims.v[axis] = RoundF32(sem_dims.v * box->desc.scale);
box->solved_dims.v[axis] = sem_dims.v;
}
else if (sem_dims.kind == UI_SizeKind_Shrink && AnyBit(box->desc.flags, UI_BoxFlag_DrawText))
{
@ -1117,7 +1147,7 @@ void UI_EndFrame(UI_Frame *frame)
{
text_size = box->glyph_run.font_ascent + box->glyph_run.font_descent;
}
box->solved_dims.v[axis] = RoundF32(text_size + (sem_dims.v * 2));
box->solved_dims.v[axis] = text_size + (sem_dims.v * 2);
}
}
}
@ -1144,7 +1174,7 @@ void UI_EndFrame(UI_Frame *frame)
found_match = 1;
}
}
box->solved_dims.v[axis] = RoundF32(match_size * sem_dims.v);
box->solved_dims.v[axis] = match_size * sem_dims.v;
}
}
}
@ -1173,7 +1203,7 @@ void UI_EndFrame(UI_Frame *frame)
}
}
}
box->solved_dims.v[axis] = CeilF32(accum + (sem_dims.v * 2));
box->solved_dims.v[axis] = accum + (sem_dims.v * 2);
}
}
}
@ -1188,7 +1218,7 @@ void UI_EndFrame(UI_Frame *frame)
UI_Size sem_dims = box->desc.pref_semantic_dims[axis];
if (sem_dims.kind == UI_SizeKind_Grow)
{
box->solved_dims.v[axis] = RoundF32(box->parent->solved_dims.v[axis] * sem_dims.v);
box->solved_dims.v[axis] = box->parent->solved_dims.v[axis] * sem_dims.v;
}
}
}
@ -1248,7 +1278,7 @@ void UI_EndFrame(UI_Frame *frame)
}
}
adjusted_size_accum += new_size;
child->solved_dims.v[axis] = RoundF32(new_size);
child->solved_dims.v[axis] = new_size;
}
}
size_accum = adjusted_size_accum;
@ -1265,13 +1295,42 @@ void UI_EndFrame(UI_Frame *frame)
{
f32 strictness = child->desc.pref_semantic_dims[axis].strictness;
f32 flex = size * (1.0 - strictness);
child->solved_dims.v[axis] = RoundF32(MaxF32(size - flex, box_size));
child->solved_dims.v[axis] = MaxF32(size - flex, box_size);
}
}
}
}
}
// Apply scale
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_Box *parent = box->parent;
box->solved_scale = box->desc.scale;
if (parent)
{
box->solved_scale *= parent->solved_scale;
}
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
UI_Size sem_dims = box->desc.pref_semantic_dims[axis];
f32 unscaled_size = box->solved_dims.v[axis];
f32 scaled_size = unscaled_size * box->solved_scale;
// if (AbsF32(1.0 - box->solved_scale) < 0.001)
// {
// scaled_size = unscaled_size;
// }
if (unscaled_size >= 1)
{
scaled_size = MaxF32(scaled_size, 1);
}
box->solved_dims.v[axis] = scaled_size;
}
}
// Compute final positions
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
@ -1336,7 +1395,9 @@ void UI_EndFrame(UI_Frame *frame)
} break;
}
}
offset = SubVec2(box->desc.floating_pos, anchor_offset);
offset = FloorVec2(offset);
final_pos = AddVec2(parent->screen_rect.p0, offset);
if (!AnyBit(box->desc.flags, UI_BoxFlag_NoFloatingClamp))
@ -1381,13 +1442,14 @@ void UI_EndFrame(UI_Frame *frame)
} break;
}
}
offset = RoundVec2(offset);
final_pos.x = parent->screen_rect.p0.x + offset.x;
final_pos.y = parent->screen_rect.p0.y + offset.y;
parent->cursor += box->solved_dims.v[parent->desc.child_layout_axis];
}
// Submit position
Vec2 rounded_final_pos = FloorVec2(final_pos);
Vec2 rounded_final_pos = final_pos;
box->screen_rect.p0 = rounded_final_pos;
box->screen_rect.p1 = AddVec2(rounded_final_pos, box->solved_dims);
@ -1485,10 +1547,11 @@ void UI_EndFrame(UI_Frame *frame)
}
// Text rects
GC_Run raw_run = box->glyph_run;
GC_Run raw_run_unscaled = box->glyph_run;
GC_Run raw_run = UI_ScaleRun(frame->arena, raw_run_unscaled, box->solved_scale);
if (AnyBit(box->desc.flags, UI_BoxFlag_DrawText) && raw_run.ready)
{
f32 max_baseline = DimsFromRng2(box->screen_rect).x;
f32 max_baseline = CeilF32(DimsFromRng2(box->screen_rect).x);
b32 should_truncate = raw_run.baseline_length > max_baseline && !AnyBit(box->desc.flags, UI_BoxFlag_NoTextTruncation);
// Truncate run
@ -1498,7 +1561,8 @@ void UI_EndFrame(UI_Frame *frame)
if (should_truncate)
{
// Get elipses run
GC_Run elipses_run = GC_RunFromString(scratch.arena, Lit("..."), box->desc.font, box->desc.font_size);
GC_Run elipses_run_unscaled = GC_RunFromString(scratch.arena, Lit("..."), box->desc.font, box->desc.font_size);
GC_Run elipses_run = UI_ScaleRun(frame->arena, elipses_run_unscaled, box->solved_scale);
f32 truncation_offset = max_baseline - elipses_run.baseline_length;
// Append non-overflowed rects

View File

@ -309,6 +309,7 @@ Struct(UI_Box)
//- Layout data
f32 cursor;
f32 final_children_size_accum[Axis_COUNTXY];
f32 solved_scale;
Vec2 solved_dims;
//- Layout results
@ -529,6 +530,11 @@ UI_Frame *UI_LastFrame(void);
Arena *UI_FrameArena(void);
Vec2 UI_CursorPos(void);
////////////////////////////////////////////////////////////
//~ Text layout helpers
GC_Run UI_ScaleRun(Arena *arena, GC_Run unscaled_run, f32 scale);
////////////////////////////////////////////////////////////
//~ End frame