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 }