Code

switch to sigc++ SPObject signals for gradient toolbar
[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
433 gr_edit (GtkWidget *button, GtkWidget *widget)
435     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
437     spinbutton_defocus(GTK_OBJECT(widget));
439     if (om) {
440         GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
441         SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
443         if (gr) {
444             GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
445             gtk_widget_show (dialog);
446         }
447     }
450 GtkWidget *
451 gr_change_widget (SPDesktop *desktop)
453     Inkscape::Selection *selection = sp_desktop_selection (desktop);
454     SPDocument *document = sp_desktop_document (desktop);
455     SPEventContext *ev = sp_desktop_event_context (desktop);
457     SPGradient *gr_selected = NULL;
458     bool gr_multi = false;
460     SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
461     bool spr_multi = false;
463     GtkTooltips *tt = gtk_tooltips_new();
465     gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
466  
467     GtkWidget *widget = gtk_hbox_new(FALSE, FALSE);
468     gtk_object_set_data(GTK_OBJECT(widget), "dtw", desktop->canvas);
469     g_object_set_data (G_OBJECT (widget), "desktop", desktop);
471     GtkWidget *om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
472     g_object_set_data (G_OBJECT (widget), "menu", om);
473   
474     gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
476     {
477     GtkWidget *buttons = gtk_hbox_new(FALSE, 1);
479     /* Fork */
480     {
481         GtkWidget *hb = gtk_hbox_new(FALSE, 1);
482         GtkWidget *b = gtk_button_new_with_label(_("Duplicate"));
483         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);
484         gtk_widget_show(b);
485         gtk_container_add(GTK_CONTAINER(hb), b);
486         gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_fork), widget);
487         gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
488     }
490     /* Edit... */
491     {
492         GtkWidget *hb = gtk_hbox_new(FALSE, 1);
493         GtkWidget *b = gtk_button_new_with_label(_("Edit..."));
494         gtk_tooltips_set_tip(tt, b, _("Edit the stops of the gradient"), NULL);
495         gtk_widget_show(b);
496         gtk_container_add(GTK_CONTAINER(hb), b);
497         gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_edit), widget);
498         gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
499     }
501     gtk_box_pack_end (GTK_BOX(widget), buttons, FALSE, FALSE, 0);
502     g_object_set_data (G_OBJECT(widget), "buttons", buttons);
503     gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
504     }
506     // connect to selection modified and changed signals
507     sigc::connection *conn1 = new sigc::connection (selection->connectChanged(
508         sigc::bind (
509             sigc::ptr_fun(&gr_tb_selection_changed),
510             (gpointer)widget )
511     ));
512     sigc::connection *conn2 = new sigc::connection (selection->connectModified(
513         sigc::bind (
514             sigc::ptr_fun(&gr_tb_selection_modified),
515             (gpointer)widget )
516     ));
518     sigc::connection *conn3 = new sigc::connection (desktop->connectToolSubselectionChanged(
519         sigc::bind (
520             sigc::ptr_fun(&gr_drag_selection_changed),
521             (gpointer)widget )
522     ));
524     // when widget is destroyed, disconnect
525     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
526     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
527     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
529     // connect to release and modified signals of the defs (i.e. when someone changes gradient)
530     sigc::connection *release_connection = new sigc::connection();
531     *release_connection = SP_DOCUMENT_DEFS(document)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), widget));
532     sigc::connection *modified_connection = new sigc::connection();
533     *modified_connection = SP_DOCUMENT_DEFS(document)->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), widget));
535     // when widget is destroyed, disconnect
536     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
537     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
539     gtk_widget_show_all (widget);
540     return widget;
543 GtkWidget *
544 sp_gradient_toolbox_new(SPDesktop *desktop)
546     GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
548     gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
549     gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
551     GtkTooltips *tt = gtk_tooltips_new();
553     sp_toolbox_add_label(tbl, _("<b>New:</b>"));
555     aux_toolbox_space(tbl, AUX_SPACING);
557     {
558     GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
559     GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
561     {
562     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
563                                               SP_BUTTON_TYPE_TOGGLE,
564                                               NULL,
565                                               "fill_gradient",
566                                               _("Create linear gradient"),
567                                               tt);
568     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
569     g_object_set_data(G_OBJECT(tbl), "linear", button);
570     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
571               prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
572     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
573     }
575     {
576     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
577                                               SP_BUTTON_TYPE_TOGGLE,
578                                               NULL,
579                                               "fill_radial",
580                                               _("Create radial (elliptic or circular) gradient"),
581                                               tt);
582     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
583     g_object_set_data(G_OBJECT(tbl), "radial", button);
584     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
585               prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
586     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
587     }
589     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
590     gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
591     }
593     aux_toolbox_space(tbl, AUX_SPACING);
595     sp_toolbox_add_label(tbl, _("on"), false);
597     aux_toolbox_space(tbl, AUX_SPACING);
599     {
600         GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
601     GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
603     {
604     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
605                                               SP_BUTTON_TYPE_TOGGLE,
606                                               NULL,
607                                               "controls_fill",
608                                               _("Create gradient in the fill"),
609                                               tt);
610     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
611     g_object_set_data(G_OBJECT(tbl), "fill", button);
612     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
613                                   prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 1);
614     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
615     }
617     {
618     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
619                                               SP_BUTTON_TYPE_TOGGLE,
620                                               NULL,
621                                               "controls_stroke",
622                                               _("Create gradient in the stroke"),
623                                               tt);
624     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
625     g_object_set_data(G_OBJECT(tbl), "stroke", button);
626     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
627                                   prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 0);
628     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
629     }
631     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
632     gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
633     }
636     sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
638     aux_toolbox_space(tbl, AUX_SPACING);
640     {
641         GtkWidget *vectors = gr_change_widget (desktop);
642         gtk_box_pack_start (GTK_BOX (tbl), vectors, FALSE, FALSE, 0);
643     }
645     gtk_widget_show_all(tbl);
646     sp_set_font_size_smaller (tbl);
648     return tbl;
654 /*
655   Local Variables:
656   mode:c++
657   c-file-style:"stroustrup"
658   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
659   indent-tabs-mode:nil
660   fill-column:99
661   End:
662 */
663 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :