coordinate space math fixes, got resize handles working in settings menu prototype

will eventually lift to its own generic widget

I still need to implement the corner resize..
This commit is contained in:
2024-05-09 04:02:33 -04:00
parent b8e8e7c88a
commit a2b6325b5b
15 changed files with 857 additions and 554 deletions

View File

@ -149,6 +149,7 @@ update :: proc( delta_time : f64 ) -> b32
}
//region 2D Camera Manual Nav
// TODO(Ed): This should be per workspace view
{
// profile("Camera Manual Nav")
digital_move_speed : f32 = 200.0
@ -184,13 +185,314 @@ update :: proc( delta_time : f64 ) -> b32
if debug_actions.cam_mouse_pan
{
if is_within_screenspace(input.mouse.pos) {
pan_velocity := input.mouse.delta * ( 1 / cam.zoom )
pan_velocity := input.mouse.delta * vec2(1, -1) * ( 1 / cam.zoom )
cam.target -= pan_velocity
}
}
}
//endregion 2D Camera Manual Nav
// TODO(Ed): We need input buffer so that we can consume input actions based on the UI with priority
//region App UI Tick
{
profile("App Screenspace Imgui")
ui_graph_build( & state.app_ui )
ui := ui_context
/*
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
{
fmt :: str_fmt_alloc
@static bar_pos := Vec2{}
bar_size := vec2( 400, 40 )
menu_bar : UI_Widget
{
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,
pos = bar_pos,
size = range2( bar_size, {}),
// padding = { 10, 10, 10, 10 },
},
}
ui_theme_via_style(theme)
menu_bar = ui_widget("App Menu Bar", UI_BoxFlags {} )
menu_bar.text = { fmt("%v", bar_pos), {} }
menu_bar.text.runes = to_runes(menu_bar.text.str)
if (menu_bar.first_frame) {
bar_pos = screen_get_corners().top_right - vec2(0, app_window.extent.y * 0.5)
}
}
// Setup Children
settings_btn : UI_Widget
{
ui_parent(menu_bar)
style := UI_Style {
flags = {
// .Origin_At_Anchor_Center
.Fixed_Height
},
bg_color = Color_Frame_Disabled,
font = default_font,
font_size = 18,
text_color = Color_White,
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}, {0, 0})
}
}
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
{
move_box = ui_button("Move Box")
if move_box.dragging {
bar_pos += input.mouse.delta
}
}
// bar_pos = {0, 400}
move_settings_spacer := ui_widget("Move-Settings Spacer", {})
move_settings_spacer.text = str_intern("spacer")
move_settings_spacer.style.font_size = 10
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,
}
}
// 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
}
}
@static settings_open := true
if settings_btn.left_clicked || settings_open
{
settings_open = true
@static pos := Vec2 {0, 0}
@static size := Vec2 { 600, 800 }
resize_border_width : f32 = 10
// Prototype for a resize box
// Will surround one box with a resize borders
// All sides can have their borders toggled
resize_box := ui_widget("Settings Menu: Resize Box", {})
{
using resize_box
style.pos = pos
style.alignment = { 0.5, 0.5 }
style.bg_color = {}
style.size = range2( size, {})
}
ui_parent(resize_box)
// Resize handles and corners
{
flags := UI_BoxFlags { .Mouse_Clickable, .Focusable }
style_resize_width := UI_Style {
flags = { .Fixed_Width },
size = range2({resize_border_width, 0}, {}),
bg_color = Color_ResizeHandle,
alignment = {0, 1},
margins = { resize_border_width, resize_border_width, 0, 0 },
}
style_resize_height := style_resize_width
style_resize_height.flags = {.Fixed_Height}
style_resize_height.size.min = {0, resize_border_width}
style_resize_height.margins = { 0, 0, resize_border_width, resize_border_width }
ui_theme_via_style(style_resize_width)
left := ui_widget("Settings Menu: Resize Left Border", flags )
right := ui_widget("Settings Menu: Resize Right Border", flags)
right.style.anchor.left = 1
right.style.alignment = {1, 1}
ui_theme_via_style(style_resize_height)
top := ui_widget("Settings Menu: Resize Top Border", flags )
bottom := ui_widget("Settings Menu: Resize Bottom Border", flags)
bottom.style.anchor.top = 1
bottom.style.alignment = {0, 0}
style_corner := UI_Style {
flags = { .Fixed_Width, .Fixed_Height },
size = range2({resize_border_width, resize_border_width}, {}),
bg_color = Color_Blue,
alignment = {0, 1}
}
ui_theme_via_style(style_corner)
corner_tl := ui_widget("Settings Menu: Corner TL", flags)
corner_tr := ui_widget("Settings Menu: Corner TR", flags)
corner_tr.style.anchor = range2({1, 0}, {})
corner_tr.style.alignment = {1, 1}
corner_bl := ui_widget("Settings Menu: Corner BL", flags)
corner_bl.style.anchor = range2({}, {0, 1})
corner_bl.style.alignment = {}
corner_br := ui_widget("Settings Menu: Corner BR", flags)
corner_br.style.anchor = range2({1, 0}, {0, 1})
corner_br.style.alignment = {1, 0}
process_handle_drag :: #force_inline proc ( handle : ^UI_Widget,
side_scalar : f32,
size_axis : ^f32,
size_delta_axis : f32,
pos_axis : ^f32,
alignment_axis : ^f32,
alignment_while_dragging : f32 )
{
if get_state().ui_context.last_pressed_key != handle.key { return }
@static was_dragging := false
@static within_drag := false
using handle.signal
if dragging
{
if ! was_dragging {
was_dragging = true
(pos_axis ^) += size_axis^ * 0.5 * side_scalar
}
(size_axis ^) += size_delta_axis * -side_scalar
(alignment_axis ^) = alignment_while_dragging
}
else if was_dragging && released
{
(pos_axis ^) += size_axis^ * 0.5 * -side_scalar
was_dragging = false
}
}
process_handle_drag( & right , -1.0, & size.x, input.mouse.delta.x, & pos.x, & resize_box.style.alignment.x, 0)
process_handle_drag( & left, 1.0, & size.x, input.mouse.delta.x, & pos.x, & resize_box.style.alignment.x, 1)
process_handle_drag( & top, -1.0, & size.y, input.mouse.delta.y, & pos.y, & resize_box.style.alignment.y, 0)
process_handle_drag( & bottom, 1.0, & size.y, input.mouse.delta.y, & pos.y, & resize_box.style.alignment.y, 1)
// process_corner_drag :: #force_inline proc()
{
}
}
settings_menu := ui_widget("Settings Menu", {})
{
using settings_menu
style.alignment = { 0.0, 1.0 }
style.bg_color = Color_BG_Panel_Translucent
// style.border_width = 1.0
// style.border_color = Color_Blue
style.margins = {
resize_border_width,
resize_border_width,
resize_border_width,
resize_border_width, }
}
ui_parent(settings_menu)
ui_theme_via_style({
bg_color = Color_Transparent,
font = default_font,
font_size = 16,
text_color = Color_White,
size = range2({0, 40}, {0, 40}) // TODO(Ed): Implment ratio scaling for height
})
frame_bar := ui_widget("Settings Menu: Frame Bar", { .Mouse_Clickable, .Focusable, .Click_To_Focus })
{
using frame_bar
style.bg_color = Color_BG_Panel
style.flags = {}
style.alignment = { 0, 1 }
// style.size = {}
style.anchor = range2( {0, 0.95}, {0, 0} )
ui_parent(frame_bar)
if dragging {
pos += input.mouse.delta
}
title := ui_text("Settings Menu: Title", str_intern("Settings Menu"))
{
using title
style.alignment = {0, 1}
style.margins = { 0, 0, 15, 0}
style.text_alignment = {0.0 , 0.5}
}
close_btn := ui_button("Settings Menu: Close Btn")
{
using close_btn
text = str_intern("close")
style.bg_color = Color_GreyRed
style.size.min = {50, 0}
style.anchor = range2( {1.0, 0}, {})
style.alignment = {1, 1}
style.text_alignment = {0.5, 0.5}
if close_btn.pressed {
settings_open = false
}
}
}
}
}
}
//endregion App UI Tick
//region WorkspaceImgui Tick
{
profile("Workspace Imgui")
@ -240,180 +542,9 @@ update :: proc( delta_time : f64 ) -> b32
// test_text_box()
// test_parenting( & default_layout, & frame_style_default )
// test_whitespace_ast( & default_layout, & frame_style_default )
/*
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
{
fmt :: str_fmt_alloc
@static bar_pos := Vec2 {}
bar_size := vec2( 400, 40 )
menu_bar : UI_Widget
{
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)
style := UI_Style {
flags = {
// .Origin_At_Anchor_Center
.Fixed_Height
},
bg_color = Color_Frame_Disabled,
font = default_font,
font_size = 18 * (1.0/cam.zoom),
text_color = Color_White,
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})
}
}
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
{
move_box = ui_button("Move Box")
if move_box.dragging {
// bar_pos += mouse_world_delta()
bar_pos += state.input.mouse.delta
}
}
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,
}
}
// 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
}
}
@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 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
should_shutdown : b32 = ! cast(b32) rl.WindowShouldClose()