Re: [AD] non blocking menu bug |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
Eric Botcazou wrote:
> Pending the rewrite I was previously talking about, we have to maintain a
> clear separation between menus and dialogs. In particular, when menus are
> invoked through the dialog layer (via d_menu_proc), their interface should
> be hidden behind that of dialogs. So we must implement hooks in the dialog
> engine so that, when a menu from a d_menu_proc is activated, we can control
> the menus through the dialog interface.
Ok, then what I'd like is basically to be able to do the following, if I need
to get the control of the dialog engine back:
dialog_message(dlg, MSG_CLOSE_MENU, 0, NULL);
any d_menu_proc object would then close their currently active menu if any.
> There is already such a hook: when a menu is activated, update_dialog() is
> basically redirected to update_menu(). If we were to implement close_menu()
> (and I'm willing to do so), we would need to devise hooks so that, for
> example, close_menu() is invoked when a MSG_END is sent to its parent
> d_menu_proc and invoked first when a MSG_END is broadcast to the whole
> dialog array containing the d_menu_proc.
I'm not too sure what you mean, so I'll let you do it, you have a better
understanding of the engine than me. Attached is what I have done so far.
Anyway, thanks for taking the problem into consideration :)
> > (3) have init_dialog() close any active menu.
>
> I don't like it when init functions close something :-)
Right!
--
Julien Cugnière
--- gui.c.old 2003-03-19 09:45:08.000000000 +0100
+++ gui.c 2003-03-19 09:47:42.000000000 +0100
@@ -1664,6 +1664,10 @@
int child_x, child_y;
ASSERT(player);
+ /* is the player finished ? */
+ if (player->ret < -1)
+ return FALSE;
+
/* find activated menu */
while (player->child)
player = player->child;
@@ -1969,6 +1973,32 @@
+/* close_menu:
+ * Recursively closes all the menus opened in a MENU_PLAYER, and makes sure
+ * the next call to update_menu will return FALSE.
+ */
+void close_menu(MENU_PLAYER *player)
+{
+ ASSERT(player);
+
+ /* find the active menu */
+ while (player->child)
+ player = player->child;
+
+ /* close all menus down to the root */
+ while (player->parent) {
+ player->ret = -2;
+ player = player->parent;
+ shutdown_menu(player->child);
+ player->child = NULL;
+ }
+
+ /* make sure the next call to update_menu will return FALSE */
+ player->ret = -2;
+}
+
+
+
/* d_menu_proc:
* Dialog procedure for adding drop down menus to a GUI dialog. This
* displays the top level menu items as a horizontal bar (eg. across the
@@ -1992,6 +2022,14 @@
d->h = m.h;
break;
+ case MSG_END:
+ if (active_menu_player) {
+ close_menu(active_menu_player);
+ shutdown_menu(active_menu_player);
+ active_menu_player = NULL;
+ }
+ break;
+
case MSG_DRAW:
layout_menu(&m, d->dp, TRUE, d->x, d->y, d->w, d->h);
draw_menu(&m);