refinements to input box prototype

Added constraints, visual feedback blink when bad input, enter can confirm setting

Adding proto-text cursor next
This commit is contained in:
Edward R. Gonzalez 2024-11-29 17:46:22 -05:00
parent 36678c1127
commit c62bf2cf07
5 changed files with 72 additions and 5 deletions

View File

@ -39,5 +39,7 @@ DebugData :: struct {
pipeline : sokol_gfx.Pipeline,
bindings : sokol_gfx.Bindings,
pass_action : sokol_gfx.Pass_Action,
}
},
last_invalid_input_time : Time,
}

View File

@ -231,6 +231,7 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b
title.layout.font_size = 12
}
iter_next :: next
input_box := ui_widget("settings_menu.engine_refresh.input_box", {.Mouse_Clickable, .Focusable, .Click_To_Focus}); {
using input_box
layout.flags = {.Fixed_Width}
@ -243,6 +244,8 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b
else if input_box.hot do style.bg_color = app_color.input_box_bg_hot
else do style.bg_color = app_color.input_box_bg
@static max_value_length : u64 = 4
@static value_str : Array(rune)
if value_str.header == nil {
error : AllocatorError
@ -255,13 +258,65 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b
}
if input_box.active {
append( & value_str, input_events.codes_pressed )
if ! input_box.was_active {
debug.last_invalid_input_time._nsec = 0
}
iter_obj := iterator( & input_events.key_events ); iter := & iter_obj
for event := iter_next( iter ); event != nil; event = iter_next( iter )
{
if event.frame_id != state.frame do break
if event.key == .backspace && event.type == .Key_Pressed {
if value_str.num > 0 {
pop( value_str)
break
}
}
if event.key == .enter && event.type == .Key_Pressed {
screen_ui.active = 0
}
}
// append( & value_str, input_events.codes_pressed )
for code in to_slice(input_events.codes_pressed) {
if value_str.num == 0 && code == '0' {
debug.last_invalid_input_time = time_now()
continue
}
if value_str.num >= max_value_length {
debug.last_invalid_input_time = time_now()
continue
}
// Only accept characters 0-9
if '0' <= code && code <= '9' {
append(&value_str, code)
}
else {
debug.last_invalid_input_time = time_now()
continue
}
}
clear( input_events.codes_pressed )
invalid_color := RGBA8 { 70, 50, 50, 255}
// Visual feedback - change background color briefly when invalid input occurs
feedback_duration :: 0.2 // seconds
curr_duration := duration_seconds( time_diff( debug.last_invalid_input_time, time_now() ))
if debug.last_invalid_input_time._nsec != 0 && curr_duration < feedback_duration {
input_box.style.bg_color = invalid_color // Or a specific error color from your theme
}
}
else if input_box.was_active
{
value, success := parse_uint(to_string(array_to_slice(value_str)))
if success {
value = clamp(value, 1, 9999)
config.engine_refresh_hz = value
}
}

View File

@ -60,6 +60,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
// Any persistent allocations are explicitly specified.
context.allocator = transient_allocator()
context.temp_allocator = transient_allocator()
}
state := new( State, persistent_allocator() )
@ -332,9 +333,9 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
ui_startup( & workspace.ui, cache_allocator = persistent_slab_allocator() )
}
debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/Lorem Ipsum (197).txt", allocator = persistent_slab_allocator())
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/Lorem Ipsum (197).txt", allocator = persistent_slab_allocator())
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/Lorem Ipsum (1022).txt", allocator = persistent_slab_allocator())
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/sokol_gp.h", allocator = persistent_slab_allocator())
debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/sokol_gp.h", allocator = persistent_slab_allocator())
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/ve_fontcache.h", allocator = persistent_slab_allocator())
alloc_error : AllocatorError; success : bool

View File

@ -341,7 +341,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

View File

@ -120,6 +120,9 @@ import "core:time"
duration_seconds :: time.duration_seconds
duration_ms :: time.duration_milliseconds
thread_sleep :: time.sleep
time_diff :: time.diff
time_now :: time.now
Time :: time.Time
import "core:unicode"
is_white_space :: unicode.is_white_space
@ -173,6 +176,7 @@ import "codebase:grime"
array_clear :: grime.array_clear
array_free :: grime.array_free
array_grow_formula :: grime.array_grow_formula
array_pop :: grime.array_pop
array_remove_at :: grime.array_remove_at
array_resize :: grime.array_resize
@ -453,6 +457,7 @@ points_to_pixels :: proc {
}
pop :: proc {
array_pop,
stack_pop,
stack_allocator_pop,
}
@ -560,6 +565,10 @@ to_runes :: proc {
string_to_runes,
}
to_slice :: proc {
array_to_slice,
}
to_string :: proc {
runes_to_string,
str_builder_to_string,