/* * Example program for the Allegro library, by Elias Pschernig. * * This program demonstrates how to use the GUI routines. From * the simple dialog controls that display a text or a bitmap to * more complex multiple choice selection lists, Allegro provides * a framework which can be customised to suit your needs. */ #include #include #include "example.h" /* maximum number of bytes a single (unicode) character can have */ #define MAX_BYTES_PER_CHAR 6 /* for the d_edit_proc object */ #define LEN 32 char the_string[(LEN + 1) * MAX_BYTES_PER_CHAR] = "Change Me!"; /* for the d_text_box_proc object */ char the_text[] = "I'm text inside a text box.\n\nI can have multiple \ lines.\n\nIf I grow too big to fit into my box, I get a scrollbar to \ the right, so you can scroll me in the vertical direction. I will never \ let you scroll in the horizontal direction, but instead I will try to \ word wrap the text."; /* for the multiple selection list */ char sel[10]; /* for the example bitmap */ DATAFILE *datafile; /* callback function to specify the contents of the listbox */ char *listbox_getter(int index, int *list_size) { static char *strings[] = { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten" }; if (index < 0) { *list_size = 11; return NULL; } else return strings[index]; } /* Used as a menu-callback, and by the quit button. */ int quit(void) { if (alert("Really Quit?", NULL, NULL, "&Yes", "&No", 'y', 'n') == 1) return D_CLOSE; else return D_O_K; } /* A custom dialog procedure, derived from d_button_proc. It intercepts * the D_CLOSE return of d_button_proc, and calls the function in dp3. */ int my_button_proc (int msg, DIALOG *d, int c) { int ret = d_button_proc (msg, d, c); if (ret == D_CLOSE && d->dp3) return ((int (*)(void))d->dp3)(); return ret; } /* Our about box. */ int about(void) { alert("* exgui *", "", "Allegro GUI Example", "Ok", 0, 0, 0); return D_O_K; } /* Another menu callback. */ int menu_callback(void) { char str[256]; ustrzcpy (str, sizeof str, active_menu->text); alert("Selected menu item:", "", ustrtok (str, "\t"), "Ok", NULL, 0, 0); return D_O_K; } /* Menu callback which toggles the checked status. */ int check_callback(void) { active_menu->flags ^= D_SELECTED; if (active_menu->flags & D_SELECTED) active_menu->text = "Checked"; else active_menu->text = "Unchecked"; alert("Menu item has been toggled!", NULL, NULL, "Ok", NULL, 0, 0); return D_O_K; } /* the submenu */ MENU submenu[] = { { "Submenu", NULL, NULL, D_DISABLED, NULL }, { "", NULL, NULL, 0, NULL }, { "Checked", check_callback, NULL, D_SELECTED, NULL }, { "Disabled", NULL, NULL, D_DISABLED, NULL }, { NULL, NULL, NULL, 0, NULL } }; /* the first menu in the menubar */ MENU menu1[] = { { "Test &1 \t1", menu_callback, NULL, 0, NULL }, { "Test &2 \t2", menu_callback, NULL, 0, NULL }, { "&Quit \tq/Esc", quit, NULL, 0, NULL }, { NULL, NULL, NULL, 0, NULL } }; /* the second menu in the menubar */ MENU menu2[] = { { "&Test", menu_callback, NULL, 0, NULL }, { "&Submenu", NULL, submenu, 0, NULL }, { NULL, NULL, NULL, 0, NULL } }; /* the help menu */ MENU helpmenu[] = { { "&About \tF1", about, NULL, 0, NULL }, { NULL, NULL, NULL, 0, NULL } }; /* the main menu-bar */ MENU the_menu[] = { { "&First", NULL, menu1, 0, NULL }, { "&Second", NULL, menu2, 0, NULL }, { "&Help", NULL, helpmenu, 0, NULL }, { NULL, NULL, NULL, 0, NULL } }; int info1(void); int info2(void); int info3(void); #define LIST_OBJECT 26 #define TEXTLIST_OBJECT 27 #define SLIDER_OBJECT 29 #define BITMAP_OBJECT 32 #define ICON_OBJECT 33 /* here it comes - the big bad ugly DIALOG array for our main dialog */ DIALOG the_dialog[] = { /* (dialog proc) (x) (y) (w) (h) (fg)(bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ /* this element just clears the screen, therefore it should come before the others */ { d_clear_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, /* these just display text, either left aligned, centered, or right aligned */ { d_text_proc, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, "d_text_proc", NULL, NULL }, { d_ctext_proc, 318, 20, 0, 0, 0, 0, 0, 0, 0, 0, "d_ctext_proc", NULL, NULL }, { d_rtext_proc, 636, 20, 0, 0, 0, 0, 0, 0, 0, 0, "d_rtext_proc", NULL, NULL }, /* lots of descriptive text elements */ { d_text_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "d_menu_proc->", NULL, NULL }, { d_text_proc, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, "d_button_proc->", NULL, NULL }, { d_text_proc, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, "d_check_proc->", NULL, NULL }, { d_text_proc, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, "d_radio_proc->", NULL, NULL }, { d_text_proc, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, "d_edit_proc->", NULL, NULL }, { d_text_proc, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, "d_list_proc->", NULL, NULL }, { d_text_proc, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, "d_text_list_proc->", NULL, NULL }, { d_text_proc, 0, 250, 0, 0, 0, 0, 0, 0, 0, 0, "d_textbox_proc->", NULL, NULL }, { d_text_proc, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0, "d_slider_proc->", NULL, NULL }, { d_text_proc, 0, 330, 0, 0, 0, 0, 0, 0, 0, 0, "d_box_proc->", NULL, NULL }, { d_text_proc, 0, 360, 0, 0, 0, 0, 0, 0, 0, 0, "d_shadow_box_proc->", NULL, NULL }, { d_text_proc, 0, 390, 0, 0, 0, 0, 0, 0, 0, 0, "d_keyboard_proc. Press F1 to see me trigger the about box.", NULL, NULL }, { d_text_proc, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, "d_clear_proc. I draw the white background.", NULL, NULL }, { d_text_proc, 0, 430, 0, 0, 0, 0, 0, 0, 0, 0, "d_yield_proc. I make us play nice with the OS scheduler.", NULL, NULL }, { d_rtext_proc, 636, 40, 0, 0, 0, 0, 0, 0, 0, 0, "<-d_bitmap_proc", NULL, NULL }, { d_rtext_proc, 636, 80, 0, 0, 0, 0, 0, 0, 0, 0, "<-d_icon_proc", NULL, NULL }, /* a menu bar - note how it auto-calculates its dimension if they are not given */ { d_menu_proc, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, the_menu, NULL, NULL }, /* some more GUI elements, all of which require you to specify their dimensions */ { d_button_proc, 160, 40, 160, 20, 0, 0, 't', 0, 0, 0, "&Toggle Me!", NULL, NULL }, { d_check_proc, 160, 70, 160, 20, 0, 0, 'c', 0, 0, 0, "&Check Me!", NULL, NULL }, { d_radio_proc, 160, 100, 160, 19, 0, 0, 's', 0, 0, 0, "&Select Me!", NULL, NULL }, { d_radio_proc, 320, 100, 160, 19, 0, 0, 'o', 0, 0, 0, "&Or Me!", NULL, NULL }, { d_edit_proc, 160, 130, 160, 8, 0, 0, 0, 0, LEN, 0, the_string, NULL, NULL }, { d_list_proc, 160, 150, 160, 44, 0, 0, 0, 0, 0, 0, (void *)listbox_getter, sel, NULL }, { d_text_list_proc, 160, 200, 160, 44, 0, 0, 0, 0, 0, 0, (void *)listbox_getter, NULL, NULL }, { d_textbox_proc, 160, 250, 160, 48, 0, 0, 0, 0, 0, 0, (void *)the_text, NULL, NULL }, { d_slider_proc, 160, 300, 160, 12, 0, 0, 0, 0, 100, 0, NULL, NULL, NULL }, { d_box_proc, 160, 330, 160, 20, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, { d_shadow_box_proc, 160, 360, 160, 20, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, /* note how we don't fill in the dp field yet, because we first need to load the bitmap */ { d_bitmap_proc, 480, 40, 30, 30, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, { d_icon_proc, 480, 80, 30, 30, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, /* the quit and info buttons use our customized dialog procedure, using dp3 as callback */ { my_button_proc, 0, 450, 160, 20, 0, 0, 'q', D_EXIT, 0, 0, "&Quit", NULL, (void *)quit }, { my_button_proc, 400, 150, 160, 20, 0, 0, 'i', D_EXIT, 0, 0, "&Info", NULL, (void *)info1 }, { my_button_proc, 400, 200, 160, 20, 0, 0, 'n', D_EXIT, 0, 0, "I&nfo", NULL, (void *)info2 }, { my_button_proc, 400, 300, 160, 20, 0, 0, 'f', D_EXIT, 0, 0, "In&fo", NULL, (void *)info3 }, /* the next two elements don't draw anything */ { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_F1, 0, (void *)about, NULL, NULL }, { d_yield_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } }; /* These three functions demonstrate how to query dialog elements. */ int info1(void) { char buf1[256]; char buf2[256] = ""; int i, s = 0, n; listbox_getter(-1, &n); /* query the list proc */ for (i = 0; i < n; i++) if (sel[i]) { uszprintf (buf1, sizeof buf1, "%i ", i); ustrzcat (buf2, sizeof buf2, buf1); s = 1; } if (s) ustrzcat (buf2, sizeof buf2, "are in the multiple selection!"); else ustrzcat (buf2, sizeof buf2, "There is no multiple selection!"); uszprintf (buf1, sizeof buf1, "Item number %i is selected!", the_dialog[LIST_OBJECT].d1); alert ("Info about the list:", buf1, buf2, "Ok", NULL, 0, 0); return D_O_K; } int info2(void) { char buf[256]; /* query the textlist proc */ uszprintf (buf, sizeof buf, "Item number %i is selected!", the_dialog[TEXTLIST_OBJECT].d1); alert ("Info about the text list:", NULL, buf, "Ok", NULL, 0, 0); return D_O_K; } int info3(void) { char buf[256]; /* query the slider proc */ uszprintf (buf, sizeof buf, "Slider position is %i!", the_dialog[SLIDER_OBJECT].d2); alert ("Info about the slider:", NULL, buf, "Ok", NULL, 0, 0); return D_O_K; } int main(int argc, char *argv[]) { char buf[256]; int i; /* initialise everything */ if (allegro_init() != 0) return 1; install_keyboard(); install_mouse(); install_timer(); if (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) != 0) { if (set_gfx_mode(GFX_SAFE, 640, 480, 0, 0) != 0) { set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); allegro_message("Unable to set any graphic mode\n%s\n", allegro_error); return 1; } } /* load the datafile */ replace_filename(buf, argv[0], "example.dat", sizeof(buf)); datafile = load_datafile(buf); if (!datafile) { set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); allegro_message("Error loading %s!\n", buf); return 1; } set_palette(datafile[THE_PALETTE].dat); /* set up colors */ gui_fg_color = makecol(0, 0, 0); gui_mg_color = makecol(128, 128, 128); gui_bg_color = makecol(200, 240, 200); set_dialog_color (the_dialog, gui_fg_color, gui_bg_color); /* white color for d_clear_proc and the d_?text_procs */ the_dialog[0].bg = makecol(255, 255, 255); for (i = 4; the_dialog[i].proc; i++) if (the_dialog[i].proc == d_text_proc || the_dialog[i].proc == d_ctext_proc || the_dialog[i].proc == d_rtext_proc) the_dialog[i].bg = the_dialog[0].bg; /* fill in bitmap pointers */ the_dialog[BITMAP_OBJECT].dp = datafile[SILLY_BITMAP].dat; the_dialog[ICON_OBJECT].dp = datafile[SILLY_BITMAP].dat; /* shift the dialog 2 pixels away from the border */ position_dialog (the_dialog, 2, 2); /* do the dialog */ do_dialog(the_dialog, -1); unload_datafile (datafile); return 0; } END_OF_MAIN()