Permalink
Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
293 lines (262 sloc) 9.96 KB
#include "allegro5/allegro.h"
#include "allegro5/allegro_native_dialog.h"
#include "allegro5/allegro_image.h"
#include <stdio.h>
#include <math.h>
#include "common.c"
/* The following is a list of menu item ids. They can be any non-zero, positive
* integer. A menu item must have an id in order for it to generate an event.
* Also, each menu item's id should be unique to get well defined results.
*/
enum {
FILE_ID = 1,
FILE_OPEN_ID,
FILE_RESIZE_ID,
FILE_FULLSCREEN_ID,
FILE_CLOSE_ID,
FILE_EXIT_ID,
DYNAMIC_ID,
DYNAMIC_CHECKBOX_ID,
DYNAMIC_DISABLED_ID,
DYNAMIC_DELETE_ID,
DYNAMIC_CREATE_ID,
HELP_ABOUT_ID
};
/* This is one way to define a menu. The entire system, nested menus and all,
* can be defined by this single array.
*/
ALLEGRO_MENU_INFO main_menu_info[] = {
ALLEGRO_START_OF_MENU("&File", FILE_ID),
{ "&Open", FILE_OPEN_ID, 0, NULL },
ALLEGRO_MENU_SEPARATOR,
{ "E&xit", FILE_EXIT_ID, 0, NULL },
ALLEGRO_END_OF_MENU,
ALLEGRO_START_OF_MENU("&Dynamic Options", DYNAMIC_ID),
{ "&Checkbox", DYNAMIC_CHECKBOX_ID, ALLEGRO_MENU_ITEM_CHECKED, NULL },
{ "&Disabled", DYNAMIC_DISABLED_ID, ALLEGRO_MENU_ITEM_DISABLED, NULL },
{ "DELETE ME!", DYNAMIC_DELETE_ID, 0, NULL },
{ "Click Me", DYNAMIC_CREATE_ID, 0, NULL },
ALLEGRO_END_OF_MENU,
ALLEGRO_START_OF_MENU("&Help", 0),
{ "&About", HELP_ABOUT_ID, 0, NULL },
ALLEGRO_END_OF_MENU,
ALLEGRO_END_OF_MENU
};
/* This is the menu on the secondary windows. */
ALLEGRO_MENU_INFO child_menu_info[] = {
ALLEGRO_START_OF_MENU("&File", 0),
{ "&Close", FILE_CLOSE_ID, 0, NULL },
ALLEGRO_END_OF_MENU,
ALLEGRO_END_OF_MENU
};
int main(int argc, char **argv)
{
const int initial_width = 320;
const int initial_height = 200;
int dcount = 0;
ALLEGRO_DISPLAY *display;
ALLEGRO_MENU *menu;
ALLEGRO_EVENT_QUEUE *queue;
ALLEGRO_TIMER *timer;
bool redraw = true;
bool menu_visible = true;
ALLEGRO_MENU *pmenu;
ALLEGRO_BITMAP *bg;
(void)argc;
(void)argv;
if (!al_init()) {
abort_example("Could not init Allegro.\n");
}
if (!al_init_native_dialog_addon()) {
abort_example("Could not init the native dialog addon.\n");
}
al_init_image_addon();
al_install_keyboard();
al_install_mouse();
queue = al_create_event_queue();
#ifdef ALLEGRO_GTK_TOPLEVEL
/* ALLEGRO_GTK_TOPLEVEL is necessary for menus with GTK. */
al_set_new_display_flags(ALLEGRO_RESIZABLE | ALLEGRO_GTK_TOPLEVEL);
#else
al_set_new_display_flags(ALLEGRO_RESIZABLE);
#endif
display = al_create_display(initial_width, initial_height);
if (!display) {
abort_example("Error creating display\n");
}
al_set_window_title(display, "ex_menu - Main Window");
menu = al_build_menu(main_menu_info);
if (!menu) {
abort_example("Error creating menu\n");
}
/* Add an icon to the Help/About item. Note that Allegro assumes ownership
* of the bitmap. */
al_set_menu_item_icon(menu, HELP_ABOUT_ID, al_load_bitmap("data/icon.tga"));
if (!al_set_display_menu(display, menu)) {
/* Since the menu could not be attached to the window, then treat it as
* a popup menu instead. */
pmenu = al_clone_menu_for_popup(menu);
al_destroy_menu(menu);
menu = pmenu;
}
else {
/* Create a simple popup menu used when right clicking. */
pmenu = al_create_popup_menu();
if (pmenu) {
al_append_menu_item(pmenu, "&Open", FILE_OPEN_ID, 0, NULL, NULL);
al_append_menu_item(pmenu, "&Resize", FILE_RESIZE_ID, 0, NULL, NULL);
al_append_menu_item(pmenu, "&Fullscreen window", FILE_FULLSCREEN_ID, 0, NULL, NULL);
al_append_menu_item(pmenu, "E&xit", FILE_EXIT_ID, 0, NULL, NULL);
}
}
timer = al_create_timer(1.0 / 60);
al_register_event_source(queue, al_get_display_event_source(display));
al_register_event_source(queue, al_get_default_menu_event_source());
al_register_event_source(queue, al_get_keyboard_event_source());
al_register_event_source(queue, al_get_mouse_event_source());
al_register_event_source(queue, al_get_timer_event_source(timer));
bg = al_load_bitmap("data/mysha.pcx");
al_start_timer(timer);
while (true) {
ALLEGRO_EVENT event;
if (redraw && al_is_event_queue_empty(queue)) {
redraw = false;
if (bg) {
float t = al_get_timer_count(timer) * 0.1;
float sw = al_get_bitmap_width(bg);
float sh = al_get_bitmap_height(bg);
float dw = al_get_display_width(display);
float dh = al_get_display_height(display);
float cx = dw/2;
float cy = dh/2;
dw *= 1.2 + 0.2 * cos(t);
dh *= 1.2 + 0.2 * cos(1.1 * t);
al_draw_scaled_bitmap(bg, 0, 0, sw, sh,
cx - dw/2, cy - dh/2, dw, dh, 0);
}
al_flip_display();
}
al_wait_for_event(queue, &event);
if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
if (event.display.source == display) {
/* Closing the primary display */
break;
}
else {
/* Closing a secondary display */
al_set_display_menu(event.display.source, NULL);
al_destroy_display(event.display.source);
}
}
else if (event.type == ALLEGRO_EVENT_MENU_CLICK) {
/* data1: id
* data2: display (could be null)
* data3: menu (could be null)
*/
if (event.user.data2 == (intptr_t) display) {
/* The main window. */
if (event.user.data1 == FILE_OPEN_ID) {
ALLEGRO_DISPLAY *d = al_create_display(320, 240);
if (d) {
ALLEGRO_MENU *menu = al_build_menu(child_menu_info);
al_set_display_menu(d, menu);
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
al_register_event_source(queue, al_get_display_event_source(d));
al_set_target_backbuffer(display);
al_set_window_title(d, "ex_menu - Child Window");
}
}
else if (event.user.data1 == DYNAMIC_CHECKBOX_ID) {
al_set_menu_item_flags(menu, DYNAMIC_DISABLED_ID, al_get_menu_item_flags(menu, DYNAMIC_DISABLED_ID) ^ ALLEGRO_MENU_ITEM_DISABLED);
al_set_menu_item_caption(menu, DYNAMIC_DISABLED_ID,
(al_get_menu_item_flags(menu, DYNAMIC_DISABLED_ID) & ALLEGRO_MENU_ITEM_DISABLED) ?
"&Disabled" : "&Enabled");
}
else if (event.user.data1 == DYNAMIC_DELETE_ID) {
al_remove_menu_item(menu, DYNAMIC_DELETE_ID);
}
else if (event.user.data1 == DYNAMIC_CREATE_ID) {
if (dcount < 5) {
char new_name[10];
++dcount;
if (dcount == 1) {
/* append a separator */
al_append_menu_item(al_find_menu(menu, DYNAMIC_ID), NULL, 0, 0, NULL, NULL);
}
sprintf(new_name, "New #%d", dcount);
al_append_menu_item(al_find_menu(menu, DYNAMIC_ID), new_name, 0, 0, NULL, NULL);
if (dcount == 5) {
/* disable the option */
al_set_menu_item_flags(menu, DYNAMIC_CREATE_ID, ALLEGRO_MENU_ITEM_DISABLED);
}
}
}
else if (event.user.data1 == HELP_ABOUT_ID) {
al_show_native_message_box(display, "About", "ex_menu",
"This is a sample program that shows how to use menus",
"OK", 0);
}
else if (event.user.data1 == FILE_EXIT_ID) {
break;
}
else if (event.user.data1 == FILE_RESIZE_ID) {
int w = al_get_display_width(display) * 2;
int h = al_get_display_height(display) * 2;
if (w > 960)
w = 960;
if (h > 600)
h = 600;
al_resize_display(display, w, h);
}
else if (event.user.data1 == FILE_FULLSCREEN_ID) {
int flags = al_get_display_flags(display);
bool value = (flags & ALLEGRO_FULLSCREEN_WINDOW) ? true : false;
al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, !value);
}
}
else {
/* The child window */
if (event.user.data1 == FILE_CLOSE_ID) {
ALLEGRO_DISPLAY *d = (ALLEGRO_DISPLAY *) event.user.data2;
if (d) {
al_set_display_menu(d, NULL);
al_destroy_display(d);
}
}
}
}
else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
/* Popup a context menu on a right click. */
if (event.mouse.display == display && event.mouse.button == 2) {
if (pmenu) {
if (!al_popup_menu(pmenu, display)) {
log_printf("Couldn't popup menu!\n");
}
}
}
}
else if (event.type == ALLEGRO_EVENT_KEY_CHAR) {
/* Toggle the menu if the spacebar is pressed */
if (event.keyboard.display == display) {
if (event.keyboard.unichar == ' ') {
if (menu_visible)
al_remove_display_menu(display);
else
al_set_display_menu(display, menu);
menu_visible = !menu_visible;
}
}
}
else if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) {
al_acknowledge_resize(display);
redraw = true;
}
else if (event.type == ALLEGRO_EVENT_TIMER) {
redraw = true;
}
}
/* You must remove the menu before destroying the display to free resources */
al_set_display_menu(display, NULL);
return 0;
}