Mercurial > dwindows
comparison gtk/dw.c @ 54:c4e1139d9872
Added new tree functions, and fixed a memory leak as well as use of
invalid memory when a button destroys itself.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sat, 17 Nov 2001 17:40:16 +0000 |
parents | 0804483f6320 |
children | b6948eac375a |
comparison
equal
deleted
inserted
replaced
53:8add9a616d0e | 54:c4e1139d9872 |
---|---|
88 void _container_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data); | 88 void _container_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data); |
89 void _item_select_event(GtkWidget *widget, GtkWidget *child, gpointer data); | 89 void _item_select_event(GtkWidget *widget, GtkWidget *child, gpointer data); |
90 void _expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data); | 90 void _expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data); |
91 void _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data); | 91 void _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data); |
92 void _tree_select_event(GtkTree *tree, GtkWidget *child, gpointer data); | 92 void _tree_select_event(GtkTree *tree, GtkWidget *child, gpointer data); |
93 void _tree_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data); | |
93 | 94 |
94 void msleep(long period); | 95 void msleep(long period); |
95 | 96 |
96 typedef struct | 97 typedef struct |
97 { | 98 { |
106 void *func; | 107 void *func; |
107 gpointer data; | 108 gpointer data; |
108 | 109 |
109 } SignalHandler; | 110 } SignalHandler; |
110 | 111 |
111 #define SIGNALMAX 14 | 112 #define SIGNALMAX 15 |
112 | 113 |
113 /* A list of signal forwarders, to account for paramater differences. */ | 114 /* A list of signal forwarders, to account for paramater differences. */ |
114 SignalList SignalTranslate[SIGNALMAX] = { | 115 SignalList SignalTranslate[SIGNALMAX] = { |
115 { _configure_event, "configure_event" }, | 116 { _configure_event, "configure_event" }, |
116 { _key_press_event, "key_press_event" }, | 117 { _key_press_event, "key_press_event" }, |
121 { _expose_event, "expose_event" }, | 122 { _expose_event, "expose_event" }, |
122 { _activate_event, "activate" }, | 123 { _activate_event, "activate" }, |
123 { _generic_event, "clicked" }, | 124 { _generic_event, "clicked" }, |
124 { _container_select_event, "container-select" }, | 125 { _container_select_event, "container-select" }, |
125 { _container_context_event, "container-context" }, | 126 { _container_context_event, "container-context" }, |
127 { _tree_context_event, "tree-context" }, | |
126 { _item_select_event, "item-select" }, | 128 { _item_select_event, "item-select" }, |
127 { _tree_select_event, "tree-select" }, | 129 { _tree_select_event, "tree-select" }, |
128 { _set_focus_event, "set-focus" } | 130 { _set_focus_event, "set-focus" } |
129 }; | 131 }; |
130 | 132 |
233 | 235 |
234 if(work) | 236 if(work) |
235 { | 237 { |
236 int (*closefunc)(HWND, void *) = work->func; | 238 int (*closefunc)(HWND, void *) = work->func; |
237 | 239 |
238 closefunc(widget, data); | 240 closefunc(widget, work->data); |
239 } | 241 } |
240 return TRUE; | 242 return TRUE; |
241 } | 243 } |
242 | 244 |
243 gint _key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data) | 245 gint _key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data) |
365 contextfunc(work->window, text, event->x, event->y, work->data); | 367 contextfunc(work->window, text, event->x, event->y, work->data); |
366 } | 368 } |
367 } | 369 } |
368 } | 370 } |
369 | 371 |
372 void _tree_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data) | |
373 { | |
374 SignalHandler *work = (SignalHandler *)data; | |
375 | |
376 if(work) | |
377 { | |
378 if(event->button == 3) | |
379 { | |
380 void (*contextfunc)(HWND, char *, int, int, void *, void *) = work->func; | |
381 char *text = (char *)gtk_object_get_data(GTK_OBJECT(widget), "text"); | |
382 void *itemdata = (void *)gtk_object_get_data(GTK_OBJECT(widget), "itemdata"); | |
383 | |
384 if(widget != work->window) | |
385 { | |
386 GtkWidget *tree = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(work->window)); | |
387 | |
388 if(tree && GTK_IS_TREE(tree)) | |
389 { | |
390 GtkWidget *lastselect = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(tree), "lastselect"); | |
391 | |
392 if(lastselect && GTK_IS_TREE_ITEM(lastselect)) | |
393 { | |
394 text = (char *)gtk_object_get_data(GTK_OBJECT(lastselect), "text"); | |
395 itemdata = (void *)gtk_object_get_data(GTK_OBJECT(lastselect), "itemdata"); | |
396 } | |
397 } | |
398 } | |
399 | |
400 contextfunc(work->window, text, event->x, event->y, work->data, itemdata); | |
401 } | |
402 } | |
403 } | |
404 | |
370 void _tree_select_event(GtkTree *tree, GtkWidget *child, gpointer data) | 405 void _tree_select_event(GtkTree *tree, GtkWidget *child, gpointer data) |
371 { | 406 { |
372 SignalHandler *work = (SignalHandler *)data; | 407 SignalHandler *work = (SignalHandler *)data; |
373 | 408 |
374 if(work) | 409 if(work) |
375 { | 410 { |
376 void (*treeselectfunc)(HWND, HWND, char *, void *) = work->func; | 411 void (*treeselectfunc)(HWND, HWND, char *, void *, void *) = work->func; |
377 char *text = (char *)gtk_object_get_data(GTK_OBJECT(child), "text"); | 412 char *text = (char *)gtk_object_get_data(GTK_OBJECT(child), "text"); |
378 | 413 void *itemdata = (char *)gtk_object_get_data(GTK_OBJECT(child), "itemdata"); |
379 treeselectfunc(work->window, child, text, work->data); | 414 GtkWidget *treeroot = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(child), "tree"); |
415 | |
416 if(treeroot && GTK_IS_TREE(treeroot)) | |
417 gtk_object_set_data(GTK_OBJECT(treeroot), "lastselect", (gpointer)child); | |
418 treeselectfunc(work->window, child, text, itemdata, work->data); | |
380 } | 419 } |
381 } | 420 } |
382 | 421 |
383 void _container_select_event(GtkWidget *widget, GdkEventButton *event, gpointer data) | 422 void _container_select_event(GtkWidget *widget, GdkEventButton *event, gpointer data) |
384 { | 423 { |
970 DW_MUTEX_LOCK; | 1009 DW_MUTEX_LOCK; |
971 if(GTK_IS_WIDGET(handle)) | 1010 if(GTK_IS_WIDGET(handle)) |
972 gtk_widget_destroy(handle); | 1011 gtk_widget_destroy(handle); |
973 DW_MUTEX_UNLOCK; | 1012 DW_MUTEX_UNLOCK; |
974 return 0; | 1013 return 0; |
1014 } | |
1015 | |
1016 /* Causes entire window to be invalidated and redrawn. | |
1017 * Parameters: | |
1018 * handle: Toplevel window handle to be redrawn. | |
1019 */ | |
1020 void dw_window_redraw(HWND handle) | |
1021 { | |
975 } | 1022 } |
976 | 1023 |
977 /* | 1024 /* |
978 * Changes a window's parent to newparent. | 1025 * Changes a window's parent to newparent. |
979 * Parameters: | 1026 * Parameters: |
2690 * Parameters: | 2737 * Parameters: |
2691 * handle: Handle to the tree to be inserted. | 2738 * handle: Handle to the tree to be inserted. |
2692 * title: The text title of the entry. | 2739 * title: The text title of the entry. |
2693 * icon: Handle to coresponding icon. | 2740 * icon: Handle to coresponding icon. |
2694 * parent: Parent handle or 0 if root. | 2741 * parent: Parent handle or 0 if root. |
2695 */ | 2742 * itemdata: Item specific data. |
2696 HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent) | 2743 */ |
2744 HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent, void *itemdata) | |
2697 { | 2745 { |
2698 GtkWidget *item, *tree, *subtree, *label, *hbox, *pixmap; | 2746 GtkWidget *item, *tree, *subtree, *label, *hbox, *pixmap; |
2699 GdkPixmap *gdkpix; | 2747 GdkPixmap *gdkpix; |
2700 GdkBitmap *gdkbmp; | 2748 GdkBitmap *gdkbmp; |
2701 int _locked_by_me = FALSE; | 2749 int _locked_by_me = FALSE; |
2708 return NULL; | 2756 return NULL; |
2709 } | 2757 } |
2710 item = gtk_tree_item_new(); | 2758 item = gtk_tree_item_new(); |
2711 label = gtk_label_new(title); | 2759 label = gtk_label_new(title); |
2712 gtk_object_set_data(GTK_OBJECT(item), "text", (gpointer)strdup(title)); | 2760 gtk_object_set_data(GTK_OBJECT(item), "text", (gpointer)strdup(title)); |
2761 gtk_object_set_data(GTK_OBJECT(item), "itemdata", (gpointer)itemdata); | |
2762 gtk_object_set_data(GTK_OBJECT(item), "tree", (gpointer)tree); | |
2713 hbox = gtk_hbox_new(FALSE, 2); | 2763 hbox = gtk_hbox_new(FALSE, 2); |
2764 gtk_object_set_data(GTK_OBJECT(item), "hbox", (gpointer)hbox); | |
2714 gdkpix = _find_pixmap(&gdkbmp, icon, hbox); | 2765 gdkpix = _find_pixmap(&gdkbmp, icon, hbox); |
2715 pixmap = gtk_pixmap_new(gdkpix, gdkbmp); | 2766 pixmap = gtk_pixmap_new(gdkpix, gdkbmp); |
2716 gtk_container_add(GTK_CONTAINER(item), hbox); | 2767 gtk_container_add(GTK_CONTAINER(item), hbox); |
2717 gtk_box_pack_start(GTK_BOX(hbox), pixmap, FALSE, TRUE, 0); | 2768 gtk_box_pack_start(GTK_BOX(hbox), pixmap, FALSE, TRUE, 0); |
2718 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0); | 2769 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0); |
2731 subtree = gtk_tree_new(); | 2782 subtree = gtk_tree_new(); |
2732 | 2783 |
2733 if(thisfunc && work) | 2784 if(thisfunc && work) |
2734 gtk_signal_connect(GTK_OBJECT(subtree), "select-child", GTK_SIGNAL_FUNC(thisfunc), work); | 2785 gtk_signal_connect(GTK_OBJECT(subtree), "select-child", GTK_SIGNAL_FUNC(thisfunc), work); |
2735 | 2786 |
2787 thisfunc = (void *)gtk_object_get_data(GTK_OBJECT(tree), "container-context-func"); | |
2788 work = (void *)gtk_object_get_data(GTK_OBJECT(tree), "container-context-data"); | |
2789 | |
2790 if(thisfunc && work) | |
2791 gtk_signal_connect(GTK_OBJECT(subtree), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), work); | |
2792 | |
2736 gtk_object_set_user_data(GTK_OBJECT(parent), subtree); | 2793 gtk_object_set_user_data(GTK_OBJECT(parent), subtree); |
2737 gtk_tree_set_selection_mode(GTK_TREE(subtree), GTK_SELECTION_SINGLE); | 2794 gtk_tree_set_selection_mode(GTK_TREE(subtree), GTK_SELECTION_SINGLE); |
2738 gtk_tree_set_view_mode(GTK_TREE(subtree), GTK_TREE_VIEW_ITEM); | 2795 gtk_tree_set_view_mode(GTK_TREE(subtree), GTK_TREE_VIEW_ITEM); |
2739 gtk_tree_item_set_subtree(GTK_TREE_ITEM(parent), subtree); | 2796 gtk_tree_item_set_subtree(GTK_TREE_ITEM(parent), subtree); |
2797 gtk_tree_item_collapse(GTK_TREE_ITEM(parent)); | |
2740 gtk_widget_show(subtree); | 2798 gtk_widget_show(subtree); |
2799 gtk_tree_item_expand(GTK_TREE_ITEM(parent)); | |
2800 gtk_tree_item_collapse(GTK_TREE_ITEM(parent)); | |
2741 } | 2801 } |
2742 gtk_tree_append(GTK_TREE(subtree), item); | 2802 gtk_tree_append(GTK_TREE(subtree), item); |
2743 } | 2803 } |
2744 else | 2804 else |
2745 gtk_tree_append(GTK_TREE(tree), item); | 2805 gtk_tree_append(GTK_TREE(tree), item); |
2806 gtk_tree_item_expand(GTK_TREE_ITEM(item)); | |
2807 gtk_tree_item_collapse(GTK_TREE_ITEM(item)); | |
2746 gtk_widget_show(item); | 2808 gtk_widget_show(item); |
2747 DW_MUTEX_UNLOCK; | 2809 DW_MUTEX_UNLOCK; |
2748 return item; | 2810 return item; |
2811 } | |
2812 | |
2813 /* | |
2814 * Sets the text and icon of an item in a tree window (widget). | |
2815 * Parameters: | |
2816 * handle: Handle to the tree containing the item. | |
2817 * item: Handle of the item to be modified. | |
2818 * title: The text title of the entry. | |
2819 * icon: Handle to coresponding icon. | |
2820 */ | |
2821 void dw_tree_set(HWND handle, HWND item, char *title, unsigned long icon) | |
2822 { | |
2823 GtkWidget *label, *hbox, *pixmap; | |
2824 GdkPixmap *gdkpix; | |
2825 GdkBitmap *gdkbmp; | |
2826 char *oldtext; | |
2827 int _locked_by_me = FALSE; | |
2828 | |
2829 DW_MUTEX_LOCK; | |
2830 oldtext = (char *)gtk_object_get_data(GTK_OBJECT(item), "text"); | |
2831 if(oldtext) | |
2832 free(oldtext); | |
2833 label = gtk_label_new(title); | |
2834 gtk_object_set_data(GTK_OBJECT(item), "text", (gpointer)strdup(title)); | |
2835 hbox = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(item), "hbox"); | |
2836 gtk_widget_destroy(hbox); | |
2837 hbox = gtk_hbox_new(FALSE, 2); | |
2838 gtk_object_set_data(GTK_OBJECT(item), "hbox", (gpointer)hbox); | |
2839 gdkpix = _find_pixmap(&gdkbmp, icon, hbox); | |
2840 pixmap = gtk_pixmap_new(gdkpix, gdkbmp); | |
2841 gtk_container_add(GTK_CONTAINER(item), hbox); | |
2842 gtk_box_pack_start(GTK_BOX(hbox), pixmap, FALSE, TRUE, 0); | |
2843 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0); | |
2844 gtk_widget_show(label); | |
2845 gtk_widget_show(pixmap); | |
2846 gtk_widget_show(hbox); | |
2847 DW_MUTEX_UNLOCK; | |
2848 } | |
2849 | |
2850 /* | |
2851 * Sets the item data of a tree item. | |
2852 * Parameters: | |
2853 * handle: Handle to the tree containing the item. | |
2854 * item: Handle of the item to be modified. | |
2855 * itemdata: User defined data to be associated with item. | |
2856 */ | |
2857 void dw_tree_set_data(HWND handle, HWND item, void *itemdata) | |
2858 { | |
2859 int _locked_by_me = FALSE; | |
2860 | |
2861 DW_MUTEX_LOCK; | |
2862 gtk_object_set_data(GTK_OBJECT(item), "itemdata", (gpointer)itemdata); | |
2863 DW_MUTEX_UNLOCK; | |
2864 } | |
2865 | |
2866 /* | |
2867 * Sets this item as the active selection. | |
2868 * Parameters: | |
2869 * handle: Handle to the tree window (widget) to be selected. | |
2870 * item: Handle to the item to be selected. | |
2871 */ | |
2872 void dw_tree_item_select(HWND handle, HWND item) | |
2873 { | |
2874 GtkWidget *lastselect; | |
2875 int _locked_by_me = FALSE; | |
2876 | |
2877 DW_MUTEX_LOCK; | |
2878 lastselect = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "lastselect"); | |
2879 if(lastselect && GTK_IS_TREE_ITEM(lastselect)) | |
2880 gtk_tree_item_deselect(GTK_TREE_ITEM(lastselect)); | |
2881 gtk_tree_item_select(GTK_TREE_ITEM(item)); | |
2882 gtk_object_set_data(GTK_OBJECT(handle), "lastselect", (gpointer)item); | |
2883 DW_MUTEX_UNLOCK; | |
2749 } | 2884 } |
2750 | 2885 |
2751 /* | 2886 /* |
2752 * Removes all nodes from a tree. | 2887 * Removes all nodes from a tree. |
2753 * Parameters: | 2888 * Parameters: |
2768 gtk_tree_clear_items(GTK_TREE(tree), 0, 1000000); | 2903 gtk_tree_clear_items(GTK_TREE(tree), 0, 1000000); |
2769 DW_MUTEX_UNLOCK; | 2904 DW_MUTEX_UNLOCK; |
2770 } | 2905 } |
2771 | 2906 |
2772 /* | 2907 /* |
2908 * Expands a node on a tree. | |
2909 * Parameters: | |
2910 * handle: Handle to the tree window (widget). | |
2911 * item: Handle to node to be expanded. | |
2912 */ | |
2913 void dw_tree_expand(HWND handle, HWND item) | |
2914 { | |
2915 int _locked_by_me = FALSE; | |
2916 | |
2917 DW_MUTEX_LOCK; | |
2918 if(GTK_IS_TREE_ITEM(item)) | |
2919 gtk_tree_item_expand(GTK_TREE_ITEM(item)); | |
2920 DW_MUTEX_UNLOCK; | |
2921 } | |
2922 | |
2923 /* | |
2924 * Collapses a node on a tree. | |
2925 * Parameters: | |
2926 * handle: Handle to the tree window (widget). | |
2927 * item: Handle to node to be collapsed. | |
2928 */ | |
2929 void dw_tree_collapse(HWND handle, HWND item) | |
2930 { | |
2931 int _locked_by_me = FALSE; | |
2932 | |
2933 DW_MUTEX_LOCK; | |
2934 if(GTK_IS_TREE_ITEM(item)) | |
2935 gtk_tree_item_collapse(GTK_TREE_ITEM(item)); | |
2936 DW_MUTEX_UNLOCK; | |
2937 } | |
2938 | |
2939 /* | |
2773 * Removes a node from a tree. | 2940 * Removes a node from a tree. |
2774 * Parameters: | 2941 * Parameters: |
2775 * handle: Handle to the window (widget) to be cleared. | 2942 * handle: Handle to the window (widget) to be cleared. |
2776 * item: Handle to node to be deleted. | 2943 * item: Handle to node to be deleted. |
2777 */ | 2944 */ |
2778 void dw_tree_delete(HWND handle, HWND item) | 2945 void dw_tree_delete(HWND handle, HWND item) |
2779 { | 2946 { |
2780 GtkWidget *tree; | 2947 GtkWidget *tree, *lastselect; |
2781 int _locked_by_me = FALSE; | 2948 int _locked_by_me = FALSE; |
2782 | 2949 |
2783 DW_MUTEX_LOCK; | 2950 DW_MUTEX_LOCK; |
2784 tree = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle)); | 2951 tree = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle)); |
2785 if(!tree || !GTK_IS_TREE(tree)) | 2952 if(!tree || !GTK_IS_TREE(tree)) |
2786 { | 2953 { |
2787 DW_MUTEX_UNLOCK; | 2954 DW_MUTEX_UNLOCK; |
2788 return; | 2955 return; |
2789 } | 2956 } |
2957 | |
2958 lastselect = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "lastselect"); | |
2959 if(lastselect == item) | |
2960 gtk_object_set_data(GTK_OBJECT(handle), "lastselect", NULL); | |
2961 | |
2790 gtk_tree_remove_item(GTK_TREE(tree), item); | 2962 gtk_tree_remove_item(GTK_TREE(tree), item); |
2963 gtk_widget_destroy(item); | |
2791 DW_MUTEX_UNLOCK; | 2964 DW_MUTEX_UNLOCK; |
2792 } | 2965 } |
2793 | 2966 |
2794 int _dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator, int extra) | 2967 int _dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator, int extra) |
2795 { | 2968 { |
5198 else if(GTK_IS_CLIST(thiswindow) && strcmp(signame, "container-context") == 0) | 5371 else if(GTK_IS_CLIST(thiswindow) && strcmp(signame, "container-context") == 0) |
5199 { | 5372 { |
5200 thisname = "button_press_event"; | 5373 thisname = "button_press_event"; |
5201 thisfunc = _findsigfunc("container-context"); | 5374 thisfunc = _findsigfunc("container-context"); |
5202 } | 5375 } |
5376 else if(GTK_IS_TREE(thiswindow) && strcmp(signame, "container-context") == 0) | |
5377 { | |
5378 thisfunc = _findsigfunc("tree-context"); | |
5379 | |
5380 work->window = window; | |
5381 work->data = data; | |
5382 work->func = sigfunc; | |
5383 | |
5384 gtk_object_set_data(GTK_OBJECT(thiswindow), "container-context-func", (gpointer)thisfunc); | |
5385 gtk_object_set_data(GTK_OBJECT(thiswindow), "container-context-data", (gpointer)work); | |
5386 gtk_signal_connect(GTK_OBJECT(thiswindow), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), work); | |
5387 gtk_signal_connect(GTK_OBJECT(window), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), work); | |
5388 DW_MUTEX_UNLOCK; | |
5389 return; | |
5390 } | |
5203 else if(GTK_IS_CLIST(thiswindow) && strcmp(signame, "container-select") == 0) | 5391 else if(GTK_IS_CLIST(thiswindow) && strcmp(signame, "container-select") == 0) |
5204 { | 5392 { |
5205 thisname = "button_press_event"; | 5393 thisname = "button_press_event"; |
5206 thisfunc = _findsigfunc("container-select"); | 5394 thisfunc = _findsigfunc("container-select"); |
5207 } | 5395 } |