Mercurial > dwindows
comparison 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 |
comparison
equal
deleted
inserted
replaced
2272:2ce302c43f48 | 2273:95796965bb01 |
---|---|
1004 data = g_object_get_data(G_OBJECT(_DWApp), textbuf); | 1004 data = g_object_get_data(G_OBJECT(_DWApp), textbuf); |
1005 g_object_set_data(G_OBJECT(_DWApp), textbuf, NULL); | 1005 g_object_set_data(G_OBJECT(_DWApp), textbuf, NULL); |
1006 | 1006 |
1007 if(func) | 1007 if(func) |
1008 func((HWND)DW_ULONGLONG_TO_POINTER(g_variant_get_uint64(param)), data); | 1008 func((HWND)DW_ULONGLONG_TO_POINTER(g_variant_get_uint64(param)), data); |
1009 } | |
1010 | |
1011 /* Handle menu click callbacks */ | |
1012 static void _dw_menu_handler(GSimpleAction *action, GVariant *param, gpointer data) | |
1013 { | |
1014 SignalHandler work = _dw_get_signal_handler(data); | |
1015 | |
1016 if(work.window) | |
1017 { | |
1018 int (*genericfunc)(HWND, void *) = work.func; | |
1019 | |
1020 genericfunc(work.window, work.data); | |
1021 } | |
1009 } | 1022 } |
1010 | 1023 |
1011 static void _dw_app_activate(GApplication *app, gpointer user_data) | 1024 static void _dw_app_activate(GApplication *app, gpointer user_data) |
1012 { | 1025 { |
1013 /* Not sure why this signal is required, but GLib gives warnings | 1026 /* Not sure why this signal is required, but GLib gives warnings |
2216 } | 2229 } |
2217 *menu = NULL; | 2230 *menu = NULL; |
2218 } | 2231 } |
2219 } | 2232 } |
2220 | 2233 |
2221 char _dw_removetilde(char *dest, const char *src) | 2234 char _dw_removetilde(char *action, char *dest, const char *src) |
2222 { | 2235 { |
2223 int z, cur=0; | 2236 int z, cur=0; |
2224 char accel = '\0'; | 2237 char accel = '\0'; |
2225 | 2238 |
2226 for(z=0;z<strlen(src);z++) | 2239 for(z=0;z<strlen(src);z++) |
2227 { | 2240 { |
2228 if(src[z] != '~') | 2241 if(src[z] == '~') |
2229 { | 2242 { |
2243 action[cur] = dest[cur] = '_'; | |
2244 accel = src[z+1]; | |
2245 } | |
2246 else if(src[z] == ' ') | |
2247 { | |
2248 action[cur] = '_'; | |
2230 dest[cur] = src[z]; | 2249 dest[cur] = src[z]; |
2231 cur++; | |
2232 } | 2250 } |
2233 else | 2251 else |
2234 { | 2252 { |
2235 dest[cur] = '_'; | 2253 action[cur] = src[z]; |
2236 accel = src[z+1]; | 2254 dest[cur] = src[z]; |
2237 cur++; | 2255 } |
2238 } | 2256 cur++; |
2239 } | 2257 } |
2240 dest[cur] = 0; | 2258 dest[cur] = 0; |
2241 return accel; | 2259 return accel; |
2242 } | 2260 } |
2243 | 2261 |
2253 * check: If TRUE menu is "check"able. | 2271 * check: If TRUE menu is "check"able. |
2254 * submenu: Handle to an existing menu to be a submenu or NULL. | 2272 * submenu: Handle to an existing menu to be a submenu or NULL. |
2255 */ | 2273 */ |
2256 HWND dw_menu_append_item(HMENUI menu, const char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu) | 2274 HWND dw_menu_append_item(HMENUI menu, const char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu) |
2257 { | 2275 { |
2276 GSimpleAction *action = NULL; | |
2258 GMenuItem *tmphandle = NULL; | 2277 GMenuItem *tmphandle = NULL; |
2259 GMenuModel *menumodel; | 2278 GMenuModel *menumodel; |
2260 char accel, *temptitle = alloca(strlen(title)+1); | 2279 char *temptitle = alloca(strlen(title)+1); |
2280 char *tempaction = alloca(strlen(title)+1); | |
2261 int submenucount; | 2281 int submenucount; |
2262 | 2282 |
2263 if(!menu) | 2283 if(!menu) |
2264 return NULL; | 2284 return 0; |
2265 | 2285 |
2266 if(GTK_IS_POPOVER_MENU_BAR(menu)) | 2286 if(GTK_IS_POPOVER_MENU_BAR(menu)) |
2267 menumodel = gtk_popover_menu_bar_get_menu_model(GTK_POPOVER_MENU_BAR(menu)); | 2287 menumodel = gtk_popover_menu_bar_get_menu_model(GTK_POPOVER_MENU_BAR(menu)); |
2268 else | 2288 else |
2269 menumodel = gtk_popover_menu_get_menu_model(GTK_POPOVER_MENU(menu)); | 2289 menumodel = gtk_popover_menu_get_menu_model(GTK_POPOVER_MENU(menu)); |
2270 accel = _dw_removetilde(temptitle, title); | 2290 _dw_removetilde(tempaction, temptitle, title); |
2271 submenucount = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "_dw_submenucount")); | 2291 submenucount = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "_dw_submenucount")); |
2272 | 2292 |
2273 if (strlen(temptitle) == 0) | 2293 if (strlen(temptitle) == 0) |
2274 tmphandle = g_menu_item_new_section(NULL, NULL); | 2294 tmphandle = g_menu_item_new_section(NULL, NULL); |
2275 else | 2295 else |
2276 { | 2296 { |
2277 char numbuf[25] = {0}; | 2297 char tempbuf[101] = {0}; |
2278 | 2298 |
2279 if(submenu) | 2299 if(submenu) |
2280 { | 2300 { |
2281 char tempbuf[101] = {0}; | |
2282 GMenuModel *submenumodel; | 2301 GMenuModel *submenumodel; |
2283 | 2302 |
2284 if(GTK_IS_POPOVER_MENU_BAR(submenu)) | 2303 if(GTK_IS_POPOVER_MENU_BAR(submenu)) |
2285 submenumodel = gtk_popover_menu_bar_get_menu_model(GTK_POPOVER_MENU_BAR(submenu)); | 2304 submenumodel = gtk_popover_menu_bar_get_menu_model(GTK_POPOVER_MENU_BAR(submenu)); |
2286 else | 2305 else |
2292 g_object_set_data(G_OBJECT(menu), tempbuf, (gpointer)submenu); | 2311 g_object_set_data(G_OBJECT(menu), tempbuf, (gpointer)submenu); |
2293 g_object_set_data(G_OBJECT(menu), "_dw_submenucount", GINT_TO_POINTER(submenucount)); | 2312 g_object_set_data(G_OBJECT(menu), "_dw_submenucount", GINT_TO_POINTER(submenucount)); |
2294 } | 2313 } |
2295 else | 2314 else |
2296 { | 2315 { |
2297 tmphandle=g_menu_item_new(temptitle, NULL); | 2316 char numbuf[25] = {0}; |
2317 | |
2318 snprintf(tempbuf, 100, "menu.%s", tempaction); | |
2319 action = g_simple_action_new(tempbuf, NULL); | |
2320 g_object_ref(G_OBJECT(action)); | |
2321 tmphandle=g_menu_item_new(temptitle, tempbuf); | |
2298 snprintf(numbuf, 24, "%lu", id); | 2322 snprintf(numbuf, 24, "%lu", id); |
2299 g_object_set_data(G_OBJECT(menu), numbuf, (gpointer)tmphandle); | 2323 g_object_set_data(G_OBJECT(menu), numbuf, (gpointer)tmphandle); |
2324 g_object_set_data(G_OBJECT(menu), "_dw_action", (gpointer)action); | |
2300 } | 2325 } |
2301 } | 2326 } |
2302 | 2327 |
2303 if(end) | 2328 if(end) |
2304 g_menu_append_item(G_MENU(menumodel), tmphandle); | 2329 g_menu_append_item(G_MENU(menumodel), tmphandle); |
2305 else | 2330 else |
2306 g_menu_prepend_item(G_MENU(menumodel), tmphandle); | 2331 g_menu_prepend_item(G_MENU(menumodel), tmphandle); |
2307 | 2332 |
2308 g_object_set_data(G_OBJECT(tmphandle), "_dw_id", GINT_TO_POINTER(id)); | 2333 g_object_set_data(G_OBJECT(tmphandle), "_dw_id", GINT_TO_POINTER(id)); |
2309 | 2334 |
2310 /*if(flags & DW_MIS_DISABLED) | 2335 if(action) |
2311 gtk_widget_set_sensitive(tmphandle, FALSE);*/ | 2336 g_simple_action_set_enabled(action, (flags & DW_MIS_DISABLED) ? FALSE : TRUE); |
2312 return (HWND)tmphandle; | 2337 return (HWND)tmphandle; |
2313 } | 2338 } |
2314 | 2339 |
2315 GtkWidget *_find_submenu_id(GtkWidget *start, const char *name) | 2340 GMenuItem *_dw_find_submenu_id(HMENUI start, const char *name) |
2316 { | 2341 { |
2317 GtkWidget *tmp; | 2342 GMenuItem *tmp; |
2318 int z, submenucount = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(start), "_dw_submenucount")); | 2343 int z, submenucount = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(start), "_dw_submenucount")); |
2319 | 2344 |
2320 if((tmp = g_object_get_data(G_OBJECT(start), name))) | 2345 if((tmp = g_object_get_data(G_OBJECT(start), name))) |
2321 return tmp; | 2346 return tmp; |
2322 | 2347 |
2323 for(z=0;z<submenucount;z++) | 2348 for(z=0;z<submenucount;z++) |
2324 { | 2349 { |
2325 char tempbuf[101] = {0}; | 2350 char tempbuf[101] = {0}; |
2326 GtkWidget *submenu, *menuitem; | 2351 GMenuItem *menuitem; |
2352 HMENUI submenu; | |
2327 | 2353 |
2328 snprintf(tempbuf, 100, "_dw_submenu%d", z); | 2354 snprintf(tempbuf, 100, "_dw_submenu%d", z); |
2329 | 2355 |
2330 if((submenu = g_object_get_data(G_OBJECT(start), tempbuf))) | 2356 if((submenu = g_object_get_data(G_OBJECT(start), tempbuf))) |
2331 { | 2357 { |
2332 if((menuitem = _find_submenu_id(submenu, name))) | 2358 if((menuitem = _dw_find_submenu_id(submenu, name))) |
2333 return menuitem; | 2359 return menuitem; |
2334 } | 2360 } |
2335 } | 2361 } |
2336 return NULL; | 2362 return NULL; |
2337 } | 2363 } |
2344 * check: TRUE for checked FALSE for not checked. | 2370 * check: TRUE for checked FALSE for not checked. |
2345 * deprecated: use dw_menu_item_set_state() | 2371 * deprecated: use dw_menu_item_set_state() |
2346 */ | 2372 */ |
2347 void dw_menu_item_set_check(HMENUI menu, unsigned long id, int check) | 2373 void dw_menu_item_set_check(HMENUI menu, unsigned long id, int check) |
2348 { | 2374 { |
2349 #if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ | 2375 #if 0 |
2350 char numbuf[25] = {0}; | 2376 char numbuf[25] = {0}; |
2351 GtkWidget *tmphandle; | 2377 GMenuItem *tmphandle; |
2352 | 2378 |
2353 if(!menu) | 2379 if(!menu) |
2354 return; | 2380 return; |
2355 | 2381 |
2356 snprintf(numbuf, 24, "%lu", id); | 2382 snprintf(numbuf, 24, "%lu", id); |
2357 tmphandle = _find_submenu_id(menu, numbuf); | 2383 tmphandle = _dw_find_submenu_id(menu, numbuf); |
2358 | 2384 |
2359 if(tmphandle) | 2385 if(tmphandle && G_IS_MENU_ITEM(tmphandle)) |
2360 { | 2386 { |
2361 _dw_ignore_click = 1; | 2387 GSimpleAction *action = g_object_get_data(G_OBJECT(tmphandle), "_dw_action"); |
2388 | |
2362 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(tmphandle)) != check) | 2389 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(tmphandle)) != check) |
2363 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check); | 2390 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check); |
2364 _dw_ignore_click = 0; | |
2365 } | 2391 } |
2366 #endif | 2392 #endif |
2367 } | 2393 } |
2368 | 2394 |
2369 /* | 2395 /* |
2373 * id: Menuitem id. | 2399 * id: Menuitem id. |
2374 * state: TRUE for checked FALSE for not checked. | 2400 * state: TRUE for checked FALSE for not checked. |
2375 */ | 2401 */ |
2376 void dw_menu_item_set_state(HMENUI menu, unsigned long id, unsigned long state) | 2402 void dw_menu_item_set_state(HMENUI menu, unsigned long id, unsigned long state) |
2377 { | 2403 { |
2378 #if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ | |
2379 char numbuf[25] = {0}; | 2404 char numbuf[25] = {0}; |
2380 GtkWidget *tmphandle; | 2405 GMenuItem *tmphandle; |
2381 int check; | |
2382 | 2406 |
2383 if(!menu) | 2407 if(!menu) |
2384 return; | 2408 return; |
2385 | 2409 |
2386 snprintf(numbuf, 24, "%lu", id); | 2410 snprintf(numbuf, 24, "%lu", id); |
2387 tmphandle = _find_submenu_id(menu, numbuf); | 2411 tmphandle = _dw_find_submenu_id(menu, numbuf); |
2388 | 2412 |
2389 if ( (state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED) ) | 2413 if(tmphandle && G_IS_MENU_ITEM(tmphandle)) |
2390 { | 2414 { |
2391 if ( state & DW_MIS_CHECKED ) | 2415 GSimpleAction *action = g_object_get_data(G_OBJECT(tmphandle), "_dw_action"); |
2392 check = 1; | 2416 |
2393 else | 2417 #if 0 |
2394 check = 0; | 2418 if((state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED)) |
2395 | 2419 { |
2396 if (tmphandle) | 2420 int check = 0; |
2397 { | 2421 |
2398 _dw_ignore_click = 1; | 2422 if(state & DW_MIS_CHECKED) |
2423 check = 1; | |
2424 | |
2399 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(tmphandle)) != check) | 2425 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(tmphandle)) != check) |
2400 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check); | 2426 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check); |
2401 _dw_ignore_click = 0; | 2427 } |
2402 } | 2428 #endif |
2403 } | 2429 if((state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED)) |
2404 if ( (state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED) ) | 2430 { |
2405 { | 2431 if(state & DW_MIS_ENABLED) |
2406 if (tmphandle ) | 2432 g_simple_action_set_enabled(action, TRUE); |
2407 { | |
2408 _dw_ignore_click = 1; | |
2409 if ( state & DW_MIS_ENABLED ) | |
2410 gtk_widget_set_sensitive( tmphandle, TRUE ); | |
2411 else | 2433 else |
2412 gtk_widget_set_sensitive( tmphandle, FALSE ); | 2434 g_simple_action_set_enabled(action, FALSE); |
2413 _dw_ignore_click = 0; | 2435 } |
2414 } | 2436 } |
2415 } | |
2416 #endif | |
2417 } | 2437 } |
2418 | 2438 |
2419 /* | 2439 /* |
2420 * Deletes the menu item specified. | 2440 * Deletes the menu item specified. |
2421 * Parameters: | 2441 * Parameters: |
2425 * DW_ERROR_NONE (0) on success or DW_ERROR_UNKNOWN on failure. | 2445 * DW_ERROR_NONE (0) on success or DW_ERROR_UNKNOWN on failure. |
2426 */ | 2446 */ |
2427 int API dw_menu_delete_item(HMENUI menu, unsigned long id) | 2447 int API dw_menu_delete_item(HMENUI menu, unsigned long id) |
2428 { | 2448 { |
2429 int ret = DW_ERROR_UNKNOWN; | 2449 int ret = DW_ERROR_UNKNOWN; |
2430 #if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ | |
2431 char numbuf[25] = {0}; | 2450 char numbuf[25] = {0}; |
2432 GtkWidget *tmphandle; | 2451 GMenuItem *tmphandle; |
2433 | 2452 |
2434 if(!menu) | 2453 if(!menu) |
2435 return ret; | 2454 return ret; |
2436 | 2455 |
2437 snprintf(numbuf, 24, "%lu", id); | 2456 snprintf(numbuf, 24, "%lu", id); |
2438 tmphandle = _find_submenu_id(menu, numbuf); | 2457 tmphandle = _dw_find_submenu_id(menu, numbuf); |
2439 | 2458 |
2440 if(tmphandle) | 2459 if(tmphandle && G_IS_MENU_ITEM(tmphandle)) |
2441 { | 2460 { |
2442 if(GTK_IS_WIDGET(tmphandle)) | 2461 /* g_menu_remove(menu, position); */ |
2443 g_object_unref(G_OBJECT(tmphandle)); | 2462 g_object_unref(G_OBJECT(tmphandle)); |
2444 g_object_set_data(G_OBJECT(menu), numbuf, NULL); | 2463 g_object_set_data(G_OBJECT(menu), numbuf, NULL); |
2445 ret = DW_ERROR_NONE; | 2464 ret = DW_ERROR_NONE; |
2446 } | 2465 } |
2447 #endif | |
2448 return ret; | 2466 return ret; |
2449 } | 2467 } |
2450 | 2468 |
2451 /* | 2469 /* |
2452 * Pops up a context menu at given x and y coordinates. | 2470 * Pops up a context menu at given x and y coordinates. |
2456 * x: X coordinate. | 2474 * x: X coordinate. |
2457 * y: Y coordinate. | 2475 * y: Y coordinate. |
2458 */ | 2476 */ |
2459 void dw_menu_popup(HMENUI *menu, HWND parent, int x, int y) | 2477 void dw_menu_popup(HMENUI *menu, HWND parent, int x, int y) |
2460 { | 2478 { |
2461 if(!menu || !*menu) | 2479 if(menu && *menu && GTK_IS_WIDGET(*menu)) |
2462 return; | 2480 { |
2463 | 2481 GtkWidget *popover = gtk_popover_new(); |
2464 #if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ | 2482 |
2465 popup = parent; | 2483 gtk_popover_set_child(GTK_POPOVER(popover), GTK_WIDGET(*menu)); |
2466 | 2484 gtk_popover_set_offset(GTK_POPOVER(popover), x, y); |
2467 gtk_menu_popup_at_pointer(GTK_MENU(*menu), NULL); | 2485 gtk_popover_set_autohide(GTK_POPOVER(popover), TRUE); |
2468 #endif | 2486 gtk_popover_popup(GTK_POPOVER(popover)); |
2469 *menu = NULL; | 2487 *menu = NULL; |
2488 } | |
2470 } | 2489 } |
2471 | 2490 |
2472 | 2491 |
2473 /* | 2492 /* |
2474 * Returns the current X and Y coordinates of the mouse pointer. | 2493 * Returns the current X and Y coordinates of the mouse pointer. |
9519 return NULL; | 9538 return NULL; |
9520 } | 9539 } |
9521 /* GTK signal name for check buttons is "toggled" not "clicked" */ | 9540 /* GTK signal name for check buttons is "toggled" not "clicked" */ |
9522 else if(GTK_IS_CHECK_BUTTON(object) && strcmp(signal->name, DW_SIGNAL_CLICKED) == 0) | 9541 else if(GTK_IS_CHECK_BUTTON(object) && strcmp(signal->name, DW_SIGNAL_CLICKED) == 0) |
9523 strcpy(signal->gname, "toggled"); | 9542 strcpy(signal->gname, "toggled"); |
9543 /* For menu items, get the G(Simple)Action and the signal is "activate" */ | |
9544 else if(G_IS_MENU_ITEM(object) && strcmp(signal->name, DW_SIGNAL_CLICKED) == 0) | |
9545 { | |
9546 GSimpleAction *action = G_SIMPLE_ACTION(g_object_get_data(object, "_dw_action")); | |
9547 | |
9548 if(action) | |
9549 { | |
9550 int cid, sigid = _dw_set_signal_handler(G_OBJECT(action), (HWND)object, sigfunc, data, (gpointer)_dw_menu_handler, discfunc); | |
9551 | |
9552 params[0] = DW_INT_TO_POINTER(sigid); | |
9553 params[2] = DW_POINTER(object); | |
9554 cid = g_signal_connect_data(G_OBJECT(action), "activate", G_CALLBACK(_dw_menu_handler), params, _dw_signal_disconnect, 0); | |
9555 _dw_set_signal_handler_id(object, sigid, cid); | |
9556 } | |
9557 return NULL; | |
9558 } | |
9524 return object; | 9559 return object; |
9525 } | 9560 } |
9526 | 9561 |
9527 GObject *_dw_mouse_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data) | 9562 GObject *_dw_mouse_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data) |
9528 { | 9563 { |