79#ifndef RETROFONT_PRESENT
80# error "retrofont not present!"
85#ifndef RETROGUI_TRACE_LVL
86# define RETROGUI_TRACE_LVL 0
89#ifndef RETROGUI_COLOR_BORDER
95# define RETROGUI_COLOR_BORDER RETROFLAT_COLOR_DARKBLUE
98#ifndef RETROGUI_CTL_TEXT_SZ_MAX
105#ifndef RETROGUI_KEY_ACTIVATE
111# define RETROGUI_KEY_ACTIVATE RETROFLAT_KEY_SPACE
114#ifndef RETROGUI_KEY_NEXT
120# define RETROGUI_KEY_NEXT RETROFLAT_KEY_DOWN
123#ifndef RETROGUI_KEY_PREV
129# define RETROGUI_KEY_PREV RETROFLAT_KEY_UP
132#ifndef RETROGUI_KEY_SEL_NEXT
138# define RETROGUI_KEY_SEL_NEXT RETROFLAT_KEY_RIGHT
141#ifndef RETROGUI_KEY_SEL_PREV
147# define RETROGUI_KEY_SEL_PREV RETROFLAT_KEY_LEFT
150#ifndef RETROGUI_PAD_ACTIVATE
156# define RETROGUI_PAD_ACTIVATE RETROFLAT_PAD_A
159#ifndef RETROGUI_PAD_NEXT
165# define RETROGUI_PAD_NEXT RETROFLAT_PAD_DOWN
168#ifndef RETROGUI_PAD_PREV
174# define RETROGUI_PAD_PREV RETROFLAT_PAD_UP
177#ifndef RETROGUI_PAD_SEL_NEXT
183# define RETROGUI_PAD_SEL_NEXT RETROFLAT_PAD_RIGHT
186#ifndef RETROGUI_PAD_SEL_PREV
192# define RETROGUI_PAD_SEL_PREV RETROFLAT_PAD_LEFT
195# define RETROGUI_CTL_TEXT_SZ_MAX 128
198#ifndef RETROGUI_CTL_SZ_MAX_INIT
199# define RETROGUI_CTL_SZ_MAX_INIT 20
202#ifndef RETROGUI_PADDING
207# define RETROGUI_PADDING 5
210#ifndef RETROGUI_BTN_LBL_SZ_MAX
211# define RETROGUI_BTN_LBL_SZ_MAX 64
214#ifndef RETROGUI_BTN_LBL_PADDED_X
215# define RETROGUI_BTN_LBL_PADDED_X 8
218#ifndef RETROGUI_BTN_LBL_PADDED_Y
219# define RETROGUI_BTN_LBL_PADDED_Y 8
222#ifndef RETROGUI_CTL_TEXT_BLINK_FRAMES
223# define RETROGUI_CTL_TEXT_BLINK_FRAMES 15
226#ifndef RETROGUI_CTL_LISTBOX_CURSOR_RADIUS
227# define RETROGUI_CTL_LISTBOX_CURSOR_RADIUS 8
230#ifndef RETROGUI_CTL_LISTBOX_STR_SZ_MAX
231# define RETROGUI_CTL_LISTBOX_STR_SZ_MAX 255
234#ifndef RETROGUI_CTL_TEXT_CUR_WH
235# define RETROGUI_CTL_TEXT_CUR_WH 8
238#ifndef RETROGUI_DEBOUNCE_MAX_DEFAULT
239# define RETROGUI_DEBOUNCE_MAX_DEFAULT 100
248#define RETROGUI_FLAGS_DIRTY 0x01
255#define RETROGUI_FLAGS_FONT_OWNED 0x02
257#define RETROGUI_FILLBAR_FLAG_SHOWNUM 0x02
259#define _retrogui_copy_str( field, src_str, dest_ctl, str_tmp, str_sz ) \
261 assert( NULL != src_str ); \
262 debug_printf( RETROGUI_TRACE_LVL, \
263 "copying string \"%s\" to " #dest_ctl, src_str ); \
264 if( 0 == str_sz ) { \
265 str_sz = maug_strlen( src_str ); \
266 debug_printf( RETROGUI_TRACE_LVL, \
267 "determined str sz of \"%s\": " SIZE_T_FMT, src_str, str_sz ); \
269 if( (MAUG_MHANDLE)NULL != dest_ctl. field ## _h ) { \
271 maug_mfree( dest_ctl. field ## _h ); \
275 dest_ctl. field ## _h = maug_malloc( str_sz + 1, 1 ); \
276 debug_printf( RETROGUI_TRACE_LVL, \
277 "allocated str sz for \"%s\": " SIZE_T_FMT, src_str, str_sz + 1 ); \
278 maug_cleanup_if_null_alloc( MAUG_MHANDLE, dest_ctl. field ## _h ); \
279 maug_mlock( dest_ctl. field ## _h, str_tmp ); \
280 maug_cleanup_if_null_lock( char*, str_tmp ); \
283 assert( NULL != str_tmp ); \
284 maug_mzero( str_tmp, str_sz + 1 ); \
285 debug_printf( RETROGUI_TRACE_LVL, \
286 "zeroed str sz for \"%s\": " SIZE_T_FMT, src_str, str_sz + 1 ); \
287 maug_strncpy( str_tmp, src_str, str_sz ); \
288 debug_printf( RETROGUI_TRACE_LVL, "copied str as: \"%s\"", str_tmp ); \
289 maug_munlock( dest_ctl. field ## _h, str_tmp );
294#define RETROGUI_IDC_FMT "%d"
296#define RETROGUI_IDC_NONE -1
301#define RETROGUI_COLOR_BG 1
306#define RETROGUI_COLOR_FG 2
312#define RETROGUI_COLOR_SEL_BG 3
318#define RETROGUI_COLOR_SEL_FG 4
343#define RETROGUI_CTL_TABLE_BASE( f ) \
344 f( 0, NONE, void* none; ) \
345 f( 1, LISTBOX, struct MDATA_VECTOR list; size_t sel_idx; ) \
346 f( 2, BUTTON, MAUG_MHANDLE label_h; char* label; size_t label_sz; int16_t push_frames; uint8_t font_flags; ) \
347 f( 3, LABEL, MAUG_MHANDLE label_h; char* label; size_t label_sz; uint8_t font_flags; ) \
348 f( 4, IMAGE, retroflat_blit_t image; ssize_t image_cache_id; int16_t instance; retroflat_pxxy_t src_x; retroflat_pxxy_t src_y; ) \
349 f( 5, FILLBAR, uint8_t flags; uint16_t cur; uint16_t max; )
351#ifdef RETROGUI_NO_TEXTBOX
352# define RETROGUI_CTL_TABLE( f ) RETROGUI_CTL_TABLE_BASE( f )
354# define RETROGUI_CTL_TABLE( f ) RETROGUI_CTL_TABLE_BASE( f ) \
355 f( 6, TEXTBOX, MAUG_MHANDLE text_h; char* text; size_t text_sz; size_t text_sz_max; size_t text_cur; int16_t blink_frames; )
359 f( 6, SCROLLBAR,
size_t min;
size_t max;
size_t value; )
362#ifdef RETROGUI_NO_TEXTBOX
364 (RETROGUI_CTL_TYPE_BUTTON == (ctl)->base.type || \
365 RETROGUI_CTL_TYPE_LISTBOX == (ctl)->base.type)
371 (RETROGUI_CTL_TYPE_BUTTON == (ctl)->base.type || \
372 RETROGUI_CTL_TYPE_TEXTBOX == (ctl)->base.type || \
373 RETROGUI_CTL_TYPE_LISTBOX == (ctl)->base.type)
388#if defined( RETROGUI_NATIVE_WIN )
397#define RETROGUI_CTL_TABLE_FIELDS( idx, c_name, c_fields ) \
398 struct RETROGUI_CTL_ ## c_name { \
399 struct RETROGUI_CTL_BASE base; \
409#define RETROGUI_CTL_TABLE_TYPES( idx, c_name, c_fields ) \
410 struct RETROGUI_CTL_ ## c_name c_name;
419typedef void (*retrogui_xy_cb)(
422typedef char retrogui_list_t[RETROGUI_CTL_LISTBOX_STR_SZ_MAX + 1];
441 retroflat_blit_t* draw_bmp;
442 retroflat_ms_t debounce_next;
443 retroflat_ms_t debounce_max;
444#ifdef RETROGXC_PRESENT
472 struct RETROGUI* gui, RETROFLAT_IN_KEY* p_input,
498 struct RETROGUI* gui,
const char* font_path );
500#ifndef RETROGUI_NO_TEXTBOX
515 const char* fmt, ... );
556 struct RETROGUI* gui,
size_t start, ssize_t incr );
594#define retrogui_focus_next( gui ) \
595 retrogui_focus_iter( gui, 0, 1 )
597#define retrogui_focus_prev( gui ) \
598 retrogui_focus_iter( gui, mdata_vector_ct( &((gui)->ctls) ) - 1, -1 )
602#define RETROGUI_CTL_TABLE_CONSTS( idx, c_name, c_fields ) \
603 MAUG_CONST uint8_t SEG_MCONST RETROGUI_CTL_TYPE_ ## c_name = idx;
605RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_CONSTS )
607#ifdef RETROGUI_TRACE_TOKENS
609#define RETROGUI_CTL_TABLE_NAMES( idx, c_name, f_fields ) \
612MAUG_CONST
char* SEG_MCONST gc_retrogui_ctl_names[] = {
613 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_NAMES )
668static void retrogui_destroy_NONE(
union RETROGUI_CTL* ctl ) {
692# if defined( RETROGUI_NATIVE_WIN )
696 if( !mdata_vector_is_locked( &(ctl->LISTBOX.list) ) ) {
697 mdata_vector_lock( &(ctl->LISTBOX.list) );
702 while( i < mdata_vector_ct( &(ctl->LISTBOX.list) ) ) {
704 (
char*)mdata_vector_get( &(ctl->LISTBOX.list), i, retrogui_list_t );
707#ifdef RETROGXC_PRESENT
709 gui->draw_bmp, list_i, 0, gui->font_idx,
710 ctl->base.w, ctl->base.h, &w, &h, 0 );
713 gui->draw_bmp, list_i, 0, gui->
font_h,
714 ctl->base.w, ctl->base.h, &w, &h, 0 );
721 ctl->LISTBOX.sel_idx = i;
731 mdata_vector_unlock( &(ctl->LISTBOX.list) );
734 if( MERROR_OK != retval ) {
735 idc_out = RETROGUI_IDC_NONE;
751 ctl->LISTBOX.sel_idx++;
752 if( ctl->LISTBOX.sel_idx >= mdata_vector_ct( &(ctl->LISTBOX.list) ) ) {
753 ctl->LISTBOX.sel_idx = 0;
757 gui->flags |= RETROGUI_FLAGS_DIRTY;
762 ctl->LISTBOX.sel_idx--;
764 if( ctl->LISTBOX.sel_idx >= mdata_vector_ct( &(ctl->LISTBOX.list) ) ) {
765 ctl->LISTBOX.sel_idx = mdata_vector_ct( &(ctl->LISTBOX.list) ) - 1;
769 gui->flags |= RETROGUI_FLAGS_DIRTY;
777static void retrogui_redraw_LISTBOX(
789# if defined( RETROGUI_NATIVE_WIN )
793 if( !mdata_vector_is_locked( &(ctl->LISTBOX.list) ) ) {
794 mdata_vector_lock( &(ctl->LISTBOX.list) );
798 if( RETROFLAT_COLOR_BLACK != ctl->base.bg_color ) {
799 retroflat_2d_rect( gui->draw_bmp, ctl->base.bg_color,
800 gui->x + ctl->base.x, gui->y + ctl->base.y,
804 while( i < mdata_vector_ct( &(ctl->LISTBOX.list) ) ) {
806 (
char*)mdata_vector_get( &(ctl->LISTBOX.list), i, retrogui_list_t );
807#ifdef RETROGXC_PRESENT
809 gui->draw_bmp, list_i, 0, gui->font_idx,
810 ctl->base.w, ctl->base.h, &w, &h, 0 );
813 gui->draw_bmp, list_i, 0, gui->
font_h,
814 ctl->base.w, ctl->base.h, &w, &h, 0 );
816#if RETROGUI_TRACE_LVL > 0
817 debug_printf( RETROGUI_TRACE_LVL,
818 "str height for \"%s\": " SIZE_T_FMT, list_i, h );
820 if( i == ctl->LISTBOX.sel_idx ) {
822 retroflat_2d_rect( gui->draw_bmp, ctl->base.sel_bg,
823 gui->x + ctl->base.x,
824 gui->y + ctl->base.y + item_y,
826 fg_color = ctl->base.sel_fg;
829 gui->draw_bmp, ctl->base.sel_fg,
830 gui->x + ctl->base.x,
831 gui->y + ctl->base.y + item_y,
832 RETROGUI_CTL_LISTBOX_CURSOR_RADIUS,
833 RETROGUI_CTL_LISTBOX_CURSOR_RADIUS, 0 );
836 fg_color = ctl->base.fg_color;
839#ifdef RETROGXC_PRESENT
841 gui->draw_bmp, fg_color, list_i, 0, gui->font_idx,
842 gui->x + ctl->base.x +
844 gui->y + ctl->base.y + item_y,
848 gui->draw_bmp, fg_color, list_i, 0, gui->
font_h,
849 gui->x + ctl->base.x +
851 gui->y + ctl->base.y + item_y,
863 mdata_vector_unlock( &(ctl->LISTBOX.list) );
866 assert( MERROR_OK == retval );
877# if defined( RETROGUI_NATIVE_WIN )
880 SendMessage( ctl->base.hwnd, LB_SETCURSEL, item_idx, 0 );
884 ctl->LISTBOX.sel_idx = item_idx;
897 retrogui_list_t item_stage;
900 if( !mdata_vector_is_locked( &((gui)->ctls) ) ) {
901 mdata_vector_lock( &(gui->ctls) );
905#if RETROGUI_TRACE_LVL > 0
906 debug_printf( RETROGUI_TRACE_LVL,
907 "pushing item \"%s\" to listbox " RETROGUI_IDC_FMT
"...", item, idc );
910 ctl = _retrogui_get_ctl_by_idc( gui, idc );
913 error_printf(
"could not add item: %s", item );
918# if defined( RETROGUI_NATIVE_WIN )
920 SendMessage( ctl->LISTBOX.base.hwnd, LB_ADDSTRING, 0, (LPARAM)item );
924 maug_mzero( item_stage, RETROGUI_CTL_LISTBOX_STR_SZ_MAX + 1 );
925 maug_strncpy( item_stage, item, RETROGUI_CTL_LISTBOX_STR_SZ_MAX );
926 i = mdata_vector_append(
927 &(ctl->LISTBOX.list), item_stage, RETROGUI_CTL_LISTBOX_STR_SZ_MAX + 1 );
929 retval = merror_sz_to_retval( i );
934 gui->flags |= RETROGUI_FLAGS_DIRTY;
939 mdata_vector_unlock( &(gui->ctls) );
948# if defined( RETROGUI_NATIVE_WIN )
950 ctl->base.hwnd = CreateWindow(
951 "LISTBOX", NULL, WS_CHILD | WS_VISIBLE | LBS_STANDARD,
952 gui->x + ctl->base.x, gui->y + ctl->base.y, ctl->base.w, ctl->base.h,
953 g_retroflat_state->window, (HMENU)(ctl->base.idc),
954 g_retroflat_instance, NULL );
955#if RETROGUI_TRACE_LVL > 0
956 debug_printf( RETROGUI_TRACE_LVL,
957 "listbox hwnd: %p", ctl->LISTBOX.base.hwnd );
959 if( (HWND)NULL == ctl->base.hwnd ) {
960 error_printf(
"could not create listbox" );
965 gui->flags |= RETROGUI_FLAGS_DIRTY;
998static void retrogui_destroy_LISTBOX(
union RETROGUI_CTL* ctl ) {
999 mdata_vector_free( &(ctl->LISTBOX.list) );
1005#if RETROGUI_TRACE_LVL > 0
1006 debug_printf( RETROGUI_TRACE_LVL,
1007 "initializing listbox " RETROGUI_IDC_FMT
"...", ctl->base.idc );
1010 ctl->base.bg_color = RETROFLAT_COLOR_WHITE;
1011 ctl->base.sel_fg = RETROFLAT_COLOR_WHITE;
1012 if( 2 < retroflat_screen_colors() ) {
1013 ctl->base.sel_bg = RETROFLAT_COLOR_BLUE;
1016 ctl->base.sel_bg = RETROFLAT_COLOR_BLACK;
1017 ctl->base.fg_color = RETROFLAT_COLOR_BLACK;
1032 if( 0 < ctl->BUTTON.push_frames ) {
1037 idc_out = ctl->base.idc;
1041 ctl->BUTTON.push_frames = 3;
1061static void retrogui_redraw_BUTTON(
1072 if( ctl->base.idc == gui->
focus ) {
1074 fg_color = ctl->base.sel_fg;
1077 if( ctl->base.idc == gui->
focus ) {
1079 bg_color = ctl->base.sel_bg;
1083 if( 2 >= retroflat_screen_colors() ) {
1084 push_shadow_color = RETROFLAT_COLOR_BLACK;
1085 border_color = RETROFLAT_COLOR_BLACK;
1089 gui->draw_bmp, bg_color, ctl->base.x, ctl->base.y,
1092 retroflat_2d_rect( gui->draw_bmp, border_color,
1093 gui->x + ctl->base.x, gui->y + ctl->base.y,
1094 ctl->base.w, ctl->base.h, 0 );
1099 if( 0 < ctl->BUTTON.push_frames ) {
1101 gui->draw_bmp, push_shadow_color,
1102 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + 1,
1103 gui->x + ctl->base.x + ctl->base.w - 2, gui->y + ctl->base.y + 1, 0 );
1105 gui->draw_bmp, push_shadow_color,
1106 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + 2,
1107 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + ctl->base.h - 3, 0 );
1109 gui->flags |= RETROGUI_FLAGS_DIRTY;
1110 ctl->BUTTON.push_frames--;
1115 gui->draw_bmp, RETROFLAT_COLOR_WHITE,
1116 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + 1,
1117 gui->x + ctl->base.x + ctl->base.w - 2, gui->y + ctl->base.y + 1, 0 );
1119 gui->draw_bmp, RETROFLAT_COLOR_WHITE,
1120 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + 2,
1121 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + ctl->base.h - 3, 0 );
1124 maug_mlock( ctl->BUTTON.label_h, ctl->BUTTON.label );
1125 if( NULL == ctl->BUTTON.label ) {
1126 error_printf(
"could not lock BUTTON label!" );
1131#ifdef RETROGXC_PRESENT
1134 retrofont_string_sz(
1136 gui->draw_bmp, ctl->BUTTON.label, 0,
1137#ifdef RETROGXC_PRESENT
1143 ctl->base.w, ctl->base.h, &w, &h, ctl->BUTTON.font_flags );
1145#ifdef RETROGXC_PRESENT
1150 gui->draw_bmp, fg_color, ctl->BUTTON.label, 0,
1151#ifdef RETROGXC_PRESENT
1156 gui->x + ctl->base.x + ((ctl->base.w >> 1) - (w >> 1)) + text_offset,
1157 gui->y + ctl->base.y + ((ctl->base.h >> 1) - (h >> 1)) + text_offset,
1159 ctl->base.w, ctl->base.h, ctl->BUTTON.font_flags );
1161 maug_munlock( ctl->BUTTON.label_h, ctl->BUTTON.label );
1171# if defined( RETROGUI_NATIVE_WIN )
1173 ctl->base.hwnd = CreateWindow(
1174 "BUTTON", ctl->BUTTON.label, WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
1175 gui->x + ctl->base.x, gui->y + ctl->base.y, ctl->base.w, ctl->base.h,
1176 g_retroflat_state->window, (HMENU)(ctl->base.idc),
1177 g_retroflat_instance, NULL );
1178 if( (HWND)NULL == ctl->base.hwnd ) {
1180 "Could not create button " RETROGUI_IDC_FMT
": %s",
1181 ctl->base.idc, ctl->BUTTON.label );
1182 retval = MERROR_GUI;
1187 size_t label_sz = 0;
1188 char* label_tmp = NULL;
1190#if RETROGUI_TRACE_LVL > 0
1191 debug_printf( RETROGUI_TRACE_LVL,
"pushing BUTTON control..." );
1195 label, ctl->BUTTON.label, ctl->BUTTON, label_tmp, label_sz );
1196 ctl->BUTTON.label = NULL;
1211 assert( NULL != ctl );
1212 assert( NULL == ctl->BUTTON.label );
1213 assert( (MAUG_MHANDLE)NULL != ctl->BUTTON.label_h );
1215 maug_mlock( ctl->BUTTON.label_h, ctl->BUTTON.label );
1216 maug_cleanup_if_null_lock(
char*, ctl->BUTTON.label );
1219#ifdef RETROGXC_PRESENT
1222 retrofont_string_sz(
1227#ifdef RETROGXC_PRESENT
1235 p_h, ctl->BUTTON.font_flags );
1238 *p_w += RETROGUI_BTN_LBL_PADDED_X;
1239 *p_h += RETROGUI_BTN_LBL_PADDED_Y;
1243 maug_munlock( ctl->BUTTON.label_h, ctl->BUTTON.label );
1255# if defined( RETROGUI_NATIVE_WIN )
1258 assert( NULL != ctl );
1273static void retrogui_destroy_BUTTON(
union RETROGUI_CTL* ctl ) {
1274 if( (MAUG_MHANDLE)NULL != ctl->BUTTON.label_h ) {
1275 maug_mfree( ctl->BUTTON.label_h );
1282#if RETROGUI_TRACE_LVL > 0
1283 debug_printf( RETROGUI_TRACE_LVL,
1284 "initializing button " RETROGUI_IDC_FMT
"...", ctl->base.idc );
1287 if( 2 < retroflat_screen_colors() ) {
1289 ctl->base.bg_color = RETROFLAT_COLOR_GRAY;
1290 ctl->base.sel_fg = RETROFLAT_COLOR_BLUE;
1291 ctl->base.sel_bg = RETROFLAT_COLOR_GRAY;
1293 ctl->base.fg_color = RETROFLAT_COLOR_BLACK;
1294 ctl->base.bg_color = RETROFLAT_COLOR_WHITE;
1295 ctl->base.sel_fg = RETROFLAT_COLOR_WHITE;
1296 ctl->base.sel_bg = RETROFLAT_COLOR_BLACK;
1302#ifndef RETROGUI_NO_TEXTBOX
1323# if defined( RETROGUI_NATIVE_WIN )
1327 c = retroflat_vk_to_ascii( *p_input, input_evt->key_flags );
1332 RETROFLAT_KEY_RIGHT != *p_input &&
1333 RETROFLAT_KEY_LEFT != *p_input
1339 assert( NULL == ctl->TEXTBOX.text );
1340 assert( (MAUG_MHANDLE)NULL != ctl->TEXTBOX.text_h );
1341 maug_mlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1342 if( NULL == ctl->TEXTBOX.text ) {
1343 error_printf(
"could not lock TEXTBOX text handle!" );
1347 switch( *p_input ) {
1348 case RETROFLAT_KEY_BKSP:
1350 ctl->TEXTBOX.text, ctl->TEXTBOX.text_cur, ctl->TEXTBOX.text_sz )
1353 case RETROFLAT_KEY_ENTER:
1354 idc_out = ctl->base.idc;
1357 case RETROFLAT_KEY_LEFT:
1358 if( 0 < ctl->TEXTBOX.text_cur ) {
1359 ctl->TEXTBOX.text_cur--;
1363 case RETROFLAT_KEY_RIGHT:
1364 if( ctl->TEXTBOX.text_sz > ctl->TEXTBOX.text_cur ) {
1365 ctl->TEXTBOX.text_cur++;
1370 assert( ctl->TEXTBOX.text_sz < ctl->TEXTBOX.text_sz_max );
1373 ctl->TEXTBOX.text_cur,
1374 ctl->TEXTBOX.text_sz,
1375 ctl->TEXTBOX.text_sz_max );
1383 if( NULL != ctl->TEXTBOX.text ) {
1384 maug_munlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1392static void retrogui_redraw_TEXTBOX(
1401 if( 2 >= retroflat_screen_colors() ) {
1402 shadow_color = RETROFLAT_COLOR_BLACK;
1403 border_color = RETROFLAT_COLOR_BLACK;
1406# if defined( RETROGUI_NATIVE_WIN )
1410 retroflat_2d_rect( gui->draw_bmp, ctl->base.bg_color,
1411 gui->x + ctl->base.x, gui->y + ctl->base.y,
1416 retroflat_2d_rect( gui->draw_bmp, border_color,
1417 gui->x + ctl->base.x,
1418 gui->y + ctl->base.y, ctl->base.w, 2,
1421 retroflat_2d_rect( gui->draw_bmp, border_color,
1422 gui->x + ctl->base.x,
1423 gui->y + ctl->base.y, 2, ctl->base.h,
1426 retroflat_2d_rect( gui->draw_bmp, shadow_color,
1427 gui->x + ctl->base.x,
1428 gui->y + ctl->base.y + ctl->base.h - 1,
1432 retroflat_2d_rect( gui->draw_bmp, shadow_color,
1433 gui->x + ctl->base.x + ctl->base.w - 1,
1434 gui->y + ctl->base.y, 2, ctl->base.h,
1439 assert( NULL == ctl->TEXTBOX.text );
1440 maug_mlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1441 if( NULL == ctl->TEXTBOX.text ) {
1445#ifdef RETROGXC_PRESENT
1447 gui->draw_bmp, ctl->base.fg_color,
1448 ctl->TEXTBOX.text, ctl->TEXTBOX.text_cur, gui->font_idx,
1454 gui->draw_bmp, ctl->TEXTBOX.text, ctl->TEXTBOX.text_cur, gui->font_idx,
1458 gui->draw_bmp, ctl->base.fg_color,
1459 ctl->TEXTBOX.text, ctl->TEXTBOX.text_cur, gui->
font_h,
1464 retrofont_string_sz(
1465 gui->draw_bmp, ctl->TEXTBOX.text, ctl->TEXTBOX.text_cur, gui->
font_h,
1471 if( cursor_x + RETROGUI_CTL_TEXT_CUR_WH >= ctl->base.w ) {
1474 cursor_y += RETROGUI_CTL_TEXT_CUR_WH;
1478 retroflat_2d_rect( gui->draw_bmp,
1482 RETROGUI_CTL_TEXT_CUR_WH, RETROGUI_CTL_TEXT_CUR_WH,
1485 gui->
focus == ctl->base.idc &&
1488 if( (-1 * RETROGUI_CTL_TEXT_BLINK_FRAMES) > --(ctl->TEXTBOX.blink_frames) ) {
1489 ctl->TEXTBOX.blink_frames = RETROGUI_CTL_TEXT_BLINK_FRAMES;
1492 if( NULL != ctl->TEXTBOX.text ) {
1494 #ifdef RETROGXC_PRESENT
1495 retrogxc_string_indent(
1496 gui->draw_bmp, ctl->base.fg_color,
1497 &(ctl->TEXTBOX.text[ctl->TEXTBOX.text_cur]),
1499 strlen( ctl->TEXTBOX.text ) - ctl->TEXTBOX.text_cur,
1504 ctl->base.w, ctl->base.h,
1505 cursor_x + RETROGUI_CTL_TEXT_CUR_WH, 0 );
1507 retrofont_string_indent(
1508 gui->draw_bmp, ctl->base.fg_color,
1509 &(ctl->TEXTBOX.text[ctl->TEXTBOX.text_cur]),
1511 strlen( ctl->TEXTBOX.text ) - ctl->TEXTBOX.text_cur,
1516 ctl->base.w, ctl->base.h,
1517 cursor_x + RETROGUI_CTL_TEXT_CUR_WH, 0 );
1520 maug_munlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1523 gui->flags |= RETROGUI_FLAGS_DIRTY;
1533# if defined( RETROGUI_NATIVE_WIN )
1535 ctl->base.hwnd = CreateWindow(
1536 "EDIT", 0, WS_CHILD | WS_VISIBLE | WS_BORDER,
1537 gui->x + ctl->base.x, gui->y + ctl->base.y, ctl->base.w, ctl->base.h,
1538 g_retroflat_state->window, (HMENU)(ctl->base.idc),
1539 g_retroflat_instance, NULL );
1540 if( (HWND)NULL == ctl->base.hwnd ) {
1542 "Could not create textbox: " RETROGUI_IDC_FMT, ctl->base.idc );
1543 retval = MERROR_GUI;
1549#if RETROGUI_TRACE_LVL > 0
1550 debug_printf( RETROGUI_TRACE_LVL,
1551 "clearing textbox " RETROGUI_IDC_FMT
" buffer...", ctl->base.idc );
1553 assert( (MAUG_MHANDLE)NULL == ctl->TEXTBOX.text_h );
1554 ctl->TEXTBOX.text_h = maug_malloc( RETROGUI_CTL_TEXT_SZ_MAX + 1, 1 );
1555 maug_cleanup_if_null_alloc( MAUG_MHANDLE, ctl->TEXTBOX.text_h );
1556 ctl->TEXTBOX.text_sz_max = RETROGUI_CTL_TEXT_SZ_MAX;
1558 maug_mlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1559 maug_cleanup_if_null_alloc(
char*, ctl->TEXTBOX.text );
1560#if RETROGUI_TRACE_LVL > 0
1561 debug_printf( RETROGUI_TRACE_LVL,
1562 "clearing textbox " RETROGUI_IDC_FMT
" buffer...", ctl->base.idc );
1564 maug_mzero( ctl->TEXTBOX.text, RETROGUI_CTL_TEXT_SZ_MAX + 1 );
1565 maug_munlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1594static void retrogui_destroy_TEXTBOX(
union RETROGUI_CTL* ctl ) {
1595 if( (MAUG_MHANDLE)NULL != ctl->TEXTBOX.text_h ) {
1596 maug_mfree( ctl->TEXTBOX.text_h );
1603#if RETROGUI_TRACE_LVL > 0
1604 debug_printf( RETROGUI_TRACE_LVL,
1605 "initializing textbox " RETROGUI_IDC_FMT
"...", ctl->base.idc );
1608 ctl->base.bg_color = RETROFLAT_COLOR_WHITE;
1609 ctl->base.sel_bg = RETROFLAT_COLOR_WHITE;
1610 if( 2 < retroflat_screen_colors() ) {
1611 ctl->base.sel_fg = RETROFLAT_COLOR_BLUE;
1614 ctl->base.sel_fg = RETROFLAT_COLOR_BLACK;
1615 ctl->base.fg_color = RETROFLAT_COLOR_BLACK;
1630 return RETROGUI_IDC_NONE;
1637 return RETROGUI_IDC_NONE;
1640static void retrogui_redraw_LABEL(
1644# if defined( RETROGUI_NATIVE_WIN )
1650#ifdef RETROGXC_PRESENT
1651 assert( 0 <= gui->font_idx );
1653 assert( (MAUG_MHANDLE)NULL != gui->
font_h );
1656 assert( NULL == ctl->LABEL.label );
1657 maug_mlock( ctl->LABEL.label_h, ctl->LABEL.label );
1658 if( NULL == ctl->LABEL.label ) {
1659 error_printf(
"could not lock LABEL text!" );
1663#ifdef RETROGXC_PRESENT
1668 gui->draw_bmp, ctl->base.fg_color, ctl->LABEL.label,
1669 ctl->LABEL.label_sz,
1670#ifdef RETROGXC_PRESENT
1677 ctl->LABEL.font_flags );
1681 if( NULL != ctl->LABEL.label ) {
1682 maug_munlock( ctl->LABEL.label_h, ctl->LABEL.label );
1693# if defined( RETROGUI_NATIVE_WIN )
1698 size_t label_sz = 0;
1699 char* label_tmp = NULL;
1701#if RETROGUI_TRACE_LVL > 0
1702 debug_printf( RETROGUI_TRACE_LVL,
"pushing LABEL control..." );
1706 label, ctl->LABEL.label, ctl->LABEL, label_tmp, label_sz );
1707 ctl->LABEL.label = NULL;
1735static void retrogui_destroy_LABEL(
union RETROGUI_CTL* ctl ) {
1736 if( (MAUG_MHANDLE)NULL != ctl->LABEL.label_h ) {
1737 maug_mfree( ctl->LABEL.label_h );
1744#if RETROGUI_TRACE_LVL > 0
1745 debug_printf( RETROGUI_TRACE_LVL,
1746 "initializing label " RETROGUI_IDC_FMT
"...", ctl->base.idc );
1749 if( 2 < retroflat_screen_colors() ) {
1752 ctl->base.fg_color = RETROFLAT_COLOR_BLACK;
1754 ctl->base.bg_color = RETROFLAT_COLOR_WHITE;
1766 return RETROGUI_IDC_NONE;
1773 return RETROGUI_IDC_NONE;
1776static void retrogui_redraw_IMAGE(
1779# if defined( RETROGUI_NATIVE_WIN )
1783# if defined( RETROGXC_PRESENT )
1784 if( 0 > ctl->IMAGE.image_cache_id ) {
1787#if RETROGUI_TRACE_LVL > 0
1788 debug_printf( RETROGUI_TRACE_LVL,
1789 "redrawing image ctl " RETROGUI_IDC_FMT
", cache ID " SSIZE_T_FMT
"...",
1790 ctl->base.idc, ctl->IMAGE.image_cache_id );
1792 retrogxc_blit_bitmap(
1794 ctl->IMAGE.image_cache_id,
1796 if( !retroflat_2d_bitmap_ok( gui->draw_bmp ) ) {
1799 retroflat_2d_blit_bitmap(
1801 &(ctl->IMAGE.image),
1803 ctl->IMAGE.src_x, ctl->IMAGE.src_y,
1804 gui->x + ctl->base.x, gui->y + ctl->base.y, ctl->base.w, ctl->base.h,
1805 ctl->IMAGE.instance );
1814# if defined( RETROGUI_NATIVE_WIN )
1820#if RETROGUI_TRACE_LVL > 0
1821 debug_printf( RETROGUI_TRACE_LVL,
"pushing IMAGE control..." );
1838# ifdef RETROGXC_PRESENT
1839 retval = retrogxc_bitmap_wh( ctl->IMAGE.image_cache_id, p_w, p_h );
1840 maug_cleanup_if_not_ok();
1842 if( !retroflat_2d_bitmap_ok( &(ctl->IMAGE.image) ) ) {
1843 error_printf(
"image not assigned!" );
1844 retval = MERROR_GUI;
1848 *p_w = retroflat_2d_bitmap_w( &(ctl->IMAGE.image) );
1849 *p_h = retroflat_2d_bitmap_h( &(ctl->IMAGE.image) );
1867static void retrogui_destroy_IMAGE(
union RETROGUI_CTL* ctl ) {
1868# ifndef RETROGXC_PRESENT
1869 retroflat_2d_destroy_bitmap( &(ctl->IMAGE.image) );
1876#if RETROGUI_TRACE_LVL > 0
1877 debug_printf( RETROGUI_TRACE_LVL,
1878 "initializing IMAGE " RETROGUI_IDC_FMT
"...", ctl->base.idc );
1905static void retrogui_redraw_FILLBAR(
1910 if( 0 == ctl->FILLBAR.cur ) {
1913 fill_w = ctl->base.w * ctl->FILLBAR.cur / ctl->FILLBAR.max;
1917 gui->draw_bmp, ctl->base.bg_color, ctl->base.x + fill_w, ctl->base.y,
1921 gui->draw_bmp, ctl->base.fg_color, ctl->base.x, ctl->base.y,
1930# if defined( RETROGUI_NATIVE_WIN )
1946 assert( NULL != ctl );
1960# if defined( RETROGUI_NATIVE_WIN )
1963 assert( NULL != ctl );
1978static void retrogui_destroy_FILLBAR(
union RETROGUI_CTL* ctl ) {
1984#if RETROGUI_TRACE_LVL > 0
1985 debug_printf( RETROGUI_TRACE_LVL,
1986 "initializing fillbar " RETROGUI_IDC_FMT
"...", ctl->base.idc );
1989 if( 2 < retroflat_screen_colors() ) {
1991 ctl->base.bg_color = RETROFLAT_COLOR_GRAY;
1993 ctl->base.fg_color = RETROFLAT_COLOR_BLACK;
1994 ctl->base.bg_color = RETROFLAT_COLOR_WHITE;
2008 assert( mdata_vector_is_locked( &((gui)->ctls) ) );
2010 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
2011 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
2012 if( idc == ctl->base.idc ) {
2019 error_printf(
"could not find GUI item IDC " RETROGUI_IDC_FMT, idc );
2035 assert( mdata_vector_is_locked( &((gui)->ctls) ) );
2037#if RETROGUI_TRACE_LVL > 0
2038 debug_printf( RETROGUI_TRACE_LVL,
2039 "sizing control " RETROGUI_IDC_FMT
" to: " SIZE_T_FMT
"x" SIZE_T_FMT,
2040 idc, max_w, max_h );
2043 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2046 error_printf(
"could not size item!" );
2047 retval = MERROR_GUI;
2051 #define RETROGUI_CTL_TABLE_SZ( idx, c_name, c_fields ) \
2052 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2054 retval = retrogui_sz_ ## c_name( gui, ctl, p_w, p_h, max_w, max_h ); \
2055 maug_cleanup_if_not_ok();
2058 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_SZ )
2061#if RETROGUI_TRACE_LVL > 0
2062 debug_printf( RETROGUI_TRACE_LVL,
2063 "sized control " RETROGUI_IDC_FMT
" at " SIZE_T_FMT
"x" SIZE_T_FMT
"...",
2064 ctl->base.idc, ctl->base.w, ctl->base.h );
2075 struct RETROGUI* gui, RETROFLAT_IN_KEY* p_input,
2085 if( 0 == mdata_vector_ct( &(gui->ctls) ) ) {
2086 return RETROGUI_IDC_NONE;
2089 assert( !mdata_vector_is_locked( &((gui)->ctls) ) );
2090 mdata_vector_lock( &(gui->ctls) );
2092# if defined( RETROGUI_NATIVE_WIN )
2094 if( 0 == g_retroflat_state->last_idc ) {
2099 ctl = retrogui_get_ctl_by_idc( gui, g_retroflat_state->last_idc );
2100 g_retroflat_state->last_idc = 0;
2102#if RETROGUI_TRACE_LVL > 0
2103 debug_printf( RETROGUI_TRACE_LVL,
2104 "invalid IDC: " RETROGUI_IDC_FMT, gui->
focus );
2109# ifndef RETROGUI_NO_TEXTBOX
2110 if( RETROGUI_CTL_TYPE_TEXTBOX == ctl->base.type ) {
2111 if( SendMessage( ctl->base.hwnd, EM_GETMODIFY, 0, 0 ) ) {
2112 SendMessage( ctl->base.hwnd, EM_SETMODIFY, 0, 0 );
2113#if RETROGUI_TRACE_LVL > 0
2114 debug_printf( RETROGUI_TRACE_LVL,
"mod: %d",
2115 SendMessage( ctl->base.hwnd, EM_GETMODIFY, 0, 0 ) );
2125# define RETROGUI_CTL_TABLE_CLICK( idx, c_name, c_fields ) \
2126 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2127 gui->flags |= RETROGUI_FLAGS_DIRTY; \
2128 idc_out = retrogui_click_ ## c_name( gui, ctl, p_input, input_evt );
2130# define RETROGUI_CTL_TABLE_KEY( idx, c_name, c_fields ) \
2131 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2132 gui->flags |= RETROGUI_FLAGS_DIRTY; \
2133 idc_out = retrogui_key_ ## c_name( gui, ctl, p_input, input_evt );
2135 if( 0 != *p_input ) {
2136#if RETROGUI_TRACE_LVL > 0
2137 debug_printf( RETROGUI_TRACE_LVL,
2138 "focus " RETROGUI_IDC_FMT
" input: %d", gui->
focus, *p_input );
2143 if( retroflat_get_ms() < gui->debounce_next ) {
2144#if RETROGUI_TRACE_LVL > 0
2145 debug_printf( RETROGUI_TRACE_LVL,
2146 "debo! %d vs %d", retroflat_get_ms(), gui->debounce_next );
2151 if( 0 == *p_input ) {
2159 if( 0 <= gui->
focus ) {
2160 idc_out = gui->
focus;
2162 gui->flags |= RETROGUI_FLAGS_DIRTY;
2168 retrogui_focus_next( gui );
2170#if RETROGUI_TRACE_LVL > 0
2171 debug_printf( RETROGUI_TRACE_LVL,
"next: " RETROGUI_IDC_FMT, gui->
focus );
2180 retrogui_focus_prev( gui );
2182#if RETROGUI_TRACE_LVL > 0
2183 debug_printf( RETROGUI_TRACE_LVL,
"prev: " RETROGUI_IDC_FMT, gui->
focus );
2189# ifndef RETROGUI_NO_MOUSE
2191 RETROFLAT_MOUSE_B_LEFT == *p_input ||
2192 RETROFLAT_MOUSE_B_RIGHT == *p_input
2197#if RETROGUI_TRACE_LVL > 0
2198 debug_printf( RETROGUI_TRACE_LVL,
"resetting focus for mouse click..." );
2200 gui->
focus = RETROGUI_IDC_NONE;
2202 mouse_x = input_evt->
mouse_x - gui->x;
2203 mouse_y = input_evt->
mouse_y - gui->y;
2205 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
2206 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
2208 mouse_x < ctl->base.x ||
2209 mouse_y < ctl->base.y ||
2210 mouse_x > ctl->base.x + ctl->base.w ||
2211 mouse_y > ctl->base.y + ctl->base.h
2216 if( gui->idc_prev == ctl->base.idc ) {
2219 idc_out = RETROGUI_IDC_NONE;
2223 gui->idc_prev = ctl->base.idc;
2225#if RETROGUI_TRACE_LVL > 0
2226 debug_printf( RETROGUI_TRACE_LVL,
2227 "setting focus to clicked control: " RETROGUI_IDC_FMT,
2230 gui->
focus = ctl->base.idc;
2233 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_CLICK )
2241 if( RETROGUI_IDC_NONE == gui->
focus ) {
2247 ctl = _retrogui_get_ctl_by_idc( gui, gui->
focus );
2252#if RETROGUI_TRACE_LVL > 0
2253 debug_printf( RETROGUI_TRACE_LVL,
2254 "invalid focus IDC: " RETROGUI_IDC_FMT, gui->
focus );
2260 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_KEY )
2265 gui->debounce_next = retroflat_get_ms() + gui->debounce_max;
2271 if( MERROR_OK != retval ) {
2272 idc_out = RETROGUI_IDC_NONE;
2275 mdata_vector_unlock( &(gui->ctls) );
2289 if( RETROGUI_FLAGS_DIRTY != (RETROGUI_FLAGS_DIRTY & gui->flags) ) {
2294 if( 0 == mdata_vector_ct( &(gui->ctls) ) ) {
2298 if( !mdata_vector_is_locked( &((gui)->ctls) ) ) {
2299 mdata_vector_lock( &(gui->ctls) );
2304 RETROFLAT_COLOR_BLACK != gui->bg_color &&
2305 0 < gui->w && 0 < gui->h
2307 retroflat_2d_rect( gui->draw_bmp,
2311 #define RETROGUI_CTL_TABLE_REDRAW( idx, c_name, c_fields ) \
2312 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2314 gui->flags &= ~RETROGUI_FLAGS_DIRTY; \
2315 retrogui_redraw_ ## c_name( gui, ctl );
2317 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
2318 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
2320 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_REDRAW )
2327 mdata_vector_unlock( &(gui->ctls) );
2337 size_t x,
size_t y,
size_t w,
size_t h
2343 if( !mdata_vector_is_locked( &((gui)->ctls) ) ) {
2344 mdata_vector_lock( &(gui->ctls) );
2348#if RETROGUI_TRACE_LVL > 0
2349 debug_printf( RETROGUI_TRACE_LVL,
2350 "moving control " RETROGUI_IDC_FMT
" to: " SIZE_T_FMT
", " SIZE_T_FMT,
2354 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2357 error_printf(
"could not position control!" );
2358 retval = MERROR_GUI;
2362 #define RETROGUI_CTL_TABLE_POS( idx, c_name, c_fields ) \
2363 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2365 retval = retrogui_pos_ ## c_name( gui, ctl, x, y, w, h ); \
2366 maug_cleanup_if_not_ok();
2369 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_POS )
2372#if RETROGUI_TRACE_LVL > 0
2373 debug_printf( RETROGUI_TRACE_LVL,
2374 "moved control " RETROGUI_IDC_FMT
" to " SIZE_T_FMT
", " SIZE_T_FMT
2375 " and sized to " SIZE_T_FMT
"x" SIZE_T_FMT
"...",
2376 ctl->base.idc, gui->x + ctl->base.x, gui->y + ctl->base.y,
2377 ctl->base.w, ctl->base.h );
2381 gui->flags |= RETROGUI_FLAGS_DIRTY;
2386 mdata_vector_unlock( &(gui->ctls) );
2401 assert( 0 < ctl->base.idc );
2403#ifdef RETROGXC_PRESENT
2404 if( 0 > gui->font_idx ) {
2406 if( (MAUG_MHANDLE)NULL == gui->
font_h ) {
2410 retval = MERROR_GUI;
2416#if RETROGUI_TRACE_LVL > 0
2417 debug_printf( RETROGUI_TRACE_LVL,
2418 "gui->ctls_ct: " SIZE_T_FMT, mdata_vector_ct( &(gui->ctls) ) );
2422 RETROGUI_CTL_TYPE_IMAGE != ctl->base.type &&
2423 RETROFLAT_COLOR_NULL == ctl->base.bg_color
2426 "invalid background color specified for control " RETROGUI_IDC_FMT
"!",
2428 retval = MERROR_GUI;
2434 RETROGUI_CTL_TYPE_IMAGE != ctl->base.type &&
2435 RETROFLAT_COLOR_NULL == ctl->base.fg_color
2438 "invalid foreground color specified for control " RETROGUI_IDC_FMT
"!",
2440 retval = MERROR_GUI;
2446#ifdef RETROGUI_TRACE_TOKENS
2447 debug_printf( RETROGUI_TRACE_LVL,
2448 "pushing %s " RETROGUI_IDC_FMT
" to slot " SIZE_T_FMT
"...",
2449 gc_retrogui_ctl_names[ctl->base.type], ctl->base.idc,
2450 mdata_vector_ct( &(gui->ctls) ) );
2451#elif RETROGUI_TRACE_LVL > 0
2452 debug_printf( RETROGUI_TRACE_LVL,
2453 "pushing control type %d, " RETROGUI_IDC_FMT
" to slot " SIZE_T_FMT
"...",
2454 ctl->base.type, ctl->base.idc, mdata_vector_ct( &(gui->ctls) ) );
2457 mdata_vector_append( &(gui->ctls), ctl,
sizeof(
union RETROGUI_CTL ) );
2459 gui->flags |= RETROGUI_FLAGS_DIRTY;
2464 if( !mdata_vector_is_locked( &((gui)->ctls) ) ) {
2465 mdata_vector_lock( &(gui->ctls) );
2470 ctl = mdata_vector_get_last( &(gui->ctls),
2472 assert( NULL != ctl );
2474#if RETROGUI_TRACE_LVL > 0
2475# define RETROGUI_CTL_TABLE_PUSH( idx, c_name, c_fields ) \
2476 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2477 debug_printf( RETROGUI_TRACE_LVL, \
2478 "running " #c_name " push hook..." ); \
2479 retval = retrogui_push_ ## c_name( ctl ); \
2480 maug_cleanup_if_not_ok();
2482# define RETROGUI_CTL_TABLE_PUSH( idx, c_name, c_fields ) \
2483 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2484 retval = retrogui_push_ ## c_name( ctl ); \
2485 maug_cleanup_if_not_ok();
2489 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_PUSH )
2495 if( 0 == ctl->base.w || 0 == ctl->base.h ) {
2496#ifdef RETROGUI_TRACE_TOKENS
2497 debug_printf( RETROGUI_TRACE_LVL,
2498 "determining size for new %s control " RETROGUI_IDC_FMT
"...",
2499 gc_retrogui_ctl_names[ctl->base.type], ctl->base.idc );
2500#elif RETROGUI_TRACE_LVL > 0
2501 debug_printf( RETROGUI_TRACE_LVL,
2502 "determining size for new control type %d, " RETROGUI_IDC_FMT
"...",
2503 ctl->base.type, ctl->base.idc );
2505 retval = _retrogui_sz_ctl(
2506 gui, ctl->base.idc, &(ctl->base.w), &(ctl->base.h), 0, 0 );
2507 maug_cleanup_if_not_ok();
2511#if RETROGUI_TRACE_LVL > 0
2512 debug_printf( RETROGUI_TRACE_LVL,
2513 "setting focus to control: " RETROGUI_IDC_FMT, ctl->base.idc );
2515 gui->
focus = ctl->base.idc;
2521 mdata_vector_unlock( &(gui->ctls) );
2534 if( mdata_vector_is_locked( &((gui)->ctls) ) ) {
2535 error_printf(
"GUI is locked!" );
2539 assert( !mdata_vector_is_locked( &((gui)->ctls) ) );
2540 mdata_vector_lock( &(gui->ctls) );
2542 #define RETROGUI_CTL_TABLE_FREE_CTL( idx, c_name, c_fields ) \
2543 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2544 retrogui_destroy_ ## c_name( ctl );
2546 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
2547 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
2548 if( idc != ctl->base.idc ) {
2554 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_FREE_CTL )
2558 mdata_vector_unlock( &(gui->ctls) );
2559 mdata_vector_remove( &(gui->ctls), i );
2560 mdata_vector_lock( &(gui->ctls) );
2564 mdata_vector_unlock( &(gui->ctls) );
2574 struct RETROGUI* gui,
const char* font_path
2578#ifdef RETROGXC_PRESENT
2579 gui->font_idx = retrogxc_load_font( font_path, 0, 33, 93 );
2581 gui->font_idx, (ssize_t)0, SSIZE_T_FMT, MERROR_GUI );
2584 maug_cleanup_if_not_ok();
2587 gui->flags |= RETROGUI_FLAGS_FONT_OWNED;
2594#ifndef RETROGUI_NO_TEXTBOX
2603 if( !mdata_vector_is_locked( &((gui)->ctls) ) ) {
2604 mdata_vector_lock( &(gui->ctls) );
2608 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2611 error_printf(
"could not get control text!" );
2612 retval = MERROR_GUI;
2616 if( RETROGUI_CTL_TYPE_TEXTBOX == ctl->base.type ) {
2617# if defined( RETROGUI_NATIVE_WIN )
2620 maug_mlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
2621 maug_cleanup_if_null_lock(
char*, ctl->TEXTBOX.text );
2623 maug_strncpy( buffer, ctl->TEXTBOX.text, buffer_sz );
2625 }
else if( RETROGUI_CTL_TYPE_LABEL == ctl->base.type ) {
2626# if defined( RETROGUI_NATIVE_WIN )
2629 maug_mlock( ctl->LABEL.label_h, ctl->LABEL.label );
2630 maug_cleanup_if_null_lock(
char*, ctl->LABEL.label );
2632 maug_strncpy( buffer, ctl->LABEL.label, buffer_sz );
2639 if( RETROGUI_CTL_TYPE_TEXTBOX == ctl->base.type ) {
2640 if( NULL != ctl->TEXTBOX.text ) {
2641 maug_munlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
2644 }
else if( RETROGUI_CTL_TYPE_LABEL == ctl->base.type ) {
2645 if( NULL != ctl->LABEL.label ) {
2646 maug_munlock( ctl->LABEL.label_h, ctl->LABEL.label );
2651 mdata_vector_unlock( &(gui->ctls) );
2667 if( !mdata_vector_is_locked( &((gui)->ctls) ) ) {
2668 mdata_vector_lock( &(gui->ctls) );
2672 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2675 error_printf(
"could not get control selection!" );
2676 retval = MERROR_GUI;
2680 assert( RETROGUI_CTL_TYPE_LISTBOX == ctl->base.type );
2682# if defined( RETROGUI_NATIVE_WIN )
2683 idx = SendMessage( ctl->base.hwnd, LB_GETCARETINDEX, 0, 0 );
2685 idx = ctl->LISTBOX.sel_idx;
2691 mdata_vector_unlock( &(gui->ctls) );
2694 if( MERROR_OK != retval ) {
2710 assert( !mdata_vector_is_locked( &((gui)->ctls) ) );
2711 mdata_vector_lock( &(gui->ctls) );
2713#if RETROGUI_TRACE_LVL > 0
2714 debug_printf( RETROGUI_TRACE_LVL,
2715 "setting control " RETROGUI_IDC_FMT
" color %u to: %d",
2716 idc, color_key, color_val );
2720 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2723 error_printf(
"could not set control color!" );
2724 retval = MERROR_GUI;
2728 switch( color_key ) {
2735 error_printf(
"invalid color key specified: %u", color_key );
2741 mdata_vector_unlock( &(gui->ctls) );
2750 const char* fmt, ...
2753 size_t label_sz = 0;
2754 char* label_tmp = NULL;
2755 char* buffer = NULL;
2757 MAUG_MHANDLE buffer_h = (MAUG_MHANDLE)NULL;
2760 assert( !mdata_vector_is_locked( &((gui)->ctls) ) );
2761 mdata_vector_lock( &(gui->ctls) );
2763#if RETROGUI_TRACE_LVL > 0
2764 debug_printf( RETROGUI_TRACE_LVL,
2765 "setting control " RETROGUI_IDC_FMT
" text to: %s", idc, fmt );
2769 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2772 error_printf(
"could not set control text!" );
2773 retval = MERROR_GUI;
2778 buffer_h = maug_malloc( 1, buffer_sz + 1 );
2779 maug_cleanup_if_null_alloc( MAUG_MHANDLE, buffer_h );
2781 assert( 0 < buffer_sz );
2783 maug_mlock( buffer_h, buffer );
2784 maug_cleanup_if_null_lock(
char*, buffer );
2785 maug_mzero( buffer, buffer_sz + 1 );
2787 assert( NULL != buffer );
2791 maug_mzero( buffer, buffer_sz + 1);
2795 va_start( args, fmt );
2796 maug_vsnprintf( buffer, buffer_sz, fmt, args );
2801 if( RETROGUI_CTL_TYPE_BUTTON == ctl->base.type ) {
2802 assert( NULL == ctl->BUTTON.label );
2803 _retrogui_copy_str( label, buffer, ctl->BUTTON, label_tmp, buffer_sz );
2804 }
else if( RETROGUI_CTL_TYPE_LABEL == ctl->base.type ) {
2805 assert( NULL == ctl->LABEL.label );
2806 _retrogui_copy_str( label, buffer, ctl->LABEL, label_tmp, label_sz );
2807#ifndef RETROGUI_NO_TEXTBOX
2808 }
else if( RETROGUI_CTL_TYPE_TEXTBOX == ctl->base.type ) {
2809 assert( NULL == ctl->TEXTBOX.text );
2811 label_sz = RETROGUI_CTL_TEXT_SZ_MAX;
2813 text, buffer, ctl->TEXTBOX, label_tmp, label_sz );
2814 ctl->TEXTBOX.text_cur = 0;
2817 error_printf(
"invalid control type! no label!" );
2822 gui->flags |= RETROGUI_FLAGS_DIRTY;
2826 if( NULL != buffer ) {
2827 maug_munlock( buffer_h, buffer );
2830 if( (MAUG_MHANDLE)NULL != buffer_h ) {
2831 maug_mfree( buffer_h );
2834 mdata_vector_unlock( &(gui->ctls) );
2848 if( !mdata_vector_is_locked( &((gui)->ctls) ) ) {
2849 mdata_vector_lock( &(gui->ctls) );
2853#if RETROGUI_TRACE_LVL > 0
2854 debug_printf( RETROGUI_TRACE_LVL,
2855 "setting control " RETROGUI_IDC_FMT
" image to: %s", idc, path );
2859 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2862 error_printf(
"could not set control image!" );
2863 retval = MERROR_GUI;
2868 if( RETROGUI_CTL_TYPE_IMAGE == ctl->base.type ) {
2869 if( NULL != path ) {
2870# if defined( RETROGXC_PRESENT )
2871 ctl->IMAGE.image_cache_id = retrogxc_load_bitmap( path, flags );
2873 retroflat_2d_load_bitmap( path, &(ctl->IMAGE.image), flags );
2876# ifdef RETROGXC_PRESENT
2877 ctl->IMAGE.image_cache_id = -1;
2879 retroflat_2d_destroy_bitmap( &(ctl->IMAGE.image) );
2883 error_printf(
"invalid control type! no image!" );
2888 gui->flags |= RETROGUI_FLAGS_DIRTY;
2893 mdata_vector_unlock( &(gui->ctls) );
2909 if( !mdata_vector_is_locked( &((gui)->ctls) ) ) {
2910 mdata_vector_lock( &(gui->ctls) );
2914#if RETROGUI_TRACE_LVL > 0
2915 debug_printf( RETROGUI_TRACE_LVL,
2916 "setting control " RETROGUI_IDC_FMT
" level to: %u", idc, level );
2920 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2923 error_printf(
"could not set control level!" );
2924 retval = MERROR_GUI;
2929 if( RETROGUI_CTL_TYPE_FILLBAR == ctl->base.type ) {
2930 ctl->FILLBAR.cur = level;
2932 ctl->FILLBAR.max = max;
2935 error_printf(
"invalid control type! no level!" );
2940 gui->flags |= RETROGUI_FLAGS_DIRTY;
2945 mdata_vector_unlock( &(gui->ctls) );
2958#if RETROGUI_TRACE_LVL > 0
2959 debug_printf( RETROGUI_TRACE_LVL,
2960 "initializing control base " RETROGUI_IDC_FMT
"...", idc );
2965 ctl->base.type = type;
2966 ctl->base.idc = idc;
2967 ctl->base.fg_color = RETROFLAT_COLOR_NULL;
2968 ctl->base.bg_color = RETROFLAT_COLOR_NULL;
2969 ctl->base.sel_fg = RETROFLAT_COLOR_NULL;
2970 ctl->base.sel_bg = RETROFLAT_COLOR_NULL;
2972 #define RETROGUI_CTL_TABLE_INITS( idx, c_name, c_fields ) \
2973 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2974 retrogui_init_ ## c_name( ctl );
2977 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_INITS )
2980# ifdef RETROGXC_PRESENT
2981 if( RETROGUI_CTL_TYPE_IMAGE == type ) {
2982 ctl->IMAGE.image_cache_id = -1;
2996 if( mdata_vector_is_locked( &((gui)->ctls) ) ) {
2997 error_printf(
"GUI is locked!" );
3001 if( 0 == mdata_vector_ct( &(gui->ctls) ) ) {
3005 assert( !mdata_vector_is_locked( &((gui)->ctls) ) );
3006 mdata_vector_lock( &(gui->ctls) );
3008 #define RETROGUI_CTL_TABLE_FREE( idx, c_name, c_fields ) \
3009 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
3010 retrogui_destroy_ ## c_name( ctl );
3012 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
3013 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
3015 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_FREE )
3019 mdata_vector_unlock( &(gui->ctls) );
3021# ifndef RETROGXC_PRESENT
3022 if( RETROGUI_FLAGS_FONT_OWNED == (RETROGUI_FLAGS_FONT_OWNED & gui->flags) ) {
3023 maug_mfree( gui->
font_h );
3029 mdata_vector_free( &(gui->ctls) );
3037 struct RETROGUI* gui,
size_t start, ssize_t incr
3043 ssize_t i_before = -1;
3046 if( 0 == mdata_vector_ct( &(gui->ctls) ) ) {
3050 if( !mdata_vector_is_locked( &((gui)->ctls) ) ) {
3051 mdata_vector_lock( &(gui->ctls) );
3057 i = start ; mdata_vector_ct( &(gui->ctls) ) > i && 0 <= i ; i += incr
3059 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
3062 }
else if( RETROGUI_IDC_NONE == gui->
focus || 0 <= i_before ) {
3064 idc_out = ctl->base.idc;
3065#if RETROGUI_TRACE_LVL > 0
3066 debug_printf( RETROGUI_TRACE_LVL,
3067 "moving focus to control: " RETROGUI_IDC_FMT, idc_out );
3069 gui->
focus = idc_out;
3072 }
else if( ctl->base.idc == gui->
focus ) {
3084 for( i = mdata_vector_ct( &(gui->ctls) ) - 1 ; 0 <= i ; i-- ) {
3085 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
3088#if RETROGUI_TRACE_LVL > 0
3090 RETROGUI_TRACE_LVL,
"skipping: " RETROGUI_IDC_FMT, i );
3094 idc_out = ctl->base.idc;
3095#if RETROGUI_TRACE_LVL > 0
3096 debug_printf( RETROGUI_TRACE_LVL,
3097 "moving focus to control: " RETROGUI_IDC_FMT, idc_out );
3099 gui->
focus = idc_out;
3104 }
else if( mdata_vector_ct( &(gui->ctls) ) <= i ) {
3106 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
3107 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
3110#if RETROGUI_TRACE_LVL > 0
3112 RETROGUI_TRACE_LVL,
"skipping: " RETROGUI_IDC_FMT, i );
3116 idc_out = ctl->base.idc;
3117#if RETROGUI_TRACE_LVL > 0
3118 debug_printf( RETROGUI_TRACE_LVL,
3119 "moving focus to control: " RETROGUI_IDC_FMT, idc_out );
3121 gui->
focus = idc_out;
3127 error_printf(
"invalid focus: " RETROGUI_IDC_FMT, i );
3134 gui->flags |= RETROGUI_FLAGS_DIRTY;
3136 if( MERROR_OK != retval ) {
3137 idc_out = merror_retval_to_sz( retval );
3141 mdata_vector_unlock( &(gui->ctls) );
3144#if RETROGUI_TRACE_LVL > 0
3146 RETROGUI_TRACE_LVL,
"selected IDC: " RETROGUI_IDC_FMT, idc_out );
3157 maug_mzero( gui,
sizeof(
struct RETROGUI ) );
3159 gui->bg_color = RETROFLAT_COLOR_BLACK;
3160 gui->
focus = RETROGUI_IDC_NONE;
3161 gui->debounce_max = RETROGUI_DEBOUNCE_MAX_DEFAULT;
3163#if RETROGUI_TRACE_LVL > 0
3164 debug_printf( RETROGUI_TRACE_LVL,
"initialized GUI" );
3172#define RETROGUI_CTL_TABLE_CONSTS( idx, c_name, c_fields ) \
3173 extern MAUG_CONST uint8_t SEG_MCONST RETROGUI_CTL_TYPE_ ## c_name;
3175RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_CONSTS )
3177#ifdef RETROGUI_TRACE_TOKENS
3178extern MAUG_CONST
char* gc_retrogui_ctl_names[];
int MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:19
int8_t RETROFLAT_COLOR
Defines an index in the platform-specific color-table.
Definition retroflt.h:325
void retroflat_ellipse(struct RETROFLAT_BITMAP *target, const RETROFLAT_COLOR color, int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags)
Draw an ellipse onto the target ::RETROFLAT_BITMAP.
#define RETROFLAT_FLAGS_FILL
Flag for retroflat_rect() or retroflat_ellipse(), indicating drawn shape should be filled.
Definition retroflt.h:373
void retroflat_message(uint8_t flags, const char *title, const char *format,...)
Display a message in a dialog box and/or on stderr.
#define RETROFLAT_MSG_FLAG_ERROR
This icon/type flag indicates an error. It will try to display messages in an urgent way with a red i...
Definition retroflt.h:461
size_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition retroflt.h:870
#define RETROGUI_KEY_SEL_PREV
Overrideable constant defining the keyboard key (RETROFLAT_KEY_*) that will select the previous sub-i...
Definition retrogui.h:147
#define RETROGUI_PAD_SEL_NEXT
Overrideable constant defining the gamepad button (RETROGUI_PAD_*) that will select the next sub-item...
Definition retrogui.h:183
#define RETROGUI_KEY_NEXT
Overrideable constant defining the keyboard key (RETROFLAT_KEY_*) that will select the next activatea...
Definition retrogui.h:120
#define RETROGUI_KEY_ACTIVATE
Overrideable constant defining the keyboard key (RETROFLAT_KEY_*) that will activate the RETROGUI_CTL...
Definition retrogui.h:111
#define RETROGUI_PAD_ACTIVATE
Overrideable constant defining the gamepad button (RETROFLAT_PAD_*) that will activate the RETROGUI_C...
Definition retrogui.h:156
#define RETROGUI_PAD_SEL_PREV
Overrideable constant defining the gamepad button (RETROGUI_PAD_*) that will select the previous sub-...
Definition retrogui.h:192
#define RETROGUI_PAD_NEXT
Overrideable constant defining the gamepad button (RETROFLAT_PAD_*) that will select the next activat...
Definition retrogui.h:165
#define RETROGUI_KEY_PREV
Overrideable constant defining the keyboard key (RETROFLAT_KEY_*) that will select the previous activ...
Definition retrogui.h:129
#define RETROGUI_KEY_SEL_NEXT
Overrideable constant defining the keyboard key (RETROFLAT_KEY_*) that will select the next sub-item ...
Definition retrogui.h:138
#define RETROGUI_PAD_PREV
Overrideable constant defining the gamepad button (RETROFLAT_PAD_*) that will select the previous act...
Definition retrogui.h:174
#define RETROGUI_PADDING
Overrideable constant defining the padding for text inside of controls in pixels.
Definition retrogui.h:207
#define RETROGUI_CTL_TABLE_FIELDS(idx, c_name, c_fields)
Creates the corresponding RETROGUI_* structs from RETROGUI_CTL_TABLE that populate union RETROGUI_CTL...
Definition retrogui.h:397
#define retrogui_can_focus_ctl(ctl)
Determine if a RETROGUI_CTL can hold RETROGUI::focus.
Definition retrogui.h:370
#define RETROGUI_CTL_TABLE_TYPES(idx, c_name, c_fields)
Adds the structs created by RETROGUI_CTL_TABLE_FIELDS to union RETROGUI_CTL.
Definition retrogui.h:409
MERROR_RETVAL retrogui_set_ctl_level(struct RETROGUI *gui, retrogui_idc_t idc, uint16_t level, uint16_t max, uint8_t flags)
Set the current progress level displayed by a FILLBAR-type RETROGUI_CTL.
#define RETROGUI_COLOR_SEL_BG
Value for retrogui_set_ctl_color() color_key indicating selection background.
Definition retrogui.h:312
retrogui_idc_t retrogui_poll_ctls(struct RETROGUI *gui, RETROFLAT_IN_KEY *p_input, struct RETROFLAT_INPUT *input_evt)
Poll for the last clicked control and maintain listboxes and menus.
MERROR_RETVAL retrogui_remove_ctl(struct RETROGUI *gui, retrogui_idc_t idc)
Remove a control with the given unique identifier index from the given RETROGUI controller.
#define RETROGUI_COLOR_SEL_FG
Value for retrogui_set_ctl_color() color_key indicating selection foreground.
Definition retrogui.h:318
#define RETROGUI_COLOR_BG
Value for retrogui_set_ctl_color() color_key indicating background.
Definition retrogui.h:301
MERROR_RETVAL retrogui_destroy(struct RETROGUI *gui)
Free memory held by a RETROGUI controller internally and clean up any subordinate controls.
retrogui_idc_t retrogui_focus_iter(struct RETROGUI *gui, size_t start, ssize_t incr)
Increment RETROGUI::focus, skipping elements that cannot hold focus.
MERROR_RETVAL retrogui_init(struct RETROGUI *gui)
Prepare a RETROGUI controller for use.
MERROR_RETVAL retrogui_set_font(struct RETROGUI *gui, const char *font_path)
Load the RetroFont API for the given RETROGUI to draw its controls with. Use RetroGXCache API if avai...
int16_t retrogui_idc_t
Unique identifying constant number for controls.
Definition retrogui.h:292
#define RETROGUI_COLOR_BORDER
RetroGUI will try to use this color on non-monochrome systems instead of black to draw things like bo...
Definition retrogui.h:95
MERROR_RETVAL retrogui_set_ctl_image(struct RETROGUI *gui, retrogui_idc_t idc, const char *path, uint8_t flags)
Set the image displayed by an IMAGE-type RETROGUI_CTL.
#define RETROGUI_COLOR_FG
Value for retrogui_set_ctl_color() color_key indicating foreground.
Definition retrogui.h:306
void retrofont_string(retroflat_blit_t *target, RETROFLAT_COLOR color, const char *str, size_t str_sz, MAUG_MHANDLE font_h, size_t x, size_t y, size_t max_w, size_t max_h, uint8_t flags)
Draw a string with the given font.
#define RETROFONT_FLAG_SZ_MIN
Flag for retroflat_string_sz() to return the size of the shortest line in a multi-line string.
Definition retrofnt.h:39
MERROR_RETVAL retrofont_load(const char *font_name, MAUG_MHANDLE *p_font_h, uint8_t glyph_h, uint16_t first_glyph, uint16_t glyphs_count)
Load a font for drawing.
A vector of uniformly-sized objects, stored contiguously.
Definition mdata.h:93
size_t item_sz
Size, in bytes, of each item.
Definition mdata.h:111
Fields common to ALL RETROGUI_CTL types.
Definition retrogui.h:377
Definition retrogui.h:430
MAUG_MHANDLE font_h
Font used to draw any attached RETROGUI_CTL.
Definition retrogui.h:456
retrogui_idc_t focus
Unique identifying index for current highlighted RETROGUI_CTL.
Definition retrogui.h:440
Definition retrogui.h:412