Fixed issue with ui_signal_from_box
Biggest win was getting the intial fixes for overlapping boxes. Eventually I'll need to add support for sorting actives of top-most ancestors (pretty much just remove from linked list and add to last position (adjust indices of adjacent and new top most, etc)
This commit is contained in:
parent
1afe74b4b5
commit
5b24e591eb
@ -21,8 +21,8 @@ The dependencies are:
|
||||
* Odin repo's base, core, and vendor(raylib) libaries
|
||||
* An ini parser
|
||||
|
||||
The client(sectr) module's organization is relatively flat due to the nature of odin's package management not allowing for cyclic dependencies across modules, and modules can only be in one directory.
|
||||
This makes it difficult to unflatten as the depedency chain must clear with no inter-module collisions, not something organic todo in a prototype...
|
||||
The client(sectr) module's organization is relatively flat due to the nature of odin's module suste, not allowing for cyclic dependencies across modules, and modules can only be in one directory.
|
||||
This makes it difficult to unflatten, not something organic todo in a prototype...
|
||||
|
||||
Even so the notatble groups are:
|
||||
|
||||
@ -37,7 +37,7 @@ Even so the notatble groups are:
|
||||
* Parser : AST generation, editing, and serialization. A 1/3 of this prototype will most likely be this alone.
|
||||
* UI : AST visualzation & editing, backend visualization, project organizationa via workspaces (2d cavnases)
|
||||
* Will most likely be the bulk of this prototype.
|
||||
* PIMGUI (Persistent Immediate Mode User Interface);
|
||||
* PIMGUI (Persistent Immediate Mode User Interface)
|
||||
* Auto-layout with heavy procedural generation of box widgets
|
||||
|
||||
There is some unused code in `code/__imgui_raddbg`. Its a partial translation of some data structures from raddbg's ui.
|
||||
|
@ -207,6 +207,7 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
*/
|
||||
if true
|
||||
{
|
||||
profile("App Menu Bar")
|
||||
fmt :: str_fmt_alloc
|
||||
|
||||
@static bar_pos := Vec2{0, 100}
|
||||
@ -234,7 +235,7 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
}
|
||||
|
||||
ui_theme_via_style(theme)
|
||||
menu_bar = ui_widget("App Menu Bar", {} )
|
||||
menu_bar = ui_widget("App Menu Bar", { .Mouse_Clickable} )
|
||||
menu_bar.text = to_str_runes_pair( fmt("%v", bar_pos))
|
||||
|
||||
if (menu_bar.first_frame) {
|
||||
@ -277,6 +278,15 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
if move_box.active {
|
||||
bar_pos += input.mouse.delta
|
||||
}
|
||||
using move_box
|
||||
hot := ui_box_from_key(ui.curr_cache, ui.hot)
|
||||
if hot != nil {
|
||||
text = to_str_runes_pair(str_fmt_tmp("Hot box: %v %v", hot.label.str, hot.hot_delta))
|
||||
style.font = default_font
|
||||
style.font_size = 12
|
||||
style.text_color = Color_White
|
||||
style.text_alignment = {0, 1}
|
||||
}
|
||||
}
|
||||
|
||||
move_settings_spacer := ui_widget("Move-Settings Spacer", {})
|
||||
@ -315,6 +325,7 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
@static settings_open := true
|
||||
if settings_btn.pressed || settings_open
|
||||
{
|
||||
profile("Settings Menu")
|
||||
settings_open = true
|
||||
|
||||
resize_border_width : f32 = 20
|
||||
@ -336,6 +347,10 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
style.alignment = { 1.0, 0.5 }
|
||||
style.bg_color = Color_BG_Panel_Translucent
|
||||
style.size = range2( size, {})
|
||||
text = to_str_runes_pair(str_fmt_tmp("Hot Delta: %v", hot_delta))
|
||||
style.font = default_font
|
||||
style.font_size = 12
|
||||
style.text_color = Color_White
|
||||
}
|
||||
|
||||
ui_parent(settings_menu)
|
||||
|
11
code/ui.odin
11
code/ui.odin
@ -138,6 +138,8 @@ UI_Box :: struct {
|
||||
disabled_delta : f32,
|
||||
style_delta : f32,
|
||||
|
||||
parent_index : i32,
|
||||
|
||||
// prev_computed : UI_Computed,
|
||||
// prev_style : UI_Style,v
|
||||
// mouse : UI_InteractState,
|
||||
@ -276,6 +278,7 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
|
||||
if parent != nil
|
||||
{
|
||||
dll_full_push_back( null_box, parent, curr_box )
|
||||
curr_box.parent_index = parent.num_children
|
||||
parent.num_children += 1
|
||||
curr_box.parent = parent
|
||||
}
|
||||
@ -398,3 +401,11 @@ ui_parent_pop :: proc() {
|
||||
|
||||
@(deferred_none = ui_parent_pop)
|
||||
ui_parent :: #force_inline proc( ui : ^UI_Box) { ui_parent_push( ui ) }
|
||||
|
||||
// Topmost ancestor that is not the root
|
||||
ui_top_ancestor :: #force_inline proc "contextless" ( box : ^UI_Box ) -> (^UI_Box) {
|
||||
using ui := get_state().ui_context
|
||||
ancestor := box
|
||||
for ; ancestor.parent != root; ancestor = ancestor.parent {}
|
||||
return ancestor
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package sectr
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
UI_Signal :: struct {
|
||||
cursor_pos : Vec2,
|
||||
drag_delta : Vec2,
|
||||
@ -33,6 +35,25 @@ ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
|
||||
// profile_begin( "Cursor collision")
|
||||
signal.cursor_pos = ui_cursor_pos()
|
||||
signal.cursor_over = cast(b8) pos_within_range2( signal.cursor_pos, box.computed.bounds )
|
||||
|
||||
// TODO(Ed): We eventually need to setup a sorted root based on last active history
|
||||
UnderCheck:
|
||||
{
|
||||
if ! signal.cursor_over do break UnderCheck
|
||||
|
||||
last_root := ui_box_from_key( ui.prev_cache, ui.root.key )
|
||||
if last_root == nil do break UnderCheck
|
||||
|
||||
top_ancestor := ui_top_ancestor(box)
|
||||
if top_ancestor.parent_index != last_root.num_children - 1
|
||||
{
|
||||
for curr := last_root.last; curr != nil && curr.key != box.key; curr = curr.prev {
|
||||
if pos_within_range2( signal.cursor_pos, curr.computed.bounds ) && curr.parent_index > top_ancestor.parent_index {
|
||||
signal.cursor_over = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// profile_end()
|
||||
|
||||
// profile_begin("misc")
|
||||
@ -42,13 +63,17 @@ ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
|
||||
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_hot := (box.hot_delta > 0)
|
||||
was_active := (ui.active == box.key) && (box.active_delta > 0)
|
||||
was_disabled := box.disabled_delta > 0
|
||||
if was_hot {
|
||||
// runtime.debug_trap()
|
||||
}
|
||||
|
||||
if mouse_clickable && signal.cursor_over && left_pressed
|
||||
if mouse_clickable && signal.cursor_over && left_pressed && was_hot
|
||||
{
|
||||
ui.hot = box.key
|
||||
// runtime.debug_trap()
|
||||
// ui.hot = box.key
|
||||
ui.active = box.key
|
||||
ui.active_mouse[MouseBtn.Left] = box.key
|
||||
|
||||
@ -61,7 +86,7 @@ ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
|
||||
|
||||
if mouse_clickable && ! signal.cursor_over && left_released
|
||||
{
|
||||
box.hot_delta = 0
|
||||
box.active_delta = 0
|
||||
|
||||
ui.active = UI_Key(0)
|
||||
ui.active_mouse[MouseBtn.Left] = UI_Key(0)
|
||||
@ -94,15 +119,18 @@ ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
|
||||
is_disabled := UI_BoxFlag.Disabled in box.flags
|
||||
is_hot := ui.hot == box.key
|
||||
is_active := ui.active == box.key
|
||||
is_rooted := ui.root == box.parent
|
||||
|
||||
if signal.cursor_over && ! is_disabled
|
||||
if mouse_clickable && signal.cursor_over && ! is_disabled
|
||||
{
|
||||
hot_vacant := ui.hot == UI_Key(0)
|
||||
active_vacant := ui.active == UI_Key(0)
|
||||
// (active_vacant is_active)
|
||||
if (hot_vacant && signal.cursor_over || is_hot)
|
||||
if signal.cursor_over
|
||||
{
|
||||
if ! hot_vacant {
|
||||
prev := ui_box_from_key( ui.curr_cache, ui.hot )
|
||||
prev.hot_delta = 0
|
||||
}
|
||||
// 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 ))
|
||||
@ -112,16 +140,17 @@ ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
|
||||
ui.hot_start_style = box.style
|
||||
}
|
||||
}
|
||||
else
|
||||
else if ! signal.cursor_over && was_hot
|
||||
{
|
||||
is_hot = false
|
||||
if ui.hot == box.key {
|
||||
ui.hot = UI_Key(0)
|
||||
}
|
||||
ui.hot = UI_Key(0)
|
||||
is_hot = false
|
||||
box.hot_delta = 0
|
||||
}
|
||||
|
||||
if mouse_clickable && signal.cursor_over && left_released
|
||||
{
|
||||
box.active_delta = 0
|
||||
|
||||
ui.active = UI_Key(0)
|
||||
ui.active_mouse[MouseBtn.Left] = UI_Key(0)
|
||||
|
||||
@ -143,9 +172,6 @@ ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
|
||||
box.style_delta += frame_delta
|
||||
}
|
||||
}
|
||||
else {
|
||||
box.hot_delta = 0
|
||||
}
|
||||
if is_active
|
||||
{
|
||||
box.active_delta += frame_delta
|
||||
|
@ -107,6 +107,7 @@ ui_resizable_handles :: proc( parent : ^UI_Widget,
|
||||
corner_br := true,
|
||||
corner_bl := true, )
|
||||
{
|
||||
profile(#procedure)
|
||||
handle_left : UI_Widget
|
||||
handle_right : UI_Widget
|
||||
handle_top : UI_Widget
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 373733fb2b410cd51b4d674b09f5ed9e38677c99
|
||||
Subproject commit e1b5ccf2dc07b6218c8d7c2ec3184594d085af89
|
Loading…
Reference in New Issue
Block a user