|
Allegro GUI: How to keep widgets from blocking |
Tobias Dammers
Member #2,604
August 2002
|
Some of the allegro gui widgets, e.g. buttons, block everything while they are pressed, that is, when clicked, their dialog procedure only exits after the mouse button has been released. Is there any way around this behaviour, other than a major allegro gui rewrite or using a different gui package altogether? The reason why I need this is that I am using the allegro gui routines in a buffered context. The problem is that in some modes, the buffering includes stretching to display a 400x300 logical screen at reasonable size on modern displays. This is especially necessary when in windowed mode (a 400x300 window on a 1600x1200 screen doesn't look retro, it just looks tiny). But when a dialog proc blocks the whole process, it will just draw to the back buffer over and over, without giving me a chance to flip. I could of course add the flipping code to the button, but I don't think that's an elegant solution... --- |
Matt Smith
Member #783
November 2000
|
if you look at the code for d_button_proc, it blocks for no particularly good reason, and causes d_icon_proc, d_radio_proc etc to block with it. You can replace this with a much simpler widget which simply responds to MSG_CLICK or MSG_LPRESS As for elegant solutions, don't worry about it You'll never get very far with Allegro GUI if you insist on elegant code. Hacks upon hacks are the order of the day. You can easily end up with a custom widget for every single item in your dialog. Here is an example from attf2pcx of a custom version of d_radio_proc written to avoid d_button_proc's unnecessary blocking
|
Tobias Dammers
Member #2,604
August 2002
|
There is one problem with this approach though; if the user holds down the button, drags the mouse out of the button area while holding the LMB down, and then releases the LMB outside the button area, the button should not be triggered. (At least that is the default behaviour in pretty much every modern GUI - windows does it, macosx does it, and I bet kde, gnome and what have you on linux do the same). I guess I'll add some flipping code to the custom d_button_proc. This means some unnecessary flipping, but that shouldn't be anything a modern system couldn't handle (especially at 400x300 @ 8bpp); and it will sort of ruin my modular program architecture, but what the heck. BTW., allegro GUI isn't that bad if you write your own graphics routines for the dialog procs, and add a few helper funcs like this one:
This baby (along with some other helpers) allows me to construct dialogs dynamically. I could, for example, have a base class set up a basic dialog layout (say, a settings dialog), and a child class can just append its specific widgets to it. After that, the base class appends the common [OK] and [Cancel] buttons, adds a nice frame, centers the dialog on screen, and executes it. Depending on the result, one of two virtual functions is called to process the result. --- |
Matt Smith
Member #783
November 2000
|
A useful solution could be a dialog player which provides MSG_MOUSELEAVE messages, but at first sight this would be difficult to do in a re-entrant way, as the player would have to keep track of where the mouse has been. |
Tobias Dammers
Member #2,604
August 2002
|
My solution would be to have a D_MOUSE_OWNER flag in the widget, or a DIALOG* mouse_owner in the dialog player. A widget would return a special message when it want to "own" the mouse, and as long as it doesn't return anything other than D_O_K, it will get all input messages exclusively. But this, just like your solution, would require a rather extensive rewrite of the allegro GUI. Maybe I'll do it anyway... --- |
Steve Terry
Member #1,989
March 2002
|
I do just that in NAS which doesn't block when the user presses a button. It's very state driven so there is no while loops like the Allegro GUI does. You can always look at my source and use the techniques for you own purposes. ___________________________________ |
Tobias Dammers
Member #2,604
August 2002
|
I might even consider using NAS altogether. I'll look into it as soom as I find the time... --- |
|