pushing what I have rn, decided not to go this route

Instead going with ![img](https://i.imgur.com/S3tjZUu.png)
This commit is contained in:
Edward R. Gonzalez 2024-05-13 10:40:29 -04:00
parent e8c3312b69
commit 0744069b0d
9 changed files with 71 additions and 70 deletions

View File

@ -5,6 +5,9 @@
},
{
"path": "scripts"
},
{
"path": "."
}
],
"settings": {

View File

@ -352,8 +352,8 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32
// Timing
{
// profile("Client tick timing processing")
// config.engine_refresh_hz = uint(monitor_refresh_hz)
config.engine_refresh_hz = 10
config.engine_refresh_hz = uint(monitor_refresh_hz)
// config.engine_refresh_hz = 10
frametime_target_ms = 1.0 / f64(config.engine_refresh_hz) * S_To_MS
sub_ms_granularity_required := frametime_target_ms <= Frametime_High_Perf_Threshold_MS

View File

@ -344,14 +344,17 @@ render_screen_ui :: proc()
// Sort roots children by top-level order
current := root.first
for ; current != nil; current = ui_box_tranverse_next( current, is_destructive = true )
for ; current != nil; current = ui_box_tranverse_next( current, is_destructive = false )
{
// profile("Box")
parent := current.parent
if parent == ui.root && current.ancestors == -1 {
// current.parent = nil
// current.first = nil
// current.last = nil
// This is a deceased rooted box
// Ignore it as its not constructed this frame
// continue
continue
}
style := current.style
@ -408,28 +411,6 @@ render_screen_ui :: proc()
}
// profile_end()
// if .Mouse_Resizable in current.flags
// {
// // profile("Resize Bounds")
// resize_border_width := cast(f32) get_state().config.ui_resize_border_width
// resize_percent_width := computed_size * (resize_border_width * 1.0/ 200.0)
// resize_border_non_range := add(current.computed.bounds, range2(
// { resize_percent_width.x, -resize_percent_width.x },
// { -resize_percent_width.x, resize_percent_width.x }))
// render_resize := range2(
// resize_border_non_range.min,
// resize_border_non_range.max,
// )
// rect_resize := rl.Rectangle {
// render_resize.min.x,
// render_resize.min.y,
// render_resize.max.x - render_resize.min.x,
// render_resize.max.y - render_resize.min.y,
// }
// draw_rectangle_lines( rect_padding, current, Color_Red, line_thickness )
// }
point_radius : f32 = 3
// profile_begin("circles")

View File

@ -6,14 +6,15 @@ import "core:math/linalg"
// The UI_Box's actual positioning and sizing
// There is an excess of rectangles here for debug puproses.
UI_Computed :: struct {
fresh : b32, // If the auto-layout has been computed for the current frame
// anchors : Range2, // Bounds for anchors within parent
// margins : Range2, // Bounds for margins within parent
padding : Range2, // Bounds for padding's starting bounds (will be offset by border if there is one), only here for debug vis
bounds : Range2, // Bounds for box itself
padding : Range2, // Bounds for padding's starting bounds (will be offset by border if there is one)
content : Range2, // Bounds for content (text or children)
text_pos : Vec2, // Position of text within content
text_size : Vec2, // Size of text within content
fresh : b32, // If the auto-layout has been computed for the current frame
}
UI_LayoutDirectionX :: enum(i32) {
@ -73,6 +74,7 @@ UI_LayoutFlag :: enum u32 {
Size_To_Text,
// TODO(Ed): Implement this!
// Wrap text around the box, text_alignment specifies the justification for its compostion when wrapping.
Text_Wrap,
Count,

View File

@ -1,14 +1,15 @@
package sectr
// Note(Ed): This is naturally pretty expensive
ui_box_compute_layout :: proc( box : ^UI_Box )
ui_box_compute_layout :: proc( box : ^UI_Box,
ancestors_layout_required : b32 = false,
root_layout_required : b32 = false )
{
profile("Layout Box")
state := get_state()
ui := state.ui_context
parent := box.parent
// TODO(Ed): Add support to premmtively compute ancestor's layouts
// if parent != ui.root && ! parent.computed.fresh {
// ui_box_compute_layout( parent )
// }
@ -45,6 +46,9 @@ ui_box_compute_layout :: proc( box : ^UI_Box )
If fixed size (X or Y):
* Ignore Parent constraints (can only be clipped)
If an axis is auto-sized by a ratio of the other axis
*
If auto-sized:
* Enforce parent size constraint of bounds relative to
where the adjusted content bounds are after applying margins & anchors.

View File

@ -69,10 +69,11 @@ ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas
// runtime.debug_trap()
}
// Check to see if this box is active
if mouse_clickable && signal.cursor_over && left_pressed && was_hot
{
top_ancestor := ui_top_ancestor(box)
if ui.root.last != top_ancestor && false
if ui.root.last != top_ancestor
{
// dll_full_pop(top_ancestor, top_ancestor.parent)
// dll_full_push_back( top_ancestor.parent, top_ancestor, nil )
@ -81,7 +82,7 @@ ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas
right := top_ancestor.next
if left != nil {
left.next = top_ancestor.prev
left.next = top_ancestor.next
}
else {
// We are the first box on root,
@ -92,10 +93,17 @@ ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas
if ui.root.last != nil
{
// ui.root.last - > top_ancestor
ui.root.last.next = top_ancestor
top_ancestor.prev = ui.root.last
prev_last := ui.root.last
ui.root.last = top_ancestor
prev_last.next = top_ancestor
top_ancestor.prev = prev_last
top_ancestor.next = nil
if left == nil && right == prev_last
{
right.prev = nil
right.next = top_ancestor
}
}
else
{
@ -105,8 +113,8 @@ ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas
ui.root.first.next = top_ancestor
top_ancestor.prev = ui.root.first
top_ancestor.next = nil
ui.root.last = top_ancestor
}
ui.root.last = top_ancestor
for curr := right; curr != nil; curr = curr.next {
curr.parent_index -= 1
@ -147,26 +155,26 @@ ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas
// TODO(Ed) : Add keyboard interaction support
}
// TODO(Ed): Should panning and scrolling get supported here? (problably not...)
// TODO(Ed) : Add scrolling support
if UI_BoxFlag.Scroll_X in box.flags {
// if UI_BoxFlag.Scroll_X in box.flags {
}
if UI_BoxFlag.Scroll_Y 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_X in box.flags {
}
if UI_BoxFlag.Pan_Y 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
// TODO(Ed): It should be able to enter hot without mouse_clickable
if mouse_clickable && signal.cursor_over && ! is_disabled
{
hot_vacant := ui.hot == UI_Key(0)

View File

@ -1,5 +1,6 @@
package sectr
// TODO(Ed): We problably can embedd this info into the UI_Layout with the regular text_alignment
UI_TextAlign :: enum u32 {
Left,
Center,
@ -20,7 +21,7 @@ UI_Style :: struct {
border_color : Color,
// TODO(Ed): We cannot support individual corners unless we add it to raylib (or finally change the rendering backend)
corner_radii : [Corner.Count]f32,
corner_radii : [Corner.Count]f32,
// TODO(Ed) : Add support for this eventually
blur_size : f32,
@ -31,9 +32,8 @@ UI_Style :: struct {
// TODO(Ed): Add support for custom shader
// shader : UI_Shader,
font : FontID,
// TODO(Ed): Should this get moved to the layout struct? Techncially font-size is mainly
text_color : Color,
font : FontID,
text_color : Color,
// TODO(Ed) : Support setting the cursor state
cursor : UI_Cursor,

View File

@ -42,7 +42,7 @@ test_draggable :: proc()
corner_radii = { 0.3, 0.3, 0.3, 0.3 },
})
draggable := ui_widget( "Draggable Box!", UI_BoxFlags { .Mouse_Clickable, .Mouse_Resizable } )
draggable := ui_widget( "Draggable Box!", UI_BoxFlags { .Mouse_Clickable } )
if draggable.first_frame {
debug.draggable_box_pos = draggable.layout.pos + { 0, -100 }
debug.draggable_box_size = draggable.layout.size.min
@ -87,7 +87,7 @@ test_parenting :: proc( default_layout : ^UI_Layout, frame_style_default : ^UI_S
parent_style := frame_style_default ^
ui_style(parent_style)
parent := ui_widget( "Parent", { .Mouse_Clickable, .Mouse_Resizable })
parent := ui_widget( "Parent", { .Mouse_Clickable })
ui_parent_push(parent)
{
if parent.first_frame {

View File

@ -59,22 +59,19 @@ UI_BoxFlag :: enum u64 {
Click_To_Focus,
Mouse_Clickable,
Mouse_Resizable,
Keyboard_Clickable,
Scroll_X,
Scroll_Y,
// Pan_X,
// Pan_Y,
Pan_X,
Pan_Y,
Screenspace,
// Scroll_X,
// Scroll_Y,
// Screenspace,
Count,
}
UI_BoxFlags :: bit_set[UI_BoxFlag; u64]
UI_BoxFlag_Scroll :: UI_BoxFlags { .Scroll_X, .Scroll_Y }
// UI_BoxFlag_Scroll :: UI_BoxFlags { .Scroll_X, .Scroll_Y }
UI_Cursor :: struct {
placeholder : int,
@ -110,7 +107,10 @@ UI_Box :: struct {
text : StrRunesPair,
// Regenerated per frame.
using links : DLL_NodeFull( UI_Box ), // first, last, prev, next
// first, last : The first and last child of this box
// prev, next : The adjacent neighboring boxes who are children of to the same parent
using links : DLL_NodeFull( UI_Box ),
parent : ^UI_Box,
num_children : i32,
ancestors : i32, // This value for rooted widgets gets set to -1 after rendering see ui_box_make() for the reason.
@ -126,7 +126,7 @@ UI_Box :: struct {
style : UI_Style,
// Persistent Data
first_frame : b8,
first_frame : b8, // TODO(Ed): Move to end if keeping as b8
hot_delta : f32,
active_delta : f32,
disabled_delta : f32,
@ -148,8 +148,8 @@ UI_Built_Boxes_Array_Size :: 16 * Kilobyte
UI_State :: struct {
// TODO(Ed) : Use these
build_arenas : [2]Arena,
build_arena : ^ Arena,
// build_arenas : [2]Arena,
// build_arena : ^ Arena,
built_box_count : i32,
@ -165,7 +165,7 @@ UI_State :: struct {
// So long as their parent-index is non-negative they'll be rendered
// Do we need to recompute the layout?
layout_dirty : b32,
// layout_dirty : b32,
// TODO(Ed) : Look into using a build arena like Ryan does for these possibly (and thus have a linked-list stack)
layout_combo_stack : StackFixed( UI_LayoutCombo, UI_Style_Stack_Size ),
@ -300,7 +300,10 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
}
if parent != nil
{
if parent != ui.root || curr_box.first_frame
// There are three possible reasons to just add as usual:
// 1. Its not rooted, which means we don't track order
// 2.
if parent != ui.root || curr_box.first_frame //|| (prev_box.prev == nil && prev_box.next == nil)
{
// Only occurs when this is no prior history for rooted boxes
// Otherwise regular children always complete this
@ -335,11 +338,11 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
{
// Make only todo if links are properly wiped on current
set_error : AllocatorError
if curr_box.prev == nil && prev_box.prev != nil {
if curr_box.prev == nil && prev_box.prev != nil && prev_box.ancestors == 1 {
curr_box.prev, set_error = zpl_hmap_set( curr_cache, cast(u64) prev_box.prev.key, prev_box.prev ^ )
verify( set_error == AllocatorError.None, "Failed to set zpl_hmap due to allocator error" )
}
if curr_box.next == nil && prev_box.next != nil {
if curr_box.next == nil && prev_box.next != nil && prev_box.ancestors == 1 {
curr_box.next, set_error = zpl_hmap_set( curr_cache, cast(u64) prev_box.next.key, prev_box.next ^ )
verify( set_error == AllocatorError.None, "Failed to set zpl_hmap due to allocator error" )
}