From fde09656a60089e81a81767f5a40e9eec7a58e4c Mon Sep 17 00:00:00 2001 From: hgn Date: Thu, 2 Oct 2025 12:12:23 +0000 Subject: [PATCH] textbox/console --- foundation.kv | 11 ++++ include/common_api.h | 1 + include/graphics_api.h | 2 +- source/engine/console.c | 8 ++- source/engine/input.c | 5 ++ source/graphics/ui.c | 133 ++++++++++++++++++++++++++-------------- 6 files changed, 111 insertions(+), 49 deletions(-) diff --git a/foundation.kv b/foundation.kv index b67b322..7de37de 100644 --- a/foundation.kv +++ b/foundation.kv @@ -69,6 +69,17 @@ add source/foundation/async.c description "button,action,axis name" } } + ccmd + { + name unbind + description "Unbind all bindings that match" + function _input_unbind_ccmd + + parameter + { + description "binding" + } + } ccmd { diff --git a/include/common_api.h b/include/common_api.h index 4b95e61..61a0b11 100644 --- a/include/common_api.h +++ b/include/common_api.h @@ -78,6 +78,7 @@ struct stretchy_allocator void stretchy_init( struct stretchy_allocator *stretchy, u32 element_size ); void *stretchy_append( struct stretchy_allocator *stretchy ); void *stretchy_get( struct stretchy_allocator *stretchy, u32 index ); +void *stretchy_delete( struct stretchy_allocator *stretchy, u32 index ); // TODO u32 stretchy_count( struct stretchy_allocator *stretchy ); void stretchy_free( struct stretchy_allocator *stretchy ); diff --git a/include/graphics_api.h b/include/graphics_api.h index 5cfff55..10c2bde 100644 --- a/include/graphics_api.h +++ b/include/graphics_api.h @@ -116,6 +116,7 @@ void _ui_input_text( const c8 *text ); #define MOUSE_RIGHT 0x2 #define UI_AUTOFOCUS 0x1 +#define UI_MULTILINE 0x2 bool _ui_update(void); void _ui_draw(void); @@ -179,7 +180,6 @@ enum button_action _ui_slider( i16 rect[4], i32 vertical, f32 min, f32 max, f32 enum textbox_action { k_textbox_no_action, - k_textbox_click, k_textbox_enter, k_textbox_input_up, k_textbox_input_down, diff --git a/source/engine/console.c b/source/engine/console.c index 5a46710..f334f7a 100644 --- a/source/engine/console.c +++ b/source/engine/console.c @@ -14,5 +14,11 @@ void _engine_console_ui(void) _graphics_line_rect( (i16[]){ 0, kerning[1] * i, _engine.w, kerning[1] }, (union colour){{0,255,0,255}} ); _graphics_line_rect( history_box, (union colour){{0,255,255,255}} ); - _ui_textbox( (i16[]){ 0, kerning[1]*32, _engine.w, kerning[1] }, _input_buffer, sizeof(_input_buffer), 1, UI_AUTOFOCUS ); + enum textbox_action action = _ui_textbox( (i16[]){ 0, kerning[1]*32, _engine.w, kerning[1] }, _input_buffer, sizeof(_input_buffer), 1, UI_AUTOFOCUS ); + + if( action == k_textbox_enter ) + { + _console_execute( _input_buffer, 0, 0 ); + _input_buffer[0] = '\0'; + } } diff --git a/source/engine/input.c b/source/engine/input.c index bf0c5ec..6c98055 100644 --- a/source/engine/input.c +++ b/source/engine/input.c @@ -292,6 +292,11 @@ i32 _input_bind_ccmd( struct console_arguments *args ) return 0; } +i32 _input_unbind_ccmd( struct console_arguments *args ) +{ + return -1; +} + // bind LEFT ui_left <---- action // bind RIGHT ui_right <---- action // bind SHIFT ui_select diff --git a/source/graphics/ui.c b/source/graphics/ui.c index ee65482..1d32969 100644 --- a/source/graphics/ui.c +++ b/source/graphics/ui.c @@ -32,9 +32,11 @@ struct struct { i32 cursor_user, cursor_pos; + u32 flags; c8 *text_buffer; u32 text_buffer_length; enum ui_text_encoding text_buffer_encoding; + enum textbox_action action; } textbox; @@ -409,8 +411,10 @@ void _ui_input_action( enum ui_action action, bool super ) } else if( action == k_ui_action_enter ) { - _ui_textbox_input_string( (const c8[]){ '\n', 0 } ); - //_ui.active_control_type = k_ui_control_none; + if( _ui.controls.textbox.flags & UI_MULTILINE ) + _ui_textbox_input_string( (const c8[]){ '\n', 0 } ); + else + _ui.controls.textbox.action = k_textbox_enter; } else if( action == k_ui_action_home ) _ui_textbox_set_cursor_user( 0, super ); @@ -428,53 +432,63 @@ void _ui_input_action( enum ui_action action, bool super ) } else if( action == k_ui_action_up ) { - i16 user_co[2] = {-1, -1}; - i32 result_index = -1; - struct ui_string_decoder decoder, decoder1; - ui_string_decode_init( &decoder, _ui.controls.textbox.text_buffer, _ui.controls.textbox.text_buffer_encoding ); - decoder1 = decoder; - bool loop; do - { - loop = ui_string_decode( &decoder ); - if( decoder.character_index == _ui.controls.textbox.cursor_user ) - { - user_co[0] = decoder.grid_co[0]; - user_co[1] = decoder.grid_co[1]; - loop = 0; - } - } while( loop ); - bool loop1; do - { - loop1 = ui_string_decode( &decoder1 ); - if( decoder1.grid_co[1] == user_co[1]-1 ) - if( decoder1.grid_co[0] <= user_co[0] ) - result_index = decoder1.character_index; - } while( loop1 ); - - if( result_index != -1 ) - _ui_textbox_set_cursor_user( result_index, super ); + if( _ui.controls.textbox.flags & UI_MULTILINE ) + { + i16 user_co[2] = {-1, -1}; + i32 result_index = -1; + struct ui_string_decoder decoder, decoder1; + ui_string_decode_init( &decoder, _ui.controls.textbox.text_buffer, _ui.controls.textbox.text_buffer_encoding ); + decoder1 = decoder; + bool loop; do + { + loop = ui_string_decode( &decoder ); + if( decoder.character_index == _ui.controls.textbox.cursor_user ) + { + user_co[0] = decoder.grid_co[0]; + user_co[1] = decoder.grid_co[1]; + loop = 0; + } + } while( loop ); + bool loop1; do + { + loop1 = ui_string_decode( &decoder1 ); + if( decoder1.grid_co[1] == user_co[1]-1 ) + if( decoder1.grid_co[0] <= user_co[0] ) + result_index = decoder1.character_index; + } while( loop1 ); + + if( result_index != -1 ) + _ui_textbox_set_cursor_user( result_index, super ); + } + else + _ui.controls.textbox.action = k_textbox_input_up; } else if( action == k_ui_action_down ) { - i16 user_co[2] = { -1, -1 }; - i32 result_index = -1; - struct ui_string_decoder decoder; - ui_string_decode_init( &decoder, _ui.controls.textbox.text_buffer, _ui.controls.textbox.text_buffer_encoding ); - bool loop; do - { - loop = ui_string_decode( &decoder ); - if( decoder.character_index == _ui.controls.textbox.cursor_user ) - { - user_co[0] = decoder.grid_co[0]; - user_co[1] = decoder.grid_co[1]; - } - if( decoder.grid_co[1] == user_co[1]+1 ) - if( decoder.grid_co[0] <= user_co[0] ) - result_index = decoder.character_index; - } while( loop ); + if( _ui.controls.textbox.flags & UI_MULTILINE ) + { + i16 user_co[2] = { -1, -1 }; + i32 result_index = -1; + struct ui_string_decoder decoder; + ui_string_decode_init( &decoder, _ui.controls.textbox.text_buffer, _ui.controls.textbox.text_buffer_encoding ); + bool loop; do + { + loop = ui_string_decode( &decoder ); + if( decoder.character_index == _ui.controls.textbox.cursor_user ) + { + user_co[0] = decoder.grid_co[0]; + user_co[1] = decoder.grid_co[1]; + } + if( decoder.grid_co[1] == user_co[1]+1 ) + if( decoder.grid_co[0] <= user_co[0] ) + result_index = decoder.character_index; + } while( loop ); - if( result_index != -1 ) - _ui_textbox_set_cursor_user( result_index, super ); + if( result_index != -1 ) + _ui_textbox_set_cursor_user( result_index, super ); + } + else + _ui.controls.textbox.action = k_textbox_input_up; } else if( action == k_ui_action_indent ) { @@ -495,12 +509,32 @@ enum textbox_action _ui_textbox( i16 rect[4], c8 *text_buffer, u32 text_buffer_l i16 kerning[3]; _font_get_kerning( kerning ); - if( (_ui_button( rect ) == k_button_click) || (flags & UI_AUTOFOCUS) ) + bool init = 0; + if( _ui_button( rect ) == k_button_click ) + init = 1; + + if( flags & UI_AUTOFOCUS ) + { + if( _ui.active_control_type != k_ui_control_textbox ) + init = 1; + else if( _ui.controls.textbox.text_buffer != text_buffer ) + init = 1; + + if( init ) + { + _ui.controls.textbox.cursor_pos = 0; + _ui.controls.textbox.cursor_user = 0; + } + } + + if( init ) { _ui.active_control_type = k_ui_control_textbox; _ui.controls.textbox.text_buffer = text_buffer; _ui.controls.textbox.text_buffer_length = text_buffer_length; _ui.controls.textbox.text_buffer_encoding = _ui.text_encoding; + _ui.controls.textbox.flags = flags; + _ui.controls.textbox.action = k_textbox_no_action; } union colour text_colour = (union colour){{255,255,255,255}}; @@ -569,7 +603,12 @@ enum textbox_action _ui_textbox( i16 rect[4], c8 *text_buffer, u32 text_buffer_l } } _ui_text( rect, text_buffer, k_ui_align_x_left, text_colour ); - return k_textbox_no_action; + + enum textbox_action return_action = _ui.controls.textbox.action; + _ui.controls.textbox.action = k_textbox_no_action; + if( (return_action == k_textbox_enter) && !(flags & UI_MULTILINE ) ) + _ui.active_control_type = k_ui_control_none; + return return_action; } enum dropdown_action _ui_dropdown( i16 rect[4], struct ui_dropdown_option *options, u32 option_count, i32 *value ) -- 2.25.1