comparison gtk4/dw.c @ 2317:a2020f907a6c

GTK4: Implement checkable menu items.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 16 Feb 2021 06:39:37 +0000
parents 1f85311baa65
children 5951752fa7af
comparison
equal deleted inserted replaced
2316:1f85311baa65 2317:a2020f907a6c
382 382
383 pthread_key_t _dw_fg_color_key; 383 pthread_key_t _dw_fg_color_key;
384 pthread_key_t _dw_bg_color_key; 384 pthread_key_t _dw_bg_color_key;
385 pthread_key_t _dw_event_key; 385 pthread_key_t _dw_event_key;
386 386
387 static int _dw_ignore_expand = 0;
388 static pthread_t _dw_thread = (pthread_t)-1; 387 static pthread_t _dw_thread = (pthread_t)-1;
389 388
390 #define _DW_TREE_TYPE_CONTAINER 1 389 #define _DW_TREE_TYPE_CONTAINER 1
391 #define _DW_TREE_TYPE_TREE 2 390 #define _DW_TREE_TYPE_TREE 2
392 #define _DW_TREE_TYPE_LISTBOX 3 391 #define _DW_TREE_TYPE_LISTBOX 3
1053 static gint _dw_tree_expand_event(GtkTreeView *widget, GtkTreeIter *iter, GtkTreePath *path, gpointer data) 1052 static gint _dw_tree_expand_event(GtkTreeView *widget, GtkTreeIter *iter, GtkTreePath *path, gpointer data)
1054 { 1053 {
1055 SignalHandler work = _dw_get_signal_handler(data); 1054 SignalHandler work = _dw_get_signal_handler(data);
1056 int retval = FALSE; 1055 int retval = FALSE;
1057 1056
1058 if(!_dw_ignore_expand && work.window) 1057 if(work.window)
1059 { 1058 {
1060 int (*treeexpandfunc)(HWND, HTREEITEM, void *) = work.func; 1059 int (*treeexpandfunc)(HWND, HTREEITEM, void *) = work.func;
1061 retval = treeexpandfunc(work.window, (HTREEITEM)iter, work.data); 1060 retval = treeexpandfunc(work.window, (HTREEITEM)iter, work.data);
1062 } 1061 }
1063 return retval; 1062 return retval;
1299 1298
1300 /* Handle menu click callbacks */ 1299 /* Handle menu click callbacks */
1301 static void _dw_menu_handler(GSimpleAction *action, GVariant *param, gpointer data) 1300 static void _dw_menu_handler(GSimpleAction *action, GVariant *param, gpointer data)
1302 { 1301 {
1303 SignalHandler work = _dw_get_signal_handler(data); 1302 SignalHandler work = _dw_get_signal_handler(data);
1303 GVariant *action_state = g_action_get_state(G_ACTION(action));
1304
1305 /* Handle toggling checkable menu items automatically, before the callback */
1306 if(action_state)
1307 {
1308 gboolean active = g_variant_get_boolean(action_state);
1309 GVariant *new_state = g_variant_new_boolean(!active);
1310 g_simple_action_set_state(action, new_state);
1311 }
1304 1312
1305 if(work.window) 1313 if(work.window)
1306 { 1314 {
1307 int (*genericfunc)(HWND, void *) = work.func; 1315 int (*genericfunc)(HWND, void *) = work.func;
1308 1316
2735 int menugroup = DW_POINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "_dw_menugroup")); 2743 int menugroup = DW_POINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "_dw_menugroup"));
2736 char *actionname; 2744 char *actionname;
2737 2745
2738 snprintf(tempbuf, 100, "menu%d.action%lu", menugroup, id); 2746 snprintf(tempbuf, 100, "menu%d.action%lu", menugroup, id);
2739 actionname = strchr(tempbuf, '.'); 2747 actionname = strchr(tempbuf, '.');
2740 action = g_simple_action_new(&actionname[1], NULL); 2748 if(check)
2749 action = g_simple_action_new_stateful(&actionname[1], NULL, g_variant_new_boolean (FALSE));
2750 else
2751 action = g_simple_action_new(&actionname[1], NULL);
2741 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(action)); 2752 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(action));
2742 tmphandle=(HWND)g_menu_item_new(temptitle, tempbuf); 2753 tmphandle=(HWND)g_menu_item_new(temptitle, tempbuf);
2743 snprintf(numbuf, 24, "%lu", id); 2754 snprintf(numbuf, 24, "%lu", id);
2744 g_object_set_data(G_OBJECT(menu), numbuf, (gpointer)tmphandle); 2755 g_object_set_data(G_OBJECT(menu), numbuf, (gpointer)tmphandle);
2745 g_object_set_data(G_OBJECT(tmphandle), "_dw_action", (gpointer)action); 2756 g_object_set_data(G_OBJECT(tmphandle), "_dw_action", (gpointer)action);
2790 * menu: The handle the the existing menu. 2801 * menu: The handle the the existing menu.
2791 * id: Menuitem id. 2802 * id: Menuitem id.
2792 * check: TRUE for checked FALSE for not checked. 2803 * check: TRUE for checked FALSE for not checked.
2793 * deprecated: use dw_menu_item_set_state() 2804 * deprecated: use dw_menu_item_set_state()
2794 */ 2805 */
2795 void dw_menu_item_set_check(HMENUI menu, unsigned long id, int check) 2806 DW_FUNCTION_DEFINITION(dw_menu_item_set_check, void, HMENUI menu, ULONG cid, int check)
2796 { 2807 DW_FUNCTION_ADD_PARAM3(menu, cid, check)
2797 #if 0 2808 DW_FUNCTION_NO_RETURN(dw_menu_item_set_check)
2798 char numbuf[25] = {0}; 2809 DW_FUNCTION_RESTORE_PARAM3(menu, HMENUI, cid, ULONG, check, int)
2799 GMenuItem *tmphandle; 2810 {
2800 2811 if(menu)
2801 if(!menu) 2812 {
2802 return; 2813 char numbuf[25] = {0};
2803 2814 GMenuItem *tmphandle;
2804 snprintf(numbuf, 24, "%lu", id); 2815
2805 tmphandle = _dw_find_submenu_id(menu, numbuf); 2816 snprintf(numbuf, 24, "%lu", cid);
2806 2817 tmphandle = _dw_find_submenu_id(menu, numbuf);
2807 if(tmphandle && G_IS_MENU_ITEM(tmphandle)) 2818
2808 { 2819 if(tmphandle && G_IS_MENU_ITEM(tmphandle))
2809 GSimpleAction *action = g_object_get_data(G_OBJECT(tmphandle), "_dw_action"); 2820 {
2810 2821 GSimpleAction *action = g_object_get_data(G_OBJECT(tmphandle), "_dw_action");
2811 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(tmphandle)) != check) 2822
2812 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check); 2823 if(action)
2813 } 2824 {
2814 #endif 2825 GVariant *action_state = g_action_get_state(G_ACTION(action));
2826 gboolean thischeck = check;
2827
2828 if(!action_state || (g_variant_get_boolean(action_state) != thischeck))
2829 {
2830 GVariant *new_state = g_variant_new_boolean(thischeck);
2831 g_simple_action_set_state(action, new_state);
2832 }
2833 }
2834 }
2835 }
2836 DW_FUNCTION_RETURN_NOTHING;
2815 } 2837 }
2816 2838
2817 /* 2839 /*
2818 * Sets the state of a menu item. 2840 * Sets the state of a menu item.
2819 * Parameters: 2841 * Parameters:
2824 DW_FUNCTION_DEFINITION(dw_menu_item_set_state, void, HMENUI menu, ULONG cid, ULONG state) 2846 DW_FUNCTION_DEFINITION(dw_menu_item_set_state, void, HMENUI menu, ULONG cid, ULONG state)
2825 DW_FUNCTION_ADD_PARAM3(menu, cid, state) 2847 DW_FUNCTION_ADD_PARAM3(menu, cid, state)
2826 DW_FUNCTION_NO_RETURN(dw_menu_item_set_state) 2848 DW_FUNCTION_NO_RETURN(dw_menu_item_set_state)
2827 DW_FUNCTION_RESTORE_PARAM3(menu, HMENUI, cid, ULONG, state, ULONG) 2849 DW_FUNCTION_RESTORE_PARAM3(menu, HMENUI, cid, ULONG, state, ULONG)
2828 { 2850 {
2829 char numbuf[25] = {0};
2830 GMenuItem *tmphandle;
2831
2832 if(menu) 2851 if(menu)
2833 { 2852 {
2853 char numbuf[25] = {0};
2854 GMenuItem *tmphandle;
2855
2834 snprintf(numbuf, 24, "%lu", cid); 2856 snprintf(numbuf, 24, "%lu", cid);
2835 tmphandle = _dw_find_submenu_id(menu, numbuf); 2857 tmphandle = _dw_find_submenu_id(menu, numbuf);
2836 2858
2837 if(tmphandle && G_IS_MENU_ITEM(tmphandle)) 2859 if(tmphandle && G_IS_MENU_ITEM(tmphandle))
2838 { 2860 {
2839 GSimpleAction *action = g_object_get_data(G_OBJECT(tmphandle), "_dw_action"); 2861 GSimpleAction *action = g_object_get_data(G_OBJECT(tmphandle), "_dw_action");
2840 2862
2841 #if 0 2863 if(action)
2842 if((state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED))
2843 { 2864 {
2844 int check = 0; 2865 if((state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED))
2845 2866 {
2846 if(state & DW_MIS_CHECKED) 2867 GVariant *action_state = g_action_get_state(G_ACTION(action));
2847 check = 1; 2868 gboolean check = false;
2848 2869
2849 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(tmphandle)) != check) 2870 if(state & DW_MIS_CHECKED)
2850 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check); 2871 check = true;
2851 } 2872
2852 #endif 2873 if(!action_state || (g_variant_get_boolean(action_state) != check))
2853 if((state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED)) 2874 {
2854 { 2875 GVariant *new_state = g_variant_new_boolean(check);
2855 if(state & DW_MIS_ENABLED) 2876 g_simple_action_set_state(action, new_state);
2856 g_simple_action_set_enabled(action, TRUE); 2877 }
2857 else 2878 }
2858 g_simple_action_set_enabled(action, FALSE); 2879 if((state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED))
2880 {
2881 if(state & DW_MIS_ENABLED)
2882 g_simple_action_set_enabled(action, TRUE);
2883 else
2884 g_simple_action_set_enabled(action, FALSE);
2885 }
2859 } 2886 }
2860 } 2887 }
2861 } 2888 }
2862 DW_FUNCTION_RETURN_NOTHING; 2889 DW_FUNCTION_RETURN_NOTHING;
2863 } 2890 }
8551 gtk_label_set_xalign(GTK_LABEL(handle2), x); 8578 gtk_label_set_xalign(GTK_LABEL(handle2), x);
8552 gtk_label_set_yalign(GTK_LABEL(handle2), y); 8579 gtk_label_set_yalign(GTK_LABEL(handle2), y);
8553 if(style & DW_DT_WORDBREAK) 8580 if(style & DW_DT_WORDBREAK)
8554 gtk_label_set_wrap(GTK_LABEL(handle), TRUE); 8581 gtk_label_set_wrap(GTK_LABEL(handle), TRUE);
8555 } 8582 }
8556 if(G_IS_MENU_ITEM(handle2) && (mask & (DW_MIS_ENABLED | DW_MIS_DISABLED))) 8583 if(G_IS_MENU_ITEM(handle2))
8557 { 8584 {
8558 GSimpleAction *action = g_object_get_data(G_OBJECT(handle2), "_dw_action"); 8585 GSimpleAction *action = g_object_get_data(G_OBJECT(handle2), "_dw_action");
8559 8586
8560 if((style & DW_MIS_ENABLED) || (style & DW_MIS_DISABLED)) 8587 if(action)
8561 { 8588 {
8562 if(style & DW_MIS_ENABLED) 8589 if(mask & (DW_MIS_ENABLED | DW_MIS_DISABLED))
8563 g_simple_action_set_enabled(action, TRUE); 8590 {
8564 else 8591 if((style & DW_MIS_ENABLED) || (style & DW_MIS_DISABLED))
8565 g_simple_action_set_enabled(action, FALSE); 8592 {
8566 } 8593 if(style & DW_MIS_ENABLED)
8567 } 8594 g_simple_action_set_enabled(action, TRUE);
8568 /* TODO: Convert to GMenuModel */ 8595 else
8569 #if GTK3 8596 g_simple_action_set_enabled(action, FALSE);
8570 if(GTK_IS_CHECK_MENU_ITEM(handle2) && (mask & (DW_MIS_CHECKED | DW_MIS_UNCHECKED)) 8597 }
8571 { 8598 }
8572 int check = 0; 8599 if(mask & (DW_MIS_CHECKED | DW_MIS_UNCHECKED))
8573 8600 {
8574 if ( style & DW_MIS_CHECKED ) 8601 GVariant *action_state = g_action_get_state(G_ACTION(action));
8575 check = 1; 8602 gboolean check = false;
8576 8603
8577 _dw_ignore_click = 1; 8604 if(style & DW_MIS_CHECKED)
8578 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(handle2)) != check) 8605 check = true;
8579 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(handle2), check); 8606
8580 _dw_ignore_click = 0; 8607 if(!action_state || (g_variant_get_boolean(action_state) != check))
8581 } 8608 {
8582 #endif 8609 GVariant *new_state = g_variant_new_boolean(check);
8610 g_simple_action_set_state(action, new_state);
8611 }
8612 }
8613 }
8614 }
8583 DW_FUNCTION_RETURN_NOTHING; 8615 DW_FUNCTION_RETURN_NOTHING;
8584 } 8616 }
8585 8617
8586 /* 8618 /*
8587 * Adds a new page to specified notebook. 8619 * Adds a new page to specified notebook.