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
19 #include <cstring>
20 #include <string>
21 #include <gtk/gtk.h>
23 #include "selection.h"
25 #include "helper/unit-menu.h"
28 #include <gtkmm/label.h>
29 #include <gtkmm/box.h>
30 #include <gtkmm/table.h>
32 /**
33 * Creates a label widget with the given text, at the given col, row
34 * position in the table.
35 */
36 Gtk::Label *
37 spw_label(Gtk::Table *table, const gchar *label_text, int col, int row)
38 {
39 Gtk::Label *label_widget = new Gtk::Label(label_text);
40 g_assert(label_widget != NULL);
42 label_widget->set_alignment(1.0, 0.5);
43 label_widget->show();
44 table->attach(*label_widget, col, col+1, row, row+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 4, 0);
45 return label_widget;
46 }
48 GtkWidget *
49 spw_label_old(GtkWidget *table, const gchar *label_text, int col, int row)
50 {
51 GtkWidget *label_widget;
53 label_widget = gtk_label_new (label_text);
54 g_assert(label_widget != NULL);
55 gtk_misc_set_alignment (GTK_MISC (label_widget), 1.0, 0.5);
56 gtk_widget_show (label_widget);
57 gtk_table_attach (GTK_TABLE (table), label_widget, col, col+1, row, row+1,
58 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0);
59 return label_widget;
60 }
62 /**
63 * Creates a horizontal layout manager with 4-pixel spacing between children
64 * and space for 'width' columns.
65 */
66 Gtk::HBox *
67 spw_hbox(Gtk::Table * table, int width, int col, int row)
68 {
69 /* Create a new hbox with a 4-pixel spacing between children */
70 Gtk::HBox *hb = new Gtk::HBox(false, 4);
71 g_assert(hb != NULL);
72 hb->show();
73 table->attach(*hb, col, col+width, row, row+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
74 return hb;
75 }
77 /**
78 * Creates a checkbutton widget and adds it to a vbox.
79 * This is a compound widget that includes a label.
80 */
81 GtkWidget *spw_vbox_checkbutton(GtkWidget *dialog, GtkWidget *vbox,
82 const gchar *label, const gchar *tip, gchar *key, GCallback cb)
83 {
84 g_assert (dialog != NULL);
85 g_assert (vbox != NULL);
87 GtkTooltips *tt = gtk_tooltips_new ();
89 GtkWidget *b = gtk_check_button_new_with_label (label);
90 gtk_tooltips_set_tip(tt, b, tip, NULL);
91 g_assert (b != NULL);
92 gtk_widget_show (b);
93 gtk_box_pack_start (GTK_BOX (vbox), b, FALSE, FALSE, 0);
94 gtk_object_set_data (GTK_OBJECT (b), "key", key);
95 gtk_object_set_data (GTK_OBJECT (dialog), key, b);
96 g_signal_connect (G_OBJECT (b), "toggled", cb, dialog);
97 return b;
98 }
101 /**
102 * Creates a checkbutton widget and adds it to a table.
103 * This is a compound widget that includes a label.
104 */
105 GtkWidget *
106 spw_checkbutton(GtkWidget * dialog, GtkWidget * table,
107 const gchar * label, gchar * key, int /*col*/, int row,
108 int insensitive, GCallback cb)
109 {
110 GtkWidget *b;
112 g_assert(dialog != NULL);
113 g_assert(table != NULL);
115 GtkWidget *l = gtk_label_new (label);
116 gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
117 gtk_widget_show (l);
118 gtk_table_attach (GTK_TABLE (table), l, 0, 1, row, row+1,
119 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
121 b = gtk_check_button_new ();
122 gtk_widget_show (b);
123 gtk_table_attach (GTK_TABLE (table), b, 1, 2, row, row+1,
124 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
125 gtk_object_set_data (GTK_OBJECT (b), "key", key);
126 gtk_object_set_data (GTK_OBJECT (dialog), key, b);
127 g_signal_connect (G_OBJECT (b), "toggled", cb, dialog);
128 if (insensitive == 1) {
129 gtk_widget_set_sensitive (b, FALSE);
130 }
131 return b;
132 }
134 /**
135 * Creates a dropdown widget. This is a compound widget that includes
136 * a label as well as the dropdown.
137 */
138 GtkWidget *
139 spw_dropdown(GtkWidget * dialog, GtkWidget * table,
140 const gchar * label_text, gchar * key, int row,
141 GtkWidget * selector
142 )
143 {
144 g_assert(dialog != NULL);
145 g_assert(table != NULL);
146 g_assert(selector != NULL);
148 spw_label_old(table, label_text, 0, row);
150 gtk_widget_show (selector);
151 gtk_table_attach (GTK_TABLE (table), selector, 1, 2, row, row+1,
152 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
153 gtk_object_set_data (GTK_OBJECT (dialog), key, selector);
154 return selector;
155 }
157 /**
158 * Creates a unit selector widget, used for selecting whether one wishes
159 * to measure screen elements in millimeters, points, etc. This is a
160 * compound unit that includes a label as well as the dropdown selector.
161 */
162 GtkWidget *
163 spw_unit_selector(GtkWidget * dialog, GtkWidget * table,
164 const gchar * label_text, gchar * key, int row,
165 GtkWidget * us, GCallback cb, bool can_be_negative)
166 {
167 GtkWidget * sb;
168 GtkObject * a;
170 g_assert(dialog != NULL);
171 g_assert(table != NULL);
172 g_assert(us != NULL);
174 spw_label_old(table, label_text, 0, row);
176 a = gtk_adjustment_new (0.0, can_be_negative?-1e6:0, 1e6, 1.0, 10.0, 10.0);
177 g_assert(a != NULL);
178 gtk_object_set_data (GTK_OBJECT (a), "key", key);
179 gtk_object_set_data (GTK_OBJECT (a), "unit_selector", us);
180 gtk_object_set_data (GTK_OBJECT (dialog), key, a);
181 sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (us), GTK_ADJUSTMENT (a));
182 sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0, 4);
183 g_assert(sb != NULL);
184 gtk_widget_show (sb);
185 gtk_table_attach (GTK_TABLE (table), sb, 1, 2, row, row+1,
186 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
187 g_signal_connect (G_OBJECT (a), "value_changed", cb, dialog);
188 return sb;
189 }
191 void
192 sp_set_font_size_recursive (GtkWidget *w, gpointer font)
193 {
194 guint size = GPOINTER_TO_UINT (font);
196 PangoFontDescription* pan = pango_font_description_new ();
197 pango_font_description_set_size (pan, size);
199 gtk_widget_modify_font (w, pan);
201 if (GTK_IS_CONTAINER(w)) {
202 gtk_container_foreach (GTK_CONTAINER(w), (GtkCallback) sp_set_font_size_recursive, font);
203 }
205 pango_font_description_free (pan);
206 }
208 void
209 sp_set_font_size (GtkWidget *w, guint font)
210 {
211 sp_set_font_size_recursive (w, GUINT_TO_POINTER(font));
212 }
214 void
215 sp_set_font_size_smaller (GtkWidget *w)
216 {
217 PangoContext *pc = gtk_widget_get_pango_context (w);
218 PangoFontDescription* pfd = pango_context_get_font_description (pc);
219 guint size = pango_font_description_get_size (pfd);
220 sp_set_font_size_recursive (w, GUINT_TO_POINTER((int) (0.8*size)));
221 }
223 /**
224 \brief Finds the descendant of w which has the data with the given key and returns the data, or NULL if there's none
225 */
226 gpointer
227 sp_search_by_data_recursive (GtkWidget *w, gpointer key)
228 {
229 gpointer r = NULL;
231 if (w && GTK_IS_OBJECT(w)) {
232 r = gtk_object_get_data (GTK_OBJECT(w), (gchar *) key);
233 }
234 if (r) return r;
236 if (GTK_IS_CONTAINER(w)) {
237 GList *ch = gtk_container_get_children (GTK_CONTAINER(w));
238 for (GList *i = ch; i != NULL; i = i->next) {
239 r = sp_search_by_data_recursive(GTK_WIDGET(i->data), key);
240 if (r) return r;
241 }
242 }
244 return NULL;
245 }
247 /**
248 \brief Returns the descendant of w which has the given key and value pair, or NULL if there's none
249 */
250 GtkWidget *
251 sp_search_by_value_recursive (GtkWidget *w, gchar *key, gchar *value)
252 {
253 gchar *r = NULL;
254 GtkWidget *child;
256 if (w && GTK_IS_OBJECT(w)) {
257 r = (gchar *) gtk_object_get_data (GTK_OBJECT(w), key);
258 }
259 if (r && !strcmp (r, value)) return w;
261 if (GTK_IS_CONTAINER(w)) {
262 GList *ch = gtk_container_get_children (GTK_CONTAINER(w));
263 for (GList *i = ch; i != NULL; i = i->next) {
264 child = sp_search_by_value_recursive(GTK_WIDGET(i->data), key, value);
265 if (child) return child;
266 }
267 }
269 return NULL;
270 }
272 /*
273 Local Variables:
274 mode:c++
275 c-file-style:"stroustrup"
276 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
277 indent-tabs-mode:nil
278 fill-column:99
279 End:
280 */
281 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :