X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vg_console.h;h=1024b82ac468b0b6e6c08d557e7561e965ffc387;hb=76d234b7dc5e6500e8a54009b367e7620f11ef97;hp=d5da84729b2f5e770baf1863c3b8406aaf4f73ef;hpb=651edda3736812c89f43c11319c6b485ff14ea19;p=vg.git diff --git a/vg_console.h b/vg_console.h index d5da847..1024b82 100644 --- a/vg_console.h +++ b/vg_console.h @@ -7,7 +7,7 @@ #define VG_GAME #endif -#include "vg/vg_ui.h" +#include "vg/vg_imgui.h" #include "vg/vg_log.h" #define VG_VAR_F32( NAME, ... ) \ @@ -18,8 +18,9 @@ { u32 flags=0x00; __VA_ARGS__ ;\ vg_console_reg_var( #NAME, &NAME, k_var_dtype_i32, flags ); } -#define VG_VAR_PERSISTENT 0x1 -#define VG_VAR_CHEAT 0x2 +#define VG_VAR_PERSISTENT 0x1 +#define VG_VAR_CHEAT 0x2 +#define VG_VAR_CHEATTOGGLE 0x4 typedef struct vg_var vg_var; typedef struct vg_cmd vg_cmd; @@ -35,8 +36,9 @@ struct vg_console{ k_var_dtype_f32 } data_type; - u32 flags; + + union{ u32 _u32; f32 _f32; i32 _i32; } defaults; } vars[ 128 ]; @@ -63,48 +65,37 @@ struct vg_console{ char input[96], input_copy[96]; - int cursor_user, cursor_pos, string_length; char history[32][96]; int history_last, history_pos, history_count; - int enabled; + i32 enabled, cheats; } -vg_console; +static vg_console; - -VG_STATIC void _vg_console_draw( void ); +static void _vg_console_draw( void ); void _vg_console_println( const char *str ); -VG_STATIC int _vg_console_list( int argc, char const *argv[] ); -VG_STATIC void _vg_console_init(void); -VG_STATIC void _vg_console_write_persistent(void); -VG_STATIC void _vg_console_free(void); -VG_STATIC void vg_execute_console_input( const char *cmd ); +static int _vg_console_list( int argc, char const *argv[] ); +static void _vg_console_init(void); +static void _vg_console_write_persistent(void); +static void _vg_console_free(void); +static void vg_execute_console_input( const char *cmd ); /* * Console interface */ -VG_STATIC void console_make_selection( int* start, int* end ); -VG_STATIC void console_move_cursor( int* cursor0, int* cursor1, - int dir, int snap_together ); -VG_STATIC int console_makeroom( int datastart, int length ); -VG_STATIC int console_delete_char( int direction ); -VG_STATIC void console_to_clipboard(void); -VG_STATIC void console_clipboard_paste(void); -VG_STATIC void console_put_char( char c ); -VG_STATIC void console_history_get( char* buf, int entry_num ); -VG_STATIC int _vg_console_enabled(void); -VG_STATIC void console_proc_key( SDL_Keysym ev ); +static void console_history_get( char* buf, int entry_num ); +static int _vg_console_enabled(void); +static void console_proc_key( SDL_Keysym ev ); /* * Implementation */ -VG_STATIC int _vg_console_enabled(void) -{ +static int _vg_console_enabled(void){ return vg_console.enabled; } -VG_STATIC +static void vg_console_reg_var( const char *alias, void *ptr, enum vg_var_dtype type, u32 flags ) { @@ -117,10 +108,14 @@ void vg_console_reg_var( const char *alias, void *ptr, enum vg_var_dtype type, var->data_type = type; var->flags = flags; + if ( type == k_var_dtype_f32 ) var->defaults._f32 = *((f32 *)ptr); + else if( type == k_var_dtype_i32 ) var->defaults._i32 = *((i32 *)ptr); + else if( type == k_var_dtype_u32 ) var->defaults._u32 = *((u32 *)ptr); + vg_info( "Console variable '%s' registered\n", alias ); } -VG_STATIC +static void vg_console_reg_cmd( const char *alias, int (*function)(int argc, const char *argv[]), void (*poll_suggest)(int argc, const char *argv[]) ) @@ -137,96 +132,7 @@ void vg_console_reg_cmd( const char *alias, vg_info( "Console function '%s' registered\n", alias ); } -VG_STATIC void _vg_console_draw(void) -{ - if( !vg_console.enabled ) - return; - - SDL_AtomicLock( &log_print_sl ); - - int ptr = vg_log.buffer_line_current; - int const fh = 14, - log_lines = 32; - int console_lines = VG_MIN( log_lines, vg_log.buffer_line_count ); - - vg_uictx.cursor[0] = 0; - vg_uictx.cursor[1] = 0; - vg_uictx.cursor[3] = log_lines*fh; - ui_fill_x(); - - /* - * log - */ - ui_new_node(); - { - ui_fill_rect( vg_uictx.cursor, 0x77181818 ); - - vg_uictx.cursor[3] = fh; - ui_align_bottom(); - - for( int i=0; iname ); @@ -240,14 +146,12 @@ VG_STATIC int _vg_console_list( int argc, char const *argv[] ) return 0; } -int _test_break( int argc, const char *argv[] ) -{ +int _test_break( int argc, const char *argv[] ){ vg_fatal_error( "Test crash from main, after loading (console)" ); return 0; } -int _vg_console_exec( int argc, const char *argv[] ) -{ +int _vg_console_exec( int argc, const char *argv[] ){ if( argc < 1 ) return 0; char path[256]; @@ -275,20 +179,40 @@ int _vg_console_exec( int argc, const char *argv[] ) return 0; } -VG_STATIC void _vg_console_init(void) -{ +int _ccmd_vg_console_defaults( int argc, const char *argv[] ){ + for( int i=0; idata_type; + void *ptr = cv->data; + + if ( type == k_var_dtype_f32 ) *((f32 *)ptr) = cv->defaults._f32; + else if( type == k_var_dtype_i32 ) *((i32 *)ptr) = cv->defaults._i32; + else if( type == k_var_dtype_u32 ) *((u32 *)ptr) = cv->defaults._u32; + } + + return 0; +} + +static void _vg_console_init(void){ vg_console_reg_cmd( "list", _vg_console_list, NULL ); vg_console_reg_cmd( "crash", _test_break, NULL ); vg_console_reg_cmd( "exec", _vg_console_exec, NULL ); + vg_console_reg_cmd( "defaults", _ccmd_vg_console_defaults, NULL ); + vg_console_reg_var( "cheats", &vg_console.cheats, k_var_dtype_i32, +#ifdef VG_DEVWINDOW + VG_VAR_PERSISTENT +#else + 0 +#endif + ); } -VG_STATIC void vg_console_load_autos(void) -{ +static void vg_console_load_autos(void){ _vg_console_exec( 1, (const char *[]){ "auto.conf" } ); } -VG_STATIC void _vg_console_write_persistent(void) -{ +static void _vg_console_write_persistent(void){ FILE *fp = fopen( "cfg/auto.conf", "w" ); for( int i=0; i= 2 ){ + if( cv->flags & VG_VAR_CHEAT ){ + if( !vg_console.cheats ){ + vg_error( "variable is cheat protected\n" ); + return; + } + } + if( (cv->data_type == k_var_dtype_u32) || (cv->data_type == k_var_dtype_i32) ) { int *ptr = cv->data; *ptr = atoi( args[1] ); + + if( cv->flags & VG_VAR_CHEATTOGGLE ){ + if( *ptr ){ + _ccmd_vg_console_defaults( 0, NULL ); + } + } } else if( cv->data_type == k_var_dtype_f32 ){ float *ptr = cv->data; @@ -428,8 +365,7 @@ VG_STATIC void vg_execute_console_input( const char *cmd ) vg_error( "No command/var named '%s'. Use 'list' to view all\n", args[0] ); } -u32 str_lev_distance( const char *s1, const char *s2 ) -{ +u32 str_lev_distance( const char *s1, const char *s2 ){ u32 m = strlen( s1 ), n = strlen( s2 ); @@ -466,8 +402,7 @@ u32 str_lev_distance( const char *s1, const char *s2 ) return costs[n]; } -u32 str_lcs( const char *s1, const char *s2 ) -{ +u32 str_lcs( const char *s1, const char *s2 ){ u32 m = VG_MIN( 31, strlen( s1 ) ), n = VG_MIN( 31, strlen( s2 ) ); @@ -491,7 +426,7 @@ u32 str_lcs( const char *s1, const char *s2 ) } /* str must not fuckoff ever! */ -VG_STATIC void console_suggest_score_text( const char *str, const char *input, +static void console_suggest_score_text( const char *str, const char *input, int minscore ) { /* filter duplicates */ @@ -527,8 +462,12 @@ VG_STATIC void console_suggest_score_text( const char *str, const char *input, } } -VG_STATIC void console_update_suggestions(void) +static void console_update_suggestions(void) { + if( vg_ui.focused_control_type != k_ui_control_textbox || + vg_ui.textbuf != vg_console.input ) + return; + vg_console.suggestion_count = 0; vg_console.suggestion_select = -1; vg_console.suggestion_maxlen = 0; @@ -540,24 +479,19 @@ VG_STATIC void console_update_suggestions(void) * - cursors should match */ - if( vg_console.cursor_pos == 0 ) - return; - - if( vg_console.cursor_pos != vg_console.cursor_user ) - return; - - if( vg_console.input[ vg_console.cursor_pos ] != '\0' ) - return; + if( vg_ui.textbox.cursor_pos == 0 ) return; + if( vg_ui.textbox.cursor_pos != vg_ui.textbox.cursor_user ) return; + if( vg_console.input[ vg_ui.textbox.cursor_pos ] != '\0' ) return; - if( (vg_console.input[ vg_console.cursor_pos -1 ] == ' ') || - (vg_console.input[ vg_console.cursor_pos -1 ] == '\t') ) + if( (vg_console.input[ vg_ui.textbox.cursor_pos -1 ] == ' ') || + (vg_console.input[ vg_ui.textbox.cursor_pos -1 ] == '\t') ) return; char temp[128]; const char *args[8]; int token_count = vg_console_tokenize( vg_console.input, temp, args ); - + if( !token_count ) return; vg_console.suggestion_pastepos = args[token_count-1]-temp; /* Score all our commands and cvars */ @@ -598,117 +532,72 @@ VG_STATIC void console_update_suggestions(void) } /* - * Console Interface + * Suggestion controls */ -VG_STATIC void console_make_selection( int* start, int* end ) -{ - *start = VG_MIN( vg_console.cursor_pos, vg_console.cursor_user ); - *end = VG_MAX( vg_console.cursor_pos, vg_console.cursor_user ); -} - -VG_STATIC void console_move_cursor( int* cursor0, int* cursor1, - int dir, int snap_together ) +static void _console_fetch_suggestion(void) { - *cursor0 = VG_MAX( 0, vg_console.cursor_user + dir ); - *cursor0 = - VG_MIN( - VG_MIN( vg_list_size(vg_console.input)-1, strlen( vg_console.input )), - *cursor0 ); - - if( snap_together ) - *cursor1 = *cursor0; -} + char *target = &vg_console.input[ vg_console.suggestion_pastepos ]; -VG_STATIC int console_makeroom( int datastart, int length ) -{ - int move_to = VG_MIN( datastart+length, vg_list_size( vg_console.input )-1 ); - int move_amount = strlen( vg_console.input )-datastart; - int move_end = - VG_MIN( move_to+move_amount, vg_list_size( vg_console.input )-1 ); - move_amount = move_end-move_to; - - if( move_amount ) - memmove( &vg_console.input[ move_to ], - &vg_console.input[ datastart ], - move_end-move_to ); - - vg_console.input[ move_end ] = '\0'; - - return VG_MIN( length, vg_list_size( vg_console.input )-datastart-1 ); -} + if( vg_console.suggestion_select == -1 ){ + strcpy( target, vg_console.input_copy ); + _ui_textbox_move_cursor( &vg_ui.textbox.cursor_user, + &vg_ui.textbox.cursor_pos, 10000, 1 ); + } + else{ + strncpy( target, + vg_console.suggestions[ vg_console.suggestion_select ].str, + vg_list_size( vg_console.input )-1 ); -VG_STATIC int console_delete_char( int direction ) -{ - int start, end; - console_make_selection( &start, &end ); - - /* There is no selection */ - if( !(end-start) ){ - if( direction == 1 ) end = VG_MIN( end+1, strlen( vg_console.input ) ); - else if( direction == -1 ) start = VG_MAX( start-1, 0 ); - } - - /* Still no selction, no need to do anything */ - if( !(end-start) ) - return start; - - /* Copy the end->terminator to start */ - int remaining_length = strlen( vg_console.input )+1-end; - memmove( &vg_console.input[ start ], - &vg_console.input[ end ], - remaining_length ); - return start; + _ui_textbox_move_cursor( &vg_ui.textbox.cursor_user, + &vg_ui.textbox.cursor_pos, 10000, 1 ); + _ui_textbox_put_char( ' ' ); + } } -VG_STATIC void console_to_clipboard(void) +static void _console_suggest_store_normal(void) { - int start, end; - console_make_selection( &start, &end ); - char buffer[512]; - - if( end-start ){ - memcpy( buffer, &vg_console.input[ start ], end-start ); - buffer[ end-start ] = 0x00; - SDL_SetClipboardText( buffer ); - } + if( vg_console.suggestion_select == -1 ){ + char *target = &vg_console.input[ vg_console.suggestion_pastepos ]; + strcpy( vg_console.input_copy, target ); + } } -VG_STATIC void console_clipboard_paste(void) +static void _console_suggest_next(void) { - if( !SDL_HasClipboardText() ) - return; + if( vg_console.suggestion_count ){ + _console_suggest_store_normal(); - char *text = SDL_GetClipboardText(); + vg_console.suggestion_select ++; - if( !text ) - return; + if( vg_console.suggestion_select >= vg_console.suggestion_count ) + vg_console.suggestion_select = -1; + + _console_fetch_suggestion(); + } +} - int datastart = console_delete_char( 0 ); - int length = strlen( text ); - int cpylength = console_makeroom( datastart, length ); +static void _console_suggest_prev(void) +{ + if( vg_console.suggestion_count ){ + _console_suggest_store_normal(); + + vg_console.suggestion_select --; - memcpy( vg_console.input + datastart, text, cpylength); - console_move_cursor( &vg_console.cursor_user, - &vg_console.cursor_pos, cpylength, 1 ); - SDL_free( text ); + if( vg_console.suggestion_select < -1 ) + vg_console.suggestion_select = vg_console.suggestion_count-1; - console_update_suggestions(); + _console_fetch_suggestion(); + } } -VG_STATIC void console_put_char( char c ) +static void _vg_console_on_update( char *buf, u32 len ) { - if( !vg_console.enabled ) - return; - - vg_console.cursor_user = console_delete_char(0); - - if( console_makeroom( vg_console.cursor_user, 1 ) ) - vg_console.input[ vg_console.cursor_user ] = c; - - console_move_cursor( &vg_console.cursor_user, &vg_console.cursor_pos, 1, 1 ); + if( buf == vg_console.input ){ + console_update_suggestions(); + } } -VG_STATIC void console_history_get( char* buf, int entry_num ) +static void console_history_get( char* buf, int entry_num ) { if( !vg_console.history_count ) return; @@ -719,295 +608,151 @@ VG_STATIC void console_history_get( char* buf, int entry_num ) strcpy( buf, vg_console.history[ pick ] ); } -/* Receed secondary cursor */ -VG_STATIC void _console_left_select(void) -{ - console_move_cursor( &vg_console.cursor_user, NULL, -1, 0 ); -} - -/* Match and receed both cursors */ -VG_STATIC void _console_left(void) -{ - int cursor_diff = vg_console.cursor_pos - vg_console.cursor_user? 0: 1; - - console_move_cursor( &vg_console.cursor_user, - &vg_console.cursor_pos, -cursor_diff, 1 ); -} - -VG_STATIC void _console_right_select(void) -{ - console_move_cursor( &vg_console.cursor_user, NULL, 1, 0 ); -} - -VG_STATIC void _console_right(void) +static void _vg_console_on_up( char *buf, u32 len ) { - int cursor_diff = vg_console.cursor_pos - vg_console.cursor_user? 0: 1; - - console_move_cursor( &vg_console.cursor_user, - &vg_console.cursor_pos, +cursor_diff, 1 ); -} - -VG_STATIC void _console_down(void) -{ - vg_console.history_pos = VG_MAX( 0, vg_console.history_pos-1 ); - console_history_get( vg_console.input, vg_console.history_pos ); - - console_move_cursor( &vg_console.cursor_user, - &vg_console.cursor_pos, - vg_list_size(vg_console.input)-1, 1 ); -} - -VG_STATIC void _console_up(void) -{ - vg_console.history_pos = VG_MAX - ( - 0, - VG_MIN - ( - vg_console.history_pos+1, - VG_MIN - ( + if( buf == vg_console.input ){ + vg_console.history_pos = + VG_MAX + ( + 0, + VG_MIN + ( + vg_console.history_pos+1, + VG_MIN + ( vg_list_size( vg_console.history ), vg_console.history_count - 1 - ) - ) - ); - - console_history_get( vg_console.input, vg_console.history_pos ); - console_move_cursor( &vg_console.cursor_user, - &vg_console.cursor_pos, - vg_list_size(vg_console.input)-1, 1); -} - -VG_STATIC void _console_backspace(void) -{ - vg_console.cursor_user = console_delete_char( -1 ); - vg_console.cursor_pos = vg_console.cursor_user; - - console_update_suggestions(); -} - -VG_STATIC void _console_delete(void) -{ - vg_console.cursor_user = console_delete_char( 1 ); - vg_console.cursor_pos = vg_console.cursor_user; - - console_update_suggestions(); + ) + ) + ); + + console_history_get( vg_console.input, vg_console.history_pos ); + _ui_textbox_move_cursor( &vg_ui.textbox.cursor_user, + &vg_ui.textbox.cursor_pos, + vg_list_size(vg_console.input)-1, 1); + } } -VG_STATIC void _console_home_select(void) +static void _vg_console_on_down( char *buf, u32 len ) { - console_move_cursor( &vg_console.cursor_user, NULL, -10000, 0 ); -} + if( buf == vg_console.input ){ + vg_console.history_pos = VG_MAX( 0, vg_console.history_pos-1 ); + console_history_get( vg_console.input, vg_console.history_pos ); -VG_STATIC void _console_home(void) -{ - console_move_cursor( &vg_console.cursor_user, - &vg_console.cursor_pos, -10000, 1 ); + _ui_textbox_move_cursor( &vg_ui.textbox.cursor_user, + &vg_ui.textbox.cursor_pos, + vg_list_size(vg_console.input)-1, 1 ); + } } -VG_STATIC void _console_end_select(void) +static void _vg_console_on_enter( char *buf, u32 len ) { - console_move_cursor( &vg_console.cursor_user, NULL, 10000, 0 ); -} + if( buf == vg_console.input ){ + if( !strlen( vg_console.input ) ) + return; -VG_STATIC void _console_end(void) -{ - console_move_cursor( &vg_console.cursor_user, - &vg_console.cursor_pos, - vg_list_size(vg_console.input)-1, 1 ); -} + vg_info( "%s\n", vg_console.input ); -VG_STATIC void _console_select_all(void) -{ - console_move_cursor( &vg_console.cursor_user, NULL, 10000, 0); - console_move_cursor( &vg_console.cursor_pos, NULL, -10000, 0); -} + if( strcmp( vg_console.input, + vg_console.history[ vg_console.history_last ]) ) + { + vg_console.history_last = ( vg_console.history_last + 1) % + vg_list_size(vg_console.history ); + vg_console.history_count = + VG_MIN( vg_list_size( vg_console.history ), + vg_console.history_count + 1 ); + strcpy( vg_console.history[ vg_console.history_last ], + vg_console.input ); + } -VG_STATIC void _console_cut(void) -{ - console_to_clipboard(); - vg_console.cursor_user = console_delete_char(0); - vg_console.cursor_pos = vg_console.cursor_user; -} + vg_console.history_pos = -1; + vg_execute_console_input( vg_console.input ); + _ui_textbox_move_cursor( &vg_ui.textbox.cursor_user, + &vg_ui.textbox.cursor_pos, -10000, 1 ); -VG_STATIC void _console_enter(void) -{ - if( !strlen( vg_console.input ) ) - return; - - vg_info( "%s\n", vg_console.input ); - - if( strcmp( vg_console.input, - vg_console.history[ vg_console.history_last ]) ) - { - vg_console.history_last = ( vg_console.history_last + 1) % - vg_list_size(vg_console.history ); - vg_console.history_count = - VG_MIN( vg_list_size( vg_console.history ), - vg_console.history_count + 1 ); - strcpy( vg_console.history[ vg_console.history_last ], - vg_console.input ); + vg_console.input[0] = '\0'; + console_update_suggestions(); } - - vg_console.history_pos = -1; - vg_execute_console_input( vg_console.input ); - console_move_cursor( &vg_console.cursor_user, - &vg_console.cursor_pos, -10000, 1 ); - vg_console.input[0] = '\0'; - - console_update_suggestions(); } -/* - * Suggestion controls - */ -VG_STATIC void _console_fetch_suggestion(void) +static void _vg_console_draw(void) { - char *target = &vg_console.input[ vg_console.suggestion_pastepos ]; + if( !vg_console.enabled ) return; - if( vg_console.suggestion_select == -1 ){ - strcpy( target, vg_console.input_copy ); - console_move_cursor( &vg_console.cursor_user, - &vg_console.cursor_pos, 10000, 1 ); - } - else{ - strncpy( target, - vg_console.suggestions[ vg_console.suggestion_select ].str, - vg_list_size( vg_console.input )-1 ); + SDL_AtomicLock( &log_print_sl ); - console_move_cursor( &vg_console.cursor_user, - &vg_console.cursor_pos, 10000, 1 ); - console_put_char( ' ' ); - } -} + int ptr = vg_log.log_line_current; + int const fh = vg_ui.font->line_height, log_lines = 32; + int console_lines = VG_MIN( log_lines, vg_log.log_line_count ); -VG_STATIC void _console_suggest_store_normal(void) -{ - if( vg_console.suggestion_select == -1 ){ - char *target = &vg_console.input[ vg_console.suggestion_pastepos ]; - strcpy( vg_console.input_copy, target ); - } -} + ui_rect rect_log = { 0, 0, vg.window_x, log_lines*fh }, + rect_input = { 0, log_lines*fh + 1, vg.window_x, fh*2 }, + rect_line = { 0, 0, vg.window_x, fh }; + + /* + * log + */ + u32 bg_colour = (ui_colour( k_ui_bg )&0x00ffffff)|0x9f000000; -VG_STATIC void _console_suggest_next(void) -{ - if( vg_console.suggestion_count ){ - _console_suggest_store_normal(); + ui_fill( rect_log, bg_colour ); + rect_line[1] = rect_log[1]+rect_log[3]-fh; - vg_console.suggestion_select ++; + for( int i=0; i= vg_console.suggestion_count ) - vg_console.suggestion_select = -1; + if( ptr < 0 ) ptr = vg_list_size( vg_log.log )-1; - _console_fetch_suggestion(); + ui_text( rect_line, vg_log.log[ptr], 1, k_ui_align_left, 0 ); + rect_line[1] -= fh; } -} - -VG_STATIC void _console_suggest_prev(void) -{ - if( vg_console.suggestion_count ){ - _console_suggest_store_normal(); - - vg_console.suggestion_select --; - - if( vg_console.suggestion_select < -1 ) - vg_console.suggestion_select = vg_console.suggestion_count-1; - - _console_fetch_suggestion(); - } -} - -/* - * Handles binds - */ -VG_STATIC void console_proc_key( SDL_Keysym ev ) -{ - /* Open / close console */ - if( ev.sym == SDLK_BACKQUOTE ){ - vg_console.enabled = !vg_console.enabled; - - if( vg_console.enabled ) - SDL_StartTextInput(); - else - SDL_StopTextInput(); - } - - if( !vg_console.enabled ) return; + + /* + * Input area + */ - struct console_mapping - { - u16 mod; - SDL_Keycode key; - - void (*handler)(void); - } - mappings[] = - { - { 0, SDLK_LEFT, _console_left }, - { KMOD_SHIFT, SDLK_LEFT, _console_left_select }, - { 0, SDLK_RIGHT, _console_right }, - { KMOD_SHIFT, SDLK_RIGHT, _console_right_select }, - { 0, SDLK_DOWN, _console_down }, - { 0, SDLK_UP, _console_up }, - { 0, SDLK_BACKSPACE, _console_backspace }, - { 0, SDLK_DELETE, _console_delete }, - { 0, SDLK_HOME, _console_home }, - { KMOD_SHIFT, SDLK_HOME, _console_home_select }, - { 0, SDLK_END, _console_end }, - { KMOD_SHIFT, SDLK_END, _console_end_select }, - { KMOD_CTRL, SDLK_a, _console_select_all }, - { KMOD_CTRL, SDLK_c, console_to_clipboard }, - { KMOD_CTRL, SDLK_x, _console_cut }, - { KMOD_CTRL, SDLK_v, console_clipboard_paste }, - { 0, SDLK_RETURN, _console_enter }, - { KMOD_CTRL, SDLK_n, _console_suggest_next }, - { KMOD_CTRL, SDLK_p, _console_suggest_prev } + struct ui_textbox_callbacks callbacks = { + .up = _vg_console_on_up, + .down = _vg_console_on_down, + .change = _vg_console_on_update, + .enter = _vg_console_on_enter }; + ui_textbox( rect_input, NULL, + vg_console.input, vg_list_size(vg_console.input), 1, + UI_TEXTBOX_AUTOFOCUS, &callbacks ); - SDL_Keymod mod = 0; - - if( ev.mod & KMOD_SHIFT ) - mod |= KMOD_SHIFT; + /* + * suggestions + */ + if( vg_console.suggestion_count ){ + ui_rect rect_suggest; + rect_copy( rect_input, rect_suggest ); - if( ev.mod & KMOD_CTRL ) - mod |= KMOD_CTRL; + rect_suggest[0] += 6 + vg_ui.font->spacing*vg_console.suggestion_pastepos; + rect_suggest[1] += rect_input[3]; + rect_suggest[2] = vg_ui.font->spacing * vg_console.suggestion_maxlen; + rect_suggest[3] = vg_console.suggestion_count * fh; - if( ev.mod & KMOD_ALT ) - mod |= KMOD_ALT; + ui_fill( rect_suggest, bg_colour ); - for( int i=0; ikey == ev.sym ){ - if( mapping->mod == 0 ){ - if( mod == 0 ){ - mapping->handler(); - return; - } - } - else if( (mod & mapping->mod) == mapping->mod ){ - mapping->handler(); - return; + for( int i=0; i