ui lerp progress
This commit is contained in:
parent
54025f670f
commit
7c6b6b73a0
@ -1636,10 +1636,14 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case V_CmdKind_toggle_window_topmost:
|
case V_CmdKind_toggle_window_topmost:
|
||||||
|
{
|
||||||
|
// TODO: Enable this
|
||||||
|
if (0)
|
||||||
{
|
{
|
||||||
b32 new = !window_frame.forced_top;
|
b32 new = !window_frame.forced_top;
|
||||||
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetForcedTop, .v = new);
|
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetForcedTop, .v = new);
|
||||||
LogInfoF("Toggled topmost: %F", FmtSint(new));
|
LogInfoF("Toggled topmost: %F", FmtSint(new));
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case V_CmdKind_spawn:
|
case V_CmdKind_spawn:
|
||||||
|
|||||||
292
src/ui/ui_core.c
292
src/ui/ui_core.c
@ -504,8 +504,8 @@ UI_Key UI_BuildBoxEx(UI_Key semantic_key)
|
|||||||
n->cmd.box.is_transient = is_transient;
|
n->cmd.box.is_transient = is_transient;
|
||||||
n->cmd.box.parent = UI_UseTop(Parent);
|
n->cmd.box.parent = UI_UseTop(Parent);
|
||||||
n->cmd.box.flags = UI_UseTop(Flags);
|
n->cmd.box.flags = UI_UseTop(Flags);
|
||||||
n->cmd.box.pref_size[Axis_X] = UI_UseTop(Width);
|
n->cmd.box.pref_semantic_dims[Axis_X] = UI_UseTop(Width);
|
||||||
n->cmd.box.pref_size[Axis_Y] = UI_UseTop(Height);
|
n->cmd.box.pref_semantic_dims[Axis_Y] = UI_UseTop(Height);
|
||||||
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);
|
||||||
@ -660,18 +660,18 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
|
|||||||
b32 is_cursor_in_box = 0;
|
b32 is_cursor_in_box = 0;
|
||||||
{
|
{
|
||||||
// TODO: More efficient test. This logic is just copied from the renderer's SDF function for now.
|
// TODO: More efficient test. This logic is just copied from the renderer's SDF function for now.
|
||||||
Vec2 p0 = box->draw_rect.p0;
|
Vec2 p0 = box->rect.p0;
|
||||||
Vec2 p1 = box->draw_rect.p1;
|
Vec2 p1 = box->rect.p1;
|
||||||
Vec2 point = frame->cursor_pos;
|
Vec2 point = frame->cursor_pos;
|
||||||
b32 is_corner = 0;
|
b32 is_corner = 0;
|
||||||
f32 non_corner_edge_dist = MinF32(MinF32(point.x - p0.x, p1.x - point.x), MinF32(point.y - p0.y, p1.y - point.y));
|
f32 non_corner_edge_dist = MinF32(MinF32(point.x - p0.x, p1.x - point.x), MinF32(point.y - p0.y, p1.y - point.y));
|
||||||
f32 corner_edge_dist = non_corner_edge_dist;
|
f32 corner_edge_dist = non_corner_edge_dist;
|
||||||
if (non_corner_edge_dist >= 0)
|
if (non_corner_edge_dist >= 0)
|
||||||
{
|
{
|
||||||
f32 tl_radius = box->draw_rounding_tl;
|
f32 tl_radius = box->rounding_tl;
|
||||||
f32 tr_radius = box->draw_rounding_tr;
|
f32 tr_radius = box->rounding_tr;
|
||||||
f32 br_radius = box->draw_rounding_br;
|
f32 br_radius = box->rounding_br;
|
||||||
f32 bl_radius = box->draw_rounding_bl;
|
f32 bl_radius = box->rounding_bl;
|
||||||
Vec2 tl = VEC2(p0.x + tl_radius, p0.y + tl_radius);
|
Vec2 tl = VEC2(p0.x + tl_radius, p0.y + tl_radius);
|
||||||
Vec2 tr = VEC2(p1.x - tr_radius, p0.y + tr_radius);
|
Vec2 tr = VEC2(p1.x - tr_radius, p0.y + tr_radius);
|
||||||
Vec2 br = VEC2(p1.x - br_radius, p1.y - br_radius);
|
Vec2 br = VEC2(p1.x - br_radius, p1.y - br_radius);
|
||||||
@ -714,7 +714,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
|
|||||||
{
|
{
|
||||||
if (hovered_box)
|
if (hovered_box)
|
||||||
{
|
{
|
||||||
hovered_box->report.last_down_mouse_offset = SubVec2(frame->cursor_pos, hovered_box->draw_rect.p0);
|
hovered_box->report.last_down_mouse_offset = SubVec2(frame->cursor_pos, hovered_box->rect.p0);
|
||||||
if (cev.button == Button_M1)
|
if (cev.button == Button_M1)
|
||||||
{
|
{
|
||||||
++hovered_box->report.m1.downs;
|
++hovered_box->report.m1.downs;
|
||||||
@ -803,7 +803,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
|
|||||||
report->active = LerpF32(report->active, target_active, active_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->draw_rect;
|
report->screen_rect = box->rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->hovered_box = hovered_box ? hovered_box->key : UI_NilKey;
|
frame->hovered_box = hovered_box ? hovered_box->key : UI_NilKey;
|
||||||
@ -909,7 +909,6 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
++UI.boxes_count;
|
++UI.boxes_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
box->last_build_tick = frame->tick;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,10 +934,6 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (box != UI.root_box)
|
if (box != UI.root_box)
|
||||||
{
|
{
|
||||||
parent = UI_BoxFromKey(cmd.box.parent);
|
parent = UI_BoxFromKey(cmd.box.parent);
|
||||||
if (!parent)
|
|
||||||
{
|
|
||||||
parent = UI.root_box;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update parent
|
// Update parent
|
||||||
@ -956,11 +951,14 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
}
|
}
|
||||||
box->parent = parent;
|
box->parent = parent;
|
||||||
|
|
||||||
// Update box
|
// 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->last_build_tick = frame->tick;
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case UI_CmdKind_SetRawTexture:
|
case UI_CmdKind_SetRawTexture:
|
||||||
@ -978,9 +976,47 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Prune cached boxes
|
//- Interpolate box sizes
|
||||||
|
|
||||||
i64 box_grace_frames = 10;
|
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
|
||||||
|
|
||||||
{
|
{
|
||||||
u64 prunes_count = 0;
|
u64 prunes_count = 0;
|
||||||
@ -990,12 +1026,27 @@ 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)
|
||||||
{
|
{
|
||||||
box->desc.pref_size[Axis_X] = UI_PIX(0, 0);
|
b32 should_prune = 0;
|
||||||
// box->desc.pref_size[Axis_Y] = UI_PIX(0, 0);
|
for (Axis axis = 0; axis < countof(box->semantic_dims); ++axis)
|
||||||
if (box->desc.is_transient || (frame->tick - box->last_build_tick > box_grace_frames))
|
|
||||||
{
|
{
|
||||||
|
UI_Size sem_size = box->semantic_dims[axis];
|
||||||
|
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;
|
prunes[prunes_count++] = box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1060,7 +1111,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
// Reset layout data
|
// Reset layout data
|
||||||
box->cursor = 0;
|
box->cursor = 0;
|
||||||
ZeroStructs(box->final_children_size_accum, countof(box->final_children_size_accum));
|
ZeroStructs(box->final_children_size_accum, countof(box->final_children_size_accum));
|
||||||
ZeroStructs(box->target_dims, countof(box->target_dims));
|
ZeroStructs(box->solved_dims, countof(box->solved_dims));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1079,12 +1130,12 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
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 pref_size = box->desc.pref_size[axis];
|
UI_Size sem_dims = box->semantic_dims[axis];
|
||||||
if (pref_size.kind == UI_SizeKind_Pixel)
|
if (sem_dims.kind == UI_SizeKind_Pixel)
|
||||||
{
|
{
|
||||||
box->target_dims[axis] = pref_size.v;
|
box->solved_dims[axis] = sem_dims.v;
|
||||||
}
|
}
|
||||||
else if (pref_size.kind == UI_SizeKind_Shrink && AnyBit(box->desc.flags, UI_BoxFlag_DrawText))
|
else if (sem_dims.kind == UI_SizeKind_Shrink && AnyBit(box->desc.flags, UI_BoxFlag_DrawText))
|
||||||
{
|
{
|
||||||
// TODO: Distinguish between baseline alignment & visual alignment
|
// TODO: Distinguish between baseline alignment & visual alignment
|
||||||
f32 text_size = 0;
|
f32 text_size = 0;
|
||||||
@ -1096,7 +1147,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
{
|
{
|
||||||
text_size = box->glyph_run.font_ascent + box->glyph_run.font_descent;
|
text_size = box->glyph_run.font_ascent + box->glyph_run.font_descent;
|
||||||
}
|
}
|
||||||
box->target_dims[axis] = text_size + (pref_size.v * 2);
|
box->solved_dims[axis] = text_size + (sem_dims.v * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1108,22 +1159,22 @@ 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 pref_size = box->desc.pref_size[axis];
|
UI_Size sem_dims = box->semantic_dims[axis];
|
||||||
if (pref_size.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->desc.pref_size[axis];
|
UI_Size ancestor_size = ancestor->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
|
||||||
match_size = ancestor->target_dims[axis];
|
match_size = ancestor->solved_dims[axis];
|
||||||
found_match = 1;
|
found_match = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
box->target_dims[axis] = match_size * pref_size.v;
|
box->solved_dims[axis] = match_size * sem_dims.v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1134,8 +1185,8 @@ 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 pref_size = box->desc.pref_size[axis];
|
UI_Size sem_dims = box->semantic_dims[axis];
|
||||||
if (pref_size.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;
|
||||||
for (UI_Box *child = box->first; child; child = child->next)
|
for (UI_Box *child = box->first; child; child = child->next)
|
||||||
@ -1144,15 +1195,15 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
{
|
{
|
||||||
if (axis == box->desc.child_layout_axis)
|
if (axis == box->desc.child_layout_axis)
|
||||||
{
|
{
|
||||||
accum += child->target_dims[axis];
|
accum += child->solved_dims[axis];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
accum = MaxF32(child->target_dims[axis], accum);
|
accum = MaxF32(child->solved_dims[axis], accum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
box->target_dims[axis] = accum + (pref_size.v * 2);
|
box->solved_dims[axis] = accum + (sem_dims.v * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1164,10 +1215,10 @@ 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 pref_size = box->desc.pref_size[axis];
|
UI_Size sem_dims = box->semantic_dims[axis];
|
||||||
if (pref_size.kind == UI_SizeKind_Grow)
|
if (sem_dims.kind == UI_SizeKind_Grow)
|
||||||
{
|
{
|
||||||
box->target_dims[axis] = box->parent->target_dims[axis] * pref_size.v;
|
box->solved_dims[axis] = box->parent->solved_dims[axis] * sem_dims.v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1178,7 +1229,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
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)
|
||||||
{
|
{
|
||||||
f32 box_size = box->target_dims[axis];
|
f32 box_size = box->solved_dims[axis];
|
||||||
// Solve non-floating violations
|
// Solve non-floating violations
|
||||||
{
|
{
|
||||||
f32 size_accum = 0;
|
f32 size_accum = 0;
|
||||||
@ -1187,8 +1238,8 @@ 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->target_dims[axis];
|
f32 size = child->solved_dims[axis];
|
||||||
f32 strictness = child->desc.pref_size[axis].strictness;
|
f32 strictness = child->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)
|
||||||
{
|
{
|
||||||
@ -1210,8 +1261,8 @@ 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->target_dims[axis];
|
f32 size = child->solved_dims[axis];
|
||||||
f32 strictness = child->desc.pref_size[axis].strictness;
|
f32 strictness = child->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)
|
||||||
@ -1227,7 +1278,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
adjusted_size_accum += new_size;
|
adjusted_size_accum += new_size;
|
||||||
child->target_dims[axis] = new_size;
|
child->solved_dims[axis] = new_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size_accum = adjusted_size_accum;
|
size_accum = adjusted_size_accum;
|
||||||
@ -1239,12 +1290,12 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
{
|
{
|
||||||
if (AnyBit(child->desc.flags, UI_BoxFlag_Floating) && !AnyBit(child->desc.flags, UI_BoxFlag_NoFloatingClamp))
|
if (AnyBit(child->desc.flags, UI_BoxFlag_Floating) && !AnyBit(child->desc.flags, UI_BoxFlag_NoFloatingClamp))
|
||||||
{
|
{
|
||||||
f32 size = child->target_dims[axis];
|
f32 size = child->solved_dims[axis];
|
||||||
if (size > box_size)
|
if (size > box_size)
|
||||||
{
|
{
|
||||||
f32 strictness = child->desc.pref_size[axis].strictness;
|
f32 strictness = child->semantic_dims[axis].strictness;
|
||||||
f32 flex = size * (1.0 - strictness);
|
f32 flex = size * (1.0 - strictness);
|
||||||
child->target_dims[axis] = MaxF32(size - flex, box_size);
|
child->solved_dims[axis] = MaxF32(size - flex, box_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1257,33 +1308,11 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
UI_Box *box = boxes_pre[pre_index];
|
UI_Box *box = boxes_pre[pre_index];
|
||||||
UI_Box *parent = box->parent;
|
UI_Box *parent = box->parent;
|
||||||
|
|
||||||
f32 lerp_rate = 20.0 * frame->dt;
|
|
||||||
if (box->gen != box->old_gen)
|
|
||||||
{
|
|
||||||
box->draw_dims[Axis_X] = 0;
|
|
||||||
box->draw_dims[Axis_Y] = 0;
|
|
||||||
}
|
|
||||||
if (box->desc.is_transient)
|
|
||||||
{
|
|
||||||
lerp_rate = 1;
|
|
||||||
}
|
|
||||||
lerp_rate = ClampF32(lerp_rate, 0, 1);
|
|
||||||
|
|
||||||
|
|
||||||
box->draw_dims[Axis_X] = LerpF32(box->draw_dims[Axis_X], box->target_dims[Axis_X], lerp_rate);
|
|
||||||
box->draw_dims[Axis_Y] = LerpF32(box->draw_dims[Axis_Y], box->target_dims[Axis_Y], lerp_rate);
|
|
||||||
|
|
||||||
Rng2 target_rect = Zi;
|
|
||||||
f32 target_rounding_tl = 0;
|
|
||||||
f32 target_rounding_tr = 0;
|
|
||||||
f32 target_rounding_br = 0;
|
|
||||||
f32 target_rounding_bl = 0;
|
|
||||||
|
|
||||||
// Initialize layout cursor based on alignment
|
// Initialize layout cursor based on alignment
|
||||||
{
|
{
|
||||||
Axis axis = box->desc.child_layout_axis;
|
Axis axis = box->desc.child_layout_axis;
|
||||||
UI_AxisAlignment alignment = box->desc.child_alignment[axis];
|
UI_AxisAlignment alignment = box->desc.child_alignment[axis];
|
||||||
f32 box_size = box->draw_dims[axis];
|
f32 box_size = box->solved_dims[axis];
|
||||||
f32 size_accum = box->final_children_size_accum[axis];
|
f32 size_accum = box->final_children_size_accum[axis];
|
||||||
switch(alignment)
|
switch(alignment)
|
||||||
{
|
{
|
||||||
@ -1301,7 +1330,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
|
|
||||||
// Position
|
// Position
|
||||||
{
|
{
|
||||||
f32 *dims_arr = box->draw_dims;
|
f32 *dims_arr = box->solved_dims;
|
||||||
Vec2 dims_vec = VEC2(dims_arr[0], dims_arr[1]);
|
Vec2 dims_vec = VEC2(dims_arr[0], dims_arr[1]);
|
||||||
Vec2 final_pos = Zi;
|
Vec2 final_pos = Zi;
|
||||||
|
|
||||||
@ -1309,16 +1338,16 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (AnyBit(box->desc.flags, UI_BoxFlag_Floating))
|
if (AnyBit(box->desc.flags, UI_BoxFlag_Floating))
|
||||||
{
|
{
|
||||||
Vec2 offset = box->desc.floating_pos;
|
Vec2 offset = box->desc.floating_pos;
|
||||||
final_pos = AddVec2(parent->draw_rect.p0, offset);
|
final_pos = AddVec2(parent->rect.p0, offset);
|
||||||
if (!AnyBit(box->desc.flags, UI_BoxFlag_NoFloatingClamp))
|
if (!AnyBit(box->desc.flags, UI_BoxFlag_NoFloatingClamp))
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
f32 overshoot = MaxF32(0, (final_pos.x + dims_vec.x) - parent->draw_rect.p1.x);
|
f32 overshoot = MaxF32(0, (final_pos.x + dims_vec.x) - parent->rect.p1.x);
|
||||||
final_pos.x = MaxF32(parent->draw_rect.p0.x, final_pos.x - overshoot);
|
final_pos.x = MaxF32(parent->rect.p0.x, final_pos.x - overshoot);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
f32 overshoot = MaxF32((final_pos.y + dims_vec.y) - parent->draw_rect.p1.y, 0);
|
f32 overshoot = MaxF32((final_pos.y + dims_vec.y) - parent->rect.p1.y, 0);
|
||||||
final_pos.y = MaxF32(parent->draw_rect.p0.y, final_pos.y - overshoot);
|
final_pos.y = MaxF32(parent->rect.p0.y, final_pos.y - overshoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1341,34 +1370,34 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
default: break;
|
default: break;
|
||||||
case UI_AxisAlignment_Center:
|
case UI_AxisAlignment_Center:
|
||||||
{
|
{
|
||||||
f32 parent_size = parent->draw_dims[axis];
|
f32 parent_size = parent->solved_dims[axis];
|
||||||
f32 box_size = dims_arr[axis];
|
f32 box_size = dims_arr[axis];
|
||||||
offset[axis] = parent_size / 2 - box_size / 2;
|
offset[axis] = parent_size / 2 - box_size / 2;
|
||||||
} break;
|
} break;
|
||||||
case UI_AxisAlignment_End:
|
case UI_AxisAlignment_End:
|
||||||
{
|
{
|
||||||
f32 parent_size = parent->draw_dims[axis];
|
f32 parent_size = parent->solved_dims[axis];
|
||||||
f32 box_size = dims_arr[axis];
|
f32 box_size = dims_arr[axis];
|
||||||
offset[axis] = parent_size - box_size;
|
offset[axis] = parent_size - box_size;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final_pos.x = parent->draw_rect.p0.x + offset[0];
|
final_pos.x = parent->rect.p0.x + offset[0];
|
||||||
final_pos.y = parent->draw_rect.p0.y + offset[1];
|
final_pos.y = parent->rect.p0.y + offset[1];
|
||||||
parent->cursor += dims_arr[parent->desc.child_layout_axis];
|
parent->cursor += dims_arr[parent->desc.child_layout_axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submit position
|
// Submit position
|
||||||
Vec2 rounded_final_pos = RoundVec2(final_pos);
|
Vec2 rounded_final_pos = RoundVec2(final_pos);
|
||||||
Vec2 rounded_dims = RoundVec2(dims_vec);
|
Vec2 rounded_dims = RoundVec2(dims_vec);
|
||||||
target_rect.p0 = FloorVec2(rounded_final_pos);
|
box->rect.p0 = FloorVec2(rounded_final_pos);
|
||||||
target_rect.p1 = AddVec2(rounded_final_pos, rounded_dims);
|
box->rect.p1 = AddVec2(rounded_final_pos, rounded_dims);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rounding
|
// Rounding
|
||||||
{
|
{
|
||||||
UI_Round rounding = box->desc.rounding;
|
UI_Round rounding = box->desc.rounding;
|
||||||
Vec2 half_dims = MulVec2(SubVec2(target_rect.p1, target_rect.p0), 0.5);
|
Vec2 half_dims = MulVec2(SubVec2(box->rect.p1, box->rect.p0), 0.5);
|
||||||
f32 min_half_dims = MinF32(half_dims.x, half_dims.y);
|
f32 min_half_dims = MinF32(half_dims.x, half_dims.y);
|
||||||
f32 final_rounding_tl = 0;
|
f32 final_rounding_tl = 0;
|
||||||
f32 final_rounding_tr = 0;
|
f32 final_rounding_tr = 0;
|
||||||
@ -1396,58 +1425,21 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
|
|
||||||
if (parent && !AllBits(box->desc.flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp))
|
if (parent && !AllBits(box->desc.flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp))
|
||||||
{
|
{
|
||||||
Vec2 vtl = SubVec2(VEC2(parent->draw_rect.p0.x, parent->draw_rect.p0.y), VEC2(target_rect.p0.x, target_rect.p0.y));
|
Vec2 vtl = SubVec2(VEC2(parent->rect.p0.x, parent->rect.p0.y), VEC2(box->rect.p0.x, box->rect.p0.y));
|
||||||
Vec2 vtr = SubVec2(VEC2(parent->draw_rect.p1.x, parent->draw_rect.p0.y), VEC2(target_rect.p1.x, target_rect.p0.y));
|
Vec2 vtr = SubVec2(VEC2(parent->rect.p1.x, parent->rect.p0.y), VEC2(box->rect.p1.x, box->rect.p0.y));
|
||||||
Vec2 vbr = SubVec2(VEC2(parent->draw_rect.p1.x, parent->draw_rect.p1.y), VEC2(target_rect.p1.x, target_rect.p1.y));
|
Vec2 vbr = SubVec2(VEC2(parent->rect.p1.x, parent->rect.p1.y), VEC2(box->rect.p1.x, box->rect.p1.y));
|
||||||
Vec2 vbl = SubVec2(VEC2(parent->draw_rect.p0.x, parent->draw_rect.p1.y), VEC2(target_rect.p0.x, target_rect.p1.y));
|
Vec2 vbl = SubVec2(VEC2(parent->rect.p0.x, parent->rect.p1.y), VEC2(box->rect.p0.x, box->rect.p1.y));
|
||||||
final_rounding_tl = MaxF32(final_rounding_tl, parent->draw_rounding_tl - Vec2Len(vtl));
|
final_rounding_tl = MaxF32(final_rounding_tl, parent->rounding_tl - Vec2Len(vtl));
|
||||||
final_rounding_tr = MaxF32(final_rounding_tr, parent->draw_rounding_tr - Vec2Len(vtr));
|
final_rounding_tr = MaxF32(final_rounding_tr, parent->rounding_tr - Vec2Len(vtr));
|
||||||
final_rounding_br = MaxF32(final_rounding_br, parent->draw_rounding_br - Vec2Len(vbr));
|
final_rounding_br = MaxF32(final_rounding_br, parent->rounding_br - Vec2Len(vbr));
|
||||||
final_rounding_bl = MaxF32(final_rounding_bl, parent->draw_rounding_bl - Vec2Len(vbl));
|
final_rounding_bl = MaxF32(final_rounding_bl, parent->rounding_bl - Vec2Len(vbl));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submit rounding
|
// Submit rounding
|
||||||
target_rounding_tl = final_rounding_tl;
|
box->rounding_tl = final_rounding_tl;
|
||||||
target_rounding_tr = final_rounding_tr;
|
box->rounding_tr = final_rounding_tr;
|
||||||
target_rounding_br = final_rounding_br;
|
box->rounding_br = final_rounding_br;
|
||||||
target_rounding_bl = final_rounding_bl;
|
box->rounding_bl = final_rounding_bl;
|
||||||
}
|
|
||||||
|
|
||||||
// Interpolate target into final rect
|
|
||||||
// {
|
|
||||||
// f32 lerp_rate = 30.0 * frame->dt;
|
|
||||||
// if (box->gen != box->old_gen)
|
|
||||||
// {
|
|
||||||
// lerp_rate = 1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// box->draw_rect.p0 = LerpVec2(box->draw_rect.p0, box->target_rect.p0, lerp_rate);
|
|
||||||
// box->draw_rect.p1 = LerpVec2(box->draw_rect.p1, box->target_rect.p1, lerp_rate);
|
|
||||||
// box->draw_rounding_tl = LerpF32(box->draw_rounding_tl, box->target_rounding_tl, lerp_rate);
|
|
||||||
// box->draw_rounding_tr = LerpF32(box->draw_rounding_tr, box->target_rounding_tr, lerp_rate);
|
|
||||||
// box->draw_rounding_br = LerpF32(box->draw_rounding_br, box->target_rounding_br, lerp_rate);
|
|
||||||
// box->draw_rounding_bl = LerpF32(box->draw_rounding_bl, box->target_rounding_bl, lerp_rate);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// {
|
|
||||||
// box->draw_rect.p0 = LerpVec2(box->draw_rect.p0, target_rect.p0, lerp_rate);
|
|
||||||
// box->draw_rect.p1 = LerpVec2(box->draw_rect.p1, target_rect.p1, lerp_rate);
|
|
||||||
// box->draw_rounding_tl = LerpF32(box->draw_rounding_tl, target_rounding_tl, lerp_rate);
|
|
||||||
// box->draw_rounding_tr = LerpF32(box->draw_rounding_tr, target_rounding_tr, lerp_rate);
|
|
||||||
// box->draw_rounding_br = LerpF32(box->draw_rounding_br, target_rounding_br, lerp_rate);
|
|
||||||
// box->draw_rounding_bl = LerpF32(box->draw_rounding_bl, target_rounding_bl, lerp_rate);
|
|
||||||
// }
|
|
||||||
|
|
||||||
{
|
|
||||||
box->draw_rect.p0 = target_rect.p0;
|
|
||||||
box->draw_rect.p1 = target_rect.p1;
|
|
||||||
box->draw_rounding_tl = target_rounding_tl;
|
|
||||||
box->draw_rounding_tr = target_rounding_tr;
|
|
||||||
box->draw_rounding_br = target_rounding_br;
|
|
||||||
box->draw_rounding_bl = target_rounding_bl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
box->gen = box->old_gen;
|
box->gen = box->old_gen;
|
||||||
@ -1467,24 +1459,24 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
UI_Box *box = boxes_pre[pre_index];
|
UI_Box *box = boxes_pre[pre_index];
|
||||||
b32 is_visible = 1;
|
b32 is_visible = 1;
|
||||||
is_visible = is_visible && (box->desc.tint.w != 0);
|
is_visible = is_visible && (box->desc.tint.w != 0);
|
||||||
is_visible = is_visible && (box->draw_rect.p1.x > box->draw_rect.p0.x);
|
is_visible = is_visible && (box->rect.p1.x > box->rect.p0.x);
|
||||||
is_visible = is_visible && (box->draw_rect.p1.y > box->draw_rect.p0.y);
|
is_visible = is_visible && (box->rect.p1.y > box->rect.p0.y);
|
||||||
if (is_visible || AnyBit(frame->frame_flags, UI_FrameFlag_Debug))
|
if (is_visible || AnyBit(frame->frame_flags, UI_FrameFlag_Debug))
|
||||||
{
|
{
|
||||||
|
|
||||||
// Box rect
|
// Box rect
|
||||||
{
|
{
|
||||||
UI_DRect *rect = PushStruct(frame->rects_arena, UI_DRect);
|
UI_DRect *rect = PushStruct(frame->rects_arena, UI_DRect);
|
||||||
rect->bounds = box->draw_rect;
|
rect->bounds = box->rect;
|
||||||
rect->background_lin = LinearFromSrgb(box->desc.background_color);
|
rect->background_lin = LinearFromSrgb(box->desc.background_color);
|
||||||
rect->border_lin = LinearFromSrgb(box->desc.border_color);
|
rect->border_lin = LinearFromSrgb(box->desc.border_color);
|
||||||
rect->debug_lin = LinearFromSrgb(box->desc.debug_color);
|
rect->debug_lin = LinearFromSrgb(box->desc.debug_color);
|
||||||
rect->tint_lin = LinearFromSrgb(box->desc.tint);
|
rect->tint_lin = LinearFromSrgb(box->desc.tint);
|
||||||
rect->border = box->desc.border;
|
rect->border = box->desc.border;
|
||||||
rect->tl_rounding = box->draw_rounding_tl;
|
rect->tl_rounding = box->rounding_tl;
|
||||||
rect->tr_rounding = box->draw_rounding_tr;
|
rect->tr_rounding = box->rounding_tr;
|
||||||
rect->br_rounding = box->draw_rounding_br;
|
rect->br_rounding = box->rounding_br;
|
||||||
rect->bl_rounding = box->draw_rounding_bl;
|
rect->bl_rounding = box->rounding_bl;
|
||||||
rect->tex = box->raw_texture;
|
rect->tex = box->raw_texture;
|
||||||
rect->tex_slice_uv = box->raw_texture_slice_uv;
|
rect->tex_slice_uv = box->raw_texture_slice_uv;
|
||||||
}
|
}
|
||||||
@ -1493,7 +1485,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
GC_Run raw_run = box->glyph_run;
|
GC_Run raw_run = box->glyph_run;
|
||||||
if (AnyBit(box->desc.flags, UI_BoxFlag_DrawText) && raw_run.ready)
|
if (AnyBit(box->desc.flags, UI_BoxFlag_DrawText) && raw_run.ready)
|
||||||
{
|
{
|
||||||
f32 max_baseline = DimsFromRng2(box->draw_rect).x;
|
f32 max_baseline = DimsFromRng2(box->rect).x;
|
||||||
b32 should_truncate = raw_run.baseline_length > max_baseline && !AnyBit(box->desc.flags, UI_BoxFlag_NoTextTruncation);
|
b32 should_truncate = raw_run.baseline_length > max_baseline && !AnyBit(box->desc.flags, UI_BoxFlag_NoTextTruncation);
|
||||||
|
|
||||||
// Truncate run
|
// Truncate run
|
||||||
@ -1549,22 +1541,22 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
f32 font_descent = raw_run.font_descent;
|
f32 font_descent = raw_run.font_descent;
|
||||||
f32 cap = raw_run.font_cap;
|
f32 cap = raw_run.font_cap;
|
||||||
f32 baseline_height = ascent + font_descent;
|
f32 baseline_height = ascent + font_descent;
|
||||||
Vec2 box_dims = DimsFromRng2(box->draw_rect);
|
Vec2 box_dims = DimsFromRng2(box->rect);
|
||||||
Vec2 baseline = Zi;
|
Vec2 baseline = Zi;
|
||||||
switch (x_alignment)
|
switch (x_alignment)
|
||||||
{
|
{
|
||||||
case UI_AxisAlignment_Start:
|
case UI_AxisAlignment_Start:
|
||||||
{
|
{
|
||||||
baseline.x = box->draw_rect.p0.x;
|
baseline.x = box->rect.p0.x;
|
||||||
} break;
|
} break;
|
||||||
case UI_AxisAlignment_End:
|
case UI_AxisAlignment_End:
|
||||||
{
|
{
|
||||||
baseline.x = box->draw_rect.p1.x;
|
baseline.x = box->rect.p1.x;
|
||||||
baseline.x -= final_baseline_length;
|
baseline.x -= final_baseline_length;
|
||||||
} break;
|
} break;
|
||||||
case UI_AxisAlignment_Center:
|
case UI_AxisAlignment_Center:
|
||||||
{
|
{
|
||||||
baseline.x = box->draw_rect.p0.x;
|
baseline.x = box->rect.p0.x;
|
||||||
baseline.x += (box_dims.x - final_baseline_length) / 2;
|
baseline.x += (box_dims.x - final_baseline_length) / 2;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -1572,17 +1564,17 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
{
|
{
|
||||||
case UI_AxisAlignment_Start:
|
case UI_AxisAlignment_Start:
|
||||||
{
|
{
|
||||||
baseline.y = box->draw_rect.p0.y;
|
baseline.y = box->rect.p0.y;
|
||||||
baseline.y += ascent;
|
baseline.y += ascent;
|
||||||
} break;
|
} break;
|
||||||
case UI_AxisAlignment_End:
|
case UI_AxisAlignment_End:
|
||||||
{
|
{
|
||||||
baseline.y = box->draw_rect.p1.y;
|
baseline.y = box->rect.p1.y;
|
||||||
baseline.y -= font_descent;
|
baseline.y -= font_descent;
|
||||||
} break;
|
} break;
|
||||||
case UI_AxisAlignment_Center:
|
case UI_AxisAlignment_Center:
|
||||||
{
|
{
|
||||||
baseline.y = box->draw_rect.p0.y;
|
baseline.y = box->rect.p0.y;
|
||||||
baseline.y += box_dims.y / 2;
|
baseline.y += box_dims.y / 2;
|
||||||
baseline.y += cap / 2;
|
baseline.y += cap / 2;
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@ -220,7 +220,7 @@ Struct(UI_BoxDesc)
|
|||||||
|
|
||||||
b32 is_transient;
|
b32 is_transient;
|
||||||
|
|
||||||
UI_Size pref_size[Axis_COUNTXY];
|
UI_Size pref_semantic_dims[Axis_COUNTXY];
|
||||||
UI_Round rounding;
|
UI_Round rounding;
|
||||||
Vec4 background_color;
|
Vec4 background_color;
|
||||||
Vec4 border_color;
|
Vec4 border_color;
|
||||||
@ -287,21 +287,21 @@ 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;
|
||||||
|
|
||||||
//- Layout data
|
//- Layout data
|
||||||
f32 cursor;
|
f32 cursor;
|
||||||
f32 final_children_size_accum[Axis_COUNTXY];
|
f32 final_children_size_accum[Axis_COUNTXY];
|
||||||
f32 target_dims[Axis_COUNTXY];
|
f32 solved_dims[Axis_COUNTXY];
|
||||||
f32 draw_dims[Axis_COUNTXY];
|
|
||||||
|
|
||||||
//- Layout results
|
//- Layout results
|
||||||
Rng2 draw_rect;
|
Rng2 rect;
|
||||||
f32 draw_rounding_tl;
|
f32 rounding_tl;
|
||||||
f32 draw_rounding_tr;
|
f32 rounding_tr;
|
||||||
f32 draw_rounding_br;
|
f32 rounding_br;
|
||||||
f32 draw_rounding_bl;
|
f32 rounding_bl;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(UI_BoxBin)
|
Struct(UI_BoxBin)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user