more progress...
This commit is contained in:
parent
595de438af
commit
e8c3312b69
@ -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
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
@ -200,6 +200,7 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
ui_screen_tick()
|
||||
|
||||
//region WorkspaceImgui Tick
|
||||
if false
|
||||
{
|
||||
profile("Workspace Imgui")
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user