Progress on setting up app's UI and horizontal/vertical box widgets

This commit is contained in:
2024-05-08 02:26:39 -04:00
parent e282397bf0
commit b8e8e7c88a
17 changed files with 577 additions and 246 deletions

View File

@ -191,9 +191,9 @@ update :: proc( delta_time : f64 ) -> b32
}
//endregion 2D Camera Manual Nav
//region Imgui Tick
//region WorkspaceImgui Tick
{
profile("Imgui Tick")
profile("Workspace Imgui")
// Creates the root box node, set its as the first parent.
ui_graph_build( & state.project.workspace.ui )
@ -238,235 +238,181 @@ update :: proc( delta_time : f64 ) -> b32
config.ui_resize_border_width = 2.5
// test_draggable()
// test_text_box()
// test_parenting( & default_layout, & frame_style_default )
// test_whitespace_ast( & default_layout, & frame_style_default )
// test_parenting()
if false
{
// frame := ui_widget( "Frame", {} )
// ui_parent(frame)
parent_layout := default_layout
parent_layout.size = range2( { 300, 300 }, {} )
parent_layout.alignment = { 0.5, 0.5 }
parent_layout.margins = { 100, 100, 100, 100 }
parent_layout.padding = { 5, 10, 5, 5 }
parent_layout.pos = { 0, 0 }
parent_theme := frame_style_default
parent_theme.layout = parent_layout
parent_theme.flags = {
// .Fixed_Position_X, .Fixed_Position_Y,
.Fixed_Width, .Fixed_Height,
}
ui_theme_via_style(parent_theme)
parent := ui_widget( "Parent", { .Mouse_Clickable, .Mouse_Resizable })
ui_parent(parent)
{
if parent.first_frame {
debug.draggable_box_pos = parent.style.layout.pos
debug.draggable_box_size = parent.style.layout.size.min
}
if parent.dragging {
debug.draggable_box_pos += mouse_world_delta()
}
if parent.resizing
{
og_layout := ui_context.active_start_style.layout
center := debug.draggable_box_pos
original_distance := linalg.distance(ui.active_start_signal.cursor_pos, center)
cursor_distance := linalg.distance(parent.cursor_pos, center)
scale_factor := cursor_distance * (1 / original_distance)
debug.draggable_box_size = og_layout.size.min * scale_factor
}
if (ui.hot == parent.key) && (ui.hot_resizable || ui.active_start_signal.resizing) {
parent.style.bg_color = Color_Blue
}
parent.style.layout.pos = debug.draggable_box_pos
parent.style.layout.size.min = debug.draggable_box_size
}
child_layout := default_layout
child_layout.size = range2({ 0, 0 }, { 0, 0 })
child_layout.alignment = { 0.5, 0.5 }
child_layout.margins = { 20, 20, 20, 20 }
child_layout.padding = { 5, 5, 5, 5 }
child_layout.anchor = range2({ 0.2, 0.1 }, { 0.1, 0.15 })
child_layout.pos = { 0, 0 }
child_theme := frame_style_default
child_theme.bg_color = Color_GreyRed
child_theme.flags = {
// .Fixed_Width, .Fixed_Height,
.Origin_At_Anchor_Center
}
child_theme.layout = child_layout
ui_theme_via_style(child_theme)
child := ui_widget( "Child", { .Mouse_Clickable })
}
// Whitespace AST test
/*
Prototype app menu
This is a menu bar for the app for now inside the same ui as the workspace's UI state
Eventually this will get moved out to its own UI state for the app itself.
*/
if true
{
profile("Whitespace AST test")
fmt :: str_fmt_alloc
text_style := frame_style_default
text_style.flags = {
.Origin_At_Anchor_Center,
.Fixed_Position_X, .Fixed_Position_Y,
// .Fixed_Width, .Fixed_Height,
}
text_style.text_alignment = { 0.0, 0.5 }
text_style.alignment = { 0.0, 1.0 }
text_style.size.min = { 1600, 30 }
@static bar_pos := Vec2 {}
bar_size := vec2( 400, 40 )
text_theme := UI_StyleTheme { styles = {
text_style,
text_style,
text_style,
text_style,
}}
text_theme.default.bg_color = Color_Transparent
text_theme.disabled.bg_color = Color_Frame_Disabled
text_theme.hot.bg_color = Color_Frame_Hover
text_theme.active.bg_color = Color_Frame_Select
ui_style_theme( text_theme )
layout_text := text_style.layout
alloc_error : AllocatorError; success : bool
// debug.lorem_content, success = os.read_entire_file( debug.path_lorem, frame_allocator() )
// debug.lorem_parse, alloc_error = pws_parser_parse( transmute(string) debug.lorem_content, frame_slab_allocator() )
// verify( alloc_error == .None, "Faield to parse due to allocation failure" )
text_space := str_intern( " " )
text_tab := str_intern( "\t")
// index := 0
widgets : Array(UI_Widget)
// widgets, alloc_error = array_init_reserve( UI_Widget, frame_slab_allocator(), 8 )
widgets, alloc_error = array_init_reserve( UI_Widget, frame_slab_allocator(), 4 * Kilobyte )
widgets_ptr := & widgets
label_id := 0
line_id := 0
for line in array_to_slice_num( debug.lorem_parse.lines )
menu_bar : UI_Widget
{
if line_id == 0 {
line_id += 1
continue
theme := UI_Style {
flags = {
},
bg_color = { 0, 0, 0, 30 },
border_color = { 0, 0, 0, 200 },
font = default_font,
font_size = 12,
text_color = Color_White,
layout = UI_Layout {
anchor = {},
border_width = 1.0 * (1.0/cam.zoom),
pos = screen_to_world(bar_pos),
size = range2( bar_size * (1.0/cam.zoom), {}),
// padding = { 10, 10, 10, 10 },
},
}
ui_theme_via_style(theme)
menu_bar = ui_widget("App Menu Bar", UI_BoxFlags {} )
}
// Setup Children
settings_btn : UI_Widget
{
ui_parent(menu_bar)
ui_style_theme_set_layout( layout_text )
line_hbox := ui_widget(str_fmt_alloc( "line %v", line_id ), {})
style := UI_Style {
flags = {
// .Origin_At_Anchor_Center
.Fixed_Height
},
bg_color = Color_Frame_Disabled,
if line_hbox.key == ui.hot
{
line_hbox.text = StringCached {}
ui_parent(line_hbox)
font = default_font,
font_size = 18 * (1.0/cam.zoom),
text_color = Color_White,
chunk_layout := layout_text
chunk_layout.alignment = { 0.0, 1.0 }
chunk_layout.anchor = range2({ 0.0, 0 }, { 0.0, 0 })
chunk_layout.pos = {}
chunk_style := text_style
chunk_style.flags = { .Fixed_Position_X, .Size_To_Text }
chunk_style.layout = chunk_layout
chunk_theme := UI_StyleTheme { styles = {
chunk_style,
chunk_style,
chunk_style,
chunk_style,
}}
ui_style_theme( chunk_theme )
head := line.first
for ; head != nil;
{
ui_style_theme_set_layout( chunk_layout )
widget : UI_Widget
#partial switch head.type
{
case .Visible:
label := str_intern( str_fmt_alloc( "%v %v", head.content.str, label_id ))
widget = ui_text( label.str, head.content )
label_id += 1
chunk_layout.pos.x += size_range2( widget.computed.bounds ).x
case .Spaces:
label := str_intern( str_fmt_alloc( "%v %v", "space", label_id ))
widget = ui_text_spaces( label.str )
label_id += 1
for idx in 1 ..< len( head.content.runes )
{
// TODO(Ed): VIRTUAL WHITESPACE
// widget.style.layout.size.x += range2_size( widget.computed.bounds )
}
chunk_layout.pos.x += size_range2( widget.computed.bounds ).x
case .Tabs:
label := str_intern( str_fmt_alloc( "%v %v", "tab", label_id ))
widget = ui_text_tabs( label.str )
label_id += 1
for idx in 1 ..< len( head.content.runes )
{
// widget.style.layout.size.x += range2_size( widget.computed.bounds )
}
chunk_layout.pos.x += size_range2( widget.computed.bounds ).x
}
array_append( widgets_ptr, widget )
head = head.next
layout = UI_Layout {
anchor = range2( {0, 0}, {0.0, 0} ),
alignment = { 0.0, 1.0 },
text_alignment = { 0.5, 0.5 },
pos = { 0, 0 },
size = range2( {25, bar_size.y} * (1.0/cam.zoom), {0, 0})
}
line_hbox.style.size.min.x = chunk_layout.pos.x
}
else
theme := UI_StyleTheme { styles = {
style,
style,
style,
style,
}}
theme.disabled.bg_color = Color_Frame_Disabled
theme.hot.bg_color = Color_White
theme.active.bg_color = Color_Frame_Select
ui_style_theme(theme)
move_box : UI_Widget
{
builder_backing : [16 * Kilobyte] byte
builder := str.builder_from_bytes( builder_backing[:] )
line_hbox.style.flags |= { .Size_To_Text }
head := line.first.next
for ; head != nil;
{
str.write_string( & builder, head.content.str )
head = head.next
move_box = ui_button("Move Box")
if move_box.dragging {
// bar_pos += mouse_world_delta()
bar_pos += state.input.mouse.delta
}
line_hbox.text = str_intern( to_string( builder ) )
// if len(line_hbox.text.str) == 0 {
// line_hbox.text = str_intern( " " )
// }
}
if len(line_hbox.text.str) > 0 {
array_append( widgets_ptr, line_hbox )
layout_text.pos.x = text_style.layout.pos.x
layout_text.pos.y += size_range2(line_hbox.computed.bounds).y
}
else {
layout_text.pos.y += size_range2( (& widgets.data[ widgets.num - 1 ]).computed.bounds ).y
move_settings_spacer := ui_widget("Move-Settings Spacer", {})
move_settings_spacer.text = str_intern("")
move_settings_spacer.style.font_size = 10 * (1.0/cam.zoom)
move_settings_spacer.style.bg_color = Color_Transparent
// settings_btn : UI_Widget
{
settings_btn = ui_button("Settings Btn")
settings_btn.text = str_intern("Settings")
settings_btn.style.flags = {
.Scale_Width_By_Height_Ratio,
}
}
line_id += 1
// HBox layout calculation?
{
hb_space_ratio_move_box := 0.1
hb_space_ratio_move_settings_spacer := 0.05
hb_space_ratio_settings_btn := 1.0
style := & move_box.box.style
style.anchor.max.x = 0.9
style = & move_settings_spacer.box.style
style.anchor.min.x = 0.1
style.anchor.max.x = 0.8
style = & settings_btn.box.style
style.anchor.min.x = 0.2
style.anchor.max.x = 0.55
}
}
label_id += 1 // Dummy action
@static settings_open := false
if settings_btn.left_clicked || settings_open
{
settings_open = true
@static pos := Vec2 {0, 0}
settings_menu := ui_widget("Settings Menu", { .Mouse_Clickable, .Focusable, .Click_To_Focus })
settings_menu.style.pos = screen_to_world(pos)
settings_menu.style.size = range2( {600, 800} * (1/cam.zoom), {})
settings_menu.style.text_alignment = {0, 0.0}
settings_menu.style.alignment = { 0.5, 0.5 }
settings_menu.style.bg_color = Color_Transparent
settings_menu.style.border_width = 1.0 * (1/cam.zoom)
settings_menu.style.border_color = Color_Blue
// settings_menu.style.padding = { 10, 10, 10, 10 }
settings_menu.text = { fmt("%v", pos), {} }
settings_menu.text.runes = to_runes(settings_menu.text.str)
settings_menu.style.font_size = 16 * (1/cam.zoom)
// pos.x += frametime_delta32() * 100
if settings_menu.dragging {
pos += state.input.mouse.delta
// pos.x += frametime_delta32() * 1
}
ui_parent(settings_menu)
frame_bar := ui_widget("Settings Menu: Frame Bar", {})
{
using frame_bar
// style.bg_color = Color_Red
style.flags = {}
style.alignment = { 0, 1 }
style.size = {}
style.anchor = range2( {0, 0.95}, {0, 0} )
// Close button
{
}
}
}
}
}
//endregion Imgui Tick
//endregion Workspace Imgui Tick
//region App Screenspace Imgui Tick
{
profile("App Screenspace Imgui")
ui_graph_build( & state.app_ui )
ui := ui_context
/*
Prototype app menu
TODO(Ed): Move it to here
*/
}
//endregion App Screenspace Imgui Tick
debug.last_mouse_pos = input.mouse.pos