more progress...

This commit is contained in:
Edward R. Gonzalez 2024-05-13 01:56:39 -04:00
parent 595de438af
commit e8c3312b69
7 changed files with 203 additions and 94 deletions

View File

@ -195,7 +195,8 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
ui_startup( & screen_ui.base, cache_allocator = persistent_slab_allocator() )
using screen_ui
menu_bar.pos = Vec2(app_window.extent) * { -1, 1 }
menu_bar.pos = { -60, 0 }
// menu_bar.pos = Vec2(app_window.extent) * { -1, 1 }
menu_bar.size = {200, 40}
settings_menu.min_size = {250, 200}
@ -338,9 +339,9 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32
rl.PollInputEvents()
debug.draw_ui_box_bounds_points = false
debug.draw_UI_padding_bounds = false
debug.draw_ui_content_bounds = false
debug.draw_ui_box_bounds_points = true
debug.draw_UI_padding_bounds = true
debug.draw_ui_content_bounds = true
should_close = update( host_delta_time )
render()
@ -351,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

@ -1,6 +1,8 @@
package sectr
#region("Import Aliases")
import "base:builtin"
copy :: builtin.copy
import "base:intrinsics"
@ -95,13 +97,17 @@ import "thirdparty:backtrace"
stacktrace :: backtrace.trace
stacktrace_lines :: backtrace.lines
#endregion("Import Aliases")
OS_Type :: type_of(ODIN_OS)
swap :: proc( a, b : ^ $Type ) -> ( ^ Type, ^ Type ) {
return b, a
}
// Proc Name Overloads Alias table
#region("Proc overload mappings")
// This has to be done on a per-module basis.
add :: proc {
@ -298,3 +304,5 @@ wedge :: proc {
wedge_vec3,
wedge_bivec3,
}
#endregion("Proc overload mappings")

View File

@ -171,6 +171,9 @@ dll_full_pop :: proc "contextless" ( node, parent : ^$Type ) {
if parent.last == node {
parent.last = node.prev
}
if parent.first == parent.last {
parent.last = nil
}
if node.prev != nil {
node.prev.next = nil
node.prev = nil

View File

@ -110,16 +110,21 @@ render_mode_2d_workspace :: proc()
profile("Imgui Render")
ui := & state.project.workspace.ui
root := ui.root
if root.num_children == 0 {
if root == nil || root.num_children == 0 {
break ImguiRender
}
state.ui_context = ui
current := root.first
for ; current != nil; current = ui_box_tranverse_next( current )
for ; current != nil; current = ui_box_tranverse_next( current, is_destructive = true )
{
// profile("Box")
parent := current.parent
if parent == ui.root && current.ancestors == -1 {
// This is a deceased rooted box
// Ignore it as its not constructed this frame
continue
}
layout := current.layout
style := current.style
@ -133,7 +138,7 @@ render_mode_2d_workspace :: proc()
// TODO(Ed) : Render Borders
// profile_begin("Calculating Raylib rectangles")
// profile_begin("Calculating Raylib rectangles")
// render_anchors := range2(
// ws_view_to_render_pos(computed.anchors.min),
// ws_view_to_render_pos(computed.anchors.max),
@ -160,44 +165,44 @@ render_mode_2d_workspace :: proc()
rect_bounds := range2_to_rl_rect( render_bounds )
rect_padding := range2_to_rl_rect( render_padding )
rect_content := range2_to_rl_rect( render_content )
// profile_end()
// profile_end()
// profile_begin("rl.DrawRectangleRounded( rect_bounds, style.layout.corner_radii[0], 9, style.bg_color )")
if style.bg_color.a != 0
{
draw_rectangle( rect_bounds, current )
}
if layout.border_width > 0 {
draw_rectangle_lines( rect_bounds, current, style.border_color, layout.border_width )
}
// profile_end()
// profile_begin("rl.DrawRectangleRounded( rect_bounds, style.layout.corner_radii[0], 9, style.bg_color )")
if style.bg_color.a != 0
{
draw_rectangle( rect_bounds, current )
}
if layout.border_width > 0 {
draw_rectangle_lines( rect_bounds, current, style.border_color, layout.border_width )
}
// profile_end()
line_thickness := 1 * cam_zoom_ratio
// profile_begin("rl.DrawRectangleRoundedLines: padding & content")
if debug.draw_UI_padding_bounds && equal_range2(computed.content, computed.padding) {
draw_rectangle_lines( rect_padding, current, Color_Debug_UI_Padding_Bounds, line_thickness )
}
else if debug.draw_ui_content_bounds {
draw_rectangle_lines( rect_content, current, Color_Debug_UI_Content_Bounds, line_thickness )
}
// profile_end()
// profile_begin("rl.DrawRectangleRoundedLines: padding & content")
if debug.draw_UI_padding_bounds && equal_range2(computed.content, computed.padding) {
draw_rectangle_lines( rect_padding, current, Color_Debug_UI_Padding_Bounds, line_thickness )
}
else if debug.draw_ui_content_bounds {
draw_rectangle_lines( rect_content, current, Color_Debug_UI_Content_Bounds, line_thickness )
}
// profile_end()
point_radius := 3 * cam_zoom_ratio
// profile_begin("circles")
if debug.draw_ui_box_bounds_points
{
// center := Vec2 {
// render_bounds.p0.x + computed_size.x * 0.5,
// render_bounds.p0.y - computed_size.y * 0.5,
// }
// rl.DrawCircleV( center, point_radius, Color_White )
// profile_begin("circles")
if debug.draw_ui_box_bounds_points
{
// center := Vec2 {
// render_bounds.p0.x + computed_size.x * 0.5,
// render_bounds.p0.y - computed_size.y * 0.5,
// }
// rl.DrawCircleV( center, point_radius, Color_White )
rl.DrawCircleV( render_bounds.p0, point_radius, Color_Red )
rl.DrawCircleV( render_bounds.p1, point_radius, Color_Blue )
}
// profile_end()
rl.DrawCircleV( render_bounds.p0, point_radius, Color_Red )
rl.DrawCircleV( render_bounds.p1, point_radius, Color_Blue )
}
// profile_end()
if len(current.text.str) > 0 {
ws_view_draw_text( current.text, ws_view_to_render_pos(computed.text_pos * {1, -1}), layout.font_size, style.text_color )
@ -339,10 +344,15 @@ render_screen_ui :: proc()
// Sort roots children by top-level order
current := root.first
for ; current != nil; current = ui_box_tranverse_next( current )
for ; current != nil; current = ui_box_tranverse_next( current, is_destructive = true )
{
// profile("Box")
parent := current.parent
if parent == ui.root && current.ancestors == -1 {
// This is a deceased rooted box
// Ignore it as its not constructed this frame
// continue
}
style := current.style
layout := current.layout
@ -375,28 +385,28 @@ render_screen_ui :: proc()
rect_bounds := range2_to_rl_rect( render_bounds )
rect_padding := range2_to_rl_rect( render_padding )
rect_content := range2_to_rl_rect( render_content )
// profile_end()
// profile_end()
// profile_begin("rl.DrawRectangleRounded( rect_bounds, style.layout.corner_radii[0], 9, style.bg_color )")
if style.bg_color.a != 0
{
draw_rectangle( rect_bounds, current )
}
if layout.border_width > 0 {
draw_rectangle_lines( rect_bounds, current, style.border_color, layout.border_width )
}
// profile_end()
// profile_begin("rl.DrawRectangleRounded( rect_bounds, style.layout.corner_radii[0], 9, style.bg_color )")
if style.bg_color.a != 0
{
draw_rectangle( rect_bounds, current )
}
if layout.border_width > 0 {
draw_rectangle_lines( rect_bounds, current, style.border_color, layout.border_width )
}
// profile_end()
line_thickness : f32 = 1
// profile_begin("rl.DrawRectangleRoundedLines: padding & content")
if debug.draw_UI_padding_bounds && equal_range2(computed.content, computed.padding) {
draw_rectangle_lines( rect_padding, current, Color_Debug_UI_Padding_Bounds, line_thickness )
}
else if debug.draw_ui_content_bounds {
draw_rectangle_lines( rect_content, current, Color_Debug_UI_Content_Bounds, line_thickness )
}
// profile_end()
// profile_begin("rl.DrawRectangleRoundedLines: padding & content")
if debug.draw_UI_padding_bounds && equal_range2(computed.content, computed.padding) {
draw_rectangle_lines( rect_padding, current, Color_Debug_UI_Padding_Bounds, line_thickness )
}
else if debug.draw_ui_content_bounds {
draw_rectangle_lines( rect_content, current, Color_Debug_UI_Content_Bounds, line_thickness )
}
// profile_end()
// if .Mouse_Resizable in current.flags
// {
@ -422,19 +432,19 @@ render_screen_ui :: proc()
point_radius : f32 = 3
// profile_begin("circles")
if debug.draw_ui_box_bounds_points
{
// center := Vec2 {
// render_bounds.p0.x + computed_size.x * 0.5,
// render_bounds.p0.y - computed_size.y * 0.5,
// }
// rl.DrawCircleV( center, point_radius, Color_White )
// profile_begin("circles")
if debug.draw_ui_box_bounds_points
{
// center := Vec2 {
// render_bounds.p0.x + computed_size.x * 0.5,
// render_bounds.p0.y - computed_size.y * 0.5,
// }
// rl.DrawCircleV( center, point_radius, Color_White )
rl.DrawCircleV( render_bounds.p0, point_radius, Color_Red )
rl.DrawCircleV( render_bounds.p1, point_radius, Color_Blue )
}
// profile_end()
rl.DrawCircleV( render_bounds.p0, point_radius, Color_Red )
rl.DrawCircleV( render_bounds.p1, point_radius, Color_Blue )
}
// profile_end()
if len(current.text.str) > 0 && style.font.key != 0 {
draw_text_screenspace( current.text, screen_to_render_pos(computed.text_pos), layout.font_size, style.text_color )

View File

@ -200,6 +200,7 @@ update :: proc( delta_time : f64 ) -> b32
ui_screen_tick()
//region WorkspaceImgui Tick
if false
{
profile("Workspace Imgui")

View File

@ -72,9 +72,52 @@ ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas
if mouse_clickable && signal.cursor_over && left_pressed && was_hot
{
top_ancestor := ui_top_ancestor(box)
dll_full_pop(top_ancestor, top_ancestor.parent)
dll_full_push_back( top_ancestor.parent, top_ancestor, nil )
if ui.root.last != top_ancestor && false
{
// dll_full_pop(top_ancestor, top_ancestor.parent)
// dll_full_push_back( top_ancestor.parent, top_ancestor, nil )
left := top_ancestor.prev
right := top_ancestor.next
if left != nil {
left.next = top_ancestor.prev
}
else {
// We are the first box on root,
ui.root.first = right
}
// right should never be null since top_ancestor is not the last node
right.prev = left
if ui.root.last != nil
{
// ui.root.last - > top_ancestor
ui.root.last.next = top_ancestor
top_ancestor.prev = ui.root.last
top_ancestor.next = nil
}
else
{
// vvv
// ui.root.first - > ui.root.last
ui.root.last = top_ancestor
ui.root.first.next = top_ancestor
top_ancestor.prev = ui.root.first
top_ancestor.next = nil
}
ui.root.last = top_ancestor
for curr := right; curr != nil; curr = curr.next {
curr.parent_index -= 1
}
// Fix up left & right references
// if left != nil && right != nil {
// right.prev = left
// left.next = right
// }
}
// runtime.debug_trap()
// ui.hot = box.key

View File

@ -113,7 +113,7 @@ UI_Box :: struct {
using links : DLL_NodeFull( UI_Box ), // first, last, prev, next
parent : ^UI_Box,
num_children : i32,
ancestors : i32,
ancestors : i32, // This value for rooted widgets gets set to -1 after rendering see ui_box_make() for the reason.
parent_index : i32,
flags : UI_BoxFlags,
@ -157,7 +157,8 @@ UI_State :: struct {
prev_cache : ^HMapZPL( UI_Box ),
curr_cache : ^HMapZPL( UI_Box ),
null_box : ^UI_Box, // Ryan had this, I don't know why yet.
null_box : ^UI_Box, // This was used with the Linked list interface...
// TODO(Ed): Should we change our convention for null boxes to use the above and nil as an invalid state?
root : ^UI_Box,
// Children of the root node are unique in that they have their order preserved per frame
// This is to support overlapping frames
@ -239,7 +240,17 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
key := ui_key_from_string( label )
links_perserved : DLL_NodeFull( UI_Box )
curr_box : (^ UI_Box)
curr_box = zpl_hmap_get( curr_cache, cast(u64) key )
if curr_box != nil && curr_box.ancestors == 1 {
// top_ancestor has had its neighboring links updated this frame
// preserve them from the refresh
links_perserved.prev = curr_box.links.prev
links_perserved.next = curr_box.links.next
}
prev_box := zpl_hmap_get( prev_cache, cast(u64) key )
{
// profile("Assigning current box")
@ -269,15 +280,12 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
// Clear non-persistent data
curr_box.computed.fresh = false
curr_box.links = {}
curr_box.links = links_perserved
curr_box.num_children = 0
curr_box.parent = nil
// curr_box.ancestors = 0
curr_box.parent_index = -1
// If there is a parent, setup the relevant references
parent := stack_peek( & parent_stack )
if curr_box.ancestors == 0 && prev_box != nil
if parent == nil && ! curr_box.first_frame
{
set_error : AllocatorError
if prev_box.first != nil {
@ -288,12 +296,36 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
curr_box.last, set_error = zpl_hmap_set( curr_cache, cast(u64) prev_box.last.key, prev_box.last ^ )
verify( set_error == AllocatorError.None, "Failed to set zpl_hmap due to allocator error" )
}
curr_box.ancestors = 0
}
if parent != nil
{
if curr_box.ancestors != 1
if parent != ui.root || curr_box.first_frame
{
dll_full_push_back( parent, curr_box, null_box )
// Only occurs when this is no prior history for rooted boxes
// Otherwise regular children always complete this
// dll_full_push_back( parent, curr_box, nil )
when true
{
// |
// v
// parent.first <nil>
if parent.first == nil {
parent.first = curr_box
parent.last = curr_box
curr_box.next = nil
curr_box.prev = nil
}
else {
// Positin is set to last, insert at end
// <parent.last.prev> <parent.last> curr_box
parent.last.next = curr_box
curr_box.prev = parent.last
parent.last = curr_box
curr_box.next = nil
}
}
curr_box.parent_index = parent.num_children
parent.num_children += 1
curr_box.parent = parent
@ -301,16 +333,18 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
}
else if prev_box != nil
{
// Order was previously restored, restore linkage
if prev_box.prev != nil {
curr_box.prev = zpl_hmap_get( curr_cache, cast(u64) prev_box.prev.key )
// Make only todo if links are properly wiped on current
set_error : AllocatorError
if curr_box.prev == nil && prev_box.prev != nil {
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 prev_box.next != nil {
curr_box.next = zpl_hmap_get( curr_cache, cast(u64) prev_box.next.key )
if curr_box.next == nil && prev_box.next != nil {
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" )
}
curr_box.parent = ui.root
curr_box.parent = parent
curr_box.ancestors = 1
curr_box.parent_index = ui.root.num_children
parent.num_children += 1
}
}
@ -319,8 +353,17 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
return curr_box
}
ui_box_tranverse_next :: proc "contextless" ( box : ^ UI_Box ) -> (^ UI_Box)
ui_box_tranverse_next :: proc "contextless" ( box : ^ UI_Box, is_destructive : b32 = false ) -> (^ UI_Box)
{
parent := box.parent
// Marking this box as deceased with no position in the box graph
if is_destructive {
// box.parent = nil
box.num_children = -1
box.ancestors = -1
}
// Check to make sure parent is present on the screen, if its not don't bother.
// If current has children, do them first
using state := get_state()
@ -336,9 +379,10 @@ ui_box_tranverse_next :: proc "contextless" ( box : ^ UI_Box ) -> (^ UI_Box)
if box.next == nil
{
// There is no more adjacent nodes
if box.parent != nil {
if box.parent != nil
{
// Lift back up to parent, and set it to its next.
return box.parent.next
return parent.next
}
}
@ -395,7 +439,6 @@ ui_graph_build_begin :: proc( ui : ^ UI_State, bounds : Vec2 = {} )
ui_parent_push(root)
}
// TODO(Ed) :: Is this even needed?
ui_graph_build_end :: proc( ui : ^UI_State )
{
profile(#procedure)