Code

Shrunk a few icon sizes.
[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_DT_SELECTION (desktop);
141     SPEventContext *ev = SP_DT_EVENTCONTEXT (desktop);
143     gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
145     sp_document_done (SP_DT_DOCUMENT (desktop));
148 gchar *
149 gr_prepare_label (SPObject *obj)
151     const gchar *id = obj->defaultLabel();
152     if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15))) 
153         return g_strdup_printf ("<small>#%s</small>", id+15);
154     return g_strdup_printf ("<small>%s</small>", id);
157 GtkWidget *
158 gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
160     SPDocument *document = SP_DT_DOCUMENT (desktop);
162     GtkWidget *om = gtk_option_menu_new ();
163     GtkWidget *m = gtk_menu_new ();
165     GSList *gl = NULL;
166     const GSList *gradients = sp_document_get_resource_list (document, "gradient");
167                 for (const GSList *i = gradients; i != NULL; i = i->next) {
168         if (SP_GRADIENT_HAS_STOPS (i->data)) {
169             gl = g_slist_prepend (gl, i->data);
170         }
171                 }
172     gl = g_slist_reverse (gl);
174     guint pos = 0;
175     guint idx = 0;
177     if (!gl) {
178         GtkWidget *l = gtk_label_new("");
179         gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients</small>"));
180         GtkWidget *i = gtk_menu_item_new ();
181         gtk_container_add (GTK_CONTAINER (i), l);
183         gtk_widget_show (i);
184         gtk_menu_append (GTK_MENU (m), i);
185         gtk_widget_set_sensitive (om, FALSE);
186     } else if (selection_empty) {
187         GtkWidget *l = gtk_label_new("");
188         gtk_label_set_markup (GTK_LABEL(l), _("<small>Nothing selected</small>"));
189         GtkWidget *i = gtk_menu_item_new ();
190         gtk_container_add (GTK_CONTAINER (i), l);
192         gtk_widget_show (i);
193         gtk_menu_append (GTK_MENU (m), i);
194         gtk_widget_set_sensitive (om, FALSE);
195     } else {
197         if (gr_selected == NULL) {
198             GtkWidget *l = gtk_label_new("");
199             gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients in selection</small>"));
200             GtkWidget *i = gtk_menu_item_new ();
201             gtk_container_add (GTK_CONTAINER (i), l);
203             gtk_widget_show (i);
204             gtk_menu_append (GTK_MENU (m), i);
205         }
207         if (gr_multi) {
208             GtkWidget *l = gtk_label_new("");
209             gtk_label_set_markup (GTK_LABEL(l), _("<small>Multiple gradients</small>"));
210             GtkWidget *i = gtk_menu_item_new ();
211             gtk_container_add (GTK_CONTAINER (i), l);
213             gtk_widget_show (i);
214             gtk_menu_append (GTK_MENU (m), i);
215         }
217         while (gl) {
218             SPGradient *gradient = SP_GRADIENT (gl->data);
219             gl = g_slist_remove (gl, gradient);
221             GtkWidget *i = gtk_menu_item_new ();
222             g_object_set_data (G_OBJECT (i), "gradient", gradient);
223             g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (gr_item_activate), desktop);
225             GtkWidget *image = sp_gradient_image_new (gradient);
227             GtkWidget *hb = gtk_hbox_new (FALSE, 4);
228             GtkWidget *l = gtk_label_new ("");
229             gchar *label = gr_prepare_label (SP_OBJECT(gradient));
230             gtk_label_set_markup (GTK_LABEL(l), label);
231             g_free (label);
232             gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
233             gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
234             gtk_box_pack_start (GTK_BOX (hb), image, FALSE, FALSE, 0);
236             gtk_widget_show_all (i);
238             gtk_container_add (GTK_CONTAINER (i), hb);
240             gtk_menu_append (GTK_MENU (m), i);
242             if (gradient == gr_selected) {
243                 pos = idx;
244             }
245             idx ++;
246         }
247         gtk_widget_set_sensitive (om, TRUE);
248     }
250     gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m);
251     /* Select the current gradient, or the Multi/Nothing line */
252     if (gr_multi || gr_selected == NULL)
253         gtk_option_menu_set_history (GTK_OPTION_MENU (om), 0);
254     else 
255         gtk_option_menu_set_history (GTK_OPTION_MENU (om), pos);
257     return om;
261 void
262 gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi) 
264     if (drag && drag->selected) {
265         GrDragger *dragger = drag->selected;
266         for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
267             GrDraggable *draggable = (GrDraggable *) i->data;
268             SPGradient *gradient = sp_item_gradient_get_vector (draggable->item, draggable->fill_or_stroke);
269             SPGradientSpread spread = sp_item_gradient_get_spread (draggable->item, draggable->fill_or_stroke);
271             if (gradient != *gr_selected) {
272                 if (*gr_selected != NULL) {
273                     *gr_multi = true;
274                 } else {
275                     *gr_selected = gradient;
276                 }
277             }
278             if (spread != *spr_selected) {
279                 if (*spr_selected != INT_MAX) {
280                     *spr_multi = true;
281                 } else {
282                     *spr_selected = spread;
283                 }
284             }
285          }
286         return;
287     } 
289    // If no selected dragger, read desktop selection
290    for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
291         SPItem *item = SP_ITEM(i->data);
292         SPStyle *style = SP_OBJECT_STYLE (item);
294         if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) { 
295             SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
296             if (SP_IS_GRADIENT (server)) {
297                 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
298                 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
299                 if (gradient != *gr_selected) {
300                     if (*gr_selected != NULL) {
301                         *gr_multi = true;
302                     } else {
303                         *gr_selected = gradient;
304                     }
305                 }
306                 if (spread != *spr_selected) {
307                     if (*spr_selected != INT_MAX) {
308                         *spr_multi = true;
309                     } else {
310                         *spr_selected = spread;
311                     }
312                 }
313             }
314         }
315         if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) { 
316             SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
317             if (SP_IS_GRADIENT (server)) {
318                 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
319                 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
320                 if (gradient != *gr_selected) {
321                     if (*gr_selected != NULL) {
322                         *gr_multi = true;
323                     } else {
324                         *gr_selected = gradient;
325                     }
326                 }
327                 if (spread != *spr_selected) {
328                     if (*spr_selected != INT_MAX) {
329                         *spr_multi = true;
330                     } else {
331                         *spr_selected = spread;
332                     }
333                 }
334             }
335         }
336     }
337  }
339 static void 
340 gr_tb_selection_changed (Inkscape::Selection *, gpointer data)
342     GtkWidget *widget = (GtkWidget *) data;
344     SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
345     if (!desktop)
346         return;
348     Inkscape::Selection *selection = SP_DT_SELECTION (desktop); // take from desktop, not from args
349     if (!selection) 
350         return;
351     
352     SPEventContext *ev = SP_DT_EVENTCONTEXT (desktop);
354     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "menu");
355     if (om) gtk_widget_destroy (om);
357     SPGradient *gr_selected = NULL;
358     bool gr_multi = false;
360     SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
361     bool spr_multi = false;
363     gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
365     om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
366     g_object_set_data (G_OBJECT (widget), "menu", om);
368     GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "buttons");
369     gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
370   
371     gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
373     gtk_widget_show_all (widget);
376 static void
377 gr_tb_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
379     gr_tb_selection_changed (selection, data);
382 static void
383 gr_drag_selection_changed (gpointer dragger, gpointer data)
385     gr_tb_selection_changed (NULL, data);
388 static void
389 gr_defs_release (SPObject *defs, GtkWidget *widget)
391     gr_tb_selection_changed (NULL, (gpointer) widget);
394 static void
395 gr_defs_modified (SPObject *defs, guint flags, GtkWidget *widget)
397     gr_tb_selection_changed (NULL, (gpointer) widget);
400 static void
401 gr_fork (GtkWidget *button, GtkWidget *widget)
403     SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
404     SPDocument *document = SP_DT_DOCUMENT (desktop);
405     Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
406     SPEventContext *ev = SP_DT_EVENTCONTEXT (desktop);
407     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
409     if (om && document) {
410         GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
411         SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
413         if (gr) {
414             SPGradient *gr_new = sp_gradient_fork_vector_if_necessary (gr);
415             if (gr_new != gr) {
416                 gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr_new);
417                 sp_document_done (document);
418             }
419         }
420     }
422     spinbutton_defocus(GTK_OBJECT(widget));
425 static void gr_disconnect_sigc (GObject *obj, sigc::connection *connection) {
426     connection->disconnect();
427     delete connection;
430 static void gr_disconnect_gsignal (GObject *widget, gpointer defs) {
431     if (defs && G_IS_OBJECT(defs))
432         sp_signal_disconnect_by_data (defs, widget);
436 static void
437 gr_edit (GtkWidget *button, GtkWidget *widget)
439     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
441     spinbutton_defocus(GTK_OBJECT(widget));
443     if (om) {
444         GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
445         SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
447         if (gr) {
448             GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
449             gtk_widget_show (dialog);
450         }
451     }
454 GtkWidget *
455 gr_change_widget (SPDesktop *desktop)
457     Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
458     SPDocument *document = SP_DT_DOCUMENT (desktop);
459     SPEventContext *ev = SP_DT_EVENTCONTEXT (desktop);
461     SPGradient *gr_selected = NULL;
462     bool gr_multi = false;
464     SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
465     bool spr_multi = false;
467     GtkTooltips *tt = gtk_tooltips_new();
469     gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
470  
471     GtkWidget *widget = gtk_hbox_new(FALSE, FALSE);
472     gtk_object_set_data(GTK_OBJECT(widget), "dtw", desktop->canvas);
473     g_object_set_data (G_OBJECT (widget), "desktop", desktop);
475     GtkWidget *om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
476     g_object_set_data (G_OBJECT (widget), "menu", om);
477   
478     gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
480     {
481     GtkWidget *buttons = gtk_hbox_new(FALSE, 1);
483     /* Fork */
484     {
485         GtkWidget *hb = gtk_hbox_new(FALSE, 1);
486         GtkWidget *b = gtk_button_new_with_label(_("Duplicate"));
487         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);
488         gtk_widget_show(b);
489         gtk_container_add(GTK_CONTAINER(hb), b);
490         gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_fork), widget);
491         gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
492     }
494     /* Edit... */
495     {
496         GtkWidget *hb = gtk_hbox_new(FALSE, 1);
497         GtkWidget *b = gtk_button_new_with_label(_("Edit..."));
498         gtk_tooltips_set_tip(tt, b, _("Edit the stops of the gradient"), NULL);
499         gtk_widget_show(b);
500         gtk_container_add(GTK_CONTAINER(hb), b);
501         gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_edit), widget);
502         gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
503     }
505     gtk_box_pack_end (GTK_BOX(widget), buttons, FALSE, FALSE, 0);
506     g_object_set_data (G_OBJECT(widget), "buttons", buttons);
507     gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
508     }
510     // connect to selection modified and changed signals
511     sigc::connection *conn1 = new sigc::connection (selection->connectChanged(
512         sigc::bind (
513             sigc::ptr_fun(&gr_tb_selection_changed),
514             (gpointer)widget )
515     ));
516     sigc::connection *conn2 = new sigc::connection (selection->connectModified(
517         sigc::bind (
518             sigc::ptr_fun(&gr_tb_selection_modified),
519             (gpointer)widget )
520     ));
522     sigc::connection *conn3 = new sigc::connection (desktop->connectToolSubselectionChanged(
523         sigc::bind (
524             sigc::ptr_fun(&gr_drag_selection_changed),
525             (gpointer)widget )
526     ));
528     // when widget is destroyed, disconnect
529     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
530     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
531     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
533     // connect to release and modified signals of the defs (i.e. when someone changes gradient)
534     g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (document)), "release", G_CALLBACK (gr_defs_release), widget);
535     g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (document)), "modified", G_CALLBACK (gr_defs_modified), widget);
537     // when widget is destroyed, disconnect
538     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_gsignal), G_OBJECT (SP_DOCUMENT_DEFS (document)));
539     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_gsignal), G_OBJECT (SP_DOCUMENT_DEFS (document)));
541     gtk_widget_show_all (widget);
542     return widget;
545 GtkWidget *
546 sp_gradient_toolbox_new(SPDesktop *desktop)
548     GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
550     gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
551     gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
553     GtkTooltips *tt = gtk_tooltips_new();
555     sp_toolbox_add_label(tbl, _("<b>New:</b>"));
557     aux_toolbox_space(tbl, AUX_SPACING);
559     {
560     GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
561     GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
563     {
564     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
565                                               SP_BUTTON_TYPE_TOGGLE,
566                                               NULL,
567                                               "fill_gradient",
568                                               _("Create linear gradient"),
569                                               tt);
570     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
571     g_object_set_data(G_OBJECT(tbl), "linear", button);
572     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
573               prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
574     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
575     }
577     {
578     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
579                                               SP_BUTTON_TYPE_TOGGLE,
580                                               NULL,
581                                               "fill_radial",
582                                               _("Create radial (elliptic or circular) gradient"),
583                                               tt);
584     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
585     g_object_set_data(G_OBJECT(tbl), "radial", button);
586     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
587               prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
588     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
589     }
591     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
592     gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
593     }
595     aux_toolbox_space(tbl, AUX_SPACING);
597     sp_toolbox_add_label(tbl, _("on"), false);
599     aux_toolbox_space(tbl, AUX_SPACING);
601     {
602         GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
603     GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
605     {
606     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
607                                               SP_BUTTON_TYPE_TOGGLE,
608                                               NULL,
609                                               "controls_fill",
610                                               _("Create gradient in the fill"),
611                                               tt);
612     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
613     g_object_set_data(G_OBJECT(tbl), "fill", button);
614     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
615                                   prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 1);
616     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
617     }
619     {
620     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
621                                               SP_BUTTON_TYPE_TOGGLE,
622                                               NULL,
623                                               "controls_stroke",
624                                               _("Create gradient in the stroke"),
625                                               tt);
626     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
627     g_object_set_data(G_OBJECT(tbl), "stroke", button);
628     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
629                                   prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 0);
630     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
631     }
633     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
634     gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
635     }
638     sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
640     aux_toolbox_space(tbl, AUX_SPACING);
642     {
643         GtkWidget *vectors = gr_change_widget (desktop);
644         gtk_box_pack_start (GTK_BOX (tbl), vectors, FALSE, FALSE, 0);
645     }
647     gtk_widget_show_all(tbl);
648     sp_set_font_size_smaller (tbl);
650     return tbl;
656 /*
657   Local Variables:
658   mode:c++
659   c-file-style:"stroustrup"
660   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
661   indent-tabs-mode:nil
662   fill-column:99
663   End:
664 */
665 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :