Moved settings menu to its own file, got min_size based on content working (only for the settings menu)

This commit is contained in:
Edward R. Gonzalez 2024-12-30 12:22:41 -05:00
parent 57d51fc7b1
commit 8905105d40
6 changed files with 616 additions and 555 deletions

View File

@ -19,24 +19,7 @@ UI_ScreenState :: struct
}
},
settings_menu : struct
{
container : UI_Widget,
engine_refresh_inputbox : UI_TextInputBox,
min_zoom_inputbox : UI_TextInputBox,
max_zoom_inputbox : UI_TextInputBox,
zoom_smooth_snappiness_input : UI_TextInputBox,
zoom_smooth_sensitivity_input : UI_TextInputBox,
zoom_digital_sensitivity_input : UI_TextInputBox,
zoom_scroll_delta_scale_input : UI_TextInputBox,
font_size_canvas_scalar_input : UI_TextInputBox,
font_size_screen_scalar_input : UI_TextInputBox,
cfg_drop_down : UI_DropDown,
zoom_mode_drop_down : UI_DropDown,
pos, size, min_size : Vec2,
is_open : b32,
is_maximized : b32,
},
settings_menu : UI_SettingsMenu
}
ui_screen_reload :: proc() {
@ -151,519 +134,3 @@ ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 = f
}
return
}
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
app_color := app_color_theme()
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
Construct_Container:
{
scope(theme_window_panel)
container = ui_widget("Settings Menu", {});
if ! settings_menu.is_maximized {
using container
layout.flags = {
// .Size_To_Content,
.Fixed_Width, .Fixed_Height,
.Fixed_Position_X, .Fixed_Position_Y,
.Origin_At_Anchor_Center
}
layout.pos = pos
layout.size = range2( size, {})
}
else {
using container
layout.flags = {.Origin_At_Anchor_Center }
layout.pos = {}
}
old_vbox := ui_box_from_key(prev_cache, ui_key_from_string("Settings Menu: VBox"))
if old_vbox != nil {
vbox_size := size_range2(old_vbox.computed.bounds)
larger_than_size := vbox_size.x > size.x || vbox_size.y > size.y
if ! settings_menu.is_maximized && larger_than_size
{
size = vbox_size
container.layout.size = range2(size, {})
}
}
should_raise |= ui_resizable_handles( & container, & pos, & size)
}
ui_parent_push(container)
vbox := ui_vbox_begin( .Top_To_Bottom, "Settings Menu: VBox", {.Mouse_Clickable}, compute_layout = true )
{
should_raise |= b32(vbox.active)
ui_parent(vbox)
Frame_Bar:
{
scope(theme_window_bar)
frame_bar := ui_hbox(.Left_To_Right, "Settings Menu: Frame Bar", { .Mouse_Clickable })
{
ui_parent(frame_bar)
scope(theme_text)
title := ui_text("Settings Menu: Title", str_intern("Settings Menu"), {.Disabled}); {
using title
layout.anchor.ratio.x = 1.0
layout.margins = { 0, 0, 15, 0}
layout.font_size = 14
}
scope(theme_window_bar_btn)
maximize_btn := ui_button("Settings Menu: Maximize Btn"); {
using maximize_btn
if maximize_btn.pressed {
settings_menu.is_maximized = ~settings_menu.is_maximized
should_raise = true
}
if settings_menu.is_maximized do text = str_intern("min")
else do text = str_intern("max")
}
close_btn := ui_button("Settings Menu: Close Btn"); {
using close_btn
text = str_intern("close")
if close_btn.hot do style.bg_color = app_color.window_btn_close_bg_hot
if close_btn.pressed do settings_menu.is_open = false
style.corner_radii = { 0, 0, 0, 0 }
}
}
if frame_bar.active {
pos += input.mouse.delta
should_raise = true
}
}
// TODO(Ed): This will eventually be most likely generalized/compressed. For now its the main scope for implementing new widgets.
app_config := ui_drop_down( & cfg_drop_down, "settings_menu.config", str_intern("App Config"), vb_compute_layout = true)
app_config.title.layout.font_size = 12
if app_config.is_open
{
ui_settings_entry_inputbox :: proc( input_box : ^UI_TextInputBox, is_even : bool, label : string, setting_title : StrRunesPair, input_policy : UI_TextInput_Policy )
{
scope( theme_table_row(is_even))
hb := ui_hbox(.Left_To_Right, str_intern_fmt("%v.hb", label).str); {
using hb
layout.size.min = {0, 25}
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
}
scope(theme_text)
title := ui_text(str_intern_fmt("%v.title", label).str, setting_title); {
using title
layout.anchor.ratio.x = 1.0
layout.margins.left = 10
layout.font_size = 12
}
ui_text_input_box( input_box, str_intern_fmt("%v.input_box", label).str, allocator = persistent_slab_allocator(), policy = input_policy )
{
using input_box
layout.flags = {.Fixed_Width}
layout.margins.left = 5
layout.padding.right = 5
layout.size.min.x = 80
style.corner_radii = { 3, 3, 3, 3 }
}
}
Engine_Refresh_Hz:
{
scope(theme_table_row(is_even = false))
hb := ui_hbox(.Left_To_Right, "settings_menu.engine_refresh_hz.hb"); { using hb
layout.size.min = {0, 25}
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
}
title : UI_Widget; {
scope(theme_text)
title = ui_text("settings_menu.engine_refresh_hz.title", str_intern("Engine Refresh Hz"))
using title
layout.anchor.ratio.x = 1.0
layout.margins.left = 10
title.layout.font_size = 12
}
engine_refresh_config: {
using min_zoom_inputbox
digits_only = true
disallow_leading_zeros = true
disallow_decimal = true
digit_min = 1
digit_max = 9999
max_length = 4
}
ui_text_input_box( & engine_refresh_inputbox, "settings_menu.engine_refresh_hz.inputbox", allocator = persistent_slab_allocator() )
{
using engine_refresh_inputbox
layout.flags = {.Fixed_Width}
layout.margins.left = 5
layout.padding.right = 5
layout.size.min.x = 80
style.corner_radii = { 3, 3, 3, 3 }
if was_active
{
value, success := parse_uint(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 1, 9999)
config.engine_refresh_hz = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.engine_refresh_hz)))
}
}
}
Min_Zoom:
{
scope( theme_table_row(is_even = true))
hb := ui_hbox(.Left_To_Right, "settings_menu.cam_min_zoom.hb"); {
using hb
layout.size.min = {0, 25}
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
}
scope(theme_text)
title := ui_text("settings_menu.cam_min_zoom.title", str_intern("Camera: Min Zoom")); {
using title
layout.anchor.ratio.x = 1.0
layout.margins.left = 10
layout.font_size = 12
}
min_zoom_config: {
using min_zoom_inputbox
digits_only = true
disallow_leading_zeros = false
disallow_decimal = false
digit_min = 0.01
digit_max = 9999
max_length = 5
}
ui_text_input_box( & min_zoom_inputbox, "settings_menu.cam_min_zoom.input_box", allocator = persistent_slab_allocator() )
{
using min_zoom_inputbox
layout.flags = {.Fixed_Width}
layout.margins.left = 5
layout.padding.right = 5
layout.size.min.x = 80
style.corner_radii = { 3, 3, 3, 3 }
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_min_zoom = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_min_zoom)))
}
}
}
Max_Zoom:
{
scope( theme_table_row(is_even = false))
hb := ui_hbox(.Left_To_Right, "settings_menu.cam_max_zoom.hb"); {
using hb
layout.size.min = {0, 25}
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
}
scope(theme_text)
title := ui_text("settings_menu.cam_max_zoom.title", str_intern("Camera: Max Zoom")); {
using title
layout.anchor.ratio.x = 1.0
layout.margins.left = 10
layout.font_size = 12
}
max_zoom_config: {
using max_zoom_inputbox
digits_only = true
disallow_leading_zeros = false
disallow_decimal = false
digit_min = 0.01
digit_max = 9999
max_length = 5
ui_text_input_box( & max_zoom_inputbox, "settings_menu.cam_max_zoom.input_box", allocator = persistent_slab_allocator() )
{
using max_zoom_inputbox
layout.flags = {.Fixed_Width}
layout.margins.left = 5
layout.padding.right = 5
layout.size.min.x = 80
style.corner_radii = { 3, 3, 3, 3 }
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_max_zoom = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_max_zoom)))
}
}
}
}
Zoom_Mode:
{
scope( theme_table_row(is_even = true))
hb := ui_hbox(.Left_To_Right, "settings_menu.cam_zoom_mode.hb"); {
using hb
layout.size.min = {0, 35}
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
}
scope(theme_text)
title := ui_text("settings_menu.cam_zoom_mode.title", str_intern("Camera: Zoom Mode")); {
using title
layout.anchor.ratio.x = 1.0
layout.margins.left = 10
layout.font_size = 12
}
// TODO(Ed): This is technically a manual drop-down as the vbox within ui_dropdown is unusuable for attaching the buttons
// This can be alleviated if we add an option for the drop-down to support a floating vbox (fixed position computed, following drop_down btn)
// For now its buttons are attached to app_config vbox
mode_selector := ui_drop_down( & zoom_mode_drop_down, "settings_menu.cam_zoom_mode.drop_down", str_intern_fmt("%s", config.cam_zoom_mode), vb_compute_layout = true )
mode_selector.btn.layout.size.min = { 80, mode_selector.btn.layout.size.min.y }
if mode_selector.is_open
{
idx := 1
for entry in CameraZoomMode
{
ui_parent(app_config.vbox)
scope(theme_button)
btn := ui_button(str_intern_fmt("settings_menu.cam_zoom_mode.%s.btn", entry).str)
{
using btn
layout.size.min = {100, 25}
layout.alignment = {1.0, 0}
layout.anchor.left = 1.0
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
ui_parent(btn)
scope(theme_text)
text_widget := ui_text(str_intern_fmt("settings_menu.cam_zoom_mode.%s.text", entry).str, str_intern_fmt("%s", entry))
}
if btn.pressed {
mode_selector.should_close = true
config.cam_zoom_mode = entry
screen_ui.active = 0
}
}
}
}
Cam_Zoom_Smooth_Snappiness:
{
ui_settings_entry_inputbox( & zoom_smooth_snappiness_input, false, "settings_menu.cam_zoom_smooth_snappiness", str_intern("Camera: Zoom Smooth Snappiness"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using zoom_smooth_snappiness_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_zoom_smooth_snappiness = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_zoom_smooth_snappiness)))
}
}
Cam_Zoom_Sensitivity_Smooth:
{
ui_settings_entry_inputbox( & zoom_smooth_sensitivity_input, true, "settings_menu.cam_zoom_sensitivity_smooth", str_intern("Camera: Zoom Smooth Sensitivity"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using zoom_smooth_sensitivity_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_zoom_sensitivity_smooth = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_zoom_sensitivity_smooth)))
}
}
Cam_Zoom_Sensitivity_Digital:
{
ui_settings_entry_inputbox( & zoom_digital_sensitivity_input, false, "settings_menu.cam_zoom_sensitivity_digital", str_intern("Camera: Zoom Digital Sensitivity"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using zoom_digital_sensitivity_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_zoom_sensitivity_digital = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_zoom_sensitivity_digital)))
}
}
Cam_Zoom_Scroll_Delta_Scale:
{
ui_settings_entry_inputbox( & zoom_scroll_delta_scale_input, true, "settings_menu.cam_zoom_scroll_delta_scale", str_intern("Camera: Zoom Scroll Delta Scale"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using zoom_scroll_delta_scale_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_zoom_scroll_delta_scale = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_zoom_scroll_delta_scale)))
}
}
Font_Size_Screen_Scalar:
{
ui_settings_entry_inputbox( & font_size_screen_scalar_input, false, "settings_menu.font_size_screen_scalar", str_intern("Font: Size Screen Scalar"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using font_size_screen_scalar_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.font_size_screen_scalar = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.font_size_screen_scalar)))
}
}
Font_Size_Canvas_Scalar:
{
ui_settings_entry_inputbox( & font_size_canvas_scalar_input, false, "settings_menu.font_size_canvas_scalar", str_intern("Font: Size Canvas Scalar"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using font_size_canvas_scalar_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.font_size_canvas_scalar = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.font_size_canvas_scalar)))
}
}
}
}
ui_vbox_end(vbox, compute_layout = false )
ui_parent_pop() // container
return
}

View File

@ -0,0 +1,551 @@
package sectr
UI_SettingsMenu :: struct
{
container : UI_Widget,
engine_refresh_inputbox : UI_TextInputBox,
min_zoom_inputbox : UI_TextInputBox,
max_zoom_inputbox : UI_TextInputBox,
zoom_smooth_snappiness_input : UI_TextInputBox,
zoom_smooth_sensitivity_input : UI_TextInputBox,
zoom_digital_sensitivity_input : UI_TextInputBox,
zoom_scroll_delta_scale_input : UI_TextInputBox,
font_size_canvas_scalar_input : UI_TextInputBox,
font_size_screen_scalar_input : UI_TextInputBox,
cfg_drop_down : UI_DropDown,
zoom_mode_drop_down : UI_DropDown,
pos, size, min_size : Vec2,
is_open : b32,
is_maximized : b32,
}
ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b32 = false)
{
profile("Settings Menu")
state := get_state()
using state
using screen_ui
if ! settings_menu.is_open do return
app_color := app_color_theme()
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
scope(theme_window_panel)
container = ui_widget("Settings Menu", {});
setup_container:
{
using container
if ! is_maximized
{
layout.flags = {
// .Size_To_Content,
.Fixed_Width, .Fixed_Height,
// .Min_Size_To_Content_Y,
.Fixed_Position_X, .Fixed_Position_Y,
.Origin_At_Anchor_Center
}
layout.pos = pos
layout.size = range2( size, {})
}
else
{
layout.flags = {.Origin_At_Anchor_Center }
layout.pos = {}
}
dragged := ui_resizable_handles( & container, & pos, & size)
should_raise |= dragged
old_vbox := ui_box_from_key(prev_cache, ui_key_from_string("Settings Menu: VBox"))
if old_vbox != nil
{
vbox_children_bounds := ui_compute_children_overall_bounds(old_vbox)
joined_size := size_range2( vbox_children_bounds )
if ! dragged
{
min_size.y = joined_size.y
if min_size.y > size.y {
pos.y += (layout.size.min.y - min_size.y) * 0.5
layout.pos = pos
layout.size.min.y = min_size.y
}
}
}
}
ui_parent_push(container)
vbox := ui_vbox_begin( .Top_To_Bottom, "Settings Menu: VBox", {.Mouse_Clickable}, compute_layout = true )
{
// should_raise |= b32(vbox.active)
ui_parent(vbox)
Frame_Bar:
{
scope(theme_window_bar)
frame_bar := ui_hbox(.Left_To_Right, "Settings Menu: Frame Bar", { .Mouse_Clickable })
{
ui_parent(frame_bar)
scope(theme_text)
title := ui_text("Settings Menu: Title", str_intern("Settings Menu"), {.Disabled}); {
using title
layout.anchor.ratio.x = 1.0
layout.margins = { 0, 0, 15, 0}
layout.font_size = 14
}
scope(theme_window_bar_btn)
maximize_btn := ui_button("Settings Menu: Maximize Btn"); {
using maximize_btn
if maximize_btn.pressed {
settings_menu.is_maximized = ~settings_menu.is_maximized
should_raise = true
}
if settings_menu.is_maximized do text = str_intern("min")
else do text = str_intern("max")
}
close_btn := ui_button("Settings Menu: Close Btn"); {
using close_btn
text = str_intern("close")
if close_btn.hot do style.bg_color = app_color.window_btn_close_bg_hot
if close_btn.pressed do settings_menu.is_open = false
style.corner_radii = { 0, 0, 0, 0 }
}
}
if frame_bar.active {
pos += input.mouse.delta
should_raise = true
}
}
// TODO(Ed): This will eventually be most likely generalized/compressed. For now its the main scope for implementing new widgets.
app_config := ui_drop_down( & cfg_drop_down, "settings_menu.config", str_intern("App Config"), vb_compute_layout = true);
app_config_closed:
{
app_config.title.layout.font_size = 12
if ! app_config.is_open do break app_config_closed
ui_settings_entry_inputbox :: proc( input_box : ^UI_TextInputBox, is_even : bool, label : string, setting_title : StrRunesPair, input_policy : UI_TextInput_Policy )
{
scope( theme_table_row(is_even))
hb := ui_hbox(.Left_To_Right, str_intern_fmt("%v.hb", label).str); {
using hb
layout.size.min = {0, 25}
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
}
scope(theme_text)
title := ui_text(str_intern_fmt("%v.title", label).str, setting_title); {
using title
layout.anchor.ratio.x = 1.0
layout.margins.left = 10
layout.font_size = 12
}
ui_text_input_box( input_box, str_intern_fmt("%v.input_box", label).str, allocator = persistent_slab_allocator(), policy = input_policy )
{
using input_box
layout.flags = {.Fixed_Width}
layout.margins.left = 5
layout.padding.right = 5
layout.size.min.x = 80
style.corner_radii = { 3, 3, 3, 3 }
}
}
Engine_Refresh_Hz:
{
scope(theme_table_row(is_even = false))
hb := ui_hbox(.Left_To_Right, "settings_menu.engine_refresh_hz.hb"); { using hb
layout.size.min = {0, 25}
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
}
title : UI_Widget; {
scope(theme_text)
title = ui_text("settings_menu.engine_refresh_hz.title", str_intern("Engine Refresh Hz"))
using title
layout.anchor.ratio.x = 1.0
layout.margins.left = 10
title.layout.font_size = 12
}
engine_refresh_config: {
using min_zoom_inputbox
digits_only = true
disallow_leading_zeros = true
disallow_decimal = true
digit_min = 1
digit_max = 9999
max_length = 4
}
ui_text_input_box( & engine_refresh_inputbox, "settings_menu.engine_refresh_hz.inputbox", allocator = persistent_slab_allocator() )
{
using engine_refresh_inputbox
layout.flags = {.Fixed_Width}
layout.margins.left = 5
layout.padding.right = 5
layout.size.min.x = 80
style.corner_radii = { 3, 3, 3, 3 }
if was_active
{
value, success := parse_uint(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 1, 9999)
config.engine_refresh_hz = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.engine_refresh_hz)))
}
}
}
Min_Zoom:
{
scope( theme_table_row(is_even = true))
hb := ui_hbox(.Left_To_Right, "settings_menu.cam_min_zoom.hb"); {
using hb
layout.size.min = {0, 25}
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
}
scope(theme_text)
title := ui_text("settings_menu.cam_min_zoom.title", str_intern("Camera: Min Zoom")); {
using title
layout.anchor.ratio.x = 1.0
layout.margins.left = 10
layout.font_size = 12
}
min_zoom_config: {
using min_zoom_inputbox
digits_only = true
disallow_leading_zeros = false
disallow_decimal = false
digit_min = 0.01
digit_max = 9999
max_length = 5
}
ui_text_input_box( & min_zoom_inputbox, "settings_menu.cam_min_zoom.input_box", allocator = persistent_slab_allocator() )
{
using min_zoom_inputbox
layout.flags = {.Fixed_Width}
layout.margins.left = 5
layout.padding.right = 5
layout.size.min.x = 80
style.corner_radii = { 3, 3, 3, 3 }
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_min_zoom = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_min_zoom)))
}
}
}
Max_Zoom:
{
scope( theme_table_row(is_even = false))
hb := ui_hbox(.Left_To_Right, "settings_menu.cam_max_zoom.hb"); {
using hb
layout.size.min = {0, 25}
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
}
scope(theme_text)
title := ui_text("settings_menu.cam_max_zoom.title", str_intern("Camera: Max Zoom")); {
using title
layout.anchor.ratio.x = 1.0
layout.margins.left = 10
layout.font_size = 12
}
max_zoom_config: {
using max_zoom_inputbox
digits_only = true
disallow_leading_zeros = false
disallow_decimal = false
digit_min = 0.01
digit_max = 9999
max_length = 5
ui_text_input_box( & max_zoom_inputbox, "settings_menu.cam_max_zoom.input_box", allocator = persistent_slab_allocator() )
{
using max_zoom_inputbox
layout.flags = {.Fixed_Width}
layout.margins.left = 5
layout.padding.right = 5
layout.size.min.x = 80
style.corner_radii = { 3, 3, 3, 3 }
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_max_zoom = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_max_zoom)))
}
}
}
}
Zoom_Mode:
{
scope( theme_table_row(is_even = true))
hb := ui_hbox(.Left_To_Right, "settings_menu.cam_zoom_mode.hb"); {
using hb
layout.size.min = {0, 35}
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
}
scope(theme_text)
title := ui_text("settings_menu.cam_zoom_mode.title", str_intern("Camera: Zoom Mode")); {
using title
layout.anchor.ratio.x = 1.0
layout.margins.left = 10
layout.font_size = 12
}
// TODO(Ed): This is technically a manual drop-down as the vbox within ui_dropdown is unusuable for attaching the buttons
// This can be alleviated if we add an option for the drop-down to support a floating vbox (fixed position computed, following drop_down btn)
// For now its buttons are attached to app_config vbox
mode_selector := ui_drop_down( & zoom_mode_drop_down, "settings_menu.cam_zoom_mode.drop_down", str_intern_fmt("%s", config.cam_zoom_mode), vb_compute_layout = true );
mode_selector_closed:
{
using mode_selector
btn.layout.size.min = { 80, btn.layout.size.min.y }
if ! is_open do break mode_selector_closed
idx := 1
for entry in CameraZoomMode
{
ui_parent(app_config.vbox)
scope(theme_button)
btn := ui_button(str_intern_fmt("settings_menu.cam_zoom_mode.%s.btn", entry).str)
{
using btn
layout.size.min = {100, 25}
layout.alignment = {1.0, 0}
layout.anchor.left = 1.0
layout.flags = {.Fixed_Height}
layout.padding = to_ui_layout_side(4)
ui_parent(btn)
scope(theme_text)
text_widget := ui_text(str_intern_fmt("settings_menu.cam_zoom_mode.%s.text", entry).str, str_intern_fmt("%s", entry))
}
if btn.pressed {
mode_selector.should_close = true
config.cam_zoom_mode = entry
screen_ui.active = 0
}
}
}
}
Cam_Zoom_Smooth_Snappiness:
{
ui_settings_entry_inputbox( & zoom_smooth_snappiness_input, false, "settings_menu.cam_zoom_smooth_snappiness", str_intern("Camera: Zoom Smooth Snappiness"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using zoom_smooth_snappiness_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_zoom_smooth_snappiness = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_zoom_smooth_snappiness)))
}
}
Cam_Zoom_Sensitivity_Smooth:
{
ui_settings_entry_inputbox( & zoom_smooth_sensitivity_input, true, "settings_menu.cam_zoom_sensitivity_smooth", str_intern("Camera: Zoom Smooth Sensitivity"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using zoom_smooth_sensitivity_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_zoom_sensitivity_smooth = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_zoom_sensitivity_smooth)))
}
}
Cam_Zoom_Sensitivity_Digital:
{
ui_settings_entry_inputbox( & zoom_digital_sensitivity_input, false, "settings_menu.cam_zoom_sensitivity_digital", str_intern("Camera: Zoom Digital Sensitivity"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using zoom_digital_sensitivity_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_zoom_sensitivity_digital = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_zoom_sensitivity_digital)))
}
}
Cam_Zoom_Scroll_Delta_Scale:
{
ui_settings_entry_inputbox( & zoom_scroll_delta_scale_input, true, "settings_menu.cam_zoom_scroll_delta_scale", str_intern("Camera: Zoom Scroll Delta Scale"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using zoom_scroll_delta_scale_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.cam_zoom_scroll_delta_scale = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.cam_zoom_scroll_delta_scale)))
}
}
Font_Size_Screen_Scalar:
{
ui_settings_entry_inputbox( & font_size_screen_scalar_input, false, "settings_menu.font_size_screen_scalar", str_intern("Font: Size Screen Scalar"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using font_size_screen_scalar_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.font_size_screen_scalar = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.font_size_screen_scalar)))
}
}
Font_Size_Canvas_Scalar:
{
ui_settings_entry_inputbox( & font_size_canvas_scalar_input, false, "settings_menu.font_size_canvas_scalar", str_intern("Font: Size Canvas Scalar"),
UI_TextInput_Policy {
digits_only = true,
disallow_leading_zeros = false,
disallow_decimal = false,
digit_min = 0.01,
digit_max = 9999,
max_length = 5,
}
)
using font_size_canvas_scalar_input
if was_active
{
value, success := parse_f32(to_string(array_to_slice(input_str)))
if success {
value = clamp(value, 0.001, 9999.0)
config.font_size_canvas_scalar = value
}
}
else
{
clear( input_str )
append( & input_str, to_runes(str_fmt("%v", config.font_size_canvas_scalar)))
}
}
}
}
ui_vbox_end(vbox, compute_layout = false )
ui_parent_pop() // container
return
}

