Code

patch from Gustav Broberg: undo annotations and history dialog
[inkscape.git] / src / widgets / gradient-toolbar.cpp
1 /*
2  * Gradient aux toolbar
3  *
4  * Authors:
5  *   bulia byak <bulia@dr.com>
6  *
7  * Copyright (C) 2005 authors
8  *
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
16 #include <gtk/gtk.h>
18 #include "macros.h"
19 #include "widgets/button.h"
20 #include "widgets/widget-sizes.h"
21 #include "widgets/spw-utilities.h"
22 #include "widgets/spinbutton-events.h"
23 #include "widgets/gradient-vector.h"
24 #include "widgets/gradient-image.h"
25 #include "style.h"
27 #include "prefs-utils.h"
28 #include "document-private.h"
29 #include "desktop.h"
30 #include "desktop-handles.h"
31 #include <glibmm/i18n.h>
33 #include "gradient-context.h"
34 #include "gradient-drag.h"
35 #include "sp-linear-gradient.h"
36 #include "sp-radial-gradient.h"
37 #include "gradient-chemistry.h"
38 #include "selection.h"
40 #include "toolbox.h"
43 //########################
44 //##       Gradient     ##
45 //########################
47 static void gr_toggle_type (GtkWidget *button, gpointer data) {
48     GtkWidget *linear = (GtkWidget *) g_object_get_data (G_OBJECT(data), "linear");
49     GtkWidget *radial = (GtkWidget *) g_object_get_data (G_OBJECT(data), "radial");
50     if (button == linear && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (linear))) {
51         prefs_set_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
52         if (radial) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radial), FALSE);
53     } else if (button == radial && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radial))) {
54         prefs_set_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_RADIAL);
55         if (linear) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear), FALSE);
56     }
57 }
59 static void gr_toggle_fillstroke (GtkWidget *button, gpointer data) {
60     GtkWidget *fill = (GtkWidget *) g_object_get_data (G_OBJECT(data), "fill");
61     GtkWidget *stroke = (GtkWidget *) g_object_get_data (G_OBJECT(data), "stroke");
62     if (button == fill && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fill))) {
63         prefs_set_int_attribute ("tools.gradient", "newfillorstroke", 1);
64         if (stroke) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (stroke), FALSE);
65     } else if (button == stroke && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (stroke))) {
66         prefs_set_int_attribute ("tools.gradient", "newfillorstroke", 0);
67         if (fill) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fill), FALSE);
68     }
69 }
71 void
72 gr_apply_gradient_to_item (SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke)
73 {
74     SPStyle *style = SP_OBJECT_STYLE (item);
76     if (do_fill) {
77         if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER) && 
78             SP_IS_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (item))) {
79             SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
80             if (SP_IS_LINEARGRADIENT (server)) {
81                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, true);
82             } else if (SP_IS_RADIALGRADIENT (server)) {
83                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, true);
84             } 
85         } else if (new_fill) {
86             sp_item_set_gradient(item, gr, new_type, true);
87         }
88     } 
90     if (do_stroke) {
91         if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER) && 
92             SP_IS_GRADIENT (SP_OBJECT_STYLE_STROKE_SERVER (item))) {
93             SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
94             if (SP_IS_LINEARGRADIENT (server)) {
95                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, false);
96             } else if (SP_IS_RADIALGRADIENT (server)) {
97                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, false);
98             } 
99         } else if (!new_fill) {
100             sp_item_set_gradient(item, gr, new_type, false);
101         }
102     }
105 /**
106 Applies gradient vector gr to the gradients attached to the selected dragger of drag, or if none,
107 to all objects in selection. If there was no previous gradient on an item, uses gradient type and
108 fill/stroke setting from preferences to create new default (linear: left/right; radial: centered)
109 gradient.
110 */
111 void
112 gr_apply_gradient (Inkscape::Selection *selection, GrDrag *drag, SPGradient *gr)
114     SPGradientType new_type = (SPGradientType) prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
115     guint new_fill = prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1);
117     // First try selected dragger
118     if (drag && drag->selected) {
119         GrDragger *dragger = drag->selected;
120         for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
121             GrDraggable *draggable = (GrDraggable *) i->data;
122             gr_apply_gradient_to_item (draggable->item, gr, new_type, new_fill, draggable->fill_or_stroke, !draggable->fill_or_stroke);
123         }
124         return;
125     }
127    // If no drag or no dragger selected, act on selection
128    for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
129        gr_apply_gradient_to_item (SP_ITEM(i->data), gr, new_type, new_fill, true, true);
130    }
133 void
134 gr_item_activate (GtkMenuItem *menuitem, gpointer data)
136     SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT (menuitem), "gradient");
137     gr = sp_gradient_ensure_vector_normalized(gr);
139     SPDesktop *desktop = (SPDesktop *) data;
140     Inkscape::Selection *selection = sp_desktop_selection (desktop);
141     SPEventContext *ev = sp_desktop_event_context (desktop);
143     gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
145     sp_document_done (sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
146                       /* TODO: annotate */ "gradient-toolbar.cpp:146");
149 gchar *
150 gr_prepare_label (SPObject *obj)
152     const gchar *id = obj->defaultLabel();
153     if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15))) 
154         return g_strdup_printf ("<small>#%s</small>", id+15);
155     return g_strdup_printf ("<small>%s</small>", id);
158 GtkWidget *
159 gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
161     SPDocument *document = sp_desktop_document (desktop);
163     GtkWidget *om = gtk_option_menu_new ();
164     GtkWidget *m = gtk_menu_new ();
166     GSList *gl = NULL;
167     const GSList *gradients = sp_document_get_resource_list (document, "gradient");
168                 for (const GSList *i = gradients; i != NULL; i = i->next) {
169         if (SP_GRADIENT_HAS_STOPS (i->data)) {
170             gl = g_slist_prepend (gl, i->data);
171         }
172                 }
173     gl = g_slist_reverse (gl);
175     guint pos = 0;
176     guint idx = 0;
178     if (!gl) {
179         GtkWidget *l = gtk_label_new("");
180         gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients</small>"));
181         GtkWidget *i = gtk_menu_item_new ();
182         gtk_container_add (GTK_CONTAINER (i), l);
184         gtk_widget_show (i);
185         gtk_menu_append (GTK_MENU (m), i);
186         gtk_widget_set_sensitive (om, FALSE);
187     } else if (selection_empty) {
188         GtkWidget *l = gtk_label_new("");
189         gtk_label_set_markup (GTK_LABEL(l), _("<small>Nothing selected</small>"));
190         GtkWidget *i = gtk_menu_item_new ();
191         gtk_container_add (GTK_CONTAINER (i), l);
193         gtk_widget_show (i);
194         gtk_menu_append (GTK_MENU (m), i);
195         gtk_widget_set_sensitive (om, FALSE);
196     } else {
198         if (gr_selected == NULL) {
199             GtkWidget *l = gtk_label_new("");
200             gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients in selection</small>"));
201             GtkWidget *i = gtk_menu_item_new ();
202             gtk_container_add (GTK_CONTAINER (i), l);
204             gtk_widget_show (i);
205             gtk_menu_append (GTK_MENU (m), i);
206         }
208         if (gr_multi) {
209             GtkWidget *l = gtk_label_new("");
210             gtk_label_set_markup (GTK_LABEL(l), _("<small>Multiple gradients</small>"));
211             GtkWidget *i = gtk_menu_item_new ();
212             gtk_container_add (GTK_CONTAINER (i), l);
214             gtk_widget_show (i);
215             gtk_menu_append (GTK_MENU (m), i);
216         }
218         while (gl) {
219             SPGradient *gradient = SP_GRADIENT (gl->data);
220             gl = g_slist_remove (gl, gradient);
222             GtkWidget *i = gtk_menu_item_new ();
223             g_object_set_data (G_OBJECT (i), "gradient", gradient);
224             g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (gr_item_activate), desktop);
226             GtkWidget *image = sp_gradient_image_new (gradient);
228             GtkWidget *hb = gtk_hbox_new (FALSE, 4);
229             GtkWidget *l = gtk_label_new ("");
230             gchar *label = gr_prepare_label (SP_OBJECT(gradient));
231             gtk_label_set_markup (GTK_LABEL(l), label);
232             g_free (label);
233             gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
234             gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
235             gtk_box_pack_start (GTK_BOX (hb), image, FALSE, FALSE, 0);
237             gtk_widget_show_all (i);
239             gtk_container_add (GTK_CONTAINER (i), hb);
241             gtk_menu_append (GTK_MENU (m), i);
243             if (gradient == gr_selected) {
244                 pos = idx;
245             }
246             idx ++;
247         }
248         gtk_widget_set_sensitive (om, TRUE);
249     }
251     gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m);
252     /* Select the current gradient, or the Multi/Nothing line */
253     if (gr_multi || gr_selected == NULL)
254         gtk_option_menu_set_history (GTK_OPTION_MENU (om), 0);
255     else 
256         gtk_option_menu_set_history (GTK_OPTION_MENU (om), pos);
258     return om;
262 void
263 gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi) 
265     if (drag && drag->selected) {
266         GrDragger *dragger = drag->selected;
267         for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
268             GrDraggable *draggable = (GrDraggable *) i->data;
269             SPGradient *gradient = sp_item_gradient_get_vector (draggable->item, draggable->fill_or_stroke);
270             SPGradientSpread spread = sp_item_gradient_get_spread (draggable->item, draggable->fill_or_stroke);
272             if (gradient != *gr_selected) {
273                 if (*gr_selected != NULL) {
274                     *gr_multi = true;
275                 } else {
276                     *gr_selected = gradient;
277                 }
278             }
279             if (spread != *spr_selected) {
280                 if (*spr_selected != INT_MAX) {
281                     *spr_multi = true;
282                 } else {
283                     *spr_selected = spread;
284                 }
285             }
286          }
287         return;
288     } 
290    // If no selected dragger, read desktop selection
291    for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
292         SPItem *item = SP_ITEM(i->data);
293         SPStyle *style = SP_OBJECT_STYLE (item);
295         if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) { 
296             SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
297             if (SP_IS_GRADIENT (server)) {
298                 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
299                 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
300                 if (gradient != *gr_selected) {
301                     if (*gr_selected != NULL) {
302                         *gr_multi = true;
303                     } else {
304                         *gr_selected = gradient;
305                     }
306                 }
307                 if (spread != *spr_selected) {
308                     if (*spr_selected != INT_MAX) {
309                         *spr_multi = true;
310                     } else {
311                         *spr_selected = spread;
312                     }
313                 }
314             }
315         }
316         if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) { 
317             SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
318             if (SP_IS_GRADIENT (server)) {
319                 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
320                 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
321                 if (gradient != *gr_selected) {
322                     if (*gr_selected != NULL) {
323                         *gr_multi = true;
324                     } else {
325                         *gr_selected = gradient;
326                     }
327                 }
328                 if (spread != *spr_selected) {
329                     if (*spr_selected != INT_MAX) {
330                         *spr_multi = true;
331                     } else {
332                         *spr_selected = spread;
333                     }
334                 }
335             }
336         }
337     }
338  }
340 static void 
341 gr_tb_selection_changed (Inkscape::Selection *, gpointer data)
343     GtkWidget *widget = (GtkWidget *) data;
345     SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
346     if (!desktop)
347         return;
349     Inkscape::Selection *selection = sp_desktop_selection (desktop); // take from desktop, not from args
350     if (!selection) 
351         return;
352     
353     SPEventContext *ev = sp_desktop_event_context (desktop);
355     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "menu");
356     if (om) gtk_widget_destroy (om);
358     SPGradient *gr_selected = NULL;
359     bool gr_multi = false;
361     SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
362     bool spr_multi = false;
364     gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
366     om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
367     g_object_set_data (G_OBJECT (widget), "menu", om);
369     GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "buttons");
370     gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
371   
372     gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
374     gtk_widget_show_all (widget);
377 static void
378 gr_tb_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
380     gr_tb_selection_changed (selection, data);
383 static void
384 gr_drag_selection_changed (gpointer dragger, gpointer data)
386     gr_tb_selection_changed (NULL, data);
389 static void
390 gr_defs_release (SPObject *defs, GtkWidget *widget)
392     gr_tb_selection_changed (NULL, (gpointer) widget);
395 static void
396 gr_defs_modified (SPObject *defs, guint flags, GtkWidget *widget)
398     gr_tb_selection_changed (NULL, (gpointer) widget);
401 static void
402 gr_fork (GtkWidget *button, GtkWidget *widget)
404     SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
405     SPDocument *document = sp_desktop_document (desktop);
406     Inkscape::Selection *selection = sp_desktop_selection (desktop);
407     SPEventContext *ev = sp_desktop_event_context (desktop);
408     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
410     if (om && document) {
411         GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
412         SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
414         if (gr) {
415             SPGradient *gr_new = sp_gradient_fork_vector_if_necessary (gr);
416             if (gr_new != gr) {
417                 gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr_new);
418                 sp_document_done (document, SP_VERB_CONTEXT_GRADIENT,
419                                   /* TODO: annotate */ "gradient-toolbar.cpp:419");
420             }
421         }
422     }
424     spinbutton_defocus(GTK_OBJECT(widget));
427 static void gr_disconnect_sigc (GObject *obj, sigc::connection *connection) {
428     connection->disconnect();
429     delete connection;
432 static void gr_disconnect_gsignal (GObject *widget, gpointer defs) {
433     if (defs && G_IS_OBJECT(defs))
434         sp_signal_disconnect_by_data (defs, widget);
438 static void
439 gr_edit (GtkWidget *button, GtkWidget *widget)
441     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
443     spinbutton_defocus(GTK_OBJECT(widget));
445     if (om) {
446         GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
447         SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
449         if (gr) {
450             GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
451             gtk_widget_show (dialog);
452         }
453     }
456 GtkWidget *
457 gr_change_widget (SPDesktop *desktop)
459     Inkscape::Selection *selection = sp_desktop_selection (desktop);
460     SPDocument *document = sp_desktop_document (desktop);
461     SPEventContext *ev = sp_desktop_event_context (desktop);
463     SPGradient *gr_selected = NULL;
464     bool gr_multi = false;
466     SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
467     bool spr_multi = false;
469     GtkTooltips *tt = gtk_tooltips_new();
471     gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
472  
473     GtkWidget *widget = gtk_hbox_new(FALSE, FALSE);
474     gtk_object_set_data(GTK_OBJECT(widget), "dtw", desktop->canvas);
475     g_object_set_data (G_OBJECT (widget), "desktop", desktop);
477     GtkWidget *om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
478     g_object_set_data (G_OBJECT (widget), "menu", om);
479   
480     gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
482     {
483     GtkWidget *buttons = gtk_hbox_new(FALSE, 1);
485     /* Fork */
486     {
487         GtkWidget *hb = gtk_hbox_new(FALSE, 1);
488         GtkWidget *b = gtk_button_new_with_label(_("Duplicate"));
489         gtk_tooltips_set_tip(tt, b, _("If the gradient is used by more than one object, create a copy of it for the selected object(s)"), NULL);
490         gtk_widget_show(b);
491         gtk_container_add(GTK_CONTAINER(hb), b);
492         gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_fork), widget);
493         gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
494     }
496     /* Edit... */
497     {
498         GtkWidget *hb = gtk_hbox_new(FALSE, 1);
499         GtkWidget *b = gtk_button_new_with_label(_("Edit..."));
500         gtk_tooltips_set_tip(tt, b, _("Edit the stops of the gradient"), NULL);
501         gtk_widget_show(b);
502         gtk_container_add(GTK_CONTAINER(hb), b);
503         gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_edit), widget);
504         gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
505     }
507     gtk_box_pack_end (GTK_BOX(widget), buttons, FALSE, FALSE, 0);
508     g_object_set_data (G_OBJECT(widget), "buttons", buttons);
509     gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
510     }
512     // connect to selection modified and changed signals
513     sigc::connection *conn1 = new sigc::connection (selection->connectChanged(
514         sigc::bind (
515             sigc::ptr_fun(&gr_tb_selection_changed),
516             (gpointer)widget )
517     ));
518     sigc::connection *conn2 = new sigc::connection (selection->connectModified(
519         sigc::bind (
520             sigc::ptr_fun(&gr_tb_selection_modified),
521             (gpointer)widget )
522     ));
524     sigc::connection *conn3 = new sigc::connection (desktop->connectToolSubselectionChanged(
525         sigc::bind (
526             sigc::ptr_fun(&gr_drag_selection_changed),
527             (gpointer)widget )
528     ));
530     // when widget is destroyed, disconnect
531     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
532     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
533     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
535     // connect to release and modified signals of the defs (i.e. when someone changes gradient)
536     g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (document)), "release", G_CALLBACK (gr_defs_release), widget);
537     g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (document)), "modified", G_CALLBACK (gr_defs_modified), widget);
539     // when widget is destroyed, disconnect
540     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_gsignal), G_OBJECT (SP_DOCUMENT_DEFS (document)));
541     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_gsignal), G_OBJECT (SP_DOCUMENT_DEFS (document)));
543     gtk_widget_show_all (widget);
544     return widget;
547 GtkWidget *
548 sp_gradient_toolbox_new(SPDesktop *desktop)
550     GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
552     gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
553     gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
555     GtkTooltips *tt = gtk_tooltips_new();
557     sp_toolbox_add_label(tbl, _("<b>New:</b>"));
559     aux_toolbox_space(tbl, AUX_SPACING);
561     {
562     GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
563     GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
565     {
566     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
567                                               SP_BUTTON_TYPE_TOGGLE,
568                                               NULL,
569                                               "fill_gradient",
570                                               _("Create linear gradient"),
571                                               tt);
572     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
573     g_object_set_data(G_OBJECT(tbl), "linear", button);
574     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
575               prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
576     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
577     }
579     {
580     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
581                                               SP_BUTTON_TYPE_TOGGLE,
582                                               NULL,
583                                               "fill_radial",
584                                               _("Create radial (elliptic or circular) gradient"),
585                                               tt);
586     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
587     g_object_set_data(G_OBJECT(tbl), "radial", button);
588     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
589               prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
590     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
591     }
593     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
594     gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
595     }
597     aux_toolbox_space(tbl, AUX_SPACING);
599     sp_toolbox_add_label(tbl, _("on"), false);
601     aux_toolbox_space(tbl, AUX_SPACING);
603     {
604         GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
605     GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
607     {
608     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
609                                               SP_BUTTON_TYPE_TOGGLE,
610                                               NULL,
611                                               "controls_fill",
612                                               _("Create gradient in the fill"),
613                                               tt);
614     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
615     g_object_set_data(G_OBJECT(tbl), "fill", button);
616     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
617                                   prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 1);
618     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
619     }
621     {
622     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
623                                               SP_BUTTON_TYPE_TOGGLE,
624                                               NULL,
625                                               "controls_stroke",
626                                               _("Create gradient in the stroke"),
627                                               tt);
628     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
629     g_object_set_data(G_OBJECT(tbl), "stroke", button);
630     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
631                                   prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 0);
632     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
633     }
635     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
636     gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
637     }
640     sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
642     aux_toolbox_space(tbl, AUX_SPACING);
644     {
645         GtkWidget *vectors = gr_change_widget (desktop);
646         gtk_box_pack_start (GTK_BOX (tbl), vectors, FALSE, FALSE, 0);
647     }
649     gtk_widget_show_all(tbl);
650     sp_set_font_size_smaller (tbl);
652     return tbl;
658 /*
659   Local Variables:
660   mode:c++
661   c-file-style:"stroustrup"
662   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
663   indent-tabs-mode:nil
664   fill-column:99
665   End:
666 */
667 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :