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