Mercurial > dwindows
diff gtk4/dw.c @ 2273:95796965bb01
GTK4: More menu work, something still isn't working.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Mon, 01 Feb 2021 20:22:30 +0000 |
parents | 2ce302c43f48 |
children | b0bdd54bb2e8 |
line wrap: on
line diff
--- a/gtk4/dw.c Mon Feb 01 10:05:42 2021 +0000 +++ b/gtk4/dw.c Mon Feb 01 20:22:30 2021 +0000 @@ -1008,6 +1008,19 @@ func((HWND)DW_ULONGLONG_TO_POINTER(g_variant_get_uint64(param)), data); } +/* Handle menu click callbacks */ +static void _dw_menu_handler(GSimpleAction *action, GVariant *param, gpointer data) +{ + SignalHandler work = _dw_get_signal_handler(data); + + if(work.window) + { + int (*genericfunc)(HWND, void *) = work.func; + + genericfunc(work.window, work.data); + } +} + static void _dw_app_activate(GApplication *app, gpointer user_data) { /* Not sure why this signal is required, but GLib gives warnings @@ -2218,24 +2231,29 @@ } } -char _dw_removetilde(char *dest, const char *src) +char _dw_removetilde(char *action, char *dest, const char *src) { int z, cur=0; char accel = '\0'; for(z=0;z<strlen(src);z++) { - if(src[z] != '~') - { + if(src[z] == '~') + { + action[cur] = dest[cur] = '_'; + accel = src[z+1]; + } + else if(src[z] == ' ') + { + action[cur] = '_'; dest[cur] = src[z]; - cur++; } else { - dest[cur] = '_'; - accel = src[z+1]; - cur++; - } + action[cur] = src[z]; + dest[cur] = src[z]; + } + cur++; } dest[cur] = 0; return accel; @@ -2255,30 +2273,31 @@ */ HWND dw_menu_append_item(HMENUI menu, const char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu) { + GSimpleAction *action = NULL; GMenuItem *tmphandle = NULL; GMenuModel *menumodel; - char accel, *temptitle = alloca(strlen(title)+1); + char *temptitle = alloca(strlen(title)+1); + char *tempaction = alloca(strlen(title)+1); int submenucount; if(!menu) - return NULL; + return 0; if(GTK_IS_POPOVER_MENU_BAR(menu)) menumodel = gtk_popover_menu_bar_get_menu_model(GTK_POPOVER_MENU_BAR(menu)); else menumodel = gtk_popover_menu_get_menu_model(GTK_POPOVER_MENU(menu)); - accel = _dw_removetilde(temptitle, title); + _dw_removetilde(tempaction, temptitle, title); submenucount = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "_dw_submenucount")); if (strlen(temptitle) == 0) tmphandle = g_menu_item_new_section(NULL, NULL); else { - char numbuf[25] = {0}; + char tempbuf[101] = {0}; if(submenu) { - char tempbuf[101] = {0}; GMenuModel *submenumodel; if(GTK_IS_POPOVER_MENU_BAR(submenu)) @@ -2294,9 +2313,15 @@ } else { - tmphandle=g_menu_item_new(temptitle, NULL); + char numbuf[25] = {0}; + + snprintf(tempbuf, 100, "menu.%s", tempaction); + action = g_simple_action_new(tempbuf, NULL); + g_object_ref(G_OBJECT(action)); + tmphandle=g_menu_item_new(temptitle, tempbuf); snprintf(numbuf, 24, "%lu", id); g_object_set_data(G_OBJECT(menu), numbuf, (gpointer)tmphandle); + g_object_set_data(G_OBJECT(menu), "_dw_action", (gpointer)action); } } @@ -2307,14 +2332,14 @@ g_object_set_data(G_OBJECT(tmphandle), "_dw_id", GINT_TO_POINTER(id)); - /*if(flags & DW_MIS_DISABLED) - gtk_widget_set_sensitive(tmphandle, FALSE);*/ + if(action) + g_simple_action_set_enabled(action, (flags & DW_MIS_DISABLED) ? FALSE : TRUE); return (HWND)tmphandle; } -GtkWidget *_find_submenu_id(GtkWidget *start, const char *name) -{ - GtkWidget *tmp; +GMenuItem *_dw_find_submenu_id(HMENUI start, const char *name) +{ + GMenuItem *tmp; int z, submenucount = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(start), "_dw_submenucount")); if((tmp = g_object_get_data(G_OBJECT(start), name))) @@ -2323,13 +2348,14 @@ for(z=0;z<submenucount;z++) { char tempbuf[101] = {0}; - GtkWidget *submenu, *menuitem; + GMenuItem *menuitem; + HMENUI submenu; snprintf(tempbuf, 100, "_dw_submenu%d", z); if((submenu = g_object_get_data(G_OBJECT(start), tempbuf))) { - if((menuitem = _find_submenu_id(submenu, name))) + if((menuitem = _dw_find_submenu_id(submenu, name))) return menuitem; } } @@ -2346,22 +2372,22 @@ */ void dw_menu_item_set_check(HMENUI menu, unsigned long id, int check) { -#if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ +#if 0 char numbuf[25] = {0}; - GtkWidget *tmphandle; + GMenuItem *tmphandle; if(!menu) return; snprintf(numbuf, 24, "%lu", id); - tmphandle = _find_submenu_id(menu, numbuf); - - if(tmphandle) - { - _dw_ignore_click = 1; + tmphandle = _dw_find_submenu_id(menu, numbuf); + + if(tmphandle && G_IS_MENU_ITEM(tmphandle)) + { + GSimpleAction *action = g_object_get_data(G_OBJECT(tmphandle), "_dw_action"); + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(tmphandle)) != check) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check); - _dw_ignore_click = 0; } #endif } @@ -2375,45 +2401,39 @@ */ void dw_menu_item_set_state(HMENUI menu, unsigned long id, unsigned long state) { -#if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ char numbuf[25] = {0}; - GtkWidget *tmphandle; - int check; + GMenuItem *tmphandle; if(!menu) return; snprintf(numbuf, 24, "%lu", id); - tmphandle = _find_submenu_id(menu, numbuf); - - if ( (state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED) ) - { - if ( state & DW_MIS_CHECKED ) - check = 1; - else - check = 0; - - if (tmphandle) - { - _dw_ignore_click = 1; + tmphandle = _dw_find_submenu_id(menu, numbuf); + + if(tmphandle && G_IS_MENU_ITEM(tmphandle)) + { + GSimpleAction *action = g_object_get_data(G_OBJECT(tmphandle), "_dw_action"); + +#if 0 + if((state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED)) + { + int check = 0; + + if(state & DW_MIS_CHECKED) + check = 1; + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(tmphandle)) != check) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check); - _dw_ignore_click = 0; - } - } - if ( (state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED) ) - { - if (tmphandle ) - { - _dw_ignore_click = 1; - if ( state & DW_MIS_ENABLED ) - gtk_widget_set_sensitive( tmphandle, TRUE ); + } +#endif + if((state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED)) + { + if(state & DW_MIS_ENABLED) + g_simple_action_set_enabled(action, TRUE); else - gtk_widget_set_sensitive( tmphandle, FALSE ); - _dw_ignore_click = 0; - } - } -#endif + g_simple_action_set_enabled(action, FALSE); + } + } } /* @@ -2427,24 +2447,22 @@ int API dw_menu_delete_item(HMENUI menu, unsigned long id) { int ret = DW_ERROR_UNKNOWN; -#if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ char numbuf[25] = {0}; - GtkWidget *tmphandle; + GMenuItem *tmphandle; if(!menu) return ret; snprintf(numbuf, 24, "%lu", id); - tmphandle = _find_submenu_id(menu, numbuf); - - if(tmphandle) - { - if(GTK_IS_WIDGET(tmphandle)) - g_object_unref(G_OBJECT(tmphandle)); + tmphandle = _dw_find_submenu_id(menu, numbuf); + + if(tmphandle && G_IS_MENU_ITEM(tmphandle)) + { + /* g_menu_remove(menu, position); */ + g_object_unref(G_OBJECT(tmphandle)); g_object_set_data(G_OBJECT(menu), numbuf, NULL); ret = DW_ERROR_NONE; } -#endif return ret; } @@ -2458,15 +2476,16 @@ */ void dw_menu_popup(HMENUI *menu, HWND parent, int x, int y) { - if(!menu || !*menu) - return; - -#if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ - popup = parent; - - gtk_menu_popup_at_pointer(GTK_MENU(*menu), NULL); -#endif - *menu = NULL; + if(menu && *menu && GTK_IS_WIDGET(*menu)) + { + GtkWidget *popover = gtk_popover_new(); + + gtk_popover_set_child(GTK_POPOVER(popover), GTK_WIDGET(*menu)); + gtk_popover_set_offset(GTK_POPOVER(popover), x, y); + gtk_popover_set_autohide(GTK_POPOVER(popover), TRUE); + gtk_popover_popup(GTK_POPOVER(popover)); + *menu = NULL; + } } @@ -9521,6 +9540,22 @@ /* GTK signal name for check buttons is "toggled" not "clicked" */ else if(GTK_IS_CHECK_BUTTON(object) && strcmp(signal->name, DW_SIGNAL_CLICKED) == 0) strcpy(signal->gname, "toggled"); + /* For menu items, get the G(Simple)Action and the signal is "activate" */ + else if(G_IS_MENU_ITEM(object) && strcmp(signal->name, DW_SIGNAL_CLICKED) == 0) + { + GSimpleAction *action = G_SIMPLE_ACTION(g_object_get_data(object, "_dw_action")); + + if(action) + { + int cid, sigid = _dw_set_signal_handler(G_OBJECT(action), (HWND)object, sigfunc, data, (gpointer)_dw_menu_handler, discfunc); + + params[0] = DW_INT_TO_POINTER(sigid); + params[2] = DW_POINTER(object); + cid = g_signal_connect_data(G_OBJECT(action), "activate", G_CALLBACK(_dw_menu_handler), params, _dw_signal_disconnect, 0); + _dw_set_signal_handler_id(object, sigid, cid); + } + return NULL; + } return object; }