diff --git a/Readme.md b/Readme.md index b3dcea2..1b219ec 100644 --- a/Readme.md +++ b/Readme.md @@ -59,3 +59,4 @@ They'll be elaborated in their own documentation ![img](docs/assets/sectr_host_2024-05-04_12-29-39.png) ![img](docs/assets/Code_2024-05-04_12-55-53.png) ![img](docs/assets/sectr_host_2024-05-11_22-34-15.png) +![img](docs/assets/sectr_host_2024-05-15_03-32-36.png) diff --git a/code/app_screen.odin b/code/app_screen.odin index 34f2fc8..e7a8809 100644 --- a/code/app_screen.odin +++ b/code/app_screen.odin @@ -21,7 +21,7 @@ UI_ScreenState :: struct settings_menu : struct { pos, size, min_size : Vec2, - vb_container : UI_VBox, + container : UI_Widget, is_open : b32, is_maximized : b32, }, @@ -42,7 +42,7 @@ ui_screen_tick :: proc() { ui_floating_manager_end() } -ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 ) +ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 = false ) { profile("App Menu Bar") fmt :: str_fmt_alloc @@ -52,41 +52,17 @@ ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 ) { using state := get_state(); using screen_ui.menu_bar - ui_layout( UI_Layout { - flags = {.Fixed_Position_X, .Fixed_Position_Y, .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center}, - // anchor = range2({0.5, 0.5}, {0.5, 0.5} ), - alignment = { 0.5, 0.5 }, - border_width = 1.0, - font_size = 12, - // pos = {}, - pos = pos, - size = range2( size, {}), - }) - ui_style( UI_Style { - bg_color = { 0, 0, 0, 30 }, - border_color = { 0, 0, 0, 200 }, - font = default_font, - text_color = Color_White, - }) + ui_theme_app_menu_bar_default() container = ui_hbox( .Left_To_Right, "Menu Bar" ) + { + using container + layout.flags = {.Fixed_Position_X, .Fixed_Position_Y, .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center} + layout.pos = pos + layout.size = range2( size, {}) + text = str_intern("menu_bar") + } - ui_layout( UI_Layout { - flags = {}, - anchor = {}, - alignment = { 0.0, 0.0 }, - text_alignment = {0.5, 0.5}, - border_width = 1.0, - font_size = 12, - }) - style_theme := to_ui_style_combo({ - bg_color = Color_Frame_Disabled, - font = default_font, - text_color = Color_White, - }) - style_theme.hot.bg_color = Color_Blue - style_theme.active.bg_color = Color_Frame_Select - ui_style(style_theme) - + ui_theme_btn_default() move_box := ui_button("Move Box"); { using move_box @@ -94,22 +70,26 @@ ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 ) pos += input.mouse.delta should_raise = true } - layout.anchor.ratio.x = 0.2 + layout.anchor.ratio.x = 0.4 } spacer := ui_spacer("Menu Bar: Move Spacer") spacer.layout.flags |= {.Fixed_Width} - spacer.layout.size.min.x = 50 + spacer.layout.size.min.x = 30 + // TODO(Ed): Implement an external composition for theme interpolation using the settings btn settings_btn.widget = ui_button("Settings Btn") - settings_btn.text = str_intern("Settings") - settings_btn.layout.flags = { - // .Scale_Width_By_Height_Ratio, - .Fixed_Width - } - settings_btn.layout.size.min.x = 100 - if settings_btn.pressed { - screen_ui.settings_menu.is_open = true + { + using settings_btn + text = str_intern("Settings") + layout.flags = { + // .Scale_Width_By_Height_Ratio, + .Fixed_Width + } + layout.size.min.x = 100 + if pressed { + screen_ui.settings_menu.is_open = true + } } spacer = ui_spacer("Menu Bar: End Spacer") @@ -118,46 +98,44 @@ ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 ) return } -ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b32) +ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b32 = false) { profile("Settings Menu") using state := get_state() using state.screen_ui - if ! settings_menu.is_open do return false + if ! settings_menu.is_open do return using settings_menu if size.x < min_size.x do size.x = min_size.x if size.y < min_size.y do size.y = min_size.y - resize_box_base := ui_widget("Settings Menu Wrapper", {}) + container = ui_widget("Settings Menu", {}) { - using resize_box_base - layout.flags = { .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center, .Fixed_Position_X, .Fixed_Position_Y } - layout.pos = pos - layout.alignment = { 0.5, 0.5 } - layout.size = range2( size, {}) - style.bg_color = Color_3D_BG + using container + layout.flags = { .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center, .Fixed_Position_X, .Fixed_Position_Y } + layout.alignment = { 0.5, 0.5 } + // style.bg_color = Color_3D_BG + style.border_color = { 0, 0, 0, 200 } + layout.border_width = 1.0 + layout.pos = pos + layout.size = range2( size, {}) } - ui_parent(resize_box_base) + ui_parent(container) if settings_menu.is_maximized { - using resize_box_base + using container layout.flags = {.Origin_At_Anchor_Center } layout.pos = {} } - ui_resizable_handles( & resize_box_base, & pos, & size) + should_raise |= ui_resizable_handles( & container, & pos, & size) - vb_container = ui_vbox_begin( .Top_To_Bottom, "Settings Menu", {.Mouse_Clickable}, compute_layout = true) + vbox := ui_vbox_begin( .Top_To_Bottom, "Settings Menu: VBox", {.Mouse_Clickable}, compute_layout = true) { - { - using vb_container - flags = {} - style.bg_color = Color_BG_Panel_Translucent - } - ui_parent(vb_container) + vbox.style.bg_color = Color_BG_Panel_Translucent + ui_parent(vbox) ui_layout( UI_Layout { - font_size = 16, - alignment = {0, 0}, + // font_size = 16, + // alignment = {0, 1}, }) ui_style( UI_Style { bg_color = Color_Transparent, @@ -165,19 +143,16 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b text_color = Color_White, }) ui_style_ref().hot.bg_color = Color_Blue - frame_bar : UI_HBox - frame_bar = ui_hbox_begin(.Left_To_Right, "Settings Menu: Frame Bar", { .Mouse_Clickable, .Focusable, .Click_To_Focus }) + frame_bar := ui_hbox_begin(.Left_To_Right, "Settings Menu: Frame Bar", { .Mouse_Clickable, .Focusable, .Click_To_Focus }) { frame_bar.style.bg_color = Color_BG_Panel frame_bar.layout.flags = {.Fixed_Height} frame_bar.layout.size.min.y = 50 - frame_bar.layout.anchor.ratio.y = 0.25 + // frame_bar.layout.anchor.ratio.y = 0.8 ui_parent(frame_bar) ui_layout( UI_Layout { - font_size = 16, - // alignment = {1, 0}, - // anchor = range2({}, {}) + font_size = 18, }) title := ui_text("Settings Menu: Title", str_intern("Settings Menu"), {.Disabled}) { @@ -187,6 +162,10 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b layout.anchor.ratio.x = 1.0 } + ui_layout( UI_Layout { + font_size = 16, + }) + ui_style(ui_style_peek()) style := ui_style_ref() style.default.bg_color = Color_Black @@ -228,65 +207,70 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b should_raise = true } - ui_style( UI_Style { - bg_color = Color_Red, - font = default_font, - text_color = Color_White, - }) - // Populate settings with values from config (hardcoded for now) + ui_layout(UI_Layout { + flags = { + // .Origin_At_Anchor_Center, + // .Fixed_Height, + }, + // pos = {0, 50}, + // size = range2({100, 100},{}), + // alignment = {0,0}, + }) + ui_style( UI_Style { + // bg_color = Color_GreyRed + }) + drop_down_bar := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config drop_down_bar", {.Mouse_Clickable}) { - ui_layout(UI_Layout { - flags = { - // .Origin_At_Anchor_Center, - // .Fixed_Height, - }, - // pos = {0, 50}, - // size = range2({100, 100},{}), - // alignment = {0,0}, - }) - ui_style( UI_Style { - bg_color = Color_GreyRed - }) + drop_down_bar.layout.anchor.ratio.y = 0.1 { - drop_down_bar := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config drop_down_bar", {.Mouse_Clickable}) - drop_down_bar.layout.anchor.ratio.y = 1.0 - // drop_down_bar.style.bg_color = Color_Red - - ui_parent(drop_down_bar) - btn := ui_button("pls") - btn.text = str_intern("Config") - btn.style.font = default_font - btn.layout.font_size = 32 - btn.layout.size.min.y = 50 - btn.layout.text_alignment = { 0.5, 0.5 } - btn.layout.flags = {.Fixed_Width, .Size_To_Text} - // btn.layout.size.min = {50, 0} - btn.style.bg_color = Color_Green - ui_hbox_end(drop_down_bar, compute_layout = false) + using drop_down_bar + text = str_intern("drop_down_bar") + style.bg_color = { 55, 55, 55, 100 } + style.font = default_font + style.text_color = Color_White + layout.flags = {.Fixed_Height} + layout.font_size = 12 + layout.text_alignment = {1, 0} + layout.size.min.y = 35 } + ui_parent(drop_down_bar) - // ui_layout(UI_Layout { - - // }) - // ui_style( UI_Style { - - // }) - // res_width_hbox := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config.resolution_width: hbox", {}) - // ui_parent(res_width_hbox) + btn := ui_text("pls", str_intern("Lets figure this out...")) + { + using btn + text = str_intern("Config") + style.font = default_font + style.text_color = Color_White + layout.flags = {.Origin_At_Anchor_Center} + layout.alignment = {0.5, 0.25} // ??? (Wtf is this alignment) + layout.anchor.ratio.x = 1.0 + layout.font_size = 12 + layout.margins = {0,0, 15, 0} + layout.size.min.y = 35 + } + ui_hbox_end(drop_down_bar, compute_layout = false) + ui_box_compute_layout(btn) } + // ui_layout(UI_Layout { + + // }) + // ui_style( UI_Style { + + // }) + // res_width_hbox := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config.resolution_width: hbox", {}) + // ui_parent(res_width_hbox) + // ui_layout_ref().default.flags = {.Fixed_Width, .Fixed_Height, .Fixed_Position_Y} // ui_layout_ref().default.size.min = {50, 50} spacer := ui_spacer("Settings Menu: Spacer") - // spacer.style.bg_color = Color_Red spacer.layout.anchor.ratio.y = 1.0 // spacer.layout.flags = {.Origin_At_Anchor_Center} // spacer.layout.alignment = {0.5, 0.5} + // spacer.style.bg_color = Color_Red - // ui_box_compute_layout(spacer) - ui_vbox_end(vb_container, compute_layout = false ) - // ui_box_compute_layout(spacer) + ui_vbox_end(vbox, compute_layout = true ) } return } diff --git a/code/colors.odin b/code/colors.odin index f1d1ba4..1e0b8cc 100644 --- a/code/colors.odin +++ b/code/colors.odin @@ -27,3 +27,30 @@ Color_3D_BG :: Color { 188, 182 , 170, 255 } Color_Debug_UI_Padding_Bounds :: Color { 40, 195, 170, 160 } Color_Debug_UI_Content_Bounds :: Color { 170, 120, 240, 160 } + +// TODO(Ed): The entire rendering pass should be post-processed by a tone curve configurable for the user +// This is how you properly support any tonality of light or dark themes and not have it be base don the monitors raw output. + +// Dark Theme + +// Brightest value limited to (text is the only exception): +Color_ThmDark_BrightLimit :: Color {230, 230, 230, 255} +// Darkness value limited to (text is the only exception): +Color_ThmDark_DarkLimit :: Color {10, 10, 10, 255} + + +Color_ThmDark_BG :: Color {33, 33, 33, 255} + +Color_ThmDark_Border_Default :: Color { 64, 64, 64, 255} + +Color_ThmDark_Btn_BG_Default :: Color { 40, 40, 40, 255} +Color_ThmDark_Btn_BG_Hot :: Color { 60, 60, 70, 255} +Color_ThmDark_Btn_BG_Active :: Color { 90, 100, 130, 255} + +Color_ThmDark_Text_Default :: Color {120, 117, 115, 255} +Color_ThmDark_Text_Hot :: Color {180, 180, 180, 255} +Color_ThmDark_Text_Active :: Color {240, 240, 240, 255} + +// Light Theme + +// LightTheme_BG :: Color { 120, 120, 120, 255 } \ No newline at end of file diff --git a/code/engine_api.odin b/code/engine_api.odin index f812dfb..3d45657 100644 --- a/code/engine_api.odin +++ b/code/engine_api.odin @@ -171,7 +171,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem // Setup the screen ui state { ui_startup( & screen_ui.base, cache_allocator = persistent_slab_allocator() ) - ui_floating_startup( & screen_ui.floating, persistent_slab_allocator(), 16 * Kilobyte, 16 * Kilobyte, "screen ui floating manager" ) + ui_floating_startup( & screen_ui.floating, persistent_slab_allocator(), 1 * Kilobyte, 1 * Kilobyte, "screen ui floating manager" ) using screen_ui menu_bar.pos = { -60, 0 } @@ -277,7 +277,7 @@ reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem, slab_reload( persistent_slab, persistent_allocator() ) - hmap_chained_reload( font_provider_data.font_cache, persistent_slab_allocator()) + hmap_chained_reload( font_provider_data.font_cache, persistent_allocator()) slab_reload( string_cache.slab, persistent_allocator() ) zpl_hmap_reload( & string_cache.table, persistent_slab_allocator()) @@ -318,9 +318,9 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32 rl.PollInputEvents() - debug.draw_ui_box_bounds_points = true - debug.draw_UI_padding_bounds = true - debug.draw_ui_content_bounds = true + debug.draw_ui_box_bounds_points = false + debug.draw_UI_padding_bounds = false + debug.draw_ui_content_bounds = false should_close = update( host_delta_time ) render() @@ -331,8 +331,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 = 6 + config.engine_refresh_hz = uint(monitor_refresh_hz) + // config.engine_refresh_hz = 6 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 diff --git a/code/grime_linked_list.odin b/code/grime_linked_list.odin index d576fcc..ff0828a 100644 --- a/code/grime_linked_list.odin +++ b/code/grime_linked_list.odin @@ -128,7 +128,7 @@ dll_pop_back :: #force_inline proc "contextless" ( current_ptr : ^(^ ($ Type)) ) } } -dll_full_insert_raw :: proc "contextless" ( null : ^($ Type), parent, pos, node : ^Type ) +dll_full_insert_raw :: proc "contextless" ( null : ^($ Type), parent : ^$ParentType, pos, node : ^Type ) { if parent.first == null { parent.first = node @@ -161,7 +161,7 @@ dll_full_insert_raw :: proc "contextless" ( null : ^($ Type), parent, pos, node } } -dll_full_pop :: proc "contextless" ( node, parent : ^$Type ) { +dll_full_pop :: proc "contextless" ( node : ^$NodeType, parent : ^$ParentType ) { if node == nil { return } @@ -171,20 +171,19 @@ 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 + prev := node.prev + next := node.next + if prev != nil { + prev.next = next node.prev = nil } - if node.next != nil { - node.next.prev = nil + if next != nil { + next.prev = prev node.next = nil } } -dll_full_push_back :: proc "contextless" ( parent, node : ^ $Type, null : ^Type ) { +dll_full_push_back :: proc "contextless" ( parent : ^$ParentType, node : ^$Type, null : ^Type ) { dll_full_insert_raw( null, parent, parent.last, node ) } diff --git a/code/grime_stack.odin b/code/grime_stack.odin index 1088941..88f79ac 100644 --- a/code/grime_stack.odin +++ b/code/grime_stack.odin @@ -185,7 +185,7 @@ stack_allocator_proc :: proc( alignment : int, old_memory : rawptr, old_size : int, - location : SourceCodeLocation = #caller_location + // location : SourceCodeLocation = #caller_location ) -> ([]byte, AllocatorError) { stack := StackAllocator { cast( ^StackAllocatorBase) allocator_data } diff --git a/code/grime_virtual_arena.odin b/code/grime_virtual_arena.odin index d942480..3ae40bc 100644 --- a/code/grime_virtual_arena.odin +++ b/code/grime_virtual_arena.odin @@ -196,7 +196,7 @@ varena_allocator_proc :: proc( alignment : int, old_memory : rawptr, old_size : int, - location : SourceCodeLocation = #caller_location + // location : SourceCodeLocation = #caller_location ) -> ( data : []byte, alloc_error : AllocatorError) { arena := cast( ^VArena) allocator_data diff --git a/code/tick_render.odin b/code/tick_render.odin index eff7fa3..3090dc5 100644 --- a/code/tick_render.odin +++ b/code/tick_render.odin @@ -32,7 +32,7 @@ render :: proc() render_mode_3d() rl.BeginDrawing() - rl.ClearBackground( Color_BG ) + rl.ClearBackground( Color_ThmDark_BG ) render_mode_2d_workspace() render_mode_screenspace() diff --git a/code/tick_update.odin b/code/tick_update.odin index b818637..cc02763 100644 --- a/code/tick_update.odin +++ b/code/tick_update.odin @@ -240,7 +240,7 @@ update :: proc( delta_time : f64 ) -> b32 // test_draggable() // test_text_box() // test_parenting( & default_layout, & frame_style_default ) - test_whitespace_ast( & default_layout, & frame_style_default ) + // test_whitespace_ast( & default_layout, & frame_style_default ) } //endregion Workspace Imgui Tick diff --git a/code/ui_box.odin b/code/ui_box.odin index aa0a3df..13288ac 100644 --- a/code/ui_box.odin +++ b/code/ui_box.odin @@ -87,8 +87,6 @@ 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) prev_box := zpl_hmap_get( prev_cache, cast(u64) key ) { @@ -119,15 +117,17 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box) // Clear non-persistent data curr_box.computed.fresh = false - curr_box.links = links_perserved + curr_box.links = {} curr_box.num_children = 0 // If there is a parent, setup the relevant references parent := stack_peek( & parent_stack ) if parent != nil { - dll_full_push_back( parent, curr_box, nil ) - when false + when false { + dll_full_push_back( parent, curr_box, nil ) + } + else { // | // v @@ -160,8 +160,6 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box) ui_box_tranverse_next :: proc "contextless" ( box : ^ UI_Box ) -> (^ UI_Box) { - parent := box.parent - // 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() @@ -179,6 +177,16 @@ ui_box_tranverse_next :: proc "contextless" ( box : ^ UI_Box ) -> (^ UI_Box) // There is no more adjacent nodes if box.parent != nil { + parent := box.parent + // Attempt to find a parent with a next, otherwise we just return a parent with nil + for ; parent.parent != nil; + { + if parent.next != nil { + break + } + parent = parent.parent + } + // Lift back up to parent, and set it to its next. return parent.next } diff --git a/code/ui_floating.odin b/code/ui_floating.odin index 7060401..84483d6 100644 --- a/code/ui_floating.odin +++ b/code/ui_floating.odin @@ -100,7 +100,7 @@ ui_floating_build :: proc() lookup := hmap_chained_get( tracked, transmute(u64) key ) // Check if entry is already present - if lookup != nil && lookup.prev != nil && lookup.next != nil { + if lookup != nil && (lookup.next != nil || lookup == last) { lookup.captures = to_enqueue.captures lookup.builder = to_enqueue.builder lookup.queued = true @@ -115,30 +115,36 @@ ui_floating_build :: proc() ensure(false, "Failed to allocate entry to hashtable") continue } - lookup.queued = true } else { lookup.captures = to_enqueue.captures lookup.builder = to_enqueue.builder - lookup.queued = true - continue } - + lookup.queued = true if first == nil { first = lookup last = lookup continue } - last.next = lookup - last = lookup + if first == last { + last = lookup + last.prev = first + first.next = last + continue + } + last.next = lookup + lookup.prev = last + last = lookup } array_clear(build_queue) + to_raise : ^UI_Floating for entry := first; entry != nil; entry = entry.next { - using entry - if ! queued + if ! entry.queued { + ensure(false, "There should be no queue failures yet") + if entry == first { first = entry.next @@ -162,39 +168,45 @@ ui_floating_build :: proc() entry.next = nil } - if builder( captures ) && entry != last + if entry.builder( entry.captures ) && entry != last && to_raise == nil { - PopEntry: - { - if first == nil { - first = entry - last = entry - break PopEntry - } - if entry == first - { - first = entry.next - entry.next = nil - break PopEntry - } - if entry == last - { - last = last.prev - last.prev = nil - entry.prev = nil - break PopEntry - } - - left := entry.prev - right := entry.next - - left.next = right - right.prev = left - } - - last.next = entry - last = entry + to_raise = entry } - queued = false + entry.queued = false + } + if to_raise != nil + { + dll_full_pop( to_raise, floating ) + dll_full_push_back( floating, to_raise, nil ) + // PopEntry: + // { + // if first == nil { + // first = to_raise + // last = to_raise + // break PopEntry + // } + // if to_raise == first + // { + // first = to_raise.next + // to_raise.next.prev = nil + // break PopEntry + // } + // if to_raise == last + // { + // // Do nothing no need to modify order + // return + // } + + // left := to_raise.prev + // right := to_raise.next + + // left.next = right + // right.prev = left + // } + + // last.next = to_raise + // to_raise.prev = last + // last.next = nil + // last = to_raise } } diff --git a/code/ui_layout_compute.odin b/code/ui_layout_compute.odin index 903b8e2..d68a1cb 100644 --- a/code/ui_layout_compute.odin +++ b/code/ui_layout_compute.odin @@ -170,8 +170,8 @@ ui_box_compute_layout_children :: proc( box : ^UI_Box ) { for current := box.first; current != nil; current = ui_box_tranverse_next( current ) { - // if current == box do return - // if current.computed.fresh do continue + if current == box do return + if current.computed.fresh do continue ui_box_compute_layout( current ) } } diff --git a/code/ui_layout_widget.odin b/code/ui_layout_widget.odin index 540e438..4d5a986 100644 --- a/code/ui_layout_widget.odin +++ b/code/ui_layout_widget.odin @@ -44,9 +44,9 @@ ui_layout_children_horizontally :: proc( container : ^UI_Box, direction : UI_Lay { using child.layout if ! (.Fixed_Width in flags) { - size.min.x = anchor.ratio.x * (1 / total_stretch_ratio) * avail_flex_space + size.min.x = anchor.ratio.x * (1 / total_stretch_ratio) * avail_flex_space - child.layout.margins.left - child.layout.margins.right } - flags |= {.Fixed_Width} + flags |= {.Fixed_Width} } space_used : f32 = 0.0 @@ -56,20 +56,16 @@ ui_layout_children_horizontally :: proc( container : ^UI_Box, direction : UI_Lay allocate_space(child, total_stretch_ratio, avail_flex_space) using child.layout anchor = range2({0, 0}, {0, 0}) - // alignment = { 0, 0 }// - hbox.layout.alignment pos.x = space_used - space_used += size.min.x - // size.min.y = container.computed.content.max.y - container.computed.content.min.y + space_used += size.min.x + child.layout.margins.left + child.layout.margins.right } case .Left_To_Right: for child := container.first; child != nil; child = child.next { allocate_space(child, total_stretch_ratio, avail_flex_space) using child.layout anchor = range2({0, 0}, {0, 0}) - // alignment = { 0, 0 } pos.x = space_used - space_used += size.min.x - // size.min.y = container.computed.content.max.y - container.computed.content.min.y + space_used += size.min.x + child.layout.margins.left + child.layout.margins.right } } } @@ -114,18 +110,19 @@ ui_layout_children_vertically :: proc( container : ^UI_Box, direction : UI_Layou { using child.layout if ! (.Fixed_Height in flags) { - size.min.y = anchor.ratio.y * (1 / total_stretch_ratio) * avail_flex_space + size.min.y = (anchor.ratio.y * (1 / total_stretch_ratio) * avail_flex_space) } flags |= {.Fixed_Height} } space_used : f32 = 0.0 - switch direction { + switch direction + { case .Bottom_To_Top: for child := container.last; child != nil; child = child.prev { allocate_space(child, total_stretch_ratio, avail_flex_space) using child.layout - anchor = range2({0, 0}, {0, 0}) + anchor = range2({0,0}, {0, 0}) // alignment = {0, 0} pos.y = -space_used space_used += size.min.y diff --git a/code/ui_theme.odin b/code/ui_theme.odin index 1790c41..beb7c0c 100644 --- a/code/ui_theme.odin +++ b/code/ui_theme.odin @@ -42,13 +42,141 @@ UI Themes: Comprise of UI_Box's layout & style Provides presets for themes and their interface for manipulating the combo stacks in UI_State in pairs */ +// TODO(Ed): Eventually this will have a configuration wizard, and we'll save the presets -UI_Theme_Btn_Default :: UI_Theme { +/* +UI_Theme_Template :: UI_Theme { + UI_Layout { + flags = {}, + anchor = Range2{{},{}}, + alignment = {}, + text_alignment = {}, + font_size = {}, + margins = {}, + padding = {}, + border_width = {}, + pos = {}, + size = Range2{{},{}} + }, + UI_Style { + bg_color = {}, + corner_radii = {}, + blur_size = 0, + font = {}, + text_color = {}, + cursor = 0, + } +} +*/ +@(deferred_none = ui_theme_pop) +ui_theme_app_menu_bar_default :: proc() +{ + @static theme : UI_Theme + // @static loaded : b32 = false + // if true && ! loaded + // { + layout := UI_Layout { + flags = {}, + anchor = range2({},{}), + alignment = {0.5, 0.5}, + text_alignment = {0.0, 1.5}, + font_size = 12, + margins = {0, 0, 0, 0}, + padding = {0, 0, 0, 0}, + border_width = 0.6, + pos = {0, 0}, + size = range2({},{}) + } + style := UI_Style { + bg_color = Color_ThmDark_BG, + border_color = Color_ThmDark_Border_Default, + corner_radii = {}, + blur_size = 0, + font = get_state().default_font, + text_color = Color_ThmDark_Text_Default, + cursor = {}, + } + + // loaded = true + layout_combo := to_ui_layout_combo(layout) + style_combo := to_ui_style_combo(style) + { + using layout_combo.hot + using style_combo.hot + bg_color = Color_ThmDark_Btn_BG_Hot + text_color = Color_ThmDark_Text_Hot + } + { + using layout_combo.active + using style_combo.active + bg_color = Color_ThmDark_Btn_BG_Active + text_color = Color_ThmDark_Text_Active + } + + theme = UI_Theme { + layout_combo, style_combo + } + // } + + + ui_layout_push(theme.layout) + ui_style_push(theme.style) } -@(deferred_none = ui_layout_pop) -ui_theme_btn_default :: #force_inline proc() { - ui_layout_push(UI_Theme_Btn_Default.layout) - ui_style_push(UI_Theme_Btn_Default.style) +@(deferred_none = ui_theme_pop) +ui_theme_btn_default :: proc() +{ + @static theme : UI_Theme + // @static loaded : b32 = false + // if true && ! loaded + // { + layout := UI_Layout { + flags = {}, + anchor = range2({},{}), + alignment = {0, 0}, + text_alignment = {0.5, 0.5}, + font_size = 16, + margins = {0, 0, 0, 0}, + padding = {0, 0, 0, 0}, + border_width = 1, + pos = {0, 0}, + size = range2({},{}) + } + style := UI_Style { + bg_color = Color_ThmDark_Btn_BG_Default, + border_color = Color_ThmDark_Border_Default, + corner_radii = {}, + blur_size = 0, + font = get_state().default_font, + text_color = Color_ThmDark_Text_Default, + cursor = {}, + } + + // loaded = true + layout_combo := to_ui_layout_combo(layout) + style_combo := to_ui_style_combo(style) + { + using layout_combo.hot + using style_combo.hot + bg_color = Color_ThmDark_Btn_BG_Hot + text_color = Color_ThmDark_Text_Hot + margins = {2, 2, 2, 2} + } + { + using layout_combo.active + using style_combo.active + bg_color = Color_ThmDark_Btn_BG_Active + text_color = Color_ThmDark_Text_Active + margins = {2, 2, 2, 2} + } + + theme = UI_Theme { + layout_combo, style_combo + } + // } + + + ui_layout_push(theme.layout) + ui_style_push(theme.style) } diff --git a/code/ui_widgets.odin b/code/ui_widgets.odin index 8068d81..8331afe 100644 --- a/code/ui_widgets.odin +++ b/code/ui_widgets.odin @@ -165,7 +165,7 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2, corner_tl := true, corner_br := true, corner_bl := true, - compute_layout := true) + compute_layout := true) -> (drag_signal : b32) { profile(#procedure) handle_left : UI_Widget @@ -259,15 +259,15 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2, target_alignment : Vec2, pos : ^Vec2, size : ^Vec2, - alignment : ^Vec2, ) + alignment : ^Vec2, ) -> b32 { ui := get_state().ui_context - if ui.last_pressed_key != handle.key { return } + if ui.last_pressed_key != handle.key { return false } size_delta := size_delta pos_adjust := size^ * (alignment^ - target_alignment) - @static was_dragging := false + @static was_dragging : b32 = false using handle if active @@ -287,21 +287,23 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2, alignment^ = target_alignment was_dragging = false } + return was_dragging } delta := get_state().input.mouse.delta alignment := & parent.layout.alignment - if right do process_handle_drag( & handle_right, { 1, 0 }, delta, {0, 0}, pos, size, alignment ) - if left do process_handle_drag( & handle_left, { -1, 0 }, delta, {1, 0}, pos, size, alignment ) - if top do process_handle_drag( & handle_top, { 0, 1 }, delta, {0, 0}, pos, size, alignment ) - if bottom do process_handle_drag( & handle_bottom, { 0, -1 }, delta, {0, 1}, pos, size, alignment ) - if corner_tr do process_handle_drag( & handle_corner_tr, { 1, 1 }, delta, {0, 0}, pos, size, alignment ) - if corner_tl do process_handle_drag( & handle_corner_tl, { -1, 1 }, delta, {1, 0}, pos, size, alignment ) - if corner_br do process_handle_drag( & handle_corner_br, { 1, -1 }, delta, {0, 1}, pos, size, alignment ) - if corner_bl do process_handle_drag( & handle_corner_bl, { -1, -1 }, delta, {1, 1}, pos, size, alignment ) + if right do drag_signal |= process_handle_drag( & handle_right, { 1, 0 }, delta, {0, 0}, pos, size, alignment ) + if left do drag_signal |= process_handle_drag( & handle_left, { -1, 0 }, delta, {1, 0}, pos, size, alignment ) + if top do drag_signal |= process_handle_drag( & handle_top, { 0, 1 }, delta, {0, 0}, pos, size, alignment ) + if bottom do drag_signal |= process_handle_drag( & handle_bottom, { 0, -1 }, delta, {0, 1}, pos, size, alignment ) + if corner_tr do drag_signal |= process_handle_drag( & handle_corner_tr, { 1, 1 }, delta, {0, 0}, pos, size, alignment ) + if corner_tl do drag_signal |= process_handle_drag( & handle_corner_tl, { -1, 1 }, delta, {1, 0}, pos, size, alignment ) + if corner_br do drag_signal |= process_handle_drag( & handle_corner_br, { 1, -1 }, delta, {0, 1}, pos, size, alignment ) + if corner_bl do drag_signal |= process_handle_drag( & handle_corner_bl, { -1, -1 }, delta, {1, 1}, pos, size, alignment ) ui_box_compute_layout(parent) + return } #endregion("Resizable") diff --git a/docs/assets/sectr_host_2024-05-15_03-32-36.png b/docs/assets/sectr_host_2024-05-15_03-32-36.png new file mode 100644 index 0000000..0241560 Binary files /dev/null and b/docs/assets/sectr_host_2024-05-15_03-32-36.png differ diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 7954386..7cad078 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -167,10 +167,10 @@ push-location $path_root $build_args += $flag_output_path + $module_dll $build_args += ($flag_collection + $pkg_collection_thirdparty) # $build_args += $flag_micro_architecture_native - $build_args += $flag_use_separate_modules - $build_args += $flag_thread_count + $CoreCount_Physical - $build_args += $flag_optimize_none - # $build_args += $flag_optimize_minimal + # $build_args += $flag_use_separate_modules + # $build_args += $flag_thread_count + $CoreCount_Physical + # $build_args += $flag_optimize_none + $build_args += $flag_optimize_minimal # $build_args += $flag_optimize_speed # $build_args += $falg_optimize_aggressive $build_args += $flag_debug @@ -249,8 +249,8 @@ push-location $path_root $build_args += $flag_output_path + $executable $build_args += ($flag_collection + $pkg_collection_thirdparty) # $build_args += $flag_micro_architecture_native - $build_args += $flag_use_separate_modules - $build_args += $flag_thread_count + $CoreCount_Physical + # $build_args += $flag_use_separate_modules + # $build_args += $flag_thread_count + $CoreCount_Physical $build_args += $flag_optimize_none # $build_args += $flag_optimize_minimal # $build_args += $flag_optimize_speed