[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
- To: "Coordination of admins/developers of the game programming library Allegro" <alleg-developers@xxxxxxxxxx>
- Subject: Re: [AD] native menus
- From: Matthew Leverton <meffer@xxxxxxxxxx>
- Date: Thu, 7 Jul 2011 17:36:58 -0500
On Wed, Jul 6, 2011 at 2:29 AM, Matthew Leverton <meffer@xxxxxxxxxx> wrote:
> I poked around the GTK code and it looked like too much hassle for me
> to bother with at the moment
>
Attached is a limited test implementation for GTK. It works with
ex_menu.c to show/hide the main menu bar.
But I don't know enough about how the window/display code works under
Linux... Is there even an easy way to attach a GTK menu to the window?
My test code just pops up a new detached window that contains the
menu.
Would we need something like: ALLEGRO_DISPLAY
*al_create_native_display(w,h) that under Linux would return something
that is a GTK window?
--
Matthew Leverton
Index: addons/native_dialog/gtk_dialog.c
===================================================================
--- addons/native_dialog/gtk_dialog.c (revision 14832)
+++ addons/native_dialog/gtk_dialog.c (working copy)
@@ -534,25 +534,32 @@
textlog->async_queue = NULL;
}
+/*---------------------------------------------------------------------------*/
+/* Menus */
+/*---------------------------------------------------------------------------*/
+
+/* [user thread] */
bool _al_init_menu(ALLEGRO_MENU *menu)
{
(void) menu;
- return false;
+ return true;
}
+/* [user thread] */
bool _al_init_popup_menu(ALLEGRO_MENU *menu)
{
- (void) menu;
- return false;
+ return _al_init_menu(menu);
}
+/* [user thread] */
bool _al_insert_menu_item_at(ALLEGRO_MENU_ITEM *item, int i)
{
(void) item;
(void) i;
- return false;
+ return true;
}
+/* [user thread] */
bool _al_destroy_menu_item_at(ALLEGRO_MENU_ITEM *item, int i)
{
(void) item;
@@ -560,6 +567,7 @@
return false;
}
+/* [user thread] */
bool _al_update_menu_item_at(ALLEGRO_MENU_ITEM *item, int i)
{
(void) item;
@@ -567,20 +575,126 @@
return false;
}
+typedef struct DISPLAY_MENU_ARGS DISPLAY_MENU_ARGS;
+struct DISPLAY_MENU_ARGS
+{
+ ALLEGRO_DISPLAY *display;
+ ALLEGRO_MENU *menu;
+};
+
+/* [gtk thread] */
+static void menuitem_response(ALLEGRO_MENU_ITEM *menu_item)
+{
+ if (menu_item->parent)
+ _al_emit_menu_event(menu_item->parent->display, menu_item->id);
+}
+
+/* [gtk thread] */
+GtkWidget *build_menu(GtkWidget *gmenu, ALLEGRO_MENU *amenu)
+{
+ size_t i;
+
+ for (i = 0; i < _al_vector_size(&amenu->items); ++i) {
+ ALLEGRO_MENU_ITEM *aitem = * (ALLEGRO_MENU_ITEM **) _al_vector_ref(&amenu->items, i);
+ GtkWidget *gitem = gtk_menu_item_new_with_label(al_cstr(aitem->caption));
+
+ if (aitem->popup) {
+ GtkWidget *gsubmenu = gtk_menu_new();
+ build_menu(gsubmenu, aitem->popup);
+ gtk_widget_show(gsubmenu);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(gitem), gsubmenu);
+ }
+ else if (aitem->id) {
+ g_signal_connect_swapped (gitem, "activate",
+ G_CALLBACK(menuitem_response), (gpointer) aitem);
+ }
+
+ gtk_widget_show(gitem);
+ gtk_menu_shell_append(GTK_MENU_SHELL(gmenu), gitem);
+ }
+
+ return NULL;
+}
+
+/* [gtk thread] */
+static gboolean do_show_display_menu(gpointer data)
+{
+ DISPLAY_MENU_ARGS *args = (DISPLAY_MENU_ARGS *) data;
+
+ if (!args->menu->extra1) {
+ GtkWidget *gtk_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ GtkWidget *menu_bar = gtk_menu_bar_new();
+
+ build_menu(menu_bar, args->menu);
+
+ gtk_container_add(GTK_CONTAINER(gtk_window), menu_bar);
+ gtk_widget_show(menu_bar);
+
+ gtk_window_set_default_size(GTK_WINDOW(gtk_window), 320, 32);
+ args->menu->extra1 = gtk_window;
+ }
+
+ gtk_widget_show(args->menu->extra1);
+
+ al_free(args);
+
+ return FALSE;
+}
+
+/* [user thread] */
bool _al_show_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu)
{
- (void) display;
- (void) menu;
- return false;
+ DISPLAY_MENU_ARGS *args;
+
+ if (!ensure_gtk_thread()) {
+ return false;
+ }
+
+ args = al_malloc(sizeof(*args));
+ if (!args) {
+ return false;
+ }
+
+ args->display = display;
+ args->menu = menu;
+
+ g_timeout_add(0, do_show_display_menu, args);
+
+ return true;
}
+/* [gtk thread] */
+static gboolean do_hide_display_menu(gpointer data)
+{
+ DISPLAY_MENU_ARGS *args = (DISPLAY_MENU_ARGS *) data;
+
+ gtk_widget_destroy(GTK_WIDGET(args->menu->extra1));
+ args->menu->extra1 = NULL;
+
+ al_free(args);
+
+ return FALSE;
+}
+
+/* [user thread] */
bool _al_hide_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu)
{
- (void) display;
- (void) menu;
- return false;
+ DISPLAY_MENU_ARGS *args;
+
+ args = al_malloc(sizeof(*args));
+ if (!args) {
+ return false;
+ }
+
+ args->display = display;
+ args->menu = menu;
+
+ g_timeout_add(0, do_hide_display_menu, args);
+
+ return true;
}
+
bool _al_show_popup_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu,
int x, int y, int flags)
{