View File

@ -188,6 +188,7 @@ FontData :: struct {
FrameTime :: struct {
sleep_is_granular : b32,
current_frame : u64,
delta_seconds : f64,
delta_ms : f64,
delta_ns : Duration,
@ -233,17 +234,7 @@ State :: struct {
monitor_id : i32,
monitor_refresh_hz : i32,
// using frametime : FrameTime,
sleep_is_granular : b32,
frame : u64,
frametime_delta_seconds : f64,
frametime_delta_ms : f64,
frametime_delta_ns : Duration,
frametime_target_ms : f64,
frametime_elapsed_ms : f64,
frametime_avg_ms : f64,
fps_avg : f64,
using frametime : FrameTime,
// fonts : FontData,
font_provider_ctx : FontProviderContext,
@ -278,15 +269,23 @@ State :: struct {
sokol_context : runtime.Context,
}
// NOTE: Avoid getting a mutable reference to state
get_state :: #force_inline proc "contextless" () -> ^ State {
return cast( ^ State ) Memory_App.persistent.reserve_start
}
// get_frametime :: #force_inline proc "contextless" () -> FrameTime {
// return get_state().frametime
// }
get_input_state :: #force_inline proc "contextless" () -> InputState {
return (get_state().input ^)
}
frametime_delta32 :: #force_inline proc "contextless" () -> f32 {
return cast(f32) get_state().frametime.delta_ms
}
app_config :: #force_inline proc "contextless" () -> AppConfig { return get_state().config }
app_color_theme :: #force_inline proc "contextless" () -> AppColorTheme { return get_state().config.color_theme }
debug_data :: #force_inline proc "contextless" () -> DebugData { return get_state().debug }
get_frametime :: #force_inline proc "contextless" () -> FrameTime { return get_state().frametime }
#endregion("State")

View File

@ -135,8 +135,15 @@ equal_range2 :: #force_inline proc "contextless" ( a, b : Range2 ) -> b32 {
return b32(result)
}
// Will resolve the largest range possible given a & b.
join_range2 :: proc "contextless" ( a, b : Range2 ) -> (joined : Range2) {
joined.min = min( a.min, b.min )
joined.max = max( a.max, b.max )
return
}
size_range2 :: #force_inline proc "contextless" ( value : Range2 ) -> Vec2 {
return { value.p1.x - value.p0.x, value.p0.y - value.p1.y }
return { abs( value.p1.x - value.p0.x ), abs( value.p0.y - value.p1.y ) }
}
#endregion("Range2")

View File

@ -113,6 +113,11 @@ UI_LayoutFlag :: enum u32 {
// For this to work, the children must have a minimum size set & their size overall must be greater than the parent's minimum size
Size_To_Content,
// Will set minimum size to the child with the furthest bounds on X
Min_Size_To_Content_X,
// Will set minimum size to the child with the furthest bounds on Y
Min_Size_To_Content_Y,
// Will size the box to its text.
Size_To_Text,

View File

@ -99,12 +99,36 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
adjusted_size.y = layout.size.min.y
}
border_offset := Vec2 { layout.border_width, layout.border_width }
// TODO(Ed): These are still WIP
if .Size_To_Content in layout.flags {
// Preemtively traverse the children of this parent and have them compute their layout.
// This parent will just set its size to the max bounding area of those children.
// This will recursively occur if child also depends on their content size from their children, etc.
ui_box_compute_layout_children(box)
//ui_compute_children_bounding_area(box)
// ui_box_compute_layout_children(box)
children_bounds := ui_compute_children_overall_bounds(box)
resolved_bounds := range2(
children_bounds.min - { layout.padding.left, layout.padding.bottom } - border_offset,
children_bounds.max + { layout.padding.right, layout.padding.top } + border_offset,
)
adjusted_size = size_range2( resolved_bounds )
}
if .Min_Size_To_Content_X in layout.flags {
children_bounds := ui_compute_children_overall_bounds(box)
resolved_bounds := range2(
children_bounds.min - { layout.padding.left, layout.padding.bottom } - border_offset,
children_bounds.max + { layout.padding.right, layout.padding.top } + border_offset,
)
adjusted_size.x = size_range2( resolved_bounds ).x
}
if .Min_Size_To_Content_Y in layout.flags {
children_bounds := ui_compute_children_overall_bounds(box)
resolved_bounds := range2(
children_bounds.min - { layout.padding.left, layout.padding.bottom } - border_offset,
children_bounds.max + { layout.padding.right, layout.padding.top } + border_offset,
)
adjusted_size.y = size_range2(resolved_bounds).y
}
// 5. Determine relative position
@ -146,8 +170,6 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
// 7. Padding & Content
// Determine Padding's outer bounds
border_offset := Vec2 { layout.border_width, layout.border_width }
padding_bounds := range2(
bounds.min + border_offset,
bounds.min - border_offset,
@ -183,9 +205,19 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
computed.fresh = true && !dont_mark_fresh
}
ui_compute_children_bounding_area :: proc ( box : ^UI_Box )
ui_compute_children_overall_bounds :: proc ( box : ^UI_Box ) -> ( children_bounds : Range2 )
{
// TODO(Ed): Implement this so we can have the .Size_To_Content flag supported.
for current := box.first; current != nil && current.prev != box; current = ui_box_tranverse_next_depth_first( current )
{
if current == box do return
if ! current.computed.fresh do ui_box_compute_layout( current )
if current == box.first {
children_bounds = current.computed.bounds
continue
}
children_bounds = join_range2( current.computed.bounds, children_bounds )
}
return
}
ui_box_compute_layout_children :: proc( box : ^UI_Box )