[AD] A possibly useful variation on d_keyboard_proc |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
I needed to use a function key as a shortcut in my GUI, but apparently
shortcuts are only handled as ASCII codes.
d_keyboard_proc accepts scancodes, but I didn't want to write a wrapper
function for every new shortcut. So I wrote this function, which is similar
to d_keyboard_proc except that instead of calling a function (pointed to by
dp), it sends a MSG_KEY to a DIALOG (pointed to by dp). Put differently,
it's an invisible object that forwards keypresses corresponding to its
shortcut or to a scancode (in d1 or d2) to the DIALOG pointed to by dp.
Additionally, this function allows using multiple shortcuts for the same
DIALOG easily. Not that I would recommend that kind of design though.
The code for an example is at the end of this message. Adding the function
to Allegro would just be a matter of copying d_keyboard_forward_proc into
allegro/guiproc.c, and the prototype to gui.h.
Maybe there's already some way to do the same thing but I didn't found one
although I read the docs thoroughly. Why aren't scancodes supported as
shortcuts? As DIALOG.key is an int, we could store a scancode in addition to
the ASCII code using the readkey() format. This would be better than nothing
and shouldn't break compatibility, except where reading shortcuts from
DIALOGs is involved, which shouldn't happen often. What do you think?
There is a problem with my function though. Not all keys will work. Function
keys, cursor keys, "extra cursor keys", numpad keys, esc, tab, enter and
print screen work, but shifts, controls, alts, windows, caps lock, pause and
scroll lock don't. I have no idea why, but I don't know if it's worth
examining the issue.
PS I'm not subscribed to this list but I will watch this space for any
follow-ups of course.
#include <allegro.h>
// This is the interesting function.
// The code is very similar to d_keyboard_proc in allegro/guiproc.c.
// I retained the same coding style for this function.
int d_keyboard_forward_proc(int msg, DIALOG *d, int c)
{
int ret = D_O_K;
switch (msg) {
case MSG_START:
d->w = d->h = 0;
break;
case MSG_XCHAR:
if (((c>>8) != d->d1) && ((c>>8) != d->d2))
break;
ret |= D_USED_CHAR;
/* fall through */
case MSG_KEY:
ret |= object_message((DIALOG*) (d->dp), MSG_KEY, 0);
break;
}
return ret;
}
void menu_play() {
DIALOG widgets[8];
widgets[0] = (DIALOG) {d_clear_proc, 0, 0, SCREEN_W, SCREEN_H, 0, 255, 0,
0, 0, 0, NULL, NULL, NULL};
widgets[1] = (DIALOG) {d_check_proc, 0, 0, SCREEN_W, 32, 0, 255, 'C',
0, 1, 0, "&Checkbox (F1)", NULL, NULL};
widgets[2] = (DIALOG) {d_button_proc, 0, 32, SCREEN_W, 32, 0, 255, 'B',
0, 0, 0, "&Button (F2 or home)", NULL, NULL};
widgets[3] = (DIALOG) {d_button_proc, 0, 64, SCREEN_W, 32, 0, 255, 'X',
D_EXIT, 0, 0, "E&XIT", NULL, NULL};
widgets[4] = (DIALOG) {d_keyboard_forward_proc, 0, 0, 0, 0, 0, 255, 0,
0, KEY_F1, 0, &widgets[1], NULL, NULL};
widgets[5] = (DIALOG) {d_keyboard_forward_proc, 0, 0, 0, 0, 0, 255, 0,
0, KEY_F2, KEY_HOME, &widgets[2], NULL, NULL};
widgets[6] = (DIALOG) {d_yield_proc};
widgets[7] = (DIALOG) {NULL};
popup_dialog(widgets, -1);
}
int main() {
allegro_init();
install_keyboard();
install_mouse();
if (set_gfx_mode(GFX_SAFE, 640, 480, 0, 0)) {
allegro_message("Error; set_gfx_mode");
return 1;
}
menu_play();
return 0;
}
END_OF_MAIN();
_________________________________________________________________
Bloquez les fenêtres pop-up, c'est gratuit ! http://toolbar.msn.fr