11#ifndef RETROFONT_PRESENT
12# error "retrofont not present!"
15#ifndef RETROGUI_KEY_ACTIVATE
16# define RETROGUI_KEY_ACTIVATE RETROFLAT_KEY_SPACE
19#ifndef RETROGUI_KEY_NEXT
20# define RETROGUI_KEY_NEXT RETROFLAT_KEY_DOWN
23#ifndef RETROGUI_KEY_PREV
24# define RETROGUI_KEY_PREV RETROFLAT_KEY_UP
28#define RETROGUI_FLAGS_DIRTY 0x01
30#define RETROGUI_FILLBAR_FLAG_SHOWNUM 0x02
32#ifndef RETROGUI_TRACE_LVL
33# define RETROGUI_TRACE_LVL 0
36#ifndef RETROGUI_CTL_TEXT_SZ_MAX
37# define RETROGUI_CTL_TEXT_SZ_MAX 128
40#ifndef RETROGUI_CTL_SZ_MAX_INIT
41# define RETROGUI_CTL_SZ_MAX_INIT 20
44#ifndef RETROGUI_PADDING
45# define RETROGUI_PADDING 5
48#ifndef RETROGUI_BTN_LBL_SZ_MAX
49# define RETROGUI_BTN_LBL_SZ_MAX 64
52#ifndef RETROGUI_BTN_LBL_PADDED_X
53# define RETROGUI_BTN_LBL_PADDED_X 8
56#ifndef RETROGUI_BTN_LBL_PADDED_Y
57# define RETROGUI_BTN_LBL_PADDED_Y 8
60#ifndef RETROGUI_CTL_TEXT_BLINK_FRAMES
61# define RETROGUI_CTL_TEXT_BLINK_FRAMES 15
64#define retrogui_lock( gui )
66#define retrogui_unlock( gui )
68#define retrogui_is_locked( gui ) (mdata_vector_is_locked( &((gui)->ctls) ))
70#define _retrogui_copy_str( field, src_str, dest_ctl, str_tmp, str_sz ) \
72 assert( NULL != src_str ); \
73 debug_printf( RETROGUI_TRACE_LVL, \
74 "copying string \"%s\" to " #dest_ctl, src_str ); \
76 str_sz = maug_strlen( src_str ); \
77 debug_printf( RETROGUI_TRACE_LVL, \
78 "determined str sz of \"%s\": " SIZE_T_FMT, src_str, str_sz ); \
80 if( (MAUG_MHANDLE)NULL != dest_ctl. field ## _h ) { \
82 maug_mfree( dest_ctl. field ## _h ); \
86 dest_ctl. field ## _h = maug_malloc( str_sz + 1, 1 ); \
87 debug_printf( RETROGUI_TRACE_LVL, \
88 "allocated str sz for \"%s\": " SIZE_T_FMT, src_str, str_sz + 1 ); \
89 maug_cleanup_if_null_alloc( MAUG_MHANDLE, dest_ctl. field ## _h ); \
90 maug_mlock( dest_ctl. field ## _h, str_tmp ); \
91 maug_cleanup_if_null_lock( char*, str_tmp ); \
94 assert( NULL != str_tmp ); \
95 maug_mzero( str_tmp, str_sz + 1 ); \
96 debug_printf( RETROGUI_TRACE_LVL, \
97 "zeroed str sz for \"%s\": " SIZE_T_FMT, src_str, str_sz + 1 ); \
98 maug_strncpy( str_tmp, src_str, str_sz ); \
99 debug_printf( RETROGUI_TRACE_LVL, "copied str as: \"%s\"", str_tmp ); \
100 maug_munlock( dest_ctl. field ## _h, str_tmp );
105#define RETROGUI_IDC_NONE 0
121#define RETROGUI_CTL_TABLE_BASE( f ) \
122 f( 0, NONE, void* none; ) \
123 f( 1, LISTBOX, MAUG_MHANDLE list_h; char* list; size_t list_sz; size_t list_sz_max; size_t sel_idx; ) \
124 f( 2, BUTTON, MAUG_MHANDLE label_h; char* label; size_t label_sz; int16_t push_frames; uint8_t font_flags; ) \
125 f( 3, LABEL, MAUG_MHANDLE label_h; char* label; size_t label_sz; uint8_t font_flags; ) \
126 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; ) \
127 f( 5, FILLBAR, uint8_t flags; uint16_t cur; uint16_t max; )
129#ifdef RETROGUI_NO_TEXTBOX
130# define RETROGUI_CTL_TABLE( f ) RETROGUI_CTL_TABLE_BASE( f )
132# define RETROGUI_CTL_TABLE( f ) RETROGUI_CTL_TABLE_BASE( f ) \
133 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; )
137 f( 6, SCROLLBAR,
size_t min;
size_t max;
size_t value; )
152#if defined( RETROGUI_NATIVE_WIN )
161#define RETROGUI_CTL_TABLE_FIELDS( idx, c_name, c_fields ) \
162 struct RETROGUI_CTL_ ## c_name { \
163 struct RETROGUI_CTL_BASE base; \
173#define RETROGUI_CTL_TABLE_TYPES( idx, c_name, c_fields ) \
174 struct RETROGUI_CTL_ ## c_name c_name;
183typedef void (*retrogui_xy_cb)(
196 retroflat_blit_t* draw_bmp;
197#ifdef RETROGXC_PRESENT
216 struct RETROGUI* gui, RETROFLAT_IN_KEY* p_input,
239#ifndef RETROGUI_NO_TEXTBOX
251 const char* fmt, ... );
264 struct RETROGUI* gui,
size_t start, ssize_t incr );
272#define retrogui_focus_next( gui ) \
273 retrogui_focus_iter( gui, 0, 1 )
275#define retrogui_focus_prev( gui ) \
276 retrogui_focus_iter( gui, mdata_vector_ct( &((gui)->ctls) ) - 1, -1 )
280#define RETROGUI_CTL_TABLE_CONSTS( idx, c_name, c_fields ) \
281 MAUG_CONST uint8_t RETROGUI_CTL_TYPE_ ## c_name = idx;
283RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_CONSTS )
285#define RETROGUI_CTL_TABLE_NAMES( idx, c_name, f_fields ) \
288MAUG_CONST
char* gc_retrogui_ctl_names[] = {
289 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_NAMES )
342static void retrogui_free_NONE(
union RETROGUI_CTL* ctl ) {
365# if defined( RETROGUI_NATIVE_WIN )
369 assert( NULL == ctl->LISTBOX.list );
370 assert( NULL != ctl->LISTBOX.list_h );
371 maug_mlock( ctl->LISTBOX.list_h, ctl->LISTBOX.list );
372 maug_cleanup_if_null_lock(
char*, ctl->LISTBOX.list );
375 while( i < ctl->LISTBOX.list_sz ) {
376#ifdef RETROGXC_PRESENT
378 gui->draw_bmp, &(ctl->LISTBOX.list[i]), 0, gui->font_idx,
379 ctl->base.w, ctl->base.h, &w, &h, 0 );
382 gui->draw_bmp, &(ctl->LISTBOX.list[i]), 0, gui->font_h,
383 ctl->base.w, ctl->base.h, &w, &h, 0 );
388 ctl->base.y + ((j + 1) * (h + RETROGUI_PADDING))
390 ctl->LISTBOX.sel_idx = j;
395 i += maug_strlen( &(ctl->LISTBOX.list[i]) ) + 1;
396 assert( i <= ctl->LISTBOX.list_sz );
402 if( NULL != ctl->LISTBOX.list ) {
403 maug_munlock( ctl->LISTBOX.list_h, ctl->LISTBOX.list );
406 if( MERROR_OK != retval ) {
407 idc_out = RETROGUI_IDC_NONE;
426static void retrogui_redraw_LISTBOX(
435 assert( NULL == ctl->LISTBOX.list );
437# if defined( RETROGUI_NATIVE_WIN )
441 maug_mlock( ctl->LISTBOX.list_h, ctl->LISTBOX.list );
442 if( NULL == ctl->LISTBOX.list ) {
446 retroflat_2d_rect( gui->draw_bmp, ctl->base.bg_color,
447 gui->x + ctl->base.x, gui->y + ctl->base.y,
451 while( i < ctl->LISTBOX.list_sz ) {
452#ifdef RETROGXC_PRESENT
454 gui->draw_bmp, &(ctl->LISTBOX.list[i]), 0, gui->font_idx,
455 ctl->base.w, ctl->base.h, &w, &h, 0 );
458 gui->draw_bmp, &(ctl->LISTBOX.list[i]), 0, gui->font_h,
459 ctl->base.w, ctl->base.h, &w, &h, 0 );
461 if( j == ctl->LISTBOX.sel_idx ) {
463 retroflat_2d_rect( gui->draw_bmp, ctl->base.sel_bg,
464 gui->x + ctl->base.x,
465 gui->y + ctl->base.y + (j * (h + RETROGUI_PADDING)),
467 fg_color = ctl->base.sel_fg;
469 fg_color = ctl->base.fg_color;
472#ifdef RETROGXC_PRESENT
474 gui->draw_bmp, fg_color, &(ctl->LISTBOX.list[i]), 0,
476 gui->x + ctl->base.x,
477 gui->y + ctl->base.y + (j * (h + RETROGUI_PADDING)),
481 gui->draw_bmp, fg_color, &(ctl->LISTBOX.list[i]), 0,
483 gui->x + ctl->base.x,
484 gui->y + ctl->base.y + (j * (h + RETROGUI_PADDING)),
489 i += maug_strlen( &(ctl->LISTBOX.list[i]) ) + 1;
490 assert( i <= ctl->LISTBOX.list_sz );
496 if( NULL != ctl->LISTBOX.list ) {
497 maug_munlock( ctl->LISTBOX.list_h, ctl->LISTBOX.list );
509# if defined( RETROGUI_NATIVE_WIN )
512 SendMessage( ctl->base.hwnd, LB_SETCURSEL, item_idx, 0 );
516 ctl->LISTBOX.sel_idx = item_idx;
528 MAUG_MHANDLE listbox_h_new = (MAUG_MHANDLE)NULL;
530 retrogui_lock( gui );
532 debug_printf( RETROGUI_TRACE_LVL,
533 "pushing item \"%s\" to listbox " SIZE_T_FMT
"...", item, idc );
535 ctl = _retrogui_get_ctl_by_idc( gui, idc );
538 "Adding item \"%s\" failed: Control missing!", item );
543# if defined( RETROGUI_NATIVE_WIN )
545 SendMessage( ctl->LISTBOX.base.hwnd, LB_ADDSTRING, 0, (LPARAM)item );
549 if( 0 == ctl->LISTBOX.list_sz ) {
550 ctl->LISTBOX.list_h = maug_malloc( 255,
sizeof(
char ) );
551 maug_cleanup_if_null_alloc( MAUG_MHANDLE, ctl->LISTBOX.list_h );
552 ctl->LISTBOX.list_sz_max = 255;
555 if( NULL != ctl->LISTBOX.list ) {
556 maug_munlock( ctl->LISTBOX.list_h, ctl->LISTBOX.list );
559 while( ctl->LISTBOX.list_sz + item_sz + 1 >= ctl->LISTBOX.list_sz_max ) {
560 debug_printf( RETROGUI_TRACE_LVL,
561 "resizing listbox items to " SIZE_T_FMT
"...",
562 ctl->LISTBOX.list_sz );
564 listbox_h_new, ctl->LISTBOX.list_h,
565 ctl->LISTBOX.list_sz_max * 2,
sizeof(
char ) );
566 ctl->LISTBOX.list_sz_max *= 2;
569 maug_mlock( ctl->LISTBOX.list_h, ctl->LISTBOX.list );
570 maug_cleanup_if_null_alloc(
char*, ctl->LISTBOX.list );
572 maug_strncpy( &(ctl->LISTBOX.list[ctl->LISTBOX.list_sz]), item, item_sz );
573 ctl->LISTBOX.list[ctl->LISTBOX.list_sz + item_sz] =
'\0';
574 ctl->LISTBOX.list_sz += item_sz + 1;
580 if( NULL != ctl->LISTBOX.list ) {
581 maug_munlock( ctl->LISTBOX.list_h, ctl->LISTBOX.list );
590# if defined( RETROGUI_NATIVE_WIN )
592 ctl->base.hwnd = CreateWindow(
593 "LISTBOX", NULL, WS_CHILD | WS_VISIBLE | LBS_STANDARD,
594 gui->x + ctl->base.x, gui->y + ctl->base.y, ctl->base.w, ctl->base.h,
595 g_retroflat_state->window, (HMENU)(ctl->base.idc),
596 g_retroflat_instance, NULL );
597 debug_printf( RETROGUI_TRACE_LVL,
598 "listbox hwnd: %p", ctl->LISTBOX.base.hwnd );
599 if( (HWND)NULL == ctl->base.hwnd ) {
600 error_printf(
"could not create listbox" );
636static void retrogui_free_LISTBOX(
union RETROGUI_CTL* ctl ) {
637 assert( NULL == ctl->LISTBOX.list );
638 maug_mfree( ctl->LISTBOX.list_h );
644 debug_printf( RETROGUI_TRACE_LVL,
645 "initializing listbox " SIZE_T_FMT
"...", ctl->base.idc );
647 ctl->base.fg_color = RETROFLAT_COLOR_BLACK;
648 ctl->base.bg_color = RETROFLAT_COLOR_WHITE;
649 ctl->base.sel_fg = RETROFLAT_COLOR_WHITE;
650 if( 2 < retroflat_screen_colors() ) {
651 ctl->base.sel_bg = RETROFLAT_COLOR_BLUE;
653 ctl->base.sel_bg = RETROFLAT_COLOR_BLACK;
668 if( 0 < ctl->BUTTON.push_frames ) {
673 idc_out = ctl->base.idc;
677 ctl->BUTTON.push_frames = 3;
697static void retrogui_redraw_BUTTON(
707 if( ctl->base.idc == gui->focus ) {
709 fg_color = ctl->base.sel_fg;
712 if( ctl->base.idc == gui->focus ) {
714 bg_color = ctl->base.sel_bg;
718 gui->draw_bmp, bg_color, ctl->base.x, ctl->base.y,
721 retroflat_2d_rect( gui->draw_bmp, RETROFLAT_COLOR_BLACK,
722 gui->x + ctl->base.x, gui->y + ctl->base.y,
723 ctl->base.w, ctl->base.h, 0 );
726 if( 2 >= retroflat_screen_colors() ) {
727 push_shadow_color = RETROFLAT_COLOR_BLACK;
733 if( 0 < ctl->BUTTON.push_frames ) {
735 gui->draw_bmp, push_shadow_color,
736 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + 1,
737 gui->x + ctl->base.x + ctl->base.w - 2, gui->y + ctl->base.y + 1, 0 );
739 gui->draw_bmp, push_shadow_color,
740 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + 2,
741 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + ctl->base.h - 3, 0 );
744 ctl->BUTTON.push_frames--;
749 gui->draw_bmp, RETROFLAT_COLOR_WHITE,
750 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + 1,
751 gui->x + ctl->base.x + ctl->base.w - 2, gui->y + ctl->base.y + 1, 0 );
753 gui->draw_bmp, RETROFLAT_COLOR_WHITE,
754 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + 2,
755 gui->x + ctl->base.x + 1, gui->y + ctl->base.y + ctl->base.h - 3, 0 );
758 maug_mlock( ctl->BUTTON.label_h, ctl->BUTTON.label );
759 if( NULL == ctl->BUTTON.label ) {
760 error_printf(
"could not lock BUTTON label!" );
765#ifdef RETROGXC_PRESENT
770 gui->draw_bmp, ctl->BUTTON.label, 0,
771#ifdef RETROGXC_PRESENT
777 ctl->base.w, ctl->base.h, &w, &h, ctl->BUTTON.font_flags );
779#ifdef RETROGXC_PRESENT
784 gui->draw_bmp, fg_color, ctl->BUTTON.label, 0,
785#ifdef RETROGXC_PRESENT
790 gui->x + ctl->base.x + ((ctl->base.w >> 1) - (w >> 1)) + text_offset,
791 gui->y + ctl->base.y + ((ctl->base.h >> 1) - (h >> 1)) + text_offset,
793 ctl->base.w, ctl->base.h, ctl->BUTTON.font_flags );
795 maug_munlock( ctl->BUTTON.label_h, ctl->BUTTON.label );
805# if defined( RETROGUI_NATIVE_WIN )
807 ctl->base.hwnd = CreateWindow(
808 "BUTTON", ctl->BUTTON.label, WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
809 gui->x + ctl->base.x, gui->y + ctl->base.y, ctl->base.w, ctl->base.h,
810 g_retroflat_state->window, (HMENU)(ctl->base.idc),
811 g_retroflat_instance, NULL );
812 if( (HWND)NULL == ctl->base.hwnd ) {
814 "Could not create button " SIZE_T_FMT
": %s",
815 ctl->base.idc, ctl->BUTTON.label );
822 char* label_tmp = NULL;
824 debug_printf( RETROGUI_TRACE_LVL,
"pushing BUTTON control..." );
827 label, ctl->BUTTON.label, ctl->BUTTON, label_tmp, label_sz );
828 ctl->BUTTON.label = NULL;
843 assert( NULL != ctl );
844 assert( NULL == ctl->BUTTON.label );
845 assert( NULL != ctl->BUTTON.label_h );
847 maug_mlock( ctl->BUTTON.label_h, ctl->BUTTON.label );
848 maug_cleanup_if_null_lock(
char*, ctl->BUTTON.label );
851#ifdef RETROGXC_PRESENT
859#ifdef RETROGXC_PRESENT
867 p_h, ctl->BUTTON.font_flags );
870 *p_w += RETROGUI_BTN_LBL_PADDED_X;
871 *p_h += RETROGUI_BTN_LBL_PADDED_Y;
875 maug_munlock( ctl->BUTTON.label_h, ctl->BUTTON.label );
887# if defined( RETROGUI_NATIVE_WIN )
890 assert( NULL != ctl );
905static void retrogui_free_BUTTON(
union RETROGUI_CTL* ctl ) {
906 if( NULL != ctl->BUTTON.label_h ) {
907 maug_mfree( ctl->BUTTON.label_h );
914 debug_printf( RETROGUI_TRACE_LVL,
915 "initializing button " SIZE_T_FMT
"...", ctl->base.idc );
917 ctl->base.fg_color = RETROFLAT_COLOR_BLACK;
918 if( 2 < retroflat_screen_colors() ) {
919 ctl->base.bg_color = RETROFLAT_COLOR_GRAY;
920 ctl->base.sel_fg = RETROFLAT_COLOR_BLUE;
921 ctl->base.sel_bg = RETROFLAT_COLOR_GRAY;
923 ctl->base.bg_color = RETROFLAT_COLOR_WHITE;
924 ctl->base.sel_fg = RETROFLAT_COLOR_WHITE;
925 ctl->base.sel_bg = RETROFLAT_COLOR_BLACK;
931#ifndef RETROGUI_NO_TEXTBOX
952# if defined( RETROGUI_NATIVE_WIN )
956 c = retroflat_vk_to_ascii( *p_input, input_evt->key_flags );
961 RETROFLAT_KEY_RIGHT != *p_input &&
962 RETROFLAT_KEY_LEFT != *p_input
968 assert( NULL == ctl->TEXTBOX.text );
969 assert( (MAUG_MHANDLE)NULL != ctl->TEXTBOX.text_h );
970 maug_mlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
971 if( NULL == ctl->TEXTBOX.text ) {
972 error_printf(
"could not lock TEXTBOX text handle!" );
977 case RETROFLAT_KEY_BKSP:
979 ctl->TEXTBOX.text, ctl->TEXTBOX.text_cur, ctl->TEXTBOX.text_sz )
982 case RETROFLAT_KEY_ENTER:
983 idc_out = ctl->base.idc;
986 case RETROFLAT_KEY_LEFT:
987 if( 0 < ctl->TEXTBOX.text_cur ) {
988 ctl->TEXTBOX.text_cur--;
992 case RETROFLAT_KEY_RIGHT:
993 if( ctl->TEXTBOX.text_sz > ctl->TEXTBOX.text_cur ) {
994 ctl->TEXTBOX.text_cur++;
999 assert( ctl->TEXTBOX.text_sz < ctl->TEXTBOX.text_sz_max );
1002 ctl->TEXTBOX.text_cur,
1003 ctl->TEXTBOX.text_sz,
1004 ctl->TEXTBOX.text_sz_max );
1012 if( NULL != ctl->TEXTBOX.text ) {
1013 maug_munlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1021static void retrogui_redraw_TEXTBOX(
1027 if( 2 >= retroflat_screen_colors() ) {
1028 shadow_color = RETROFLAT_COLOR_BLACK;
1031# if defined( RETROGUI_NATIVE_WIN )
1035 retroflat_2d_rect( gui->draw_bmp, ctl->base.bg_color,
1036 gui->x + ctl->base.x, gui->y + ctl->base.y,
1041 retroflat_2d_rect( gui->draw_bmp, RETROFLAT_COLOR_BLACK,
1042 gui->x + ctl->base.x,
1043 gui->y + ctl->base.y, ctl->base.w, 2,
1046 retroflat_2d_rect( gui->draw_bmp, RETROFLAT_COLOR_BLACK,
1047 gui->x + ctl->base.x,
1048 gui->y + ctl->base.y, 2, ctl->base.h,
1051 retroflat_2d_rect( gui->draw_bmp, shadow_color,
1052 gui->x + ctl->base.x,
1053 gui->y + ctl->base.y + ctl->base.h - 1,
1057 retroflat_2d_rect( gui->draw_bmp, shadow_color,
1058 gui->x + ctl->base.x + ctl->base.w - 1,
1059 gui->y + ctl->base.y, 2, ctl->base.h,
1064 assert( NULL == ctl->TEXTBOX.text );
1065 maug_mlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1066 if( NULL == ctl->TEXTBOX.text ) {
1070#ifdef RETROGXC_PRESENT
1072 gui->draw_bmp, ctl->base.fg_color, ctl->TEXTBOX.text, 0, gui->font_idx,
1073 gui->x + ctl->base.x + RETROGUI_PADDING,
1074 gui->y + ctl->base.y + RETROGUI_PADDING, ctl->base.w, ctl->base.h, 0 );
1077 gui->draw_bmp, ctl->base.fg_color, ctl->TEXTBOX.text, 0, gui->font_h,
1078 gui->x + ctl->base.x + RETROGUI_PADDING,
1079 gui->y + ctl->base.y + RETROGUI_PADDING, ctl->base.w, ctl->base.h, 0 );
1084 if( NULL != ctl->TEXTBOX.text ) {
1085 maug_munlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1089 retroflat_2d_rect( gui->draw_bmp,
1091 gui->x + ctl->base.x + RETROGUI_PADDING + (8 * ctl->TEXTBOX.text_cur),
1092 gui->y + ctl->base.y + RETROGUI_PADDING,
1096 gui->focus == ctl->base.idc &&
1099 if( (-1 * RETROGUI_CTL_TEXT_BLINK_FRAMES) > --(ctl->TEXTBOX.blink_frames) ) {
1100 ctl->TEXTBOX.blink_frames = RETROGUI_CTL_TEXT_BLINK_FRAMES;
1113# if defined( RETROGUI_NATIVE_WIN )
1115 ctl->base.hwnd = CreateWindow(
1116 "EDIT", 0, WS_CHILD | WS_VISIBLE | WS_BORDER,
1117 gui->x + ctl->base.x, gui->y + ctl->base.y, ctl->base.w, ctl->base.h,
1118 g_retroflat_state->window, (HMENU)(ctl->base.idc),
1119 g_retroflat_instance, NULL );
1120 if( (HWND)NULL == ctl->base.hwnd ) {
1122 "Could not create textbox: " SIZE_T_FMT, ctl->base.idc );
1123 retval = MERROR_GUI;
1129 debug_printf( RETROGUI_TRACE_LVL,
1130 "clearing textbox " SIZE_T_FMT
" buffer...", ctl->base.idc );
1131 assert( NULL == ctl->TEXTBOX.text_h );
1132 ctl->TEXTBOX.text_h = maug_malloc( RETROGUI_CTL_TEXT_SZ_MAX + 1, 1 );
1133 maug_cleanup_if_null_alloc( MAUG_MHANDLE, ctl->TEXTBOX.text_h );
1134 ctl->TEXTBOX.text_sz_max = RETROGUI_CTL_TEXT_SZ_MAX;
1136 maug_mlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1137 maug_cleanup_if_null_alloc(
char*, ctl->TEXTBOX.text );
1138 debug_printf( RETROGUI_TRACE_LVL,
1139 "clearing textbox " SIZE_T_FMT
" buffer...", ctl->base.idc );
1140 maug_mzero( ctl->TEXTBOX.text, RETROGUI_CTL_TEXT_SZ_MAX + 1 );
1141 maug_munlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
1170static void retrogui_free_TEXTBOX(
union RETROGUI_CTL* ctl ) {
1171 if( NULL != ctl->TEXTBOX.text_h ) {
1172 maug_mfree( ctl->TEXTBOX.text_h );
1179 debug_printf( RETROGUI_TRACE_LVL,
1180 "initializing textbox " SIZE_T_FMT
"...", ctl->base.idc );
1182 ctl->base.fg_color = RETROFLAT_COLOR_BLACK;
1183 ctl->base.bg_color = RETROFLAT_COLOR_WHITE;
1184 ctl->base.sel_bg = RETROFLAT_COLOR_WHITE;
1185 if( 2 < retroflat_screen_colors() ) {
1186 ctl->base.sel_fg = RETROFLAT_COLOR_BLUE;
1188 ctl->base.sel_fg = RETROFLAT_COLOR_BLACK;
1203 return RETROGUI_IDC_NONE;
1210 return RETROGUI_IDC_NONE;
1213static void retrogui_redraw_LABEL(
1217# if defined( RETROGUI_NATIVE_WIN )
1223#ifdef RETROGXC_PRESENT
1224 assert( 0 <= gui->font_idx );
1226 assert( (MAUG_MHANDLE)NULL != gui->font_h );
1229 assert( NULL == ctl->LABEL.label );
1230 maug_mlock( ctl->LABEL.label_h, ctl->LABEL.label );
1231 if( NULL == ctl->LABEL.label ) {
1232 error_printf(
"could not lock LABEL text!" );
1236#ifdef RETROGXC_PRESENT
1241 gui->draw_bmp, ctl->base.fg_color, ctl->LABEL.label,
1242 ctl->LABEL.label_sz,
1243#ifdef RETROGXC_PRESENT
1248 gui->x + ctl->base.x + RETROGUI_PADDING,
1249 gui->y + ctl->base.y + RETROGUI_PADDING, ctl->base.w, ctl->base.h,
1250 ctl->LABEL.font_flags );
1254 if( NULL != ctl->LABEL.label ) {
1255 maug_munlock( ctl->LABEL.label_h, ctl->LABEL.label );
1266# if defined( RETROGUI_NATIVE_WIN )
1271 size_t label_sz = 0;
1272 char* label_tmp = NULL;
1274 debug_printf( RETROGUI_TRACE_LVL,
"pushing LABEL control..." );
1277 label, ctl->LABEL.label, ctl->LABEL, label_tmp, label_sz );
1278 ctl->LABEL.label = NULL;
1306static void retrogui_free_LABEL(
union RETROGUI_CTL* ctl ) {
1307 if( NULL != ctl->LABEL.label_h ) {
1308 maug_mfree( ctl->LABEL.label_h );
1315 debug_printf( RETROGUI_TRACE_LVL,
1316 "initializing label " SIZE_T_FMT
"...", ctl->base.idc );
1318 ctl->base.fg_color = RETROFLAT_COLOR_BLACK;
1319 ctl->base.bg_color = RETROFLAT_COLOR_WHITE;
1331 return RETROGUI_IDC_NONE;
1338 return RETROGUI_IDC_NONE;
1341static void retrogui_redraw_IMAGE(
1344# if defined( RETROGUI_NATIVE_WIN )
1348# if defined( RETROGXC_PRESENT )
1349 if( 0 > ctl->IMAGE.image_cache_id ) {
1352 debug_printf( RETROGUI_TRACE_LVL,
1353 "redrawing image ctl " SIZE_T_FMT
", cache ID " SSIZE_T_FMT
"...",
1354 ctl->base.idc, ctl->IMAGE.image_cache_id );
1355 retrogxc_blit_bitmap(
1357 ctl->IMAGE.image_cache_id,
1359 if( !retroflat_2d_bitmap_ok( gui->draw_bmp ) ) {
1362 retroflat_2d_blit_bitmap(
1364 &(ctl->IMAGE.image),
1366 ctl->IMAGE.src_x, ctl->IMAGE.src_y,
1367 gui->x + ctl->base.x, gui->y + ctl->base.y, ctl->base.w, ctl->base.h,
1368 ctl->IMAGE.instance );
1377# if defined( RETROGUI_NATIVE_WIN )
1383 debug_printf( RETROGUI_TRACE_LVL,
"pushing IMAGE control..." );
1399# ifdef RETROGXC_PRESENT
1400 retval = retrogxc_bitmap_wh( ctl->IMAGE.image_cache_id, p_w, p_h );
1401 maug_cleanup_if_not_ok();
1403 if( !retroflat_2d_bitmap_ok( &(ctl->IMAGE.image) ) ) {
1404 error_printf(
"image not assigned!" );
1405 retval = MERROR_GUI;
1409 *p_w = retroflat_2d_bitmap_w( &(ctl->IMAGE.image) );
1410 *p_h = retroflat_2d_bitmap_h( &(ctl->IMAGE.image) );
1428static void retrogui_free_IMAGE(
union RETROGUI_CTL* ctl ) {
1429# ifndef RETROGXC_PRESENT
1430 retroflat_2d_destroy_bitmap( &(ctl->IMAGE.image) );
1437 debug_printf( RETROGUI_TRACE_LVL,
1438 "initializing IMAGE " SIZE_T_FMT
"...", ctl->base.idc );
1464static void retrogui_redraw_FILLBAR(
1469 if( 0 == ctl->FILLBAR.cur ) {
1472 fill_w = ctl->base.w * ctl->FILLBAR.cur / ctl->FILLBAR.max;
1476 gui->draw_bmp, ctl->base.bg_color, ctl->base.x + fill_w, ctl->base.y,
1480 gui->draw_bmp, ctl->base.fg_color, ctl->base.x, ctl->base.y,
1489# if defined( RETROGUI_NATIVE_WIN )
1505 assert( NULL != ctl );
1519# if defined( RETROGUI_NATIVE_WIN )
1522 assert( NULL != ctl );
1537static void retrogui_free_FILLBAR(
union RETROGUI_CTL* ctl ) {
1543 debug_printf( RETROGUI_TRACE_LVL,
1544 "initializing fillbar " SIZE_T_FMT
"...", ctl->base.idc );
1546 ctl->base.fg_color = RETROFLAT_COLOR_BLACK;
1547 if( 2 < retroflat_screen_colors() ) {
1548 ctl->base.bg_color = RETROFLAT_COLOR_GRAY;
1550 ctl->base.bg_color = RETROFLAT_COLOR_WHITE;
1564 assert( retrogui_is_locked( gui ) );
1566 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
1567 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
1568 if( idc == ctl->base.idc ) {
1575 debug_printf( RETROGUI_TRACE_LVL,
1576 "could not find GUI item IDC " SIZE_T_FMT, idc );
1592 assert( retrogui_is_locked( gui ) );
1594 debug_printf( RETROGUI_TRACE_LVL,
1595 "sizing control " SIZE_T_FMT
" to: " SIZE_T_FMT
"x" SIZE_T_FMT,
1596 idc, max_w, max_h );
1598 ctl = _retrogui_get_ctl_by_idc( gui, idc );
1600 error_printf(
"could not find control to size!" );
1601 retval = MERROR_GUI;
1605 #define RETROGUI_CTL_TABLE_SZ( idx, c_name, c_fields ) \
1606 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
1608 retval = retrogui_sz_ ## c_name( gui, ctl, p_w, p_h, max_w, max_h ); \
1609 maug_cleanup_if_not_ok();
1612 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_SZ )
1615 debug_printf( RETROGUI_TRACE_LVL,
1616 "sized control " SIZE_T_FMT
" at " SIZE_T_FMT
"x" SIZE_T_FMT
"...",
1617 ctl->base.idc, ctl->base.w, ctl->base.h );
1627 struct RETROGUI* gui, RETROFLAT_IN_KEY* p_input,
1637 if( 0 == mdata_vector_ct( &(gui->ctls) ) ) {
1638 return RETROGUI_IDC_NONE;
1641 assert( !retrogui_is_locked( gui ) );
1642 mdata_vector_lock( &(gui->ctls) );
1644# if defined( RETROGUI_NATIVE_WIN )
1646 if( 0 == g_retroflat_state->last_idc ) {
1651 ctl = retrogui_get_ctl_by_idc( gui, g_retroflat_state->last_idc );
1652 g_retroflat_state->last_idc = 0;
1654 debug_printf( RETROGUI_TRACE_LVL,
1655 "invalid IDC: " SIZE_T_FMT, gui->focus );
1658# ifndef RETROGUI_NO_TEXTBOX
1659 if( RETROGUI_CTL_TYPE_TEXTBOX == ctl->base.type ) {
1660 if( SendMessage( ctl->base.hwnd, EM_GETMODIFY, 0, 0 ) ) {
1661 SendMessage( ctl->base.hwnd, EM_SETMODIFY, 0, 0 );
1662 debug_printf( RETROGUI_TRACE_LVL,
"mod: %d",
1663 SendMessage( ctl->base.hwnd, EM_GETMODIFY, 0, 0 ) );
1672 #define RETROGUI_CTL_TABLE_CLICK( idx, c_name, c_fields ) \
1673 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
1674 gui->flags |= RETROGUI_FLAGS_DIRTY; \
1675 idc_out = retrogui_click_ ## c_name( gui, ctl, p_input, input_evt );
1677 #define RETROGUI_CTL_TABLE_KEY( idx, c_name, c_fields ) \
1678 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
1679 gui->flags |= RETROGUI_FLAGS_DIRTY; \
1680 idc_out = retrogui_key_ ## c_name( ctl, p_input, input_evt );
1682 if( 0 == *p_input ) {
1683 goto reset_debounce;
1685 }
else if( RETROGUI_KEY_ACTIVATE == *p_input ) {
1687 if( 0 <= gui->focus ) {
1688 idc_out = gui->focus;
1694 }
else if( RETROGUI_KEY_NEXT == *p_input ) {
1695 retrogui_focus_next( gui );
1697 debug_printf( RETROGUI_TRACE_LVL,
"next: " SSIZE_T_FMT, gui->focus );
1702 }
else if( RETROGUI_KEY_PREV == *p_input ) {
1703 retrogui_focus_prev( gui );
1705 debug_printf( RETROGUI_TRACE_LVL,
"prev: " SSIZE_T_FMT, gui->focus );
1710# ifndef RETROGUI_NO_MOUSE
1712 RETROFLAT_MOUSE_B_LEFT == *p_input ||
1713 RETROFLAT_MOUSE_B_RIGHT == *p_input
1718 gui->focus = RETROGUI_IDC_NONE;
1720 mouse_x = input_evt->
mouse_x - gui->x;
1721 mouse_y = input_evt->
mouse_y - gui->y;
1723 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
1724 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
1726 mouse_x < ctl->base.x ||
1727 mouse_y < ctl->base.y ||
1728 mouse_x > ctl->base.x + ctl->base.w ||
1729 mouse_y > ctl->base.y + ctl->base.h
1734 if( gui->idc_prev == ctl->base.idc ) {
1737 idc_out = RETROGUI_IDC_NONE;
1741 gui->idc_prev = ctl->base.idc;
1743 gui->focus = ctl->base.idc;
1746 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_CLICK )
1754 if( RETROGUI_IDC_NONE == gui->focus ) {
1755 goto reset_debounce;
1760 ctl = _retrogui_get_ctl_by_idc( gui, gui->focus );
1762 debug_printf( RETROGUI_TRACE_LVL,
1763 "invalid IDC: " SIZE_T_FMT, gui->focus );
1764 goto reset_debounce;
1768 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_KEY )
1775 gui->idc_prev = RETROGUI_IDC_NONE;
1781 if( MERROR_OK != retval ) {
1782 idc_out = RETROGUI_IDC_NONE;
1785 mdata_vector_unlock( &(gui->ctls) );
1804 if( 0 == mdata_vector_ct( &(gui->ctls) ) ) {
1808 if( !retrogui_is_locked( gui ) ) {
1809 mdata_vector_lock( &(gui->ctls) );
1814 RETROFLAT_COLOR_BLACK != gui->bg_color &&
1815 0 < gui->w && 0 < gui->h
1817 retroflat_2d_rect( gui->draw_bmp,
1821 #define RETROGUI_CTL_TABLE_REDRAW( idx, c_name, c_fields ) \
1822 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
1824 gui->flags &= ~RETROGUI_FLAGS_DIRTY; \
1825 retrogui_redraw_ ## c_name( gui, ctl );
1827 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
1828 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
1830 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_REDRAW )
1837 mdata_vector_unlock( &(gui->ctls) );
1847 size_t x,
size_t y,
size_t w,
size_t h
1853 if( !retrogui_is_locked( gui ) ) {
1854 mdata_vector_lock( &(gui->ctls) );
1858 debug_printf( RETROGUI_TRACE_LVL,
1859 "moving control " SIZE_T_FMT
" to: " SIZE_T_FMT
", " SIZE_T_FMT,
1862 ctl = _retrogui_get_ctl_by_idc( gui, idc );
1864 error_printf(
"could not position control!" );
1865 retval = MERROR_GUI;
1869 #define RETROGUI_CTL_TABLE_POS( idx, c_name, c_fields ) \
1870 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
1872 retval = retrogui_pos_ ## c_name( gui, ctl, x, y, w, h ); \
1873 maug_cleanup_if_not_ok();
1876 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_POS )
1879 debug_printf( RETROGUI_TRACE_LVL,
1880 "moved control " SIZE_T_FMT
" to " SIZE_T_FMT
", " SIZE_T_FMT
1881 " and sized to " SIZE_T_FMT
"x" SIZE_T_FMT
"...",
1882 ctl->base.idc, gui->x + ctl->base.x, gui->y + ctl->base.y,
1883 ctl->base.w, ctl->base.h );
1891 mdata_vector_unlock( &(gui->ctls) );
1906 assert( 0 < ctl->base.idc );
1908#ifdef RETROGXC_PRESENT
1909 if( 0 > gui->font_idx ) {
1911 if( (MAUG_MHANDLE)NULL == gui->font_h ) {
1915 retval = MERROR_GUI;
1921 debug_printf( RETROGUI_TRACE_LVL,
1922 "gui->ctls_ct: " SIZE_T_FMT, mdata_vector_ct( &(gui->ctls) ) );
1925 RETROGUI_CTL_TYPE_IMAGE != ctl->base.type &&
1926 RETROFLAT_COLOR_NULL == ctl->base.bg_color
1929 "invalid background color specified for control " SIZE_T_FMT
"!",
1931 retval = MERROR_GUI;
1937 RETROGUI_CTL_TYPE_IMAGE != ctl->base.type &&
1938 RETROFLAT_COLOR_NULL == ctl->base.fg_color
1941 "invalid foreground color specified for control " SIZE_T_FMT
"!",
1943 retval = MERROR_GUI;
1948 debug_printf( RETROGUI_TRACE_LVL,
1949 "pushing %s " SIZE_T_FMT
" to slot " SIZE_T_FMT
"...",
1950 gc_retrogui_ctl_names[ctl->base.type], ctl->base.idc,
1951 mdata_vector_ct( &(gui->ctls) ) );
1953 mdata_vector_append( &(gui->ctls), ctl,
sizeof(
union RETROGUI_CTL ) );
1960 if( !retrogui_is_locked( gui ) ) {
1961 mdata_vector_lock( &(gui->ctls) );
1966 ctl = mdata_vector_get_last( &(gui->ctls),
1968 assert( NULL != ctl );
1970 #define RETROGUI_CTL_TABLE_PUSH( idx, c_name, c_fields ) \
1971 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
1972 debug_printf( RETROGUI_TRACE_LVL, \
1973 "running " #c_name " push hook..." ); \
1974 retval = retrogui_push_ ## c_name( ctl ); \
1975 maug_cleanup_if_not_ok();
1978 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_PUSH )
1984 if( 0 == ctl->base.w || 0 == ctl->base.h ) {
1985 debug_printf( RETROGUI_TRACE_LVL,
1986 "determining size for new %s control " SIZE_T_FMT
"...",
1987 gc_retrogui_ctl_names[ctl->base.type], ctl->base.idc );
1988 retval = _retrogui_sz_ctl(
1989 gui, ctl->base.idc, &(ctl->base.w), &(ctl->base.h), 0, 0 );
1990 maug_cleanup_if_not_ok();
1993 if( RETROGUI_IDC_NONE == gui->focus ) {
1994 gui->focus = ctl->base.idc;
2000 mdata_vector_unlock( &(gui->ctls) );
2013 if( retrogui_is_locked( gui ) ) {
2014 error_printf(
"GUI is locked!" );
2018 assert( !retrogui_is_locked( gui ) );
2019 mdata_vector_lock( &(gui->ctls) );
2021 #define RETROGUI_CTL_TABLE_FREE_CTL( idx, c_name, c_fields ) \
2022 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2023 retrogui_free_ ## c_name( ctl );
2025 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
2026 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
2027 if( idc != ctl->base.idc ) {
2033 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_FREE_CTL )
2037 mdata_vector_unlock( &(gui->ctls) );
2038 mdata_vector_remove( &(gui->ctls), i );
2039 mdata_vector_lock( &(gui->ctls) );
2043 mdata_vector_unlock( &(gui->ctls) );
2052#ifndef RETROGUI_NO_TEXTBOX
2061 if( !retrogui_is_locked( gui ) ) {
2062 mdata_vector_lock( &(gui->ctls) );
2066 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2071 if( RETROGUI_CTL_TYPE_TEXTBOX == ctl->base.type ) {
2072# if defined( RETROGUI_NATIVE_WIN )
2075 maug_mlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
2076 maug_cleanup_if_null_lock(
char*, ctl->TEXTBOX.text );
2078 maug_strncpy( buffer, ctl->TEXTBOX.text, buffer_sz );
2080 }
else if( RETROGUI_CTL_TYPE_LABEL == ctl->base.type ) {
2081# if defined( RETROGUI_NATIVE_WIN )
2084 maug_mlock( ctl->LABEL.label_h, ctl->LABEL.label );
2085 maug_cleanup_if_null_lock(
char*, ctl->LABEL.label );
2087 maug_strncpy( buffer, ctl->LABEL.label, buffer_sz );
2094 if( RETROGUI_CTL_TYPE_TEXTBOX == ctl->base.type ) {
2095 if( NULL != ctl->TEXTBOX.text ) {
2096 maug_munlock( ctl->TEXTBOX.text_h, ctl->TEXTBOX.text );
2099 }
else if( RETROGUI_CTL_TYPE_LABEL == ctl->base.type ) {
2100 if( NULL != ctl->LABEL.label ) {
2101 maug_munlock( ctl->LABEL.label_h, ctl->LABEL.label );
2106 mdata_vector_unlock( &(gui->ctls) );
2122 if( !retrogui_is_locked( gui ) ) {
2123 mdata_vector_lock( &(gui->ctls) );
2126 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2131 assert( RETROGUI_CTL_TYPE_LISTBOX == ctl->base.type );
2133# if defined( RETROGUI_NATIVE_WIN )
2134 idx = SendMessage( ctl->base.hwnd, LB_GETCARETINDEX, 0, 0 );
2136 idx = ctl->LISTBOX.sel_idx;
2142 mdata_vector_unlock( &(gui->ctls) );
2145 if( MERROR_OK != retval ) {
2156 const char* fmt, ...
2159 size_t label_sz = 0;
2160 char* label_tmp = NULL;
2161 char* buffer = NULL;
2163 MAUG_MHANDLE buffer_h = (MAUG_MHANDLE)NULL;
2166 assert( !retrogui_is_locked( gui ) );
2167 mdata_vector_lock( &(gui->ctls) );
2169 debug_printf( RETROGUI_TRACE_LVL,
2170 "setting control " SIZE_T_FMT
" text to: %s", idc, fmt );
2173 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2175 retval = MERROR_GUI;
2180 buffer_h = maug_malloc( 1, buffer_sz + 1 );
2181 maug_cleanup_if_null_alloc( MAUG_MHANDLE, buffer_h );
2183 assert( 0 < buffer_sz );
2185 maug_mlock( buffer_h, buffer );
2186 maug_cleanup_if_null_lock(
char*, buffer );
2189 assert( NULL != buffer );
2197 va_start( args, fmt );
2198 maug_vsnprintf( buffer, buffer_sz, fmt, args );
2203 if( RETROGUI_CTL_TYPE_BUTTON == ctl->base.type ) {
2204 assert( NULL == ctl->BUTTON.label );
2205 _retrogui_copy_str( label, buffer, ctl->BUTTON, label_tmp, buffer_sz );
2206 }
else if( RETROGUI_CTL_TYPE_LABEL == ctl->base.type ) {
2207 assert( NULL == ctl->LABEL.label );
2208 _retrogui_copy_str( label, buffer, ctl->LABEL, label_tmp, label_sz );
2209#ifndef RETROGUI_NO_TEXTBOX
2210 }
else if( RETROGUI_CTL_TYPE_TEXTBOX == ctl->base.type ) {
2211 assert( NULL == ctl->TEXTBOX.text );
2213 label_sz = RETROGUI_CTL_TEXT_SZ_MAX;
2215 text, buffer, ctl->TEXTBOX, label_tmp, label_sz );
2216 ctl->TEXTBOX.text_cur = 0;
2219 error_printf(
"invalid control type! no label!" );
2228 if( NULL != buffer ) {
2229 maug_munlock( buffer_h, buffer );
2232 if( NULL != buffer_h ) {
2233 maug_mfree( buffer_h );
2236 mdata_vector_unlock( &(gui->ctls) );
2250 if( !retrogui_is_locked( gui ) ) {
2251 mdata_vector_lock( &(gui->ctls) );
2255 debug_printf( RETROGUI_TRACE_LVL,
2256 "setting control " SIZE_T_FMT
" image to: %s", idc, path );
2259 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2261 retval = MERROR_GUI;
2266 if( RETROGUI_CTL_TYPE_IMAGE == ctl->base.type ) {
2267 if( NULL != path ) {
2268# if defined( RETROGXC_PRESENT )
2269 ctl->IMAGE.image_cache_id = retrogxc_load_bitmap( path, 0 );
2271 retroflat_2d_load_bitmap( path, &(ctl->IMAGE.image), 0 );
2274# ifdef RETROGXC_PRESENT
2275 ctl->IMAGE.image_cache_id = -1;
2277 retroflat_2d_destroy_bitmap( &(ctl->IMAGE.image) );
2281 error_printf(
"invalid control type! no image!" );
2291 mdata_vector_unlock( &(gui->ctls) );
2307 if( !retrogui_is_locked( gui ) ) {
2308 mdata_vector_lock( &(gui->ctls) );
2312 debug_printf( RETROGUI_TRACE_LVL,
2313 "setting control " SIZE_T_FMT
" level to: %u", idc, level );
2316 ctl = _retrogui_get_ctl_by_idc( gui, idc );
2318 retval = MERROR_GUI;
2323 if( RETROGUI_CTL_TYPE_FILLBAR == ctl->base.type ) {
2324 ctl->FILLBAR.cur = level;
2326 ctl->FILLBAR.max = max;
2329 error_printf(
"invalid control type! no level!" );
2339 mdata_vector_unlock( &(gui->ctls) );
2352 debug_printf( RETROGUI_TRACE_LVL,
2353 "initializing control base " SIZE_T_FMT
"...", idc );
2357 ctl->base.type = type;
2358 ctl->base.idc = idc;
2359 ctl->base.fg_color = RETROFLAT_COLOR_NULL;
2360 ctl->base.bg_color = RETROFLAT_COLOR_NULL;
2361 ctl->base.sel_fg = RETROFLAT_COLOR_NULL;
2362 ctl->base.sel_bg = RETROFLAT_COLOR_NULL;
2364 #define RETROGUI_CTL_TABLE_INITS( idx, c_name, c_fields ) \
2365 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2366 retrogui_init_ ## c_name( ctl );
2369 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_INITS )
2372# ifdef RETROGXC_PRESENT
2373 if( RETROGUI_CTL_TYPE_IMAGE == type ) {
2374 ctl->IMAGE.image_cache_id = -1;
2388 if( retrogui_is_locked( gui ) ) {
2389 error_printf(
"GUI is locked!" );
2393 if( 0 == mdata_vector_ct( &(gui->ctls) ) ) {
2397 assert( !retrogui_is_locked( gui ) );
2398 mdata_vector_lock( &(gui->ctls) );
2400 #define RETROGUI_CTL_TABLE_FREE( idx, c_name, c_fields ) \
2401 } else if( RETROGUI_CTL_TYPE_ ## c_name == ctl->base.type ) { \
2402 retrogui_free_ ## c_name( ctl );
2404 for( i = 0 ; mdata_vector_ct( &(gui->ctls) ) > i ; i++ ) {
2405 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
2407 RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_FREE )
2411 mdata_vector_unlock( &(gui->ctls) );
2415 mdata_vector_free( &(gui->ctls) );
2423 struct RETROGUI* gui,
size_t start, ssize_t incr
2429 ssize_t i_before = -1;
2432 if( 0 == mdata_vector_ct( &(gui->ctls) ) ) {
2436 if( !retrogui_is_locked( gui ) ) {
2437 mdata_vector_lock( &(gui->ctls) );
2443 i = start ; mdata_vector_ct( &(gui->ctls) ) > i && 0 <= i ; i += incr
2445 ctl = mdata_vector_get( &(gui->ctls), i,
union RETROGUI_CTL );
2446 if( RETROGUI_CTL_TYPE_BUTTON != ctl->base.type ) {
2448 }
else if( RETROGUI_IDC_NONE == gui->focus || 0 <= i_before ) {
2450 idc_out = ctl->base.idc;
2451 gui->focus = idc_out;
2454 }
else if( ctl->base.idc == gui->focus ) {
2466 idc_out = mdata_vector_get( &(gui->ctls),
2467 mdata_vector_ct( &(gui->ctls) ) - 1,
union RETROGUI_CTL )->base.idc;
2468 gui->focus = idc_out;
2470 }
else if( mdata_vector_ct( &(gui->ctls) ) <= i ) {
2473 mdata_vector_get( &(gui->ctls), 0,
union RETROGUI_CTL )->base.idc;
2474 gui->focus = idc_out;
2477 error_printf(
"invalid focus: " SSIZE_T_FMT, i );
2486 if( MERROR_OK != retval ) {
2487 idc_out = merror_retval_to_sz( retval );
2491 mdata_vector_unlock( &(gui->ctls) );
2494 debug_printf( RETROGUI_TRACE_LVL,
"selected IDC: " SIZE_T_FMT, idc_out );
2506 gui->bg_color = RETROFLAT_COLOR_BLACK;
2507 gui->focus = RETROGUI_IDC_NONE;
2509 debug_printf( RETROGUI_TRACE_LVL,
"initialized GUI" );
2516#define RETROGUI_CTL_TABLE_CONSTS( idx, c_name, c_fields ) \
2517 extern MAUG_CONST uint8_t RETROGUI_CTL_TYPE_ ## c_name;
2519RETROGUI_CTL_TABLE( RETROGUI_CTL_TABLE_CONSTS )
2521extern MAUG_CONST
char* gc_retrogui_ctl_names[];
int MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:19
#define maug_mzero(ptr, sz)
Zero the block of memory pointed to by ptr.
Definition mmem.h:65
void retroflat_message(uint8_t flags, const char *title, const char *format,...)
Display a message in a dialog box and/or on stderr.
int8_t RETROFLAT_COLOR
Defines an index in the platform-specific color-table.
Definition retroflt.h:325
#define RETROFLAT_FLAGS_FILL
Flag for retroflat_rect() or retroflat_ellipse(), indicating drawn shape should be filled.
Definition retroflt.h:373
#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:456
int mouse_y
Y-coordinate of the mouse pointer in pixels if the returned event is a mouse click.
Definition retroflt.h:852
int mouse_x
X-coordinate of the mouse pointer in pixels if the returned event is a mouse click.
Definition retroflt.h:847
size_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition retroflt.h:895
#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:161
#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:173
#define RETROGUI_FLAGS_DIRTY
RETROGUI::flags indicating controls should be redrawn.
Definition retrogui.h:28
ssize_t retrogui_idc_t
Unique identifying constant number for controls.
Definition retrogui.h:103
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.
A vector of uniformly-sized objects, stored contiguously.
Definition mdata.h:89
size_t item_sz
Size, in bytes, of each item.
Definition mdata.h:105
Fields common to ALL RETROGUI_CTL types.
Definition retrogui.h:141
Definition retrogui.h:186
Definition retrogui.h:176