ui signals wip
This commit is contained in:
parent
246f63a61f
commit
d4bfdfcd4c
565
src/ui/ui_core.c
565
src/ui/ui_core.c
@ -528,6 +528,20 @@ void UI_SetRawTexture(UI_Key key, G_TextureRef tex, Rng2 uv)
|
|||||||
SllQueuePush(frame->first_cmd_node, frame->last_cmd_node, n);
|
SllQueuePush(frame->first_cmd_node, frame->last_cmd_node, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UI_ButtonState *UI_SignalButton(UI_Key key, Button button)
|
||||||
|
{
|
||||||
|
UI_Frame *frame = UI_CurrentFrame();
|
||||||
|
UI_CmdNode *n = PushStruct(frame->arena, UI_CmdNode);
|
||||||
|
n->cmd.kind = UI_CmdKind_Signal;
|
||||||
|
{
|
||||||
|
n->cmd.signal.key = key;
|
||||||
|
n->cmd.signal.button = button;
|
||||||
|
}
|
||||||
|
++frame->cmds_count;
|
||||||
|
SllQueuePush(frame->first_cmd_node, frame->last_cmd_node, n);
|
||||||
|
return &n->cmd.signal.button_state;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Report
|
//~ Report
|
||||||
|
|
||||||
@ -545,9 +559,16 @@ UI_BoxReports UI_ReportsFromKey(UI_Key key)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Begin frame
|
//~ Begin frame
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
|
UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
|
||||||
{
|
{
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Init persistent state
|
//- Init persistent state
|
||||||
|
|
||||||
@ -613,7 +634,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
|
|||||||
frame->frame_flags = frame_flags;
|
frame->frame_flags = frame_flags;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Process controller events
|
//- Process controller events into signals
|
||||||
|
|
||||||
frame->cursor_pos = prev_frame->cursor_pos;
|
frame->cursor_pos = prev_frame->cursor_pos;
|
||||||
frame->drag_cursor_pos = prev_frame->drag_cursor_pos;
|
frame->drag_cursor_pos = prev_frame->drag_cursor_pos;
|
||||||
@ -676,15 +697,13 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
|
|||||||
}
|
}
|
||||||
for (u64 button_idx = 0; button_idx < countof(report->buttons); ++button_idx)
|
for (u64 button_idx = 0; button_idx < countof(report->buttons); ++button_idx)
|
||||||
{
|
{
|
||||||
UI_ButtonReport *br = &report->buttons[button_idx];
|
UI_ButtonState *br = &report->buttons[button_idx];
|
||||||
b32 old_held = br->held;
|
b32 old_held = br->held;
|
||||||
{
|
{
|
||||||
ZeroStruct(br);
|
ZeroStruct(br);
|
||||||
}
|
}
|
||||||
br->held = old_held;
|
br->held = old_held;
|
||||||
}
|
}
|
||||||
box->reports.old_tree_capture = box->reports.tree_capture;
|
|
||||||
box->reports.tree_capture = UI_NilKey;
|
|
||||||
report->is_hot = 0;
|
report->is_hot = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,74 +829,110 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
|
|||||||
// hot_box->reports.tree_capture = hot_box->key;
|
// hot_box->reports.tree_capture = hot_box->key;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Update box reports
|
|
||||||
{
|
|
||||||
f32 lower_target = TweakFloat("UI lower blend target", -0.05, -1, 0);
|
|
||||||
f32 upper_target = TweakFloat("UI upper blend target", 1.05, 1, 10);
|
|
||||||
for (u64 pre_index = UI.boxes_count; pre_index-- > 0;)
|
|
||||||
{
|
|
||||||
UI_Box *box = prev_frame->boxes_pre[pre_index];
|
|
||||||
UI_BoxReport *report = &box->reports.draw;
|
|
||||||
UI_DebugBreak(box, UI_DebugBreakFlag_BuildReport);
|
|
||||||
|
|
||||||
if (box == hot_box)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//- Update reports from signals
|
||||||
|
for (UI_CmdNode *cmd_node = frame->first_cmd_node; cmd_node; cmd_node = cmd_node->next)
|
||||||
{
|
{
|
||||||
report->is_hot = 1;
|
UI_Cmd cmd = cmd_node->cmd;
|
||||||
box->reports.tree_capture = box->key;
|
if (cmd.kind == UI_CmdKind_Signal)
|
||||||
|
{
|
||||||
|
UI_Box *box = UI_BoxFromKey(cmd.signal.key);
|
||||||
|
if (box)
|
||||||
|
{
|
||||||
|
Button button = cmd.signal.button;
|
||||||
|
UI_ButtonState state = cmd.signal.button_state;
|
||||||
|
box->reports.draw.buttons[button] = state;
|
||||||
|
// Propagate button state upwards
|
||||||
|
for (UI_Box *parent = box->parent; parent; parent = parent->parent)
|
||||||
|
{
|
||||||
|
if (parent->desc.flags & UI_BoxFlag_CaptureThroughChildren)
|
||||||
|
{
|
||||||
|
parent->reports.draw.buttons[button] = state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!UI_MatchKey(box->reports.tree_capture, box->reports.old_tree_capture))
|
|
||||||
{
|
|
||||||
for (u64 button_idx = 0; button_idx < countof(report->buttons); ++button_idx)
|
|
||||||
{
|
|
||||||
UI_ButtonReport *button = &report->buttons[button_idx];
|
|
||||||
if (button->held)
|
|
||||||
{
|
|
||||||
button->held = 0;
|
|
||||||
button->ups += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 target_exists = (box->last_build_tick >= (frame->tick - 1)) ? upper_target : lower_target;
|
|
||||||
f32 target_hovered = report->is_hovered ? Inf : lower_target;
|
|
||||||
f32 target_hot = report->is_hot ? Inf : lower_target;
|
|
||||||
f32 target_active = box == active_box ? Inf : lower_target;
|
|
||||||
f64 target_misc = box->desc.misc;
|
|
||||||
|
|
||||||
// TODO: Configurable per-box blend rates
|
|
||||||
f32 exists_blend_rate = (30 * frame->dt);
|
|
||||||
f32 hot_blend_rate = (15 * frame->dt);
|
|
||||||
f32 active_blend_rate = (15 * frame->dt);
|
|
||||||
f32 hovered_blend_rate = (15 * frame->dt);
|
|
||||||
// f64 misc_blend_rate = (30 * frame->dt);
|
|
||||||
f64 misc_blend_rate = 1;
|
|
||||||
|
|
||||||
report->exists = SaturateF32(LerpF32(report->exists, target_exists, exists_blend_rate));
|
|
||||||
report->hot = SaturateF32(LerpF32(report->hot, target_hot, hot_blend_rate));
|
|
||||||
report->active = SaturateF32(LerpF32(report->active, target_active, active_blend_rate));
|
|
||||||
report->hovered = SaturateF32(LerpF32(report->hovered, target_hovered, hovered_blend_rate));
|
|
||||||
report->misc = SaturateF32(LerpF32(report->misc, target_misc, misc_blend_rate));
|
|
||||||
|
|
||||||
report->screen_rect = box->screen_rect;
|
|
||||||
report->screen_anchor = box->screen_anchor;
|
|
||||||
if (mouse_downs > 0)
|
|
||||||
{
|
|
||||||
box->reports.drag = *report;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Propagate upwards captures to tree
|
|
||||||
if (box->parent && !UI_IsKeyNil(box->reports.tree_capture))
|
|
||||||
{
|
|
||||||
box->parent->reports.tree_capture = box->reports.tree_capture;
|
//- Update box reports from inputs
|
||||||
UI_Box *captured_child = UI_BoxFromKey(box->reports.tree_capture);
|
// {
|
||||||
if (box->parent->desc.flags & UI_BoxFlag_CaptureThroughChildren)
|
// f32 lower_target = TweakFloat("UI lower blend target", -0.05, -1, 0);
|
||||||
{
|
// f32 upper_target = TweakFloat("UI upper blend target", 1.05, 1, 10);
|
||||||
box->parent->reports.draw = captured_child->reports.draw;
|
// for (u64 pre_index = UI.boxes_count; pre_index-- > 0;)
|
||||||
}
|
// {
|
||||||
}
|
// UI_Box *box = prev_frame->boxes_pre[pre_index];
|
||||||
}
|
// UI_BoxReport *report = &box->reports.draw;
|
||||||
}
|
// UI_DebugBreak(box, UI_DebugBreakFlag_BuildReport);
|
||||||
|
|
||||||
|
// if (box == hot_box)
|
||||||
|
// {
|
||||||
|
// report->is_hot = 1;
|
||||||
|
// box->reports.tree_capture = box->key;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // if (!UI_MatchKey(box->reports.tree_capture, box->reports.old_tree_capture))
|
||||||
|
// // {
|
||||||
|
// // for (u64 button_idx = 0; button_idx < countof(report->buttons); ++button_idx)
|
||||||
|
// // {
|
||||||
|
// // UI_ButtonState *button = &report->buttons[button_idx];
|
||||||
|
// // if (button->held)
|
||||||
|
// // {
|
||||||
|
// // button->held = 0;
|
||||||
|
// // button->ups += 1;
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// f32 target_exists = (box->last_build_tick >= (frame->tick - 1)) ? upper_target : lower_target;
|
||||||
|
// f32 target_hovered = report->is_hovered ? Inf : lower_target;
|
||||||
|
// f32 target_hot = report->is_hot ? Inf : lower_target;
|
||||||
|
// f32 target_active = box == active_box ? Inf : lower_target;
|
||||||
|
// f64 target_misc = box->desc.misc;
|
||||||
|
|
||||||
|
// // TODO: Configurable per-box blend rates
|
||||||
|
// f32 exists_blend_rate = (30 * frame->dt);
|
||||||
|
// f32 hot_blend_rate = (15 * frame->dt);
|
||||||
|
// f32 active_blend_rate = (15 * frame->dt);
|
||||||
|
// f32 hovered_blend_rate = (15 * frame->dt);
|
||||||
|
// // f64 misc_blend_rate = (30 * frame->dt);
|
||||||
|
// f64 misc_blend_rate = 1;
|
||||||
|
|
||||||
|
// report->exists = SaturateF32(LerpF32(report->exists, target_exists, exists_blend_rate));
|
||||||
|
// report->hot = SaturateF32(LerpF32(report->hot, target_hot, hot_blend_rate));
|
||||||
|
// report->active = SaturateF32(LerpF32(report->active, target_active, active_blend_rate));
|
||||||
|
// report->hovered = SaturateF32(LerpF32(report->hovered, target_hovered, hovered_blend_rate));
|
||||||
|
// report->misc = SaturateF32(LerpF32(report->misc, target_misc, misc_blend_rate));
|
||||||
|
|
||||||
|
// report->screen_rect = box->screen_rect;
|
||||||
|
// report->screen_anchor = box->screen_anchor;
|
||||||
|
// if (mouse_downs > 0)
|
||||||
|
// {
|
||||||
|
// box->reports.drag = *report;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Propagate upwards captures to tree
|
||||||
|
// if (box->parent && !UI_IsKeyNil(box->reports.tree_capture))
|
||||||
|
// {
|
||||||
|
// box->parent->reports.tree_capture = box->reports.tree_capture;
|
||||||
|
// UI_Box *captured_child = UI_BoxFromKey(box->reports.tree_capture);
|
||||||
|
// if (box->parent->desc.flags & UI_BoxFlag_CaptureThroughChildren)
|
||||||
|
// {
|
||||||
|
// box->parent->reports.draw.captures = captured_child->reports.draw.captures;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if (mouse_downs > 0)
|
if (mouse_downs > 0)
|
||||||
{
|
{
|
||||||
@ -902,6 +957,392 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
|
||||||
|
// {
|
||||||
|
// //////////////////////////////
|
||||||
|
// //- Init persistent state
|
||||||
|
|
||||||
|
// if (!UI.box_arena)
|
||||||
|
// {
|
||||||
|
// UI.box_arena = AcquireArena(Gibi(64));
|
||||||
|
// UI.gpu_frame_arena = G_AcquireArena();
|
||||||
|
// // Init frames
|
||||||
|
// for (u64 i = 0; i < countof(UI.frames); ++i)
|
||||||
|
// {
|
||||||
|
// UI_Frame *frame = &UI.frames[i];
|
||||||
|
// frame->arena = AcquireArena(Gibi(64));
|
||||||
|
// frame->rects_arena = AcquireArena(Gibi(64));
|
||||||
|
// }
|
||||||
|
// // Init root box
|
||||||
|
// {
|
||||||
|
// UI_Box *box = PushStruct(UI.box_arena, UI_Box);
|
||||||
|
// box->key = UI_RootKey;
|
||||||
|
// box->gen = 1;
|
||||||
|
// UI.boxes_count += 1;
|
||||||
|
// UI_BoxBin *bin = &UI.box_bins[box->key.v % countof(UI.box_bins)];
|
||||||
|
// bin->first = box;
|
||||||
|
// bin->last = box;
|
||||||
|
// UI.root_box = box;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //////////////////////////////
|
||||||
|
// //- Begin frame
|
||||||
|
|
||||||
|
// UI.cur_frame_tick += 1;
|
||||||
|
// UI_Frame *prev_frame = UI_PrevFrame();
|
||||||
|
// UI_Frame *frame = UI_CurrentFrame();
|
||||||
|
|
||||||
|
// {
|
||||||
|
// Arena *old_arena = frame->arena;
|
||||||
|
// Arena *old_rects_arena = frame->rects_arena;
|
||||||
|
// ZeroStruct(frame);
|
||||||
|
// frame->arena = old_arena;
|
||||||
|
// frame->rects_arena = old_rects_arena;
|
||||||
|
// }
|
||||||
|
// frame->window_frame = WND_BeginFrame(G_Format_R16G16B16A16_Float, WND_BackbufferSizeMode_MatchMonitor);
|
||||||
|
// UI.cl = G_PrepareCommandList(G_QueueKind_Direct);
|
||||||
|
// ResetArena(frame->arena);
|
||||||
|
// ResetArena(frame->rects_arena);
|
||||||
|
// G_ResetArena(UI.cl, UI.gpu_frame_arena);
|
||||||
|
|
||||||
|
// {
|
||||||
|
// i64 now_ns = TimeNs();
|
||||||
|
// i64 dt_ns = now_ns - prev_frame->time_ns;
|
||||||
|
// frame->time_ns = now_ns;
|
||||||
|
// frame->dt_ns = dt_ns;
|
||||||
|
// frame->dt = SecondsFromNs(frame->dt_ns);
|
||||||
|
// frame->tick = UI.cur_frame_tick;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Init style stack
|
||||||
|
// {
|
||||||
|
// frame->top_stack = PushStruct(frame->arena, UI_Stack);
|
||||||
|
// UI_PushDefaults();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// frame->frame_flags = frame_flags;
|
||||||
|
|
||||||
|
// //////////////////////////////
|
||||||
|
// //- Process controller events
|
||||||
|
|
||||||
|
// frame->cursor_pos = prev_frame->cursor_pos;
|
||||||
|
// frame->drag_cursor_pos = prev_frame->drag_cursor_pos;
|
||||||
|
|
||||||
|
// if (prev_frame->boxes_pre != 0)
|
||||||
|
// {
|
||||||
|
// ControllerEventsArray controller_events = frame->window_frame.controller_events;
|
||||||
|
|
||||||
|
// //- Locate boxes
|
||||||
|
// UI_Box *top_hovered_box = 0;
|
||||||
|
// UI_Box *active_box = UI_BoxFromKey(prev_frame->active_box);
|
||||||
|
|
||||||
|
// //- Update cursor pos
|
||||||
|
// for (u64 cev_index = 0; cev_index < controller_events.count; ++cev_index)
|
||||||
|
// {
|
||||||
|
// ControllerEvent *cev = &controller_events.events[cev_index];
|
||||||
|
// if (cev->kind == ControllerEventKind_CursorMove)
|
||||||
|
// {
|
||||||
|
// frame->cursor_pos = Vec2FromVec(cev->cursor_pos);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //- Init box reports
|
||||||
|
// // TODO: Iterate in post order and early out
|
||||||
|
// for (u64 pre_index = UI.boxes_count; pre_index-- > 0;)
|
||||||
|
// {
|
||||||
|
// UI_Box *box = prev_frame->boxes_pre[pre_index];
|
||||||
|
// UI_BoxReport *report = &box->reports.draw;
|
||||||
|
// b32 is_cursor_in_box = 0;
|
||||||
|
// {
|
||||||
|
// // TODO: More efficient test. This logic is just copied from the renderer's SDF function for now.
|
||||||
|
// Rng2 interactable_region = IntersectRng2(box->solved_scissor, box->screen_rect);
|
||||||
|
// Vec2 p0 = interactable_region.p0;
|
||||||
|
// Vec2 p1 = interactable_region.p1;
|
||||||
|
// Vec2 point = frame->cursor_pos;
|
||||||
|
// 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 corner_edge_dist = non_corner_edge_dist;
|
||||||
|
// if (non_corner_edge_dist >= 0)
|
||||||
|
// {
|
||||||
|
// f32 tl_radius = box->rounding_tl;
|
||||||
|
// f32 tr_radius = box->rounding_tr;
|
||||||
|
// f32 br_radius = box->rounding_br;
|
||||||
|
// f32 bl_radius = box->rounding_bl;
|
||||||
|
// Vec2 tl = VEC2(p0.x + tl_radius, p0.y + tl_radius);
|
||||||
|
// Vec2 tr = VEC2(p1.x - tr_radius, p0.y + tr_radius);
|
||||||
|
// Vec2 br = VEC2(p1.x - br_radius, p1.y - br_radius);
|
||||||
|
// Vec2 bl = VEC2(p0.x + bl_radius, p1.y - bl_radius);
|
||||||
|
// if (point.x < tl.x && point.y < tl.y) corner_edge_dist = MinF32(corner_edge_dist, tl_radius - Vec2Len(SubVec2(tl, point)));
|
||||||
|
// if (point.x > tr.x && point.y < tr.y) corner_edge_dist = MinF32(corner_edge_dist, tr_radius - Vec2Len(SubVec2(tr, point)));
|
||||||
|
// if (point.x > br.x && point.y > br.y) corner_edge_dist = MinF32(corner_edge_dist, br_radius - Vec2Len(SubVec2(br, point)));
|
||||||
|
// if (point.x < bl.x && point.y > bl.y) corner_edge_dist = MinF32(corner_edge_dist, bl_radius - Vec2Len(SubVec2(bl, point)));
|
||||||
|
// }
|
||||||
|
// is_cursor_in_box = non_corner_edge_dist >= 0 && corner_edge_dist >= 0;
|
||||||
|
// }
|
||||||
|
// report->is_hovered = is_cursor_in_box;
|
||||||
|
// if (top_hovered_box == 0 && (box->desc.flags & UI_BoxFlag_CaptureMouse) && is_cursor_in_box)
|
||||||
|
// {
|
||||||
|
// top_hovered_box = box;
|
||||||
|
// }
|
||||||
|
// for (u64 button_idx = 0; button_idx < countof(report->buttons); ++button_idx)
|
||||||
|
// {
|
||||||
|
// UI_ButtonState *br = &report->buttons[button_idx];
|
||||||
|
// b32 old_held = br->held;
|
||||||
|
// {
|
||||||
|
// ZeroStruct(br);
|
||||||
|
// }
|
||||||
|
// br->held = old_held;
|
||||||
|
// }
|
||||||
|
// box->reports.old_tree_capture = box->reports.tree_capture;
|
||||||
|
// box->reports.tree_capture = UI_NilKey;
|
||||||
|
// report->is_hot = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //- Update state from controller events
|
||||||
|
// i32 mouse_downs = 0;
|
||||||
|
// for (u64 cev_index = 0; cev_index < controller_events.count; ++cev_index)
|
||||||
|
// {
|
||||||
|
// ControllerEvent *cev = &controller_events.events[cev_index];
|
||||||
|
// switch (cev->kind)
|
||||||
|
// {
|
||||||
|
// default: break;
|
||||||
|
|
||||||
|
// case ControllerEventKind_ButtonDown:
|
||||||
|
// {
|
||||||
|
// if (IsClickButton(cev->button) || IsWheelButton(cev->button))
|
||||||
|
// {
|
||||||
|
// mouse_downs += 1;
|
||||||
|
// if (top_hovered_box && active_box == 0)
|
||||||
|
// {
|
||||||
|
// if (cev->button == Button_M1)
|
||||||
|
// {
|
||||||
|
// ++top_hovered_box->reports.draw.buttons[Button_M1].downs;
|
||||||
|
// top_hovered_box->reports.draw.buttons[Button_M1].held = 1;
|
||||||
|
// active_box = top_hovered_box;
|
||||||
|
// }
|
||||||
|
// else if (cev->button == Button_M2)
|
||||||
|
// {
|
||||||
|
// ++top_hovered_box->reports.draw.buttons[Button_M2].downs;
|
||||||
|
// top_hovered_box->reports.draw.buttons[Button_M2].held = 1;
|
||||||
|
// active_box = top_hovered_box;
|
||||||
|
// }
|
||||||
|
// else if (cev->button == Button_M3)
|
||||||
|
// {
|
||||||
|
// ++top_hovered_box->reports.draw.buttons[Button_M3].downs;
|
||||||
|
// top_hovered_box->reports.draw.buttons[Button_M3].held = 1;
|
||||||
|
// active_box = top_hovered_box;
|
||||||
|
// }
|
||||||
|
// else if (cev->button == Button_WheelUp)
|
||||||
|
// {
|
||||||
|
// ++top_hovered_box->reports.draw.buttons[Button_WheelUp].downs;
|
||||||
|
// ++top_hovered_box->reports.draw.buttons[Button_WheelUp].ups;
|
||||||
|
// ++top_hovered_box->reports.draw.buttons[Button_WheelUp].presses;
|
||||||
|
// }
|
||||||
|
// else if (cev->button == Button_WheelDown)
|
||||||
|
// {
|
||||||
|
// ++top_hovered_box->reports.draw.buttons[Button_WheelDown].downs;
|
||||||
|
// ++top_hovered_box->reports.draw.buttons[Button_WheelDown].ups;
|
||||||
|
// ++top_hovered_box->reports.draw.buttons[Button_WheelDown].presses;
|
||||||
|
// }
|
||||||
|
// cev->captures += 1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } break;
|
||||||
|
|
||||||
|
// case ControllerEventKind_ButtonUp:
|
||||||
|
// {
|
||||||
|
// if (IsClickButton(cev->button))
|
||||||
|
// {
|
||||||
|
// if (active_box)
|
||||||
|
// {
|
||||||
|
// if (cev->button == Button_M1)
|
||||||
|
// {
|
||||||
|
// if (active_box == top_hovered_box)
|
||||||
|
// {
|
||||||
|
// ++active_box->reports.draw.buttons[Button_M1].presses;
|
||||||
|
// }
|
||||||
|
// ++active_box->reports.draw.buttons[Button_M1].ups;
|
||||||
|
// if (active_box->reports.draw.buttons[Button_M1].held)
|
||||||
|
// {
|
||||||
|
// active_box->reports.draw.buttons[Button_M1].held = 0;
|
||||||
|
// active_box = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if (cev->button == Button_M2)
|
||||||
|
// {
|
||||||
|
// if (active_box == top_hovered_box)
|
||||||
|
// {
|
||||||
|
// ++active_box->reports.draw.buttons[Button_M2].presses;
|
||||||
|
// }
|
||||||
|
// ++active_box->reports.draw.buttons[Button_M2].ups;
|
||||||
|
// if (active_box->reports.draw.buttons[Button_M2].held)
|
||||||
|
// {
|
||||||
|
// active_box->reports.draw.buttons[Button_M2].held = 0;
|
||||||
|
// active_box = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if (cev->button == Button_M3)
|
||||||
|
// {
|
||||||
|
// if (active_box == top_hovered_box)
|
||||||
|
// {
|
||||||
|
// ++active_box->reports.draw.buttons[Button_M3].presses;
|
||||||
|
// }
|
||||||
|
// ++active_box->reports.draw.buttons[Button_M3].ups;
|
||||||
|
// if (active_box->reports.draw.buttons[Button_M3].held)
|
||||||
|
// {
|
||||||
|
// active_box->reports.draw.buttons[Button_M3].held = 0;
|
||||||
|
// active_box = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if (IsWheelButton(cev->button) && top_hovered_box)
|
||||||
|
// {
|
||||||
|
// cev->captures += 1;
|
||||||
|
// }
|
||||||
|
// } break;
|
||||||
|
|
||||||
|
// case ControllerEventKind_Quit:
|
||||||
|
// {
|
||||||
|
// SignalExit(0);
|
||||||
|
// } break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// UI_Box *hot_box = active_box;
|
||||||
|
// if (top_hovered_box && !active_box)
|
||||||
|
// {
|
||||||
|
// hot_box = top_hovered_box;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (hot_box)
|
||||||
|
// {
|
||||||
|
// // hot_box->reports.tree_capture = hot_box->key;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //- Update box reports from captures
|
||||||
|
// {
|
||||||
|
// f32 lower_target = TweakFloat("UI lower blend target", -0.05, -1, 0);
|
||||||
|
// f32 upper_target = TweakFloat("UI upper blend target", 1.05, 1, 10);
|
||||||
|
// for (u64 pre_index = UI.boxes_count; pre_index-- > 0;)
|
||||||
|
// {
|
||||||
|
// UI_Box *box = prev_frame->boxes_pre[pre_index];
|
||||||
|
// UI_BoxReport *report = &box->reports.draw;
|
||||||
|
// UI_DebugBreak(box, UI_DebugBreakFlag_BuildReport);
|
||||||
|
|
||||||
|
// if (box == hot_box)
|
||||||
|
// {
|
||||||
|
// report->is_hot = 1;
|
||||||
|
// box->reports.tree_capture = box->key;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // if (!UI_MatchKey(box->reports.tree_capture, box->reports.old_tree_capture))
|
||||||
|
// // {
|
||||||
|
// // for (u64 button_idx = 0; button_idx < countof(report->buttons); ++button_idx)
|
||||||
|
// // {
|
||||||
|
// // UI_ButtonState *button = &report->buttons[button_idx];
|
||||||
|
// // if (button->held)
|
||||||
|
// // {
|
||||||
|
// // button->held = 0;
|
||||||
|
// // button->ups += 1;
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// f32 target_exists = (box->last_build_tick >= (frame->tick - 1)) ? upper_target : lower_target;
|
||||||
|
// f32 target_hovered = report->is_hovered ? Inf : lower_target;
|
||||||
|
// f32 target_hot = report->is_hot ? Inf : lower_target;
|
||||||
|
// f32 target_active = box == active_box ? Inf : lower_target;
|
||||||
|
// f64 target_misc = box->desc.misc;
|
||||||
|
|
||||||
|
// // TODO: Configurable per-box blend rates
|
||||||
|
// f32 exists_blend_rate = (30 * frame->dt);
|
||||||
|
// f32 hot_blend_rate = (15 * frame->dt);
|
||||||
|
// f32 active_blend_rate = (15 * frame->dt);
|
||||||
|
// f32 hovered_blend_rate = (15 * frame->dt);
|
||||||
|
// // f64 misc_blend_rate = (30 * frame->dt);
|
||||||
|
// f64 misc_blend_rate = 1;
|
||||||
|
|
||||||
|
// report->exists = SaturateF32(LerpF32(report->exists, target_exists, exists_blend_rate));
|
||||||
|
// report->hot = SaturateF32(LerpF32(report->hot, target_hot, hot_blend_rate));
|
||||||
|
// report->active = SaturateF32(LerpF32(report->active, target_active, active_blend_rate));
|
||||||
|
// report->hovered = SaturateF32(LerpF32(report->hovered, target_hovered, hovered_blend_rate));
|
||||||
|
// report->misc = SaturateF32(LerpF32(report->misc, target_misc, misc_blend_rate));
|
||||||
|
|
||||||
|
// report->screen_rect = box->screen_rect;
|
||||||
|
// report->screen_anchor = box->screen_anchor;
|
||||||
|
// if (mouse_downs > 0)
|
||||||
|
// {
|
||||||
|
// box->reports.drag = *report;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Propagate upwards captures to tree
|
||||||
|
// if (box->parent && !UI_IsKeyNil(box->reports.tree_capture))
|
||||||
|
// {
|
||||||
|
// box->parent->reports.tree_capture = box->reports.tree_capture;
|
||||||
|
// UI_Box *captured_child = UI_BoxFromKey(box->reports.tree_capture);
|
||||||
|
// if (box->parent->desc.flags & UI_BoxFlag_CaptureThroughChildren)
|
||||||
|
// {
|
||||||
|
// box->parent->reports.draw.captures = captured_child->reports.draw.captures;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (mouse_downs > 0)
|
||||||
|
// {
|
||||||
|
// frame->drag_cursor_pos = frame->cursor_pos;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// frame->top_hovered_box = top_hovered_box ? top_hovered_box->key : UI_NilKey;
|
||||||
|
// frame->hot_box = hot_box ? hot_box->key : UI_NilKey;
|
||||||
|
// frame->active_box = active_box ? active_box->key : UI_NilKey;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //////////////////////////////
|
||||||
|
// //- Build root box
|
||||||
|
|
||||||
|
// {
|
||||||
|
// UI_SetNext(Width, UI_PIX(frame->window_frame.draw_size.x, 1));
|
||||||
|
// UI_SetNext(Height, UI_PIX(frame->window_frame.draw_size.y, 1));
|
||||||
|
// UI_SetNext(Parent, UI_NilKey);
|
||||||
|
// UI_BuildBoxEx(UI_RootKey);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return frame;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Frame helpers
|
//~ Frame helpers
|
||||||
|
|
||||||
|
|||||||
@ -209,9 +209,9 @@ Struct(UI_Stack)
|
|||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Report types
|
//~ Input types
|
||||||
|
|
||||||
Struct(UI_ButtonReport)
|
Struct(UI_ButtonState)
|
||||||
{
|
{
|
||||||
b32 held; // Persistent
|
b32 held; // Persistent
|
||||||
i32 downs; // Mouse button down events over box causing activation
|
i32 downs; // Mouse button down events over box causing activation
|
||||||
@ -219,11 +219,14 @@ Struct(UI_ButtonReport)
|
|||||||
i32 presses; // Mouse button events while box is active and hovered
|
i32 presses; // Mouse button events while box is active and hovered
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Report types
|
||||||
|
|
||||||
Struct(UI_CapturesReport)
|
Struct(UI_CapturesReport)
|
||||||
{
|
{
|
||||||
b32 is_hovered;
|
b32 is_hovered;
|
||||||
b32 is_hot;
|
b32 is_hot;
|
||||||
UI_ButtonReport buttons[Button_COUNT];
|
UI_ButtonState buttons[Button_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(UI_BoxReport)
|
Struct(UI_BoxReport)
|
||||||
@ -242,8 +245,6 @@ Struct(UI_BoxReports)
|
|||||||
{
|
{
|
||||||
UI_BoxReport draw; // Box data used for last render
|
UI_BoxReport draw; // Box data used for last render
|
||||||
UI_BoxReport drag; // Box data during last mouse button down event
|
UI_BoxReport drag; // Box data during last mouse button down event
|
||||||
UI_Key tree_capture; // Key of captured child (if any)
|
|
||||||
UI_Key old_tree_capture;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -253,6 +254,7 @@ Enum(UI_CmdKind)
|
|||||||
{
|
{
|
||||||
UI_CmdKind_None,
|
UI_CmdKind_None,
|
||||||
UI_CmdKind_BuildBox,
|
UI_CmdKind_BuildBox,
|
||||||
|
UI_CmdKind_Signal,
|
||||||
UI_CmdKind_SetRawTexture,
|
UI_CmdKind_SetRawTexture,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -297,6 +299,12 @@ Struct(UI_Cmd)
|
|||||||
{
|
{
|
||||||
UI_BoxDesc box;
|
UI_BoxDesc box;
|
||||||
struct
|
struct
|
||||||
|
{
|
||||||
|
UI_Key key;
|
||||||
|
Button button;
|
||||||
|
UI_ButtonState button_state;
|
||||||
|
} signal;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
UI_Key key;
|
UI_Key key;
|
||||||
G_TextureRef tex;
|
G_TextureRef tex;
|
||||||
@ -544,6 +552,7 @@ UI_Key UI_BuildBoxEx(UI_Key semantic_key);
|
|||||||
#define UI_BuildBox() UI_BuildBoxEx(UI_NilKey)
|
#define UI_BuildBox() UI_BuildBoxEx(UI_NilKey)
|
||||||
|
|
||||||
void UI_SetRawTexture(UI_Key key, G_TextureRef tex, Rng2 uv);
|
void UI_SetRawTexture(UI_Key key, G_TextureRef tex, Rng2 uv);
|
||||||
|
UI_ButtonState *UI_SignalButton(UI_Key key, Button button);
|
||||||
|
|
||||||
#if IsRtcEnabled
|
#if IsRtcEnabled
|
||||||
#define UI_DebugBreak(box, target_flags) do { if (box->desc.debug_break_flags & target_flags) { DEBUGBREAK; } } while (0)
|
#define UI_DebugBreak(box, target_flags) do { if (box->desc.debug_break_flags & target_flags) { DEBUGBREAK; } } while (0)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user