From ddca5e8668500620cf01626efc16e7708d1972fd Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 31 Dec 2024 00:17:05 -0500 Subject: [PATCH] Finished initial window implementation --- code/sectr/app/logger_scope.odin | 14 ++++---- code/sectr/app/screen.odin | 6 ++-- code/sectr/app/settings_menu.odin | 1 + code/sectr/engine/client_api.odin | 12 +++---- code/sectr/ui/core/base.odin | 4 +-- code/sectr/ui/core/layout_compute.odin | 4 +-- code/sectr/ui/layout_widget.odin | 2 ++ code/sectr/ui/tests.odin | 4 +-- code/sectr/ui/widgets.odin | 12 ++++--- code/sectr/ui/window.odin | 50 +++++++++++++------------- 10 files changed, 59 insertions(+), 50 deletions(-) diff --git a/code/sectr/app/logger_scope.odin b/code/sectr/app/logger_scope.odin index 773740f..e357c68 100644 --- a/code/sectr/app/logger_scope.odin +++ b/code/sectr/app/logger_scope.odin @@ -5,20 +5,20 @@ UI_LoggerScope :: struct using window : UI_Window, } -ui_logger_scope_builder :: proc( captures : rawptr = nil ) -> ( should_raise : b32 = false ) +ui_log_scope_builder :: proc( captures : rawptr = nil ) -> ( should_raise : b32 = false ) { - profile("Logger Scope") + profile("ui_log_scope_builder") - logger_scope := cast(^UI_LoggerScope) captures - using logger_scope + log_scope := cast(^UI_LoggerScope) captures + using log_scope scope(theme_window_panel) - dragged, resized, maximized, closed := ui_window( & window, "Logger Scope: Window", str_intern("Log Scope"), child_layout = .Top_To_Bottom ) + dragged, resized, maximized, closed := ui_window( & window, "log_scope.window", str_intern("Log Scope"), child_layout = .Top_To_Bottom ) should_raise |= dragged | resized | maximized return } -ui_logger_scope_open :: #force_inline proc "contextless" () { - get_state().screen_ui.logger_scope.is_open = true +ui_log_scope_open :: #force_inline proc "contextless" () { + get_state().screen_ui.log_scope.is_open = true } diff --git a/code/sectr/app/screen.odin b/code/sectr/app/screen.odin index 2216cd7..be8e211 100644 --- a/code/sectr/app/screen.odin +++ b/code/sectr/app/screen.odin @@ -10,7 +10,7 @@ UI_ScreenState :: struct // docked : UI_Docking, menu_bar : UI_ScreenMenuBar, - logger_scope : UI_LoggerScope, + log_scope : UI_LoggerScope, settings_menu : UI_SettingsMenu } @@ -29,7 +29,7 @@ ui_screen_tick :: proc( screen_ui : ^UI_ScreenState ) { ui_graph_build( screen_ui ) ui_floating_manager( & screen_ui.floating ) ui_floating("Menu Bar", & screen_ui.menu_bar, ui_screen_menu_bar_builder) - ui_floating("Logger Scope", & screen_ui.logger_scope, ui_logger_scope_builder) + ui_floating("Logger Scope", & screen_ui.log_scope, ui_log_scope_builder) ui_floating("Settings Menu", & screen_ui.settings_menu, ui_settings_menu_builder) } @@ -132,7 +132,7 @@ ui_screen_menu_bar_builder :: proc( captures : rawptr = nil ) -> (should_raise : text = str_intern("Log Scope") layout.flags = { .Scale_Width_By_Height_Ratio } layout.size.ratio.x = 2.0 - if pressed do ui_logger_scope_open() + if pressed do ui_log_scope_open() } Build_Settings_Btn: { diff --git a/code/sectr/app/settings_menu.odin b/code/sectr/app/settings_menu.odin index 2cf1506..69365c5 100644 --- a/code/sectr/app/settings_menu.odin +++ b/code/sectr/app/settings_menu.odin @@ -83,6 +83,7 @@ ui_settings_menu_builder :: proc( captures : rawptr = nil ) -> ( should_raise : } ui_parent(container) + scope(theme_transparent) vbox := ui_vbox_begin( .Top_To_Bottom, "Settings Menu: VBox", {.Mouse_Clickable}, compute_layout = false ) { should_raise |= b32(vbox.active) diff --git a/code/sectr/engine/client_api.odin b/code/sectr/engine/client_api.odin index f38d1b1..989818f 100644 --- a/code/sectr/engine/client_api.odin +++ b/code/sectr/engine/client_api.odin @@ -280,8 +280,8 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem // path_open_sans := strings.concatenate( { Path_Assets, "OpenSans-Regular.ttf" } ) // font_open_sans = font_load( path_open_sans, 16.0, "OpenSans" ) - // path_noto_sans := strings.concatenate( { Path_Assets, "NotoSans-Regular.ttf" } ) - // font_noto_sans = font_load( path_noto_sans, 16.0, "NotoSans" ) + path_noto_sans := strings.concatenate( { Path_Assets, "NotoSans-Regular.ttf" } ) + font_noto_sans = font_load( path_noto_sans, 16.0, "NotoSans" ) // path_neodgm_code := strings.concatenate( { Path_Assets, "neodgm_code.ttf"} ) // font_neodgm_code = font_load( path_neodgm_code, 32.0, "NeoDunggeunmo Code" ) @@ -289,8 +289,8 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem // path_rec_mono_linear := strings.concatenate( { Path_Assets, "RecMonoLinear-Regular-1.084.ttf" }) // font_rec_mono_linear = font_load( path_rec_mono_linear, 16.0, "RecMonoLinear Regular" ) - path_roboto_regular := strings.concatenate( { Path_Assets, "Roboto-Regular.ttf"} ) - font_roboto_regular = font_load( path_roboto_regular, 32.0, "Roboto Regular" ) + // path_roboto_regular := strings.concatenate( { Path_Assets, "Roboto-Regular.ttf"} ) + // font_roboto_regular = font_load( path_roboto_regular, 32.0, "Roboto Regular" ) // path_arial_unicode_ms := strings.concatenate( { Path_Assets, "Arial Unicode MS.ttf" } ) // font_arial_unicode_ms = font_load( path_arial_unicode_ms, 16.0, "Arial_Unicode_MS" ) @@ -298,7 +298,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem // path_arial_unicode_ms := strings.concatenate( { Path_Assets, "Arial Unicode MS.ttf" } ) // font_arial_unicode_ms = font_load( path_arial_unicode_ms, 16.0, "Arial_Unicode_MS" ) - default_font = font_roboto_regular + default_font = font_noto_sans log( "Default font loaded" ) } @@ -315,7 +315,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem // menu_bar.pos = Vec2(app_window.extent) * { -1, 1 } menu_bar.size = {240, 40} - logger_scope.min_size = {360, 200} + log_scope.min_size = {360, 200} settings_menu.min_size = {360, 200} } diff --git a/code/sectr/ui/core/base.odin b/code/sectr/ui/core/base.odin index 413cb1c..fa6dd53 100644 --- a/code/sectr/ui/core/base.odin +++ b/code/sectr/ui/core/base.odin @@ -228,9 +228,9 @@ ui_graph_build_end :: proc( ui : ^UI_State ) render_queue := array_to_slice(ui.render_queue) for current := root.first; current != nil; current = ui_box_tranverse_next_depth_first( current ) { - // if ! current.computed.fresh { + if ! current.computed.fresh { ui_box_compute_layout( current ) - // } + } when UI_Render_Method == .Layers { diff --git a/code/sectr/ui/core/layout_compute.odin b/code/sectr/ui/core/layout_compute.odin index 21b18ce..50d14a8 100644 --- a/code/sectr/ui/core/layout_compute.odin +++ b/code/sectr/ui/core/layout_compute.odin @@ -204,7 +204,6 @@ ui_box_compute_layout :: proc( box : ^UI_Box, } computed.fresh = true && !dont_mark_fresh - content_size := size_range2(computed.bounds) if .Order_Children_Left_To_Right in layout.flags { ui_layout_children_horizontally( box, .Left_To_Right ) } @@ -236,7 +235,8 @@ ui_compute_children_overall_bounds :: proc ( box : ^UI_Box ) -> ( children_bound ui_box_compute_layout_children :: proc( box : ^UI_Box ) { - for current := box.first; current != nil && current.prev != box; current = ui_box_traverse_next_breadth_first( current, ) + // for current := box.first; current != nil && current.prev != box; current = ui_box_traverse_next_breadth_first( current, ) + for current := box.first; current != nil && current.prev != box; current = ui_box_tranverse_next_depth_first( current, parent_limit = box ) { if current == box do return if current.computed.fresh do continue diff --git a/code/sectr/ui/layout_widget.odin b/code/sectr/ui/layout_widget.odin index a204b07..9fbf9ba 100644 --- a/code/sectr/ui/layout_widget.odin +++ b/code/sectr/ui/layout_widget.odin @@ -5,6 +5,8 @@ import lalg "core:math/linalg" /* Widget Layout Ops + +TODO(Ed): Review this file, these are can now be done with ui_box_compute_layout */ ui_layout_children_horizontally :: proc( container : ^UI_Box, direction : UI_LayoutDirection_X, width_ref : ^f32 = nil ) diff --git a/code/sectr/ui/tests.odin b/code/sectr/ui/tests.odin index a273148..2da5285 100644 --- a/code/sectr/ui/tests.odin +++ b/code/sectr/ui/tests.odin @@ -288,12 +288,12 @@ test_whitespace_ast :: proc( default_layout : ^UI_Layout, frame_style_default : if len(line_hbox.text.str) > 0 { array_append( widgets_ptr, line_hbox ) text_layout.pos.x = text_layout.pos.x - text_layout.pos.y += size_range2(line_hbox.computed.bounds).y + text_layout.pos.y -= size_range2(line_hbox.computed.bounds).y } else { widget := & widgets.data[ widgets.num - 1 ] if widget.box != nil { - text_layout.pos.y += size_range2( widget.computed.bounds ).y + text_layout.pos.y -= size_range2( widget.computed.bounds ).y } } diff --git a/code/sectr/ui/widgets.odin b/code/sectr/ui/widgets.odin index 639e00a..25d125f 100644 --- a/code/sectr/ui/widgets.odin +++ b/code/sectr/ui/widgets.odin @@ -40,7 +40,7 @@ ui_drop_down :: proc( drop_down : ^UI_DropDown, label : string, title_text : Str direction := UI_LayoutDirection_Y.Top_To_Bottom, btn_flags := UI_BoxFlags{}, vb_flags := UI_BoxFlags{}, - vb_compute_layout := true, + vb_compute_layout := false, btn_theme : ^UI_Theme = nil, title_theme : ^UI_Theme = nil, vb_parent : ^UI_Box = nil, @@ -125,6 +125,8 @@ fixed size or "scale by ratio" flags are not used for the width. The hbox will use the anchor's (range2) ratio.x value to determine the "stretch ratio". Keep in mind the stretch ratio is only respected if no size.min.x value is violated for each of the widgets. + +TODO(Ed): We may no longer need to manually handle early compute_layout or direct calls to ui_layout_children_horizontally */ UI_HBox :: struct { @@ -151,7 +153,7 @@ ui_hbox_begin :: proc( direction : UI_LayoutDirection_X, label : string, flags : ui_hbox_end :: proc( hbox : UI_HBox, width_ref : ^f32 = nil, compute_layout := false ) { // profile(#procedure) - // if compute_layout do ui_box_compute_layout(hbox.box, dont_mark_fresh = true) + if compute_layout do ui_box_compute_layout(hbox.box, dont_mark_fresh = true) // ui_layout_children_horizontally( hbox.box, hbox.direction, width_ref ) } @@ -757,6 +759,8 @@ fixed size or "scale by ratio" flags are not used for the width. The hbox will use the anchor's (range2) ratio.y value to determine the "stretch ratio". Keep in mind the stretch ratio is only respected if no size.min.y value is violated for each of the widgets. + +TODO(Ed): We may no longer need to manually handle early compute_layout or direct calls to ui_layout_children_horizontally */ UI_VBox :: struct { @@ -769,7 +773,7 @@ ui_vbox_begin :: proc( direction : UI_LayoutDirection_Y, label : string, flags : vbox.direction = direction vbox.box = ui_box_make( flags, label ) vbox.signal = ui_signal_from_box( vbox.box ) - // if compute_layout do ui_box_compute_layout(vbox, dont_mark_fresh = true) + if compute_layout do ui_box_compute_layout(vbox, dont_mark_fresh = true) switch direction { case .Top_To_Bottom: vbox.layout.flags |= { .Order_Children_Top_To_Bottom } @@ -782,7 +786,7 @@ ui_vbox_begin :: proc( direction : UI_LayoutDirection_Y, label : string, flags : // Auto-layout children ui_vbox_end :: proc( vbox : UI_VBox, height_ref : ^f32 = nil, compute_layout := false ) { // profile(#procedure) - // if compute_layout do ui_box_compute_layout(vbox, dont_mark_fresh = true) + if compute_layout do ui_box_compute_layout(vbox, dont_mark_fresh = true) // ui_layout_children_vertically( vbox.box, vbox.direction, height_ref ) } diff --git a/code/sectr/ui/window.odin b/code/sectr/ui/window.odin index 561ebf6..85cec75 100644 --- a/code/sectr/ui/window.odin +++ b/code/sectr/ui/window.odin @@ -3,12 +3,9 @@ package sectr UI_Window :: struct { frame : UI_Widget, + vb : UI_VBox, bar : UI_HBox, - children_box : struct #raw_union { - box : UI_Widget, - hbox : UI_HBox, - vbox : UI_VBox, - }, + children_box : UI_Widget, tile_text : UI_Widget, maximize_btn : UI_Widget, close_btn : UI_Widget, @@ -58,47 +55,52 @@ ui_window_begin :: proc( window : ^UI_Window, label : string, if size.x < min_size.x do size.x = min_size.x if size.y < min_size.y do size.y = min_size.y + scope(theme_window_panel) frame = ui_widget(label, {}) - using frame + ui_parent(frame) if ! is_maximized { - layout.flags = { - .Fixed_Width, .Fixed_Height, + frame.layout.flags = { + .Fixed_Width, .Fixed_Height, .Fixed_Position_X, .Fixed_Position_Y, - .Origin_At_Anchor_Center + .Origin_At_Anchor_Center, + // .Order_Children_Top_To_Bottom, } - layout.pos = position - layout.size = range2( size, {}) + frame.layout.pos = position + frame.layout.size = range2( size, {}) } else { - layout.flags = {.Origin_At_Anchor_Center } - layout.pos = {} + frame.layout.flags = {.Origin_At_Anchor_Center } + frame.layout.pos = {} } if resizable { resized = ui_resizable_handles( & frame, & position, & size) } + scope(theme_transparent) + vb = ui_vbox(.Top_To_Bottom, str_fmt_tmp("%s.vb", label)) + if len(title.str) > 0 || closable || maximizable || draggable { dragged, maximized, closed = ui_window_bar(window, title, closable, maximizable, draggable) } - // child_bounds = bar.computed.bounds = - // child_position - + children_box = ui_widget(str_fmt_tmp("%v.children_box", label), {}) switch child_layout { - case .None: - - case .Left_To_Right: + children_box.layout.flags |= {.Order_Children_Left_To_Right} case .Right_to_Left: + children_box.layout.flags |= {.Order_Children_Right_To_Left} case .Top_To_Bottom: + children_box.layout.flags |= {.Order_Children_Top_To_Bottom} case .Bottom_To_Top: + children_box.layout.flags |= {.Order_Children_Bottom_To_Top} + case .None: + // Do nothing } - return } @@ -130,13 +132,13 @@ ui_window_bar :: proc( window : ^UI_Window, draggable_flag : UI_BoxFlags = draggable ? {.Mouse_Clickable} : {} scope(theme_window_bar) - bar = ui_hbox(.Left_To_Right, str_intern_fmt("%v.bar", frame.label). str, draggable_flag); + bar = ui_hbox(.Left_To_Right, str_fmt_tmp("%s.bar", frame.label.str), draggable_flag); ui_parent(bar) if len(title.str) > 0 { scope(theme_text) - tile_text = ui_text( str_intern_fmt("%v.title_text", bar.label).str, title, {.Disabled}); { + tile_text = ui_text( str_fmt_tmp("%s.title_text", bar.label.str), title, {.Disabled}); { using tile_text layout.anchor.ratio.x = 1.0 layout.margins = { 0, 0, 15, 0} @@ -147,7 +149,7 @@ ui_window_bar :: proc( window : ^UI_Window, scope(theme_window_bar_btn) if maximizable { - maximize_btn = ui_button( str_intern_fmt("%v.maximize_btn", bar.label).str ); { + maximize_btn = ui_button( str_fmt_tmp("%v.maximize_btn", bar.label.str) ); { using maximize_btn if maximize_btn.pressed { is_maximized = ~is_maximized @@ -159,7 +161,7 @@ ui_window_bar :: proc( window : ^UI_Window, } if closable { - close_btn = ui_button( str_intern_fmt("%v.close_btn", bar.label).str ); { + close_btn = ui_button( str_fmt_tmp("%v.close_btn", bar.label) ); { using close_btn text = str_intern("close") if close_btn.hot do style.bg_color = app_color_theme().window_btn_close_bg_hot