Mercurial > dwindows
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; |