2024-03-08 15:45:27 -08:00
|
|
|
package sectr
|
|
|
|
|
2024-05-09 23:08:36 -07:00
|
|
|
UI_Signal :: struct {
|
|
|
|
cursor_pos : Vec2,
|
|
|
|
drag_delta : Vec2,
|
|
|
|
scroll : Vec2,
|
|
|
|
|
|
|
|
left_clicked : b8,
|
|
|
|
right_clicked : b8,
|
|
|
|
double_clicked : b8,
|
|
|
|
keyboard_clicked : b8,
|
|
|
|
|
|
|
|
active : b8,
|
|
|
|
was_active : b8,
|
|
|
|
|
|
|
|
pressed : b8,
|
|
|
|
released : b8,
|
|
|
|
cursor_over : b8,
|
|
|
|
commit : b8,
|
|
|
|
}
|
2024-03-19 09:18:39 -07:00
|
|
|
|
2024-03-08 15:45:27 -08:00
|
|
|
ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
|
|
|
|
{
|
2024-03-10 23:05:18 -07:00
|
|
|
// profile(#procedure)
|
2024-03-08 15:45:27 -08:00
|
|
|
ui := get_state().ui_context
|
|
|
|
input := get_state().input
|
|
|
|
|
|
|
|
frame_delta := frametime_delta32()
|
|
|
|
|
2024-03-08 16:51:46 -08:00
|
|
|
signal := UI_Signal {}
|
2024-03-08 15:45:27 -08:00
|
|
|
|
|
|
|
// Cursor Collision
|
2024-03-10 23:05:18 -07:00
|
|
|
// profile_begin( "Cursor collision")
|
2024-03-08 15:45:27 -08:00
|
|
|
signal.cursor_pos = ui_cursor_pos()
|
|
|
|
signal.cursor_over = cast(b8) pos_within_range2( signal.cursor_pos, box.computed.bounds )
|
2024-03-10 23:05:18 -07:00
|
|
|
// profile_end()
|
2024-03-08 15:45:27 -08:00
|
|
|
|
2024-03-10 23:05:18 -07:00
|
|
|
// profile_begin("misc")
|
2024-03-08 15:45:27 -08:00
|
|
|
left_pressed := pressed( input.mouse.left )
|
|
|
|
left_released := released( input.mouse.left )
|
|
|
|
|
|
|
|
mouse_clickable := UI_BoxFlag.Mouse_Clickable in box.flags
|
|
|
|
keyboard_clickable := UI_BoxFlag.Keyboard_Clickable in box.flags
|
|
|
|
|
|
|
|
was_hot := ui.hot == box.key && box.hot_delta > 0
|
|
|
|
was_active := ui.active == box.key && box.active_delta > 0
|
|
|
|
was_disabled := box.disabled_delta > 0
|
|
|
|
|
|
|
|
if mouse_clickable && signal.cursor_over && left_pressed
|
|
|
|
{
|
|
|
|
ui.hot = box.key
|
|
|
|
ui.active = box.key
|
|
|
|
ui.active_mouse[MouseBtn.Left] = box.key
|
2024-03-08 16:51:46 -08:00
|
|
|
|
2024-05-09 23:08:36 -07:00
|
|
|
ui.last_pressed_key = box.key
|
|
|
|
ui.active_start_style = box.style
|
2024-03-08 15:45:27 -08:00
|
|
|
|
|
|
|
signal.pressed = true
|
|
|
|
// TODO(Ed) : Support double-click detection
|
|
|
|
}
|
|
|
|
|
|
|
|
if mouse_clickable && ! signal.cursor_over && left_released
|
|
|
|
{
|
|
|
|
box.hot_delta = 0
|
|
|
|
|
|
|
|
ui.active = UI_Key(0)
|
|
|
|
ui.active_mouse[MouseBtn.Left] = UI_Key(0)
|
|
|
|
|
|
|
|
signal.released = true
|
|
|
|
signal.left_clicked = false
|
|
|
|
}
|
|
|
|
|
|
|
|
if keyboard_clickable
|
|
|
|
{
|
|
|
|
// TODO(Ed) : Add keyboard interaction support
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO(Ed) : Add scrolling support
|
|
|
|
if UI_BoxFlag.Scroll_X in box.flags {
|
|
|
|
|
|
|
|
}
|
|
|
|
if UI_BoxFlag.Scroll_Y in box.flags {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO(Ed) : Add panning support
|
|
|
|
if UI_BoxFlag.Pan_X in box.flags {
|
|
|
|
|
|
|
|
}
|
|
|
|
if UI_BoxFlag.Pan_Y in box.flags {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
is_disabled := UI_BoxFlag.Disabled in box.flags
|
|
|
|
is_hot := ui.hot == box.key
|
|
|
|
is_active := ui.active == box.key
|
2024-05-09 23:08:36 -07:00
|
|
|
is_rooted := ui.root == box.parent
|
2024-03-08 15:45:27 -08:00
|
|
|
|
2024-05-09 23:08:36 -07:00
|
|
|
if signal.cursor_over && ! is_disabled
|
2024-03-08 15:45:27 -08:00
|
|
|
{
|
2024-03-09 10:55:47 -08:00
|
|
|
hot_vacant := ui.hot == UI_Key(0)
|
|
|
|
active_vacant := ui.active == UI_Key(0)
|
2024-05-09 23:08:36 -07:00
|
|
|
// (active_vacant is_active)
|
|
|
|
if (hot_vacant && signal.cursor_over || is_hot)
|
2024-03-09 10:55:47 -08:00
|
|
|
{
|
|
|
|
// prev_hot := zpl_hmap_get( ui.prev_cache, u64(ui.hot) )
|
|
|
|
// prev_hot_label := prev_hot != nil ? prev_hot.label.str : ""
|
|
|
|
// log( str_fmt_tmp("Detected HOT via CURSOR OVER: %v is_hot: %v is_active: %v prev_hot: %v", box.label.str, is_hot, is_active, prev_hot_label ))
|
|
|
|
ui.hot = box.key
|
|
|
|
is_hot = true
|
2024-03-08 15:45:27 -08:00
|
|
|
|
2024-03-09 10:55:47 -08:00
|
|
|
ui.hot_start_style = box.style
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
is_hot = false
|
|
|
|
if ui.hot == box.key {
|
|
|
|
ui.hot = UI_Key(0)
|
|
|
|
}
|
2024-03-08 15:45:27 -08:00
|
|
|
}
|
2024-03-09 10:55:47 -08:00
|
|
|
|
2024-05-09 23:08:36 -07:00
|
|
|
if mouse_clickable && signal.cursor_over && left_released
|
|
|
|
{
|
|
|
|
ui.active = UI_Key(0)
|
|
|
|
ui.active_mouse[MouseBtn.Left] = UI_Key(0)
|
|
|
|
|
|
|
|
signal.released = true
|
|
|
|
|
|
|
|
if was_active {
|
|
|
|
signal.left_clicked = true
|
|
|
|
ui.last_clicked = box.key
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// profile_end()
|
2024-03-08 15:45:27 -08:00
|
|
|
|
|
|
|
// State Deltas update
|
2024-03-10 23:05:18 -07:00
|
|
|
// profile_begin( "state deltas upate")
|
2024-03-08 15:45:27 -08:00
|
|
|
if is_hot
|
|
|
|
{
|
|
|
|
box.hot_delta += frame_delta
|
|
|
|
if was_hot {
|
|
|
|
box.style_delta += frame_delta
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
box.hot_delta = 0
|
|
|
|
}
|
|
|
|
if is_active
|
|
|
|
{
|
|
|
|
box.active_delta += frame_delta
|
|
|
|
if was_active {
|
|
|
|
box.style_delta += frame_delta
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
box.active_delta = 0
|
|
|
|
}
|
|
|
|
if is_disabled
|
|
|
|
{
|
|
|
|
box.disabled_delta += frame_delta
|
|
|
|
if was_hot {
|
|
|
|
box.style_delta += frame_delta
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
box.disabled_delta = 0
|
|
|
|
}
|
2024-03-10 23:05:18 -07:00
|
|
|
// profile_end()
|
2024-03-08 15:45:27 -08:00
|
|
|
|
2024-05-09 23:08:36 -07:00
|
|
|
signal.active = cast(b8) is_active
|
|
|
|
signal.was_active = cast(b8) was_active
|
|
|
|
// logf("was_active: %v", was_active)
|
2024-03-08 15:45:27 -08:00
|
|
|
|
|
|
|
// Update style if not in default state
|
|
|
|
{
|
2024-03-10 23:05:18 -07:00
|
|
|
// profile("Update style")
|
|
|
|
|
2024-03-08 15:45:27 -08:00
|
|
|
if is_hot
|
|
|
|
{
|
|
|
|
if ! was_hot {
|
|
|
|
box.prev_style = box.style
|
|
|
|
box.style_delta = 0
|
|
|
|
}
|
2024-03-12 17:55:29 -07:00
|
|
|
box.style = stack_peek( & ui.theme_stack ).hot
|
2024-03-08 15:45:27 -08:00
|
|
|
}
|
|
|
|
if is_active
|
|
|
|
{
|
|
|
|
if ! was_active {
|
|
|
|
box.prev_style = box.style
|
|
|
|
box.style_delta = 0
|
|
|
|
}
|
2024-03-12 17:55:29 -07:00
|
|
|
box.style = stack_peek( & ui.theme_stack ).active
|
2024-03-08 15:45:27 -08:00
|
|
|
}
|
|
|
|
if is_disabled
|
|
|
|
{
|
|
|
|
if ! was_disabled {
|
|
|
|
box.prev_style = box.style
|
|
|
|
box.style_delta = 0
|
|
|
|
}
|
|
|
|
box.style = stack_peek( & ui.theme_stack ).disabled
|
|
|
|
}
|
|
|
|
|
|
|
|
if ! is_disabled && ! is_active && ! is_hot {
|
|
|
|
if was_disabled || was_active || was_hot {
|
|
|
|
box.prev_style = box.style
|
|
|
|
box.style_delta = 0
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
box.style_delta += frame_delta
|
|
|
|
}
|
|
|
|
box.style = stack_peek( & ui.theme_stack ).default
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-09 10:55:47 -08:00
|
|
|
if is_active && ! was_active {
|
|
|
|
ui.active_start_signal = signal
|
|
|
|
}
|
2024-05-09 23:08:36 -07:00
|
|
|
|
2024-03-08 15:45:27 -08:00
|
|
|
return signal
|
|
|
|
}
|