Show excustom.c syntax highlighted
/*
* Example program for the Allegro library, by Shawn Hargreaves.
*
* This program demonstrates how to write your own GUI objects.
*/
#include <time.h>
#include "allegro.h"
/* for the al_dialog_edit_proc() object */
char the_string[32] = "Change Me!";
/* the current time, for the clock object */
struct tm the_time;
/* helper function to draw a hand on the clock */
void draw_hand(AL_BITMAP *bmp, int value, int range, int v2, int range2, fixed length, int color)
{
fixed angle;
fixed x, y;
int w, h;
angle = ((al_int_to_fix(value) * 256) / range) +
((al_int_to_fix(v2) * 256) / (range * range2)) - al_int_to_fix(64);
x = al_fix_mul(al_fix_cos(angle), length);
y = al_fix_mul(al_fix_sin(angle), length);
w = bmp->w / 2;
h = bmp->h / 2;
al_draw_line(bmp, w, h, w + al_fix_to_int(x*w), h + al_fix_to_int(y*h), color);
}
/* custom dialog procedure for the clock object */
int clock_proc(int msg, AL_DIALOG *d, int c)
{
time_t current_time;
struct tm *t;
AL_BITMAP *temp;
fixed angle, x, y;
/* process the message */
switch (msg) {
/* initialise when we get a start message */
case MSG_START:
/* store the current time */
current_time = time(NULL);
t = localtime(¤t_time);
the_time = *t;
/* draw the clock background onto a memory bitmap */
temp = al_create_bitmap(d->w, d->h);
al_clear_to_color(temp, d->bg);
/* draw borders and a nobble in the middle */
al_draw_circle(temp, temp->w/2, temp->h/2, temp->w/2-1, d->fg);
al_draw_circle_fill(temp, temp->w/2, temp->h/2, 2, d->fg);
/* draw ticks around the edge */
for (angle=0; angle<al_int_to_fix(256); angle+=al_int_to_fix(256)/12) {
x = al_fix_cos(angle);
y = al_fix_sin(angle);
al_draw_line(temp, temp->w/2+al_fix_to_int(x*temp->w*15/32),
temp->h/2+al_fix_to_int(y*temp->w*15/32),
temp->w/2+al_fix_to_int(x*temp->w/2),
temp->h/2+al_fix_to_int(y*temp->w/2), d->fg);
}
/* store the clock background bitmap in d->dp */
d->dp = temp;
break;
/* shutdown when we get an end message */
case MSG_END:
/* destroy the clock background bitmap */
al_destroy_bitmap(d->dp);
break;
/* update the clock in response to idle messages */
case MSG_IDLE:
/* read the current time */
current_time = time(NULL);
t = localtime(¤t_time);
/* check if it has changed */
if ((the_time.tm_sec != t->tm_sec) ||
(the_time.tm_min != t->tm_min) ||
(the_time.tm_hour != t->tm_hour)) {
the_time = *t;
/* Redraw ourselves if the time has changed. Note that we have
* to turn the mouse off before doing this: the dialog manager
* turns it off whenever it sends us a draw message, but we
* are sending the message ourselves here so we are responsible
* for making sure the mouse is off first. Also note the use of
* the al_object_message function rather than a simple recursive call
* to clock_proc(). This vectors the call through the function
* pointer in the dialog object, which allows other object
* procedures to hook it, for example a different type of clock
* could process the draw messages itself but pass idle messages
* on to this procedure.
*/
al_show_mouse(NULL);
al_object_message(d, MSG_DRAW, 0);
al_show_mouse(al_screen);
}
break;
/* draw the clock in response to draw messages */
case MSG_DRAW:
/* draw onto a temporary memory bitmap to prevent flicker */
temp = al_create_bitmap(d->w, d->h);
/* copy the clock background onto the temporary bitmap */
al_blit(d->dp, temp, 0, 0, 0, 0, d->w, d->h);
/* draw the hands */
draw_hand(temp, the_time.tm_sec, 60, 0, 1, al_int_to_fix(9)/10, d->fg);
draw_hand(temp, the_time.tm_min, 60, the_time.tm_sec, 60, al_int_to_fix(5)/6, d->fg);
draw_hand(temp, the_time.tm_hour, 12, the_time.tm_min, 60, al_int_to_fix(1)/2, d->fg);
/* copy the temporary bitmap onto the al_screen */
al_blit(temp, al_screen, 0, 0, d->x, d->y, d->w, d->h);
al_destroy_bitmap(temp);
break;
}
/* always return OK status, since the clock doesn't ever need to close
* the dialog or get the input focus.
*/
return D_O_K;
}
AL_DIALOG the_dialog[] =
{
/* (dialog proc) (x) (y) (w) (h) (fg) (bg) (al_key) (flags) (d1) (d2) (dp) (dp2) (dp3) */
{ al_dialog_clear_proc, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, NULL, NULL, NULL },
{ al_dialog_edit_proc, 32, 32, 256, 8, 255, 0, 0, 0, sizeof(the_string)-1, 0, the_string, NULL, NULL },
{ al_dialog_check_proc, 32, 64, 89, 13, 255, 0, 't', 0, 0, 0, "&Toggle Me", NULL, NULL },
{ clock_proc, 192, 64, 64, 64, 255, 0, 0, 0, 0, 0, NULL, NULL, NULL },
{ al_dialog_button_proc, 120, 160, 81, 17, 255, 0, 0, D_EXIT, 0, 0, "Exit", NULL, NULL },
{ NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
};
int main()
{
int item;
allegro_init();
al_install_keyboard();
al_install_mouse();
al_install_timer();
if (al_set_gfx_mode(AL_GFX_SAFE, 320, 200, 0, 0) != 0) {
al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);
al_show_message("Unable to set any graphic mode\n%s\n", al_error);
return 1;
}
al_set_palette(al_desktop_palette);
/* We set up colors to match al_screen color depth (in case it changed) */
for (item = 0; the_dialog[item].proc; item++) {
the_dialog[item].fg = al_make_color(0, 0, 0);
the_dialog[item].bg = al_make_color(255, 255, 255);
}
al_do_dialog(the_dialog, -1);
return 0;
}
AL_END_OF_MAIN();
See more files for this project here