comparison gtk4/dw.c @ 2290:3c3f0023ae02

GTK4: Fix menu action setup by adding code to install group actions into the menu bar or popover menu when it exists. Delay setup until it is available then use the cached parent saved on the menu during subsequent creation.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 05 Feb 2021 03:24:51 +0000
parents 26a76f94f8d8
children ce1b9e558584
comparison
equal deleted inserted replaced
2289:26a76f94f8d8 2290:3c3f0023ae02
2166 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); 2166 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id));
2167 g_object_set_data(G_OBJECT(tmp), "_dw_pagearray", (gpointer)pagearray); 2167 g_object_set_data(G_OBJECT(tmp), "_dw_pagearray", (gpointer)pagearray);
2168 return tmp; 2168 return tmp;
2169 } 2169 }
2170 2170
2171 static int _dw_menugroup = 0; 2171 static unsigned int _dw_menugroup = 0;
2172
2173 /* Recurse into a menu setting the action groups on the menuparent widget */
2174 void _dw_menu_set_group_recursive(HMENUI start, GtkWidget *menuparent)
2175 {
2176 int z, submenucount = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(start), "_dw_submenucount"));
2177
2178 for(z=0;z<submenucount;z++)
2179 {
2180 char tempbuf[101] = {0};
2181 HMENUI submenu;
2182
2183 snprintf(tempbuf, 100, "_dw_submenu%d", z);
2184
2185 if((submenu = g_object_get_data(G_OBJECT(start), tempbuf)))
2186 {
2187 if(!g_object_get_data(G_OBJECT(submenu), "_dw_menuparent"))
2188 {
2189 int menugroup = DW_POINTER_TO_INT(g_object_get_data(G_OBJECT(submenu), "_dw_menugroup"));
2190 GSimpleActionGroup *group = g_object_get_data(G_OBJECT(submenu), "_dw_group");
2191 char tempbuf[25] = {0};
2192
2193 snprintf(tempbuf, 24, "menu%d", menugroup);
2194
2195 gtk_widget_insert_action_group(GTK_WIDGET(menuparent), tempbuf, G_ACTION_GROUP(group));
2196 g_object_set_data(G_OBJECT(submenu), "_dw_menuparent", (gpointer)menuparent);
2197 }
2198 _dw_menu_set_group_recursive(submenu, menuparent);
2199 }
2200 }
2201 }
2172 2202
2173 /* 2203 /*
2174 * Create a menu object to be popped up. 2204 * Create a menu object to be popped up.
2175 * Parameters: 2205 * Parameters:
2176 * id: An ID to be used for getting the resource from the 2206 * id: An ID to be used for getting the resource from the
2177 * resource file. 2207 * resource file.
2178 */ 2208 */
2179 HMENUI dw_menu_new(unsigned long id) 2209 HMENUI dw_menu_new(unsigned long id)
2180 { 2210 {
2181 GMenu *menu = g_menu_new(); 2211 GMenu *tmp = g_menu_new();
2182 /* Create the initial section and add it to the menu */ 2212 /* Create the initial section and add it to the menu */
2183 GMenu *section = g_menu_new(); 2213 GMenu *section = g_menu_new();
2184 GMenuItem *item = g_menu_item_new_section(NULL, G_MENU_MODEL(section)); 2214 GMenuItem *item = g_menu_item_new_section(NULL, G_MENU_MODEL(section));
2185 GSimpleActionGroup *group = g_simple_action_group_new(); 2215 GSimpleActionGroup *group = g_simple_action_group_new();
2186 HMENUI tmp = gtk_popover_menu_new_from_model_full(G_MENU_MODEL(menu), GTK_POPOVER_MENU_NESTED);
2187 char tempbuf[25] = {0};
2188 2216
2189 g_menu_append_item(menu, item); 2217 g_menu_append_item(tmp, item);
2190 snprintf(tempbuf, 24, "menu%d", ++_dw_menugroup); 2218
2191 gtk_widget_insert_action_group(GTK_WIDGET(tmp), tempbuf, G_ACTION_GROUP(group)); 2219 g_object_set_data(G_OBJECT(tmp), "_dw_menugroup", GINT_TO_POINTER(++_dw_menugroup));
2192
2193 g_object_set_data(G_OBJECT(tmp), "_dw_menugroup", GINT_TO_POINTER(_dw_menugroup));
2194 g_object_set_data(G_OBJECT(tmp), "_dw_group", (gpointer)group); 2220 g_object_set_data(G_OBJECT(tmp), "_dw_group", (gpointer)group);
2195 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); 2221 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id));
2196 g_object_set_data(G_OBJECT(tmp), "_dw_section", (gpointer)section); 2222 g_object_set_data(G_OBJECT(tmp), "_dw_section", (gpointer)section);
2197 return tmp; 2223 return tmp;
2198 } 2224 }
2237 g_object_set_data(G_OBJECT(tmp), "_dw_window", (gpointer)location); 2263 g_object_set_data(G_OBJECT(tmp), "_dw_window", (gpointer)location);
2238 g_object_set_data(G_OBJECT(tmp), "_dw_menugroup", GINT_TO_POINTER(_dw_menugroup)); 2264 g_object_set_data(G_OBJECT(tmp), "_dw_menugroup", GINT_TO_POINTER(_dw_menugroup));
2239 g_object_set_data(G_OBJECT(tmp), "_dw_group", (gpointer)group); 2265 g_object_set_data(G_OBJECT(tmp), "_dw_group", (gpointer)group);
2240 g_object_set_data(G_OBJECT(tmp), "_dw_section", (gpointer)section); 2266 g_object_set_data(G_OBJECT(tmp), "_dw_section", (gpointer)section);
2241 gtk_grid_attach(GTK_GRID(box), tmp, 0, 0, 1, 1); 2267 gtk_grid_attach(GTK_GRID(box), tmp, 0, 0, 1, 1);
2268 _dw_menu_set_group_recursive(tmp, GTK_WIDGET(tmp));
2242 } 2269 }
2243 return tmp; 2270 return tmp;
2244 } 2271 }
2245 2272
2246 /* 2273 /*
2265 if(box && GTK_IS_GRID(box)) 2292 if(box && GTK_IS_GRID(box))
2266 gtk_grid_remove(GTK_GRID(box), GTK_WIDGET(*menu)); 2293 gtk_grid_remove(GTK_GRID(box), GTK_WIDGET(*menu));
2267 else 2294 else
2268 g_object_unref(G_OBJECT(*menu)); 2295 g_object_unref(G_OBJECT(*menu));
2269 } 2296 }
2297 else if(G_IS_MENU(*menu))
2298 g_object_unref(G_OBJECT(*menu));
2270 *menu = NULL; 2299 *menu = NULL;
2271 } 2300 }
2272 } 2301 }
2273 2302
2274 char _dw_removetilde(char *dest, const char *src) 2303 char _dw_removetilde(char *dest, const char *src)
2307 { 2336 {
2308 GSimpleAction *action = NULL; 2337 GSimpleAction *action = NULL;
2309 GMenuItem *tmphandle = NULL; 2338 GMenuItem *tmphandle = NULL;
2310 GMenuModel *menumodel; 2339 GMenuModel *menumodel;
2311 char *temptitle = alloca(strlen(title)+1); 2340 char *temptitle = alloca(strlen(title)+1);
2312 int submenucount;
2313 2341
2314 if(!menu) 2342 if(!menu)
2315 return 0; 2343 return 0;
2316 2344
2317 /* By default we add to the menu's current section */ 2345 /* By default we add to the menu's current section */
2318 menumodel = g_object_get_data(G_OBJECT(menu), "_dw_section"); 2346 menumodel = g_object_get_data(G_OBJECT(menu), "_dw_section");
2319 _dw_removetilde(temptitle, title); 2347 _dw_removetilde(temptitle, title);
2320 submenucount = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "_dw_submenucount"));
2321 2348
2322 /* To add a separator we create a new section and add it */ 2349 /* To add a separator we create a new section and add it */
2323 if (strlen(temptitle) == 0) 2350 if (strlen(temptitle) == 0)
2324 { 2351 {
2325 GMenu *section = g_menu_new(); 2352 GMenu *section = g_menu_new();
2326 2353
2327 /* If we are creating a new section, add it to the core menu... not the section */ 2354 /* If we are creating a new section, add it to the core menu... not the section */
2328 if(GTK_IS_POPOVER_MENU_BAR(menu)) 2355 if(GTK_IS_POPOVER_MENU_BAR(menu))
2329 menumodel = gtk_popover_menu_bar_get_menu_model(GTK_POPOVER_MENU_BAR(menu)); 2356 menumodel = gtk_popover_menu_bar_get_menu_model(GTK_POPOVER_MENU_BAR(menu));
2330 else 2357 else
2331 menumodel = gtk_popover_menu_get_menu_model(GTK_POPOVER_MENU(menu)); 2358 menumodel = G_MENU_MODEL(menu);
2332 2359
2333 tmphandle = g_menu_item_new_section(NULL, G_MENU_MODEL(section)); 2360 tmphandle = g_menu_item_new_section(NULL, G_MENU_MODEL(section));
2334 g_object_set_data(G_OBJECT(menu), "_dw_section", (gpointer)section); 2361 g_object_set_data(G_OBJECT(menu), "_dw_section", (gpointer)section);
2335 } 2362 }
2336 else 2363 else
2337 { 2364 {
2338 char tempbuf[101] = {0}; 2365 char tempbuf[101] = {0};
2339 2366
2340 if(submenu) 2367 if(submenu)
2341 { 2368 {
2342 GMenuModel *submenumodel; 2369 if(G_IS_MENU(submenu))
2343 2370 {
2344 if(GTK_IS_POPOVER_MENU_BAR(submenu)) 2371 int submenucount = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "_dw_submenucount"));
2345 submenumodel = gtk_popover_menu_bar_get_menu_model(GTK_POPOVER_MENU_BAR(submenu)); 2372 GtkWidget *menuparent = GTK_WIDGET(g_object_get_data(G_OBJECT(menu), "_dw_menuparent"));
2346 else 2373
2347 submenumodel = gtk_popover_menu_get_menu_model(GTK_POPOVER_MENU(submenu)); 2374 /* If the menu being added to is a menu bar, that is the menuparent for submenus */
2348 2375 if(GTK_IS_POPOVER_MENU_BAR(menu))
2349 snprintf(tempbuf, 100, "_dw_submenu%d", submenucount); 2376 menuparent = GTK_WIDGET(menu);
2350 submenucount++; 2377
2351 tmphandle = g_menu_item_new_submenu(temptitle, submenumodel); 2378 snprintf(tempbuf, 100, "_dw_submenu%d", submenucount);
2352 g_object_set_data(G_OBJECT(menu), tempbuf, (gpointer)submenu); 2379 submenucount++;
2353 g_object_set_data(G_OBJECT(menu), "_dw_submenucount", GINT_TO_POINTER(submenucount)); 2380 tmphandle = g_menu_item_new_submenu(temptitle, G_MENU_MODEL(submenu));
2381 g_object_set_data(G_OBJECT(menu), tempbuf, (gpointer)submenu);
2382 g_object_set_data(G_OBJECT(menu), "_dw_submenucount", GINT_TO_POINTER(submenucount));
2383
2384 /* If we have a menu parent, use it to create the groups if needed */
2385 if(menuparent && !g_object_get_data(G_OBJECT(submenu), "_dw_menuparent"))
2386 _dw_menu_set_group_recursive(menu, menuparent);
2387 }
2354 } 2388 }
2355 else 2389 else
2356 { 2390 {
2357 char numbuf[25] = {0}; 2391 char numbuf[25] = {0};
2358 GSimpleActionGroup *group = g_object_get_data(G_OBJECT(menu), "_dw_group"); 2392 GSimpleActionGroup *group = g_object_get_data(G_OBJECT(menu), "_dw_group");
2519 * x: X coordinate. 2553 * x: X coordinate.
2520 * y: Y coordinate. 2554 * y: Y coordinate.
2521 */ 2555 */
2522 void dw_menu_popup(HMENUI *menu, HWND parent, int x, int y) 2556 void dw_menu_popup(HMENUI *menu, HWND parent, int x, int y)
2523 { 2557 {
2524 if(menu && *menu && GTK_IS_WIDGET(*menu)) 2558 if(menu && *menu && G_MENU(*menu))
2525 { 2559 {
2526 GtkWidget *popover = gtk_popover_new(); 2560 GtkWidget *popover = gtk_popover_new();
2561 GtkWidget *tmp = gtk_popover_menu_new_from_model_full(G_MENU_MODEL(*menu), GTK_POPOVER_MENU_NESTED);
2527 2562
2528 gtk_popover_set_child(GTK_POPOVER(popover), GTK_WIDGET(*menu)); 2563 _dw_menu_set_group_recursive(*menu, GTK_WIDGET(tmp));
2564 gtk_popover_set_child(GTK_POPOVER(popover), GTK_WIDGET(tmp));
2529 gtk_popover_set_offset(GTK_POPOVER(popover), x, y); 2565 gtk_popover_set_offset(GTK_POPOVER(popover), x, y);
2530 gtk_popover_set_autohide(GTK_POPOVER(popover), TRUE); 2566 gtk_popover_set_autohide(GTK_POPOVER(popover), TRUE);
2531 gtk_popover_popup(GTK_POPOVER(popover)); 2567 gtk_popover_popup(GTK_POPOVER(popover));
2532 *menu = NULL; 2568 *menu = NULL;
2533 } 2569 }
9582 GSimpleAction *action = G_SIMPLE_ACTION(g_object_get_data(object, "_dw_action")); 9618 GSimpleAction *action = G_SIMPLE_ACTION(g_object_get_data(object, "_dw_action"));
9583 9619
9584 if(action) 9620 if(action)
9585 { 9621 {
9586 int cid, sigid = _dw_set_signal_handler(G_OBJECT(action), (HWND)object, sigfunc, data, (gpointer)_dw_menu_handler, discfunc); 9622 int cid, sigid = _dw_set_signal_handler(G_OBJECT(action), (HWND)object, sigfunc, data, (gpointer)_dw_menu_handler, discfunc);
9587 9623 void **newparams = calloc(sizeof(void *), 3);
9588 params[0] = DW_INT_TO_POINTER(sigid); 9624
9589 params[2] = DW_POINTER(object); 9625 newparams[0] = DW_INT_TO_POINTER(sigid);
9590 cid = g_signal_connect_data(G_OBJECT(action), "activate", G_CALLBACK(_dw_menu_handler), params, _dw_signal_disconnect, 0); 9626 newparams[1] = params[1];
9627 newparams[2] = DW_POINTER(object);
9628 cid = g_signal_connect_data(G_OBJECT(action), "activate", G_CALLBACK(_dw_menu_handler), newparams, _dw_signal_disconnect, 0);
9591 _dw_set_signal_handler_id(object, sigid, cid); 9629 _dw_set_signal_handler_id(object, sigid, cid);
9592 } 9630 }
9593 return NULL; 9631 return NULL;
9594 } 9632 }
9595 return object; 9633 return object;