1 #define __SPW_UTILITIES_C__
3 /*
4 * Inkscape Widget Utilities
5 *
6 * Authors:
7 * Bryce W. Harrington <brycehar@bryceharrington.com>
8 * bulia byak <buliabyak@users.sf.net>
9 *
10 * Copyright (C) 2003 Bryce W. Harrington
11 *
12 * Released under GNU GPL, read the file 'COPYING' for more information
13 */
15 #ifdef HAVE_CONFIG_H
16 # include "config.h"
17 #endif
20 #include <gtk/gtk.h>
22 #include "selection.h"
24 #include "helper/unit-menu.h"
26 /**
27 * Creates a label widget with the given text, at the given col, row
28 * position in the table.
29 */
30 GtkWidget *
31 spw_label(GtkWidget * table, const gchar *label_text, int col, int row)
32 {
33 GtkWidget *label_widget;
35 label_widget = gtk_label_new (label_text);
36 g_assert(label_widget != NULL);
37 gtk_misc_set_alignment (GTK_MISC (label_widget), 1.0, 0.5);
38 gtk_widget_show (label_widget);
39 gtk_table_attach (GTK_TABLE (table), label_widget, col, col+1, row, row+1,
40 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0);
41 return label_widget;
42 }
44 /**
45 * Creates a horizontal layout manager with 4-pixel spacing between children
46 * and space for 'width' columns.
47 */
48 GtkWidget *
49 spw_hbox(GtkWidget * table, int width, int col, int row)
50 {
51 GtkWidget *hb;
52 /* Create a new hbox with a 4-pixel spacing between children */
53 hb = gtk_hbox_new (FALSE, 4);
54 g_assert(hb != NULL);
55 gtk_widget_show (hb);
56 gtk_table_attach (GTK_TABLE (table), hb, col, col+width, row, row+1,
57 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
58 return hb;
59 }
61 /**
62 * Creates a checkbutton widget and adds it to a vbox.
63 * This is a compound widget that includes a label.
64 */
65 GtkWidget *spw_vbox_checkbutton(GtkWidget *dialog, GtkWidget *vbox,
66 const gchar *label, const gchar *tip, gchar *key, GCallback cb)
67 {
68 g_assert (dialog != NULL);
69 g_assert (vbox != NULL);
71 GtkTooltips *tt = gtk_tooltips_new ();
73 GtkWidget *b = gtk_check_button_new_with_label (label);
74 gtk_tooltips_set_tip(tt, b, tip, NULL);
75 g_assert (b != NULL);
76 gtk_widget_show (b);
77 gtk_box_pack_start (GTK_BOX (vbox), b, FALSE, FALSE, 0);
78 gtk_object_set_data (GTK_OBJECT (b), "key", key);
79 gtk_object_set_data (GTK_OBJECT (dialog), key, b);
80 g_signal_connect (G_OBJECT (b), "toggled", cb, dialog);
81 return b;
82 }
85 /**
86 * Creates a checkbutton widget and adds it to a table.
87 * This is a compound widget that includes a label.
88 */
89 GtkWidget *
90 spw_checkbutton(GtkWidget * dialog, GtkWidget * table,
91 const gchar * label, gchar * key, int col, int row,
92 int insensitive, GCallback cb)
93 {
94 GtkWidget *b;
96 g_assert(dialog != NULL);
97 g_assert(table != NULL);
99 GtkWidget *l = gtk_label_new (label);
100 gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
101 gtk_widget_show (l);
102 gtk_table_attach (GTK_TABLE (table), l, 0, 1, row, row+1,
103 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
105 b = gtk_check_button_new ();
106 gtk_widget_show (b);
107 gtk_table_attach (GTK_TABLE (table), b, 1, 2, row, row+1,
108 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
109 gtk_object_set_data (GTK_OBJECT (b), "key", key);
110 gtk_object_set_data (GTK_OBJECT (dialog), key, b);
111 g_signal_connect (G_OBJECT (b), "toggled", cb, dialog);
112 if (insensitive == 1) {
113 gtk_widget_set_sensitive (b, FALSE);
114 }
115 return b;
116 }
118 /**
119 * Creates a dropdown widget. This is a compound widget that includes
120 * a label as well as the dropdown.
121 */
122 GtkWidget *
123 spw_dropdown(GtkWidget * dialog, GtkWidget * table,
124 const gchar * label_text, gchar * key, int row,
125 GtkWidget * selector
126 )
127 {
128 g_assert(dialog != NULL);
129 g_assert(table != NULL);
130 g_assert(selector != NULL);
132 spw_label(table, label_text, 0, row);
134 gtk_widget_show (selector);
135 gtk_table_attach (GTK_TABLE (table), selector, 1, 2, row, row+1,
136 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
137 gtk_object_set_data (GTK_OBJECT (dialog), key, selector);
138 return selector;
139 }
141 /**
142 * Creates a unit selector widget, used for selecting whether one wishes
143 * to measure screen elements in millimeters, points, etc. This is a
144 * compound unit that includes a label as well as the dropdown selector.
145 */
146 GtkWidget *
147 spw_unit_selector(GtkWidget * dialog, GtkWidget * table,
148 const gchar * label_text, gchar * key, int row,
149 GtkWidget * us, GCallback cb, bool can_be_negative)
150 {
151 GtkWidget * sb;
152 GtkObject * a;
154 g_assert(dialog != NULL);
155 g_assert(table != NULL);
156 g_assert(us != NULL);
158 spw_label(table, label_text, 0, row);
160 a = gtk_adjustment_new (0.0, can_be_negative?-1e6:0, 1e6, 1.0, 10.0, 10.0);
161 g_assert(a != NULL);
162 gtk_object_set_data (GTK_OBJECT (a), "key", key);
163 gtk_object_set_data (GTK_OBJECT (a), "unit_selector", us);
164 gtk_object_set_data (GTK_OBJECT (dialog), key, a);
165 sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (us), GTK_ADJUSTMENT (a));
166 sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0, 4);
167 g_assert(sb != NULL);
168 gtk_widget_show (sb);
169 gtk_table_attach (GTK_TABLE (table), sb, 1, 2, row, row+1,
170 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
171 g_signal_connect (G_OBJECT (a), "value_changed", cb, dialog);
172 return sb;
173 }
175 void
176 sp_set_font_size_recursive (GtkWidget *w, gpointer font)
177 {
178 guint size = GPOINTER_TO_UINT (font);
180 PangoFontDescription* pan = pango_font_description_new ();
181 pango_font_description_set_size (pan, size);
183 gtk_widget_modify_font (w, pan);
185 if (GTK_IS_CONTAINER(w)) {
186 gtk_container_foreach (GTK_CONTAINER(w), (GtkCallback) sp_set_font_size_recursive, font);
187 }
189 pango_font_description_free (pan);
190 }
192 void
193 sp_set_font_size (GtkWidget *w, guint font)
194 {
195 sp_set_font_size_recursive (w, GUINT_TO_POINTER(font));
196 }
198 void
199 sp_set_font_size_smaller (GtkWidget *w)
200 {
201 PangoContext *pc = gtk_widget_get_pango_context (w);
202 PangoFontDescription* pfd = pango_context_get_font_description (pc);
203 guint size = pango_font_description_get_size (pfd);
204 sp_set_font_size_recursive (w, GUINT_TO_POINTER((int) (0.8*size)));
205 }
207 /**
208 \brief Finds the descendant of w which has the data with the given key and returns the data, or NULL if there's none
209 */
210 gpointer
211 sp_search_by_data_recursive (GtkWidget *w, gpointer key)
212 {
213 gpointer r = NULL;
215 if (w && GTK_IS_OBJECT(w)) {
216 r = gtk_object_get_data (GTK_OBJECT(w), (gchar *) key);
217 }
218 if (r) return r;
220 if (GTK_IS_CONTAINER(w)) {
221 GList *ch = gtk_container_get_children (GTK_CONTAINER(w));
222 for (GList *i = ch; i != NULL; i = i->next) {
223 r = sp_search_by_data_recursive(GTK_WIDGET(i->data), key);
224 if (r) return r;
225 }
226 }
228 return NULL;
229 }
231 /**
232 \brief Returns the descendant of w which has the given key and value pair, or NULL if there's none
233 */
234 GtkWidget *
235 sp_search_by_value_recursive (GtkWidget *w, gchar *key, gchar *value)
236 {
237 gchar *r = NULL;
238 GtkWidget *child;
240 if (w && GTK_IS_OBJECT(w)) {
241 r = (gchar *) gtk_object_get_data (GTK_OBJECT(w), key);
242 }
243 if (r && !strcmp (r, value)) return w;
245 if (GTK_IS_CONTAINER(w)) {
246 GList *ch = gtk_container_get_children (GTK_CONTAINER(w));
247 for (GList *i = ch; i != NULL; i = i->next) {
248 child = sp_search_by_value_recursive(GTK_WIDGET(i->data), key, value);
249 if (child) return child;
250 }
251 }
253 return NULL;
254 }