mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-22 19:54:59 -07:00
rewrite ui box -> signal path for less lossy event processing & correctness; also extend to use all 3 mouse buttons. eliminate ui signal bitfields, just use flags & helper macros everywhere.
This commit is contained in:
+15
-15
@@ -96,7 +96,7 @@ ui_hover_label(String8 string)
|
||||
{
|
||||
UI_Box *box = ui_build_box_from_string(UI_BoxFlag_Clickable|UI_BoxFlag_DrawText, string);
|
||||
UI_Signal interact = ui_signal_from_box(box);
|
||||
if(interact.hovering)
|
||||
if(ui_hovering(interact))
|
||||
{
|
||||
box->flags |= UI_BoxFlag_DrawBorder;
|
||||
}
|
||||
@@ -271,7 +271,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size,
|
||||
|
||||
//- rjf: interact
|
||||
UI_Signal sig = ui_signal_from_box(box);
|
||||
if(!is_focus_active && (sig.double_clicked || sig.keyboard_clicked))
|
||||
if(!is_focus_active && sig.f&(UI_SignalFlag_DoubleClicked|UI_SignalFlag_KeyboardPressed))
|
||||
{
|
||||
String8 edit_string = pre_edit_value;
|
||||
edit_string.size = Min(edit_buffer_size, pre_edit_value.size);
|
||||
@@ -282,14 +282,14 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size,
|
||||
*cursor = txt_pt(1, edit_string.size+1);
|
||||
*mark = txt_pt(1, 1);
|
||||
}
|
||||
if(is_focus_active && sig.keyboard_clicked)
|
||||
if(is_focus_active && sig.f&UI_SignalFlag_KeyboardPressed)
|
||||
{
|
||||
ui_set_auto_focus_active_key(ui_key_zero());
|
||||
sig.commit = 1;
|
||||
sig.f |= UI_SignalFlag_Commit;
|
||||
}
|
||||
if(is_focus_active && sig.dragging)
|
||||
if(is_focus_active && ui_dragging(sig))
|
||||
{
|
||||
if(sig.pressed)
|
||||
if(ui_pressed(sig))
|
||||
{
|
||||
*mark = mouse_pt;
|
||||
}
|
||||
@@ -565,7 +565,7 @@ ui_sat_val_picker(F32 hue, F32 *out_sat, F32 *out_val, String8 string)
|
||||
UI_Signal sig = ui_signal_from_box(box);
|
||||
|
||||
// rjf: click+draw behavior
|
||||
if(sig.dragging)
|
||||
if(ui_dragging(sig))
|
||||
{
|
||||
Vec2F32 dim = dim_2f32(box->rect);
|
||||
*out_sat = (ui_mouse().x - box->rect.x0) / dim.x;
|
||||
@@ -662,7 +662,7 @@ ui_hue_picker(F32 *out_hue, F32 sat, F32 val, String8 string)
|
||||
UI_Signal sig = ui_signal_from_box(box);
|
||||
|
||||
// rjf: click+draw behavior
|
||||
if(sig.dragging)
|
||||
if(ui_dragging(sig))
|
||||
{
|
||||
Vec2F32 dim = dim_2f32(box->rect);
|
||||
*out_hue = (ui_mouse().y - box->rect.y0) / dim.y;
|
||||
@@ -740,7 +740,7 @@ ui_alpha_picker(F32 *out_alpha, String8 string)
|
||||
UI_Signal sig = ui_signal_from_box(box);
|
||||
|
||||
// rjf: click+draw behavior
|
||||
if(sig.dragging)
|
||||
if(ui_dragging(sig))
|
||||
{
|
||||
Vec2F32 dim = dim_2f32(box->rect);
|
||||
F32 drag_pct = (ui_mouse().y - box->rect.y0) / dim.y;
|
||||
@@ -889,9 +889,9 @@ ui_table_begin(U64 column_pct_count, F32 **column_pcts, String8 string)
|
||||
|
||||
// rjf: boundary dragging
|
||||
UI_Signal interact = ui_signal_from_box(box);
|
||||
if(interact.dragging)
|
||||
if(ui_dragging(interact))
|
||||
{
|
||||
if(interact.pressed)
|
||||
if(ui_pressed(interact))
|
||||
{
|
||||
Vec2F32 v = v2f32(*left_pct_ptr, *right_pct_ptr);
|
||||
ui_store_drag_struct(&v);
|
||||
@@ -1228,9 +1228,9 @@ ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_ran
|
||||
UI_ScrollPt start_pt;
|
||||
F32 scroll_space_px;
|
||||
};
|
||||
if(scroller_sig.dragging)
|
||||
if(ui_dragging(scroller_sig))
|
||||
{
|
||||
if(scroller_sig.pressed)
|
||||
if(ui_pressed(scroller_sig))
|
||||
{
|
||||
UI_ScrollBarDragData drag_data = {pt, (floor_f32(dim_2f32(scroll_area_box->rect).v[axis])-floor_f32(dim_2f32(scroller_box->rect).v[axis]))};
|
||||
ui_store_drag_struct(&drag_data);
|
||||
@@ -1244,13 +1244,13 @@ ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_ran
|
||||
ui_scroll_pt_target_idx(&new_pt, new_idx);
|
||||
new_pt.off = 0;
|
||||
}
|
||||
if(min_scroll_sig.dragging || space_before_sig.dragging)
|
||||
if(ui_dragging(min_scroll_sig) || ui_dragging(space_before_sig))
|
||||
{
|
||||
S64 new_idx = new_pt.idx-1;
|
||||
new_idx = Clamp(idx_range.min, new_idx, idx_range.max);
|
||||
ui_scroll_pt_target_idx(&new_pt, new_idx);
|
||||
}
|
||||
if(max_scroll_sig.dragging || space_after_sig.dragging)
|
||||
if(ui_dragging(max_scroll_sig) || ui_dragging(space_after_sig))
|
||||
{
|
||||
S64 new_idx = new_pt.idx+1;
|
||||
new_idx = Clamp(idx_range.min, new_idx, idx_range.max);
|
||||
|
||||
+316
-8
@@ -1012,12 +1012,6 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: tick click timers
|
||||
for(Side side = (Side)0; side < Side_COUNT; side = (Side)(side + 1))
|
||||
{
|
||||
ui_state->time_since_last_click[side] += real_dt;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
@@ -2378,8 +2372,321 @@ internal UI_Signal
|
||||
ui_signal_from_box(UI_Box *box)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
UI_Signal result = {0};
|
||||
result.box = box;
|
||||
B32 is_focus_hot = box->flags & UI_BoxFlag_FocusHot && !(box->flags & UI_BoxFlag_FocusHotDisabled);
|
||||
UI_Signal sig = {box};
|
||||
sig.event_flags |= os_get_event_flags();
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: calculate possibly-clipped box rectangle
|
||||
//
|
||||
Rng2F32 rect = box->rect;
|
||||
for(UI_Box *b = box->parent; !ui_box_is_nil(b); b = b->parent)
|
||||
{
|
||||
if(b->flags & UI_BoxFlag_Clip)
|
||||
{
|
||||
rect = intersect_2f32(rect, b->rect);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: determine if we're under the context menu or not
|
||||
//
|
||||
B32 ctx_menu_is_ancestor = 0;
|
||||
ProfScope("check context menu ancestor")
|
||||
{
|
||||
for(UI_Box *parent = box; !ui_box_is_nil(parent); parent = parent->parent)
|
||||
{
|
||||
if(parent == ui_state->ctx_menu_root)
|
||||
{
|
||||
ctx_menu_is_ancestor = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: calculate blacklist rectangles
|
||||
//
|
||||
Rng2F32 blacklist_rect = {0};
|
||||
if(!ctx_menu_is_ancestor && ui_state->ctx_menu_open)
|
||||
{
|
||||
blacklist_rect = ui_state->ctx_menu_root->rect;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: process events related to this box
|
||||
//
|
||||
B32 view_scrolled = 0;
|
||||
for(OS_Event *evt = ui_state->events->first, *next = 0;
|
||||
evt != 0;
|
||||
evt = next)
|
||||
{
|
||||
B32 taken = 0;
|
||||
next = evt->next;
|
||||
|
||||
//- rjf: skip disqualified events
|
||||
if(!os_handle_match(evt->window, ui_state->window)) {continue;}
|
||||
|
||||
//- rjf: unpack event
|
||||
Vec2F32 evt_mouse = evt->pos;
|
||||
B32 evt_mouse_in_bounds = !contains_2f32(blacklist_rect, evt_mouse) && contains_2f32(rect, evt_mouse);
|
||||
UI_MouseButtonKind evt_mouse_button_kind = (evt->key == OS_Key_LeftMouseButton ? UI_MouseButtonKind_Left :
|
||||
evt->key == OS_Key_MiddleMouseButton ? UI_MouseButtonKind_Middle :
|
||||
evt->key == OS_Key_RightMouseButton ? UI_MouseButtonKind_Right :
|
||||
UI_MouseButtonKind_Left);
|
||||
B32 evt_key_is_mouse = (evt->key == OS_Key_LeftMouseButton ||
|
||||
evt->key == OS_Key_MiddleMouseButton ||
|
||||
evt->key == OS_Key_RightMouseButton);
|
||||
sig.event_flags |= evt->flags;
|
||||
|
||||
//- rjf: mouse presses in box -> set hot/active; mark signal accordingly
|
||||
if(box->flags & UI_BoxFlag_MouseClickable &&
|
||||
evt->kind == OS_EventKind_Press &&
|
||||
evt_mouse_in_bounds &&
|
||||
evt_key_is_mouse)
|
||||
{
|
||||
ui_state->hot_box_key = box->key;
|
||||
ui_state->active_box_key[evt_mouse_button_kind] = box->key;
|
||||
sig.f |= (UI_SignalFlag_LeftPressed<<evt_mouse_button_kind);
|
||||
ui_state->drag_start_mouse = evt->pos;
|
||||
if(ui_key_match(box->key, ui_state->last_press_key[evt_mouse_button_kind]) &&
|
||||
evt->timestamp_us-ui_state->last_press_timestamp_us[evt_mouse_button_kind] <= 1000000*os_double_click_time())
|
||||
{
|
||||
sig.f |= (UI_SignalFlag_LeftDoubleClicked<<evt_mouse_button_kind);
|
||||
}
|
||||
ui_state->last_press_key[evt_mouse_button_kind] = box->key;
|
||||
ui_state->last_press_timestamp_us[evt_mouse_button_kind] = evt->timestamp_us;
|
||||
taken = 1;
|
||||
}
|
||||
|
||||
//- rjf: mouse releases in active box -> unset active; mark signal accordingly
|
||||
if(box->flags & UI_BoxFlag_MouseClickable &&
|
||||
evt->kind == OS_EventKind_Release &&
|
||||
ui_key_match(ui_state->active_box_key[evt_mouse_button_kind], box->key) &&
|
||||
evt_mouse_in_bounds &&
|
||||
evt_key_is_mouse)
|
||||
{
|
||||
ui_state->active_box_key[evt_mouse_button_kind] = ui_key_zero();
|
||||
sig.f |= (UI_SignalFlag_LeftReleased<<evt_mouse_button_kind);
|
||||
sig.f |= (UI_SignalFlag_LeftClicked<<evt_mouse_button_kind);
|
||||
taken = 1;
|
||||
}
|
||||
|
||||
//- rjf: mouse releases outside active box -> unset hot/active
|
||||
if(box->flags & UI_BoxFlag_MouseClickable &&
|
||||
evt->kind == OS_EventKind_Release &&
|
||||
ui_key_match(ui_state->active_box_key[evt_mouse_button_kind], box->key) &&
|
||||
!evt_mouse_in_bounds &&
|
||||
evt_key_is_mouse)
|
||||
{
|
||||
ui_state->hot_box_key = ui_key_zero();
|
||||
ui_state->active_box_key[evt_mouse_button_kind] = ui_key_zero();
|
||||
sig.f |= (UI_SignalFlag_LeftReleased<<evt_mouse_button_kind);
|
||||
taken = 1;
|
||||
}
|
||||
|
||||
//- rjf: focus is hot & keyboard click -> mark signal
|
||||
if(box->flags & UI_BoxFlag_KeyboardClickable &&
|
||||
is_focus_hot &&
|
||||
evt->kind == OS_EventKind_Press &&
|
||||
evt->key == OS_Key_Return)
|
||||
{
|
||||
sig.f |= UI_SignalFlag_KeyboardPressed;
|
||||
taken = 1;
|
||||
}
|
||||
|
||||
//- rjf: scrolling
|
||||
if(box->flags & UI_BoxFlag_Scroll &&
|
||||
evt->kind == OS_EventKind_Scroll &&
|
||||
evt->flags != OS_EventFlag_Ctrl &&
|
||||
evt_mouse_in_bounds)
|
||||
{
|
||||
Vec2F32 delta = evt->delta;
|
||||
if(evt->flags & OS_EventFlag_Shift)
|
||||
{
|
||||
Swap(F32, delta.x, delta.y);
|
||||
}
|
||||
sig.scroll.x += (S16)(delta.x/30.f);
|
||||
sig.scroll.y += (S16)(delta.y/30.f);
|
||||
taken = 1;
|
||||
}
|
||||
|
||||
//- rjf: view scrolling
|
||||
if(box->flags & UI_BoxFlag_ViewScroll && box->first_touched_build_index != box->last_touched_build_index &&
|
||||
evt->kind == OS_EventKind_Scroll &&
|
||||
evt->flags != OS_EventFlag_Ctrl &&
|
||||
evt_mouse_in_bounds)
|
||||
{
|
||||
Vec2F32 delta = evt->delta;
|
||||
if(evt->flags & OS_EventFlag_Shift)
|
||||
{
|
||||
Swap(F32, delta.x, delta.y);
|
||||
}
|
||||
if(!(box->flags & UI_BoxFlag_ViewScrollX))
|
||||
{
|
||||
delta.x = 0;
|
||||
}
|
||||
if(!(box->flags & UI_BoxFlag_ViewScrollY))
|
||||
{
|
||||
delta.y = 0;
|
||||
}
|
||||
os_eat_event(ui_state->events, evt);
|
||||
box->view_off_target.x += delta.x;
|
||||
box->view_off_target.y += delta.y;
|
||||
view_scrolled = 1;
|
||||
taken = 1;
|
||||
}
|
||||
|
||||
//- rjf: taken -> eat event
|
||||
if(taken)
|
||||
{
|
||||
os_eat_event(ui_state->events, evt);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: process nav actions related to this box
|
||||
//
|
||||
{
|
||||
for(UI_NavActionNode *n = ui_state->nav_actions->first, *next = 0;
|
||||
n != 0;
|
||||
n = next)
|
||||
{
|
||||
next = n->next;
|
||||
UI_NavAction *action = &n->v;
|
||||
B32 taken = 0;
|
||||
if(is_focus_hot && box->flags & UI_BoxFlag_KeyboardClickable && action->flags & UI_NavActionFlag_Copy)
|
||||
{
|
||||
ui_state->clipboard_copy_key = box->key;
|
||||
taken = 1;
|
||||
}
|
||||
if(box->flags & UI_BoxFlag_Clickable && box->fastpath_codepoint != 0)
|
||||
{
|
||||
B32 ancestor_is_focused = 0;
|
||||
for(UI_Box *parent = box->parent; !ui_box_is_nil(parent); parent = parent->parent)
|
||||
{
|
||||
if(parent->flags & UI_BoxFlag_FocusActive)
|
||||
{
|
||||
ancestor_is_focused = 1;
|
||||
if(parent->flags & UI_BoxFlag_FocusActiveDisabled ||
|
||||
!ui_key_match(parent->default_nav_focus_active_key, ui_key_zero()))
|
||||
{
|
||||
ancestor_is_focused = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ancestor_is_focused && action->insertion.size != 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String32 insertion32 = str32_from_8(scratch.arena, action->insertion);
|
||||
if(insertion32.size == 1 && insertion32.str[0] == box->fastpath_codepoint)
|
||||
{
|
||||
taken = 1;
|
||||
sig.f |= UI_SignalFlag_Clicked|UI_SignalFlag_Pressed;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
if(taken)
|
||||
{
|
||||
ui_nav_eat_action_node(ui_nav_actions(), n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: clamp view scrolling
|
||||
//
|
||||
if(view_scrolled && box->flags & UI_BoxFlag_ViewClamp)
|
||||
{
|
||||
Vec2F32 max_view_off_target =
|
||||
{
|
||||
ClampBot(0, box->view_bounds.x - box->fixed_size.x),
|
||||
ClampBot(0, box->view_bounds.y - box->fixed_size.y),
|
||||
};
|
||||
if(box->flags & UI_BoxFlag_ViewClampX) { box->view_off_target.x = Clamp(0, box->view_off_target.x, max_view_off_target.x); }
|
||||
if(box->flags & UI_BoxFlag_ViewClampY) { box->view_off_target.y = Clamp(0, box->view_off_target.y, max_view_off_target.y); }
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: active -> dragging
|
||||
//
|
||||
for(EachEnumVal(UI_MouseButtonKind, k))
|
||||
{
|
||||
if(ui_key_match(ui_state->active_box_key[k], box->key))
|
||||
{
|
||||
sig.f |= (UI_SignalFlag_LeftDragging<<k);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: mouse is over this box's rect -> always mark mouse-over
|
||||
//
|
||||
{
|
||||
if(contains_2f32(rect, ui_state->mouse) &&
|
||||
!contains_2f32(blacklist_rect, ui_state->mouse))
|
||||
{
|
||||
sig.f |= UI_SignalFlag_MouseOver;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: mouse is over this box's rect, no other hot key? -> set hot key, mark hovering
|
||||
//
|
||||
{
|
||||
if(contains_2f32(rect, ui_state->mouse) &&
|
||||
!contains_2f32(blacklist_rect, ui_state->mouse) &&
|
||||
(ui_key_match(ui_state->hot_box_key, ui_key_zero()) || ui_key_match(ui_state->hot_box_key, box->key)) &&
|
||||
(ui_key_match(ui_state->active_box_key[UI_MouseButtonKind_Left], ui_key_zero()) || ui_key_match(ui_state->active_box_key[UI_MouseButtonKind_Left], box->key)) &&
|
||||
(ui_key_match(ui_state->active_box_key[UI_MouseButtonKind_Middle], ui_key_zero()) || ui_key_match(ui_state->active_box_key[UI_MouseButtonKind_Middle], box->key)) &&
|
||||
(ui_key_match(ui_state->active_box_key[UI_MouseButtonKind_Right], ui_key_zero()) || ui_key_match(ui_state->active_box_key[UI_MouseButtonKind_Right], box->key)))
|
||||
{
|
||||
ui_state->hot_box_key = box->key;
|
||||
sig.f |= UI_SignalFlag_Hovering;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: clicking on something outside the context menu kills the context menu
|
||||
//
|
||||
if(!ctx_menu_is_ancestor && sig.f & (UI_SignalFlag_LeftPressed|UI_SignalFlag_RightPressed|UI_SignalFlag_MiddlePressed))
|
||||
{
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: get default nav ancestor
|
||||
//
|
||||
UI_Box *default_nav_parent = &ui_g_nil_box;
|
||||
for(UI_Box *p = ui_top_parent(); !ui_box_is_nil(p); p = p->parent)
|
||||
{
|
||||
if(p->flags & UI_BoxFlag_DefaultFocusNav)
|
||||
{
|
||||
default_nav_parent = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: clicking in default nav -> set navigation state to this box
|
||||
//
|
||||
if(box->flags & UI_BoxFlag_ClickToFocus && sig.f&UI_SignalFlag_Pressed && !ui_box_is_nil(default_nav_parent))
|
||||
{
|
||||
default_nav_parent->default_nav_focus_next_hot_key = box->key;
|
||||
if(!ui_key_match(default_nav_parent->default_nav_focus_active_key, box->key))
|
||||
{
|
||||
default_nav_parent->default_nav_focus_next_active_key = ui_key_zero();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ProfEnd();
|
||||
return sig;
|
||||
|
||||
#if 0
|
||||
ProfBeginFunction();
|
||||
UI_Signal result = {box};
|
||||
result.event_flags = os_get_event_flags();
|
||||
B32 disabled = !!(box->flags & UI_BoxFlag_Disabled);
|
||||
B32 is_focused = !!(box->flags & UI_BoxFlag_FocusHot) && !(box->flags & UI_BoxFlag_FocusHotDisabled);
|
||||
@@ -2745,6 +3052,7 @@ ui_signal_from_box(UI_Box *box)
|
||||
|
||||
ProfEnd();
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
+67
-12
@@ -351,24 +351,79 @@ struct UI_BoxList
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef U32 UI_SignalFlags;
|
||||
enum
|
||||
{
|
||||
// rjf: mouse press -> box was pressed while hovering
|
||||
UI_SignalFlag_LeftPressed = (1<<0),
|
||||
UI_SignalFlag_MiddlePressed = (1<<1),
|
||||
UI_SignalFlag_RightPressed = (1<<2),
|
||||
|
||||
// rjf: dragging -> box was previously pressed, user is still holding button
|
||||
UI_SignalFlag_LeftDragging = (1<<3),
|
||||
UI_SignalFlag_MiddleDragging = (1<<4),
|
||||
UI_SignalFlag_RightDragging = (1<<5),
|
||||
|
||||
// rjf: released -> box was previously pressed & user released, in or out of bounds
|
||||
UI_SignalFlag_LeftReleased = (1<<6),
|
||||
UI_SignalFlag_MiddleReleased = (1<<7),
|
||||
UI_SignalFlag_RightReleased = (1<<8),
|
||||
|
||||
// rjf: clicked -> box was previously pressed & user released, in bounds
|
||||
UI_SignalFlag_LeftClicked = (1<<9),
|
||||
UI_SignalFlag_MiddleClicked = (1<<10),
|
||||
UI_SignalFlag_RightClicked = (1<<11),
|
||||
|
||||
// rjf: double clicked -> box was previously clicked, pressed again
|
||||
UI_SignalFlag_LeftDoubleClicked = (1<<12),
|
||||
UI_SignalFlag_MiddleDoubleClicked = (1<<13),
|
||||
UI_SignalFlag_RightDoubleClicked = (1<<14),
|
||||
|
||||
// rjf: triple clicked -> box was previously clicked twice, pressed again
|
||||
UI_SignalFlag_LeftTripleClicked = (1<<15),
|
||||
UI_SignalFlag_MiddleTripleClicked = (1<<16),
|
||||
UI_SignalFlag_RightTripleClicked = (1<<17),
|
||||
|
||||
// rjf: keyboard pressed -> box had focus, user activated via their keyboard
|
||||
UI_SignalFlag_KeyboardPressed = (1<<18),
|
||||
|
||||
// rjf: passive mouse info
|
||||
UI_SignalFlag_Hovering = (1<<19), // hovering specifically this box
|
||||
UI_SignalFlag_MouseOver = (1<<20), // mouse is over, but may be occluded
|
||||
|
||||
// rjf: committing state changes via user interaction
|
||||
UI_SignalFlag_Commit = (1<<21),
|
||||
|
||||
// rjf: high-level combos
|
||||
UI_SignalFlag_Pressed = UI_SignalFlag_LeftPressed|UI_SignalFlag_KeyboardPressed,
|
||||
UI_SignalFlag_Released = UI_SignalFlag_LeftReleased,
|
||||
UI_SignalFlag_Clicked = UI_SignalFlag_LeftClicked|UI_SignalFlag_KeyboardPressed,
|
||||
UI_SignalFlag_DoubleClicked = UI_SignalFlag_LeftDoubleClicked,
|
||||
UI_SignalFlag_TripleClicked = UI_SignalFlag_LeftTripleClicked,
|
||||
UI_SignalFlag_Dragging = UI_SignalFlag_LeftDragging,
|
||||
};
|
||||
|
||||
typedef struct UI_Signal UI_Signal;
|
||||
struct UI_Signal
|
||||
{
|
||||
UI_Box *box;
|
||||
OS_EventFlags event_flags;
|
||||
Vec2S16 scroll;
|
||||
B8 clicked :1;
|
||||
B8 keyboard_clicked :1;
|
||||
B8 double_clicked :1;
|
||||
B8 right_clicked :1;
|
||||
B8 pressed :1;
|
||||
B8 released :1;
|
||||
B8 dragging :1;
|
||||
B8 hovering :1;
|
||||
B8 mouse_over :1;
|
||||
B8 commit :1;
|
||||
UI_SignalFlags f;
|
||||
};
|
||||
|
||||
#define ui_pressed(s) !!((s).f&UI_SignalFlag_Pressed)
|
||||
#define ui_clicked(s) !!((s).f&UI_SignalFlag_Clicked)
|
||||
#define ui_released(s) !!((s).f&UI_SignalFlag_Released)
|
||||
#define ui_double_clicked(s) !!((s).f&UI_SignalFlag_DoubleClicked)
|
||||
#define ui_triple_clicked(s) !!((s).f&UI_SignalFlag_TripleClicked)
|
||||
#define ui_middle_clicked(s) !!((s).f&UI_SignalFlag_MiddleClicked)
|
||||
#define ui_right_clicked(s) !!((s).f&UI_SignalFlag_RightClicked)
|
||||
#define ui_dragging(s) !!((s).f&UI_SignalFlag_Dragging)
|
||||
#define ui_hovering(s) !!((s).f&UI_SignalFlag_Hovering)
|
||||
#define ui_mouse_over(s) !!((s).f&UI_SignalFlag_MouseOver)
|
||||
#define ui_committed(s) !!((s).f&UI_SignalFlag_Commit)
|
||||
|
||||
typedef struct UI_Nav UI_Nav;
|
||||
struct UI_Nav
|
||||
{
|
||||
@@ -429,8 +484,8 @@ struct UI_State
|
||||
UI_Key hot_box_key;
|
||||
UI_Key active_box_key[UI_MouseButtonKind_COUNT];
|
||||
UI_Key clipboard_copy_key;
|
||||
F32 time_since_last_click[UI_MouseButtonKind_COUNT];
|
||||
UI_Key last_click_key[UI_MouseButtonKind_COUNT];
|
||||
U64 last_press_timestamp_us[UI_MouseButtonKind_COUNT];
|
||||
UI_Key last_press_key[UI_MouseButtonKind_COUNT];
|
||||
Vec2F32 drag_start_mouse;
|
||||
Arena *drag_state_arena;
|
||||
String8 drag_state_data;
|
||||
|
||||
Reference in New Issue
Block a user