Code

Conversion to toolbars and preserve size upon undock
[inkscape.git] / src / widgets / gradient-toolbar.cpp
1 /*
2  * Gradient aux toolbar
3  *
4  * Authors:
5  *   bulia byak <bulia@dr.com>
6  *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
7  *
8  * Copyright (C) 2007 Johan Engelen
9  * Copyright (C) 2005 authors
10  *
11  * Released under GNU GPL, read the file 'COPYING' for more information
12  */
14 #ifdef HAVE_CONFIG_H
15 # include "config.h"
16 #endif
18 #include <gtk/gtk.h>
20 #include "macros.h"
21 #include "widgets/button.h"
22 #include "widgets/widget-sizes.h"
23 #include "widgets/spw-utilities.h"
24 #include "widgets/spinbutton-events.h"
25 #include "widgets/gradient-vector.h"
26 #include "widgets/gradient-image.h"
27 #include "style.h"
29 #include "prefs-utils.h"
30 #include "document-private.h"
31 #include "desktop.h"
32 #include "desktop-handles.h"
33 #include <glibmm/i18n.h>
35 #include "gradient-context.h"
36 #include "gradient-drag.h"
37 #include "sp-linear-gradient.h"
38 #include "sp-radial-gradient.h"
39 #include "gradient-chemistry.h"
40 #include "selection.h"
42 #include "toolbox.h"
45 //########################
46 //##       Gradient     ##
47 //########################
49 static void gr_toggle_type (GtkWidget *button, gpointer data) {
50     GtkWidget *linear = (GtkWidget *) g_object_get_data (G_OBJECT(data), "linear");
51     GtkWidget *radial = (GtkWidget *) g_object_get_data (G_OBJECT(data), "radial");
52     if (button == linear && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (linear))) {
53         prefs_set_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
54         if (radial) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radial), FALSE);
55     } else if (button == radial && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radial))) {
56         prefs_set_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_RADIAL);
57         if (linear) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear), FALSE);
58     }
59 }
61 static void gr_toggle_fillstroke (GtkWidget *button, gpointer data) {
62     GtkWidget *fill = (GtkWidget *) g_object_get_data (G_OBJECT(data), "fill");
63     GtkWidget *stroke = (GtkWidget *) g_object_get_data (G_OBJECT(data), "stroke");
64     if (button == fill && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fill))) {
65         prefs_set_int_attribute ("tools.gradient", "newfillorstroke", 1);
66         if (stroke) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (stroke), FALSE);
67     } else if (button == stroke && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (stroke))) {
68         prefs_set_int_attribute ("tools.gradient", "newfillorstroke", 0);
69         if (fill) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fill), FALSE);
70     }
71 }
73 void
74 gr_apply_gradient_to_item (SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke)
75 {
76     SPStyle *style = SP_OBJECT_STYLE (item);
78     if (do_fill) {
79         if (style && (style->fill.isPaintserver()) &&
80             SP_IS_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (item))) {
81             SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
82             if (SP_IS_LINEARGRADIENT (server)) {
83                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, true);
84             } else if (SP_IS_RADIALGRADIENT (server)) {
85                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, true);
86             }
87         } else if (new_fill) {
88             sp_item_set_gradient(item, gr, new_type, true);
89         }
90     }
92     if (do_stroke) {
93         if (style && (style->stroke.isPaintserver()) &&
94             SP_IS_GRADIENT (SP_OBJECT_STYLE_STROKE_SERVER (item))) {
95             SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
96             if (SP_IS_LINEARGRADIENT (server)) {
97                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, false);
98             } else if (SP_IS_RADIALGRADIENT (server)) {
99                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, false);
100             }
101         } else if (!new_fill) {
102             sp_item_set_gradient(item, gr, new_type, false);
103         }
104     }
107 /**
108 Applies gradient vector gr to the gradients attached to the selected dragger of drag, or if none,
109 to all objects in selection. If there was no previous gradient on an item, uses gradient type and
110 fill/stroke setting from preferences to create new default (linear: left/right; radial: centered)
111 gradient.
112 */
113 void
114 gr_apply_gradient (Inkscape::Selection *selection, GrDrag *drag, SPGradient *gr)
116     SPGradientType new_type = (SPGradientType) prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
117     guint new_fill = prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1);
120     // GRADIENTFIXME: make this work for multiple selected draggers.
122     // First try selected dragger
123     if (drag && drag->selected) {
124         GrDragger *dragger = (GrDragger*) drag->selected->data;
125         for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
126             GrDraggable *draggable = (GrDraggable *) i->data;
127             gr_apply_gradient_to_item (draggable->item, gr, new_type, new_fill, draggable->fill_or_stroke, !draggable->fill_or_stroke);
128         }
129         return;
130     }
132    // If no drag or no dragger selected, act on selection
133    for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
134        gr_apply_gradient_to_item (SP_ITEM(i->data), gr, new_type, new_fill, new_fill, !new_fill);
135    }
138 void
139 gr_item_activate (GtkMenuItem *menuitem, gpointer data)
141     SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT (menuitem), "gradient");
142     gr = sp_gradient_ensure_vector_normalized(gr);
144     SPDesktop *desktop = (SPDesktop *) data;
145     Inkscape::Selection *selection = sp_desktop_selection (desktop);
146     SPEventContext *ev = sp_desktop_event_context (desktop);
148     gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
150     sp_document_done (sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
151                       _("Assign gradient to object"));
154 gchar *
155 gr_prepare_label (SPObject *obj)
157     const gchar *id = obj->defaultLabel();
158     if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15)))
159         return g_strdup_printf ("<small>#%s</small>", id+15);
160     return g_strdup_printf ("<small>%s</small>", id);
163 GtkWidget *
164 gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
166     SPDocument *document = sp_desktop_document (desktop);
168     GtkWidget *om = gtk_option_menu_new ();
169     GtkWidget *m = gtk_menu_new ();
171     GSList *gl = NULL;
172     const GSList *gradients = sp_document_get_resource_list (document, "gradient");
173     for (const GSList *i = gradients; i != NULL; i = i->next) {
174         if (SP_GRADIENT_HAS_STOPS (i->data)) {
175             gl = g_slist_prepend (gl, i->data);
176         }
177     }
178     gl = g_slist_reverse (gl);
180     guint pos = 0;
181     guint idx = 0;
183     if (!gl) {
184         GtkWidget *l = gtk_label_new("");
185         gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients</small>"));
186         GtkWidget *i = gtk_menu_item_new ();
187         gtk_container_add (GTK_CONTAINER (i), l);
189         gtk_widget_show (i);
190         gtk_menu_append (GTK_MENU (m), i);
191         gtk_widget_set_sensitive (om, FALSE);
192     } else if (selection_empty) {
193         GtkWidget *l = gtk_label_new("");
194         gtk_label_set_markup (GTK_LABEL(l), _("<small>Nothing selected</small>"));
195         GtkWidget *i = gtk_menu_item_new ();
196         gtk_container_add (GTK_CONTAINER (i), l);
198         gtk_widget_show (i);
199         gtk_menu_append (GTK_MENU (m), i);
200         gtk_widget_set_sensitive (om, FALSE);
201     } else {
203         if (gr_selected == NULL) {
204             GtkWidget *l = gtk_label_new("");
205             gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients in selection</small>"));
206             GtkWidget *i = gtk_menu_item_new ();
207             gtk_container_add (GTK_CONTAINER (i), l);
209             gtk_widget_show (i);
210             gtk_menu_append (GTK_MENU (m), i);
211         }
213         if (gr_multi) {
214             GtkWidget *l = gtk_label_new("");
215             gtk_label_set_markup (GTK_LABEL(l), _("<small>Multiple gradients</small>"));
216             GtkWidget *i = gtk_menu_item_new ();
217             gtk_container_add (GTK_CONTAINER (i), l);
219             gtk_widget_show (i);
220             gtk_menu_append (GTK_MENU (m), i);
221         }
223         while (gl) {
224             SPGradient *gradient = SP_GRADIENT (gl->data);
225             gl = g_slist_remove (gl, gradient);
227             GtkWidget *i = gtk_menu_item_new ();
228             g_object_set_data (G_OBJECT (i), "gradient", gradient);
229             g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (gr_item_activate), desktop);
231             GtkWidget *image = sp_gradient_image_new (gradient);
233             GtkWidget *hb = gtk_hbox_new (FALSE, 4);
234             GtkWidget *l = gtk_label_new ("");
235             gchar *label = gr_prepare_label (SP_OBJECT(gradient));
236             gtk_label_set_markup (GTK_LABEL(l), label);
237             g_free (label);
238             gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
239             gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
240             gtk_box_pack_start (GTK_BOX (hb), image, FALSE, FALSE, 0);
242             gtk_widget_show_all (i);
244             gtk_container_add (GTK_CONTAINER (i), hb);
246             gtk_menu_append (GTK_MENU (m), i);
248             if (gradient == gr_selected) {
249                 pos = idx;
250             }
251             idx ++;
252         }
253         gtk_widget_set_sensitive (om, TRUE);
254     }
256     gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m);
257     /* Select the current gradient, or the Multi/Nothing line */
258     if (gr_multi || gr_selected == NULL)
259         gtk_option_menu_set_history (GTK_OPTION_MENU (om), 0);
260     else
261         gtk_option_menu_set_history (GTK_OPTION_MENU (om), pos);
263     return om;
267 void
268 gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi)
270     if (drag && drag->selected) {
271         // GRADIENTFIXME: make this work for more than one selected dragger?
272         GrDragger *dragger = (GrDragger*) drag->selected->data;
273         for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
274             GrDraggable *draggable = (GrDraggable *) i->data;
275             SPGradient *gradient = sp_item_gradient_get_vector (draggable->item, draggable->fill_or_stroke);
276             SPGradientSpread spread = sp_item_gradient_get_spread (draggable->item, draggable->fill_or_stroke);
278             if (gradient != *gr_selected) {
279                 if (*gr_selected != NULL) {
280                     *gr_multi = true;
281                 } else {
282                     *gr_selected = gradient;
283                 }
284             }
285             if (spread != *spr_selected) {
286                 if (*spr_selected != INT_MAX) {
287                     *spr_multi = true;
288                 } else {
289                     *spr_selected = spread;
290                 }
291             }
292          }
293         return;
294     }
296    // If no selected dragger, read desktop selection
297    for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
298         SPItem *item = SP_ITEM(i->data);
299         SPStyle *style = SP_OBJECT_STYLE (item);
301         if (style && (style->fill.isPaintserver())) {
302             SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
303             if (SP_IS_GRADIENT (server)) {
304                 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
305                 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
306                 if (gradient != *gr_selected) {
307                     if (*gr_selected != NULL) {
308                         *gr_multi = true;
309                     } else {
310                         *gr_selected = gradient;
311                     }
312                 }
313                 if (spread != *spr_selected) {
314                     if (*spr_selected != INT_MAX) {
315                         *spr_multi = true;
316                     } else {
317                         *spr_selected = spread;
318                     }
319                 }
320             }
321         }
322         if (style && (style->stroke.isPaintserver())) {
323             SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
324             if (SP_IS_GRADIENT (server)) {
325                 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
326                 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
327                 if (gradient != *gr_selected) {
328                     if (*gr_selected != NULL) {
329                         *gr_multi = true;
330                     } else {
331                         *gr_selected = gradient;
332                     }
333                 }
334                 if (spread != *spr_selected) {
335                     if (*spr_selected != INT_MAX) {
336                         *spr_multi = true;
337                     } else {
338                         *spr_selected = spread;
339                     }
340                 }
341             }
342         }
343     }
344  }
346 static void
347 gr_tb_selection_changed (Inkscape::Selection *, gpointer data)
349     GtkWidget *widget = (GtkWidget *) data;
351     SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
352     if (!desktop)
353         return;
355     Inkscape::Selection *selection = sp_desktop_selection (desktop); // take from desktop, not from args
356     if (!selection)
357         return;
359     SPEventContext *ev = sp_desktop_event_context (desktop);
361     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "menu");
362     if (om) gtk_widget_destroy (om);
364     SPGradient *gr_selected = NULL;
365     bool gr_multi = false;
367     SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
368     bool spr_multi = false;
370     gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
372     om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
373     g_object_set_data (G_OBJECT (widget), "menu", om);
375     GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "buttons");
376     gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
378     gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
380     gtk_widget_show_all (widget);
383 static void
384 gr_tb_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
386     gr_tb_selection_changed (selection, data);
389 static void
390 gr_drag_selection_changed (gpointer dragger, gpointer data)
392     gr_tb_selection_changed (NULL, data);
395 static void
396 gr_defs_release (SPObject *defs, GtkWidget *widget)
398     gr_tb_selection_changed (NULL, (gpointer) widget);
401 static void
402 gr_defs_modified (SPObject *defs, guint flags, GtkWidget *widget)
404     gr_tb_selection_changed (NULL, (gpointer) widget);
407 static void gr_disconnect_sigc (GObject *obj, sigc::connection *connection) {
408     connection->disconnect();
409     delete connection;
412 static void
413 gr_edit (GtkWidget *button, GtkWidget *widget)
415     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
417     spinbutton_defocus(GTK_OBJECT(widget));
419     if (om) {
420         GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
421         SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
423         if (gr) {
424             GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
425             gtk_widget_show (dialog);
426         }
427     }
430 GtkWidget *
431 gr_change_widget (SPDesktop *desktop)
433     Inkscape::Selection *selection = sp_desktop_selection (desktop);
434     SPDocument *document = sp_desktop_document (desktop);
435     SPEventContext *ev = sp_desktop_event_context (desktop);
437     SPGradient *gr_selected = NULL;
438     bool gr_multi = false;
440     SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
441     bool spr_multi = false;
443     GtkTooltips *tt = gtk_tooltips_new();
445     gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
447     GtkWidget *widget = gtk_hbox_new(FALSE, FALSE);
448     gtk_object_set_data(GTK_OBJECT(widget), "dtw", desktop->canvas);
449     g_object_set_data (G_OBJECT (widget), "desktop", desktop);
451     GtkWidget *om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
452     g_object_set_data (G_OBJECT (widget), "menu", om);
454     gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
456     {
457     GtkWidget *buttons = gtk_hbox_new(FALSE, 1);
459     /* Edit... */
460     {
461         GtkWidget *hb = gtk_hbox_new(FALSE, 1);
462         GtkWidget *b = gtk_button_new_with_label(_("Edit..."));
463         gtk_tooltips_set_tip(tt, b, _("Edit the stops of the gradient"), NULL);
464         gtk_widget_show(b);
465         gtk_container_add(GTK_CONTAINER(hb), b);
466         gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_edit), widget);
467         gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
468     }
470     gtk_box_pack_end (GTK_BOX(widget), buttons, FALSE, FALSE, 0);
471     g_object_set_data (G_OBJECT(widget), "buttons", buttons);
472     gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
473     }
475     // connect to selection modified and changed signals
476     sigc::connection *conn1 = new sigc::connection (selection->connectChanged(
477         sigc::bind (
478             sigc::ptr_fun(&gr_tb_selection_changed),
479             (gpointer)widget )
480     ));
481     sigc::connection *conn2 = new sigc::connection (selection->connectModified(
482         sigc::bind (
483             sigc::ptr_fun(&gr_tb_selection_modified),
484             (gpointer)widget )
485     ));
487     sigc::connection *conn3 = new sigc::connection (desktop->connectToolSubselectionChanged(
488         sigc::bind (
489             sigc::ptr_fun(&gr_drag_selection_changed),
490             (gpointer)widget )
491     ));
493     // when widget is destroyed, disconnect
494     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
495     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
496     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
498     // connect to release and modified signals of the defs (i.e. when someone changes gradient)
499     sigc::connection *release_connection = new sigc::connection();
500     *release_connection = SP_DOCUMENT_DEFS(document)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), widget));
501     sigc::connection *modified_connection = new sigc::connection();
502     *modified_connection = SP_DOCUMENT_DEFS(document)->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), widget));
504     // when widget is destroyed, disconnect
505     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
506     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
508     gtk_widget_show_all (widget);
509     return widget;
512 GtkWidget *
513 sp_gradient_toolbox_new(SPDesktop *desktop)
515     GtkWidget *tbl = gtk_toolbar_new();
517     gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
518     gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
520     GtkTooltips *tt = gtk_tooltips_new();
522     sp_toolbox_add_label(tbl, _("<b>New:</b>"));
524     // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
526     {
527     GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
528     GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
530     {
531     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
532                                               SP_BUTTON_TYPE_TOGGLE,
533                                               NULL,
534                                               "fill_gradient",
535                                               _("Create linear gradient"),
536                                               tt);
537     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
538     g_object_set_data(G_OBJECT(tbl), "linear", button);
539     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
540               prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
541     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
542     }
544     {
545     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
546                                               SP_BUTTON_TYPE_TOGGLE,
547                                               NULL,
548                                               "fill_radial",
549                                               _("Create radial (elliptic or circular) gradient"),
550                                               tt);
551     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
552     g_object_set_data(G_OBJECT(tbl), "radial", button);
553     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
554               prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
555     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
556     }
558     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
559     gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), cvbox, "", "" );
560     }
562     // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
564     sp_toolbox_add_label(tbl, _("on"), false);
566     // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
568     {
569         GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
570     GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
572     {
573     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
574                                               SP_BUTTON_TYPE_TOGGLE,
575                                               NULL,
576                                               "controls_fill",
577                                               _("Create gradient in the fill"),
578                                               tt);
579     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
580     g_object_set_data(G_OBJECT(tbl), "fill", button);
581     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
582                                   prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 1);
583     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
584     }
586     {
587     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
588                                               SP_BUTTON_TYPE_TOGGLE,
589                                               NULL,
590                                               "controls_stroke",
591                                               _("Create gradient in the stroke"),
592                                               tt);
593     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
594     g_object_set_data(G_OBJECT(tbl), "stroke", button);
595     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
596                                   prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 0);
597     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
598     }
600     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
601     gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), cvbox, "", "" );
602     }
605     sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
607     // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
609     {
610         GtkWidget *vectors = gr_change_widget (desktop);
611         gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), vectors, "", "" );
612     }
614     gtk_widget_show_all(tbl);
615     sp_set_font_size_smaller (tbl);
617     return tbl;
623 /*
624   Local Variables:
625   mode:c++
626   c-file-style:"stroustrup"
627   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
628   indent-tabs-mode:nil
629   fill-column:99
630   End:
631 */
632 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :