textbox/console
authorhgn <hgodden00@gmail.com>
Thu, 2 Oct 2025 12:12:23 +0000 (12:12 +0000)
committerhgn <hgodden00@gmail.com>
Thu, 2 Oct 2025 12:12:23 +0000 (12:12 +0000)
foundation.kv
include/common_api.h
include/graphics_api.h
source/engine/console.c
source/engine/input.c
source/graphics/ui.c

index b67b322ea863cb5bacf7ae52a40c96195bf2739a..7de37dee6fc7f402fb093abfac0c2c0fe962ffe9 100644 (file)
@@ -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
    {
index 4b95e613ce547331595687ac400ffc45c078662a..61a0b117831714b84e43bf22c298b9dc6fcd2fc2 100644 (file)
@@ -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 );
 
index 5cfff55e79a87d732ee1bb5fa36570f676e33506..10c2bdef1e66c7e700812637d6be2b520c8b41c1 100644 (file)
@@ -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,
index 5a46710e045bc7e2995cc5a2284352e5d7254512..f334f7a3a246b0d59467d40d1c0d180cdbb73cfe 100644 (file)
@@ -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';
+   }
 }
index bf0c5ec93f7dd7b4fddfc0e30cf0755733a7186d..6c98055fbcf85fc28eac133a4df4c68927098ef2 100644 (file)
@@ -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
index ee65482cf844e42bd8b3ae9eb8a8b54aeeb463b7..1d3296976e8d50b55f43979c1ac1bd7081749315 100644 (file)
@@ -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 )