Code

Merge and cleanup of GSoC C++-ification project.
[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  *   Abhishek Sharma
8  *
9  * Copyright (C) 2007 Johan Engelen
10  * Copyright (C) 2005 authors
11  *
12  * Released under GNU GPL, read the file 'COPYING' for more information
13  */
15 #ifdef HAVE_CONFIG_H
16 # include "config.h"
17 #endif
19 #include <gtk/gtk.h>
21 #include "macros.h"
22 #include "widgets/button.h"
23 #include "widgets/widget-sizes.h"
24 #include "widgets/spw-utilities.h"
25 #include "widgets/spinbutton-events.h"
26 #include "widgets/gradient-vector.h"
27 #include "widgets/gradient-image.h"
28 #include "style.h"
30 #include "preferences.h"
31 #include "document-private.h"
32 #include "desktop.h"
33 #include "desktop-handles.h"
34 #include <glibmm/i18n.h>
36 #include "gradient-context.h"
37 #include "gradient-drag.h"
38 #include "sp-linear-gradient.h"
39 #include "sp-radial-gradient.h"
40 #include "gradient-chemistry.h"
41 #include "selection.h"
42 #include "ui/icon-names.h"
44 #include "toolbox.h"
46 using Inkscape::DocumentUndo;
48 //########################
49 //##       Gradient     ##
50 //########################
52 static void gr_toggle_type (GtkWidget *button, gpointer data) {
53     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
54     GtkWidget *linear = (GtkWidget *) g_object_get_data (G_OBJECT(data), "linear");
55     GtkWidget *radial = (GtkWidget *) g_object_get_data (G_OBJECT(data), "radial");
56     if (button == linear && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (linear))) {
57         prefs->setInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR);
58         if (radial) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radial), FALSE);
59     } else if (button == radial && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radial))) {
60         prefs->setInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_RADIAL);
61         if (linear) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear), FALSE);
62     }
63 }
65 static void gr_toggle_fillstroke (GtkWidget *button, gpointer data) {
66     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
67     GtkWidget *fill = (GtkWidget *) g_object_get_data (G_OBJECT(data), "fill");
68     GtkWidget *stroke = (GtkWidget *) g_object_get_data (G_OBJECT(data), "stroke");
69     if (button == fill && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fill))) {
70         prefs->setBool("/tools/gradient/newfillorstroke", true);
71         if (stroke) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (stroke), FALSE);
72     } else if (button == stroke && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (stroke))) {
73         prefs->setBool("/tools/gradient/newfillorstroke", false);
74         if (fill) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fill), FALSE);
75     }
76 }
78 void gr_apply_gradient_to_item( SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke )
79 {
80     SPStyle *style = item->style;
82     if (do_fill) {
83         if (style && (style->fill.isPaintserver()) &&
84             SP_IS_GRADIENT( item->style->getFillPaintServer() )) {
85             SPPaintServer *server = item->style->getFillPaintServer();
86             if ( SP_IS_LINEARGRADIENT(server) ) {
87                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, true);
88             } else if ( SP_IS_RADIALGRADIENT(server) ) {
89                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, true);
90             }
91         } else if (new_fill) {
92             sp_item_set_gradient(item, gr, new_type, true);
93         }
94     }
96     if (do_stroke) {
97         if (style && (style->stroke.isPaintserver()) &&
98             SP_IS_GRADIENT( item->style->getStrokePaintServer() )) {
99             SPPaintServer *server = item->style->getStrokePaintServer();
100             if ( SP_IS_LINEARGRADIENT(server) ) {
101                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, false);
102             } else if ( SP_IS_RADIALGRADIENT(server) ) {
103                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, false);
104             }
105         } else if (!new_fill) {
106             sp_item_set_gradient(item, gr, new_type, false);
107         }
108     }
111 /**
112 Applies gradient vector gr to the gradients attached to the selected dragger of drag, or if none,
113 to all objects in selection. If there was no previous gradient on an item, uses gradient type and
114 fill/stroke setting from preferences to create new default (linear: left/right; radial: centered)
115 gradient.
116 */
117 void
118 gr_apply_gradient (Inkscape::Selection *selection, GrDrag *drag, SPGradient *gr)
120     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
121     SPGradientType new_type = (SPGradientType) prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR);
122     guint new_fill = prefs->getBool("/tools/gradient/newfillorstroke", true);
125     // GRADIENTFIXME: make this work for multiple selected draggers.
127     // First try selected dragger
128     if (drag && drag->selected) {
129         GrDragger *dragger = (GrDragger*) drag->selected->data;
130         for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
131             GrDraggable *draggable = (GrDraggable *) i->data;
132             gr_apply_gradient_to_item (draggable->item, gr, new_type, new_fill, draggable->fill_or_stroke, !draggable->fill_or_stroke);
133         }
134         return;
135     }
137    // If no drag or no dragger selected, act on selection
138    for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
139        gr_apply_gradient_to_item (SP_ITEM(i->data), gr, new_type, new_fill, new_fill, !new_fill);
140    }
143 void
144 gr_item_activate (GtkMenuItem *menuitem, gpointer data)
146     SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT (menuitem), "gradient");
147     gr = sp_gradient_ensure_vector_normalized(gr);
149     SPDesktop *desktop = (SPDesktop *) data;
150     Inkscape::Selection *selection = sp_desktop_selection (desktop);
151     SPEventContext *ev = sp_desktop_event_context (desktop);
153     gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
155     DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
156                        _("Assign gradient to object"));
159 gchar *
160 gr_prepare_label (SPObject *obj)
162     const gchar *id = obj->defaultLabel();
163     if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15)))
164         return g_strdup_printf ("<small>#%s</small>", id+15);
165     return g_strdup_printf ("<small>%s</small>", id);
168 GtkWidget *gr_vector_list(SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
170     SPDocument *document = sp_desktop_document (desktop);
172     GtkWidget *om = gtk_option_menu_new ();
173     GtkWidget *m = gtk_menu_new ();
175     GSList *gl = NULL;
176     const GSList *gradients = document->getResourceList("gradient");
177     for (const GSList *i = gradients; i != NULL; i = i->next) {
178         SPGradient *grad = SP_GRADIENT(i->data);
179         if ( grad->hasStops() && !grad->isSolid() ) {
180             gl = g_slist_prepend (gl, i->data);
181         }
182     }
183     gl = g_slist_reverse (gl);
185     guint pos = 0;
186     guint idx = 0;
188     if (!gl) {
189         // The document has no gradients
190         GtkWidget *l = gtk_label_new("");
191         gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients</small>"));
192         GtkWidget *i = gtk_menu_item_new ();
193         gtk_container_add (GTK_CONTAINER (i), l);
195         gtk_widget_show (i);
196         gtk_menu_append (GTK_MENU (m), i);
197         gtk_widget_set_sensitive (om, FALSE);
198     } else if (selection_empty) {
199         // Document has gradients, but nothing is currently selected.
200         GtkWidget *l = gtk_label_new("");
201         gtk_label_set_markup (GTK_LABEL(l), _("<small>Nothing selected</small>"));
202         GtkWidget *i = gtk_menu_item_new ();
203         gtk_container_add (GTK_CONTAINER (i), l);
205         gtk_widget_show (i);
206         gtk_menu_append (GTK_MENU (m), i);
207         gtk_widget_set_sensitive (om, FALSE);
208     } else {
210         if (gr_selected == NULL) {
211             GtkWidget *l = gtk_label_new("");
212             gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients in selection</small>"));
213             GtkWidget *i = gtk_menu_item_new ();
214             gtk_container_add (GTK_CONTAINER (i), l);
216             gtk_widget_show (i);
217             gtk_menu_append (GTK_MENU (m), i);
218         }
220         if (gr_multi) {
221             GtkWidget *l = gtk_label_new("");
222             gtk_label_set_markup (GTK_LABEL(l), _("<small>Multiple gradients</small>"));
223             GtkWidget *i = gtk_menu_item_new ();
224             gtk_container_add (GTK_CONTAINER (i), l);
226             gtk_widget_show (i);
227             gtk_menu_append (GTK_MENU (m), i);
228         }
230         while (gl) {
231             SPGradient *gradient = SP_GRADIENT (gl->data);
232             gl = g_slist_remove (gl, gradient);
234             GtkWidget *i = gtk_menu_item_new ();
235             g_object_set_data (G_OBJECT (i), "gradient", gradient);
236             g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (gr_item_activate), desktop);
238             GtkWidget *image = sp_gradient_image_new (gradient);
240             GtkWidget *hb = gtk_hbox_new (FALSE, 4);
241             GtkWidget *l = gtk_label_new ("");
242             gchar *label = gr_prepare_label(gradient);
243             gtk_label_set_markup (GTK_LABEL(l), label);
244             g_free (label);
245             gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
246             gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
247             gtk_box_pack_start (GTK_BOX (hb), image, FALSE, FALSE, 0);
249             gtk_widget_show_all (i);
251             gtk_container_add (GTK_CONTAINER (i), hb);
253             gtk_menu_append (GTK_MENU (m), i);
255             if (gradient == gr_selected) {
256                 pos = idx;
257             }
258             idx ++;
259         }
260         gtk_widget_set_sensitive (om, TRUE);
261     }
263     gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m);
264     /* Select the current gradient, or the Multi/Nothing line */
265     if (gr_multi || gr_selected == NULL)
266         gtk_option_menu_set_history (GTK_OPTION_MENU (om), 0);
267     else
268         gtk_option_menu_set_history (GTK_OPTION_MENU (om), pos);
270     return om;
274 void gr_read_selection( Inkscape::Selection *selection,
275                         GrDrag *drag,
276                         SPGradient *&gr_selected,
277                         bool &gr_multi,
278                         SPGradientSpread &spr_selected,
279                         bool &spr_multi )
281     if (drag && drag->selected) {
282         // GRADIENTFIXME: make this work for more than one selected dragger?
283         GrDragger *dragger = static_cast<GrDragger*>(drag->selected->data);
284         for (GSList const* i = dragger->draggables; i; i = i->next) { // for all draggables of dragger
285             GrDraggable *draggable = static_cast<GrDraggable *>(i->data);
286             SPGradient *gradient = sp_item_gradient_get_vector(draggable->item, draggable->fill_or_stroke);
287             SPGradientSpread spread = sp_item_gradient_get_spread(draggable->item, draggable->fill_or_stroke);
289             if (gradient && gradient->isSolid()) {
290                 gradient = 0;
291             }
293             if (gradient && (gradient != gr_selected)) {
294                 if (gr_selected) {
295                     gr_multi = true;
296                 } else {
297                     gr_selected = gradient;
298                 }
299             }
300             if (spread != spr_selected) {
301                 if (spr_selected != INT_MAX) {
302                     spr_multi = true;
303                 } else {
304                     spr_selected = spread;
305                 }
306             }
307          }
308         return;
309     }
311    // If no selected dragger, read desktop selection
312    for (GSList const* i = selection->itemList(); i; i = i->next) {
313         SPItem *item = SP_ITEM(i->data);
314         SPStyle *style = item->style;
316         if (style && (style->fill.isPaintserver())) {
317             SPPaintServer *server = item->style->getFillPaintServer();
318             if ( SP_IS_GRADIENT(server) ) {
319                 SPGradient *gradient = SP_GRADIENT(server)->getVector();
320                 SPGradientSpread spread = SP_GRADIENT(server)->fetchSpread();
322                 if (gradient && gradient->isSolid()) {
323                     gradient = 0;
324                 }
326                 if (gradient && (gradient != gr_selected)) {
327                     if (gr_selected) {
328                         gr_multi = true;
329                     } else {
330                         gr_selected = gradient;
331                     }
332                 }
333                 if (spread != spr_selected) {
334                     if (spr_selected != INT_MAX) {
335                         spr_multi = true;
336                     } else {
337                         spr_selected = spread;
338                     }
339                 }
340             }
341         }
342         if (style && (style->stroke.isPaintserver())) {
343             SPPaintServer *server = item->style->getStrokePaintServer();
344             if ( SP_IS_GRADIENT(server) ) {
345                 SPGradient *gradient = SP_GRADIENT(server)->getVector();
346                 SPGradientSpread spread = SP_GRADIENT(server)->fetchSpread();
348                 if (gradient && gradient->isSolid()) {
349                     gradient = 0;
350                 }
352                 if (gradient && (gradient != gr_selected)) {
353                     if (gr_selected) {
354                         gr_multi = true;
355                     } else {
356                         gr_selected = gradient;
357                     }
358                 }
359                 if (spread != spr_selected) {
360                     if (spr_selected != INT_MAX) {
361                         spr_multi = true;
362                     } else {
363                         spr_selected = spread;
364                     }
365                 }
366             }
367         }
368     }
369  }
371 static void gr_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointer data)
373     GtkWidget *widget = GTK_WIDGET(data);
375     SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop"));
376     if (desktop) {
377         Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args
378         if (selection) {
379             SPEventContext *ev = sp_desktop_event_context(desktop);
381             GtkWidget *om = (GtkWidget *) g_object_get_data(G_OBJECT(widget), "menu");
382             if (om) {
383                 gtk_widget_destroy(om);
384                 om = 0;
385             }
387             SPGradient *gr_selected = 0;
388             bool gr_multi = false;
390             SPGradientSpread spr_selected = static_cast<SPGradientSpread>(INT_MAX); // meaning undefined
391             bool spr_multi = false;
393             gr_read_selection(selection, ev ? ev->get_drag() : 0, gr_selected, gr_multi, spr_selected, spr_multi);
395             om = gr_vector_list(desktop, selection->isEmpty(), gr_selected, gr_multi);
396             g_object_set_data(G_OBJECT(widget), "menu", om);
398             GtkWidget *buttons = (GtkWidget *) g_object_get_data(G_OBJECT(widget), "buttons");
399             gtk_widget_set_sensitive(buttons, (gr_selected && !gr_multi));
401             gtk_box_pack_start(GTK_BOX(widget), om, TRUE, TRUE, 0);
403             gtk_widget_show_all(widget);
404         }
405     }
408 static void
409 gr_tb_selection_modified (Inkscape::Selection *selection, guint /*flags*/, gpointer data)
411     gr_tb_selection_changed (selection, data);
414 static void
415 gr_drag_selection_changed (gpointer /*dragger*/, gpointer data)
417     gr_tb_selection_changed (NULL, data);
420 static void
421 gr_defs_release (SPObject */*defs*/, GtkWidget *widget)
423     gr_tb_selection_changed (NULL, (gpointer) widget);
426 static void
427 gr_defs_modified (SPObject */*defs*/, guint /*flags*/, GtkWidget *widget)
429     gr_tb_selection_changed (NULL, (gpointer) widget);
432 static void gr_disconnect_sigc (GObject */*obj*/, sigc::connection *connection) {
433     connection->disconnect();
434     delete connection;
437 static void
438 gr_edit (GtkWidget */*button*/, GtkWidget *widget)
440     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
442     spinbutton_defocus(GTK_OBJECT(widget));
444     if (om) {
445         GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
446         SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
448         if (gr) {
449             GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
450             gtk_widget_show (dialog);
451         }
452     }
455 GtkWidget * gr_change_widget(SPDesktop *desktop)
457     Inkscape::Selection *selection = sp_desktop_selection (desktop);
458     SPDocument *document = sp_desktop_document (desktop);
459     SPEventContext *ev = sp_desktop_event_context (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() : 0, gr_selected, gr_multi, spr_selected, spr_multi);
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);
478     gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
480     {
481     GtkWidget *buttons = gtk_hbox_new(FALSE, 1);
483     /* Edit... */
484     {
485         GtkWidget *hb = gtk_hbox_new(FALSE, 1);
486         GtkWidget *b = gtk_button_new_with_label(_("Edit..."));
487         gtk_tooltips_set_tip(tt, b, _("Edit the stops of the gradient"), 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_edit), widget);
491         gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
492     }
494     gtk_box_pack_end (GTK_BOX(widget), buttons, FALSE, FALSE, 0);
495     g_object_set_data (G_OBJECT(widget), "buttons", buttons);
496     gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
497     }
499     // connect to selection modified and changed signals
500     sigc::connection *conn1 = new sigc::connection (selection->connectChanged(
501         sigc::bind (
502             sigc::ptr_fun(&gr_tb_selection_changed),
503             (gpointer)widget )
504     ));
505     sigc::connection *conn2 = new sigc::connection (selection->connectModified(
506         sigc::bind (
507             sigc::ptr_fun(&gr_tb_selection_modified),
508             (gpointer)widget )
509     ));
511     sigc::connection *conn3 = new sigc::connection (desktop->connectToolSubselectionChanged(
512         sigc::bind (
513             sigc::ptr_fun(&gr_drag_selection_changed),
514             (gpointer)widget )
515     ));
517     // when widget is destroyed, disconnect
518     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
519     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
520     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
522     // connect to release and modified signals of the defs (i.e. when someone changes gradient)
523     sigc::connection *release_connection = new sigc::connection();
524     *release_connection = SP_DOCUMENT_DEFS(document)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), widget));
525     sigc::connection *modified_connection = new sigc::connection();
526     *modified_connection = SP_DOCUMENT_DEFS(document)->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), widget));
528     // when widget is destroyed, disconnect
529     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
530     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
532     gtk_widget_show_all (widget);
533     return widget;
536 GtkWidget *
537 sp_gradient_toolbox_new(SPDesktop *desktop)
539     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
540     GtkWidget *tbl = gtk_toolbar_new();
542     gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
543     gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
545     GtkTooltips *tt = gtk_tooltips_new();
547     sp_toolbox_add_label(tbl, _("<b>New:</b>"));
549     // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
551     {
552     GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
553     GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
555     {
556     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
557                                               SP_BUTTON_TYPE_TOGGLE,
558                                               NULL,
559                                               INKSCAPE_ICON_PAINT_GRADIENT_LINEAR,
560                                               _("Create linear gradient"),
561                                               tt);
562     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
563     g_object_set_data(G_OBJECT(tbl), "linear", button);
564     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
565               prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
566     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
567     }
569     {
570     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
571                                               SP_BUTTON_TYPE_TOGGLE,
572                                               NULL,
573                                               INKSCAPE_ICON_PAINT_GRADIENT_RADIAL,
574                                               _("Create radial (elliptic or circular) gradient"),
575                                               tt);
576     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
577     g_object_set_data(G_OBJECT(tbl), "radial", button);
578     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
579               prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
580     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
581     }
583     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
584     gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), cvbox, "", "" );
585     }
587     // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
589     sp_toolbox_add_label(tbl, _("on"), false);
591     // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
593     {
594         GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
595     GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
597     {
598     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
599                                               SP_BUTTON_TYPE_TOGGLE,
600                                               NULL,
601                                               INKSCAPE_ICON_OBJECT_FILL,
602                                               _("Create gradient in the fill"),
603                                               tt);
604     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
605     g_object_set_data(G_OBJECT(tbl), "fill", button);
606     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
607                                   prefs->getBool("/tools/gradient/newfillorstroke", true));
608     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
609     }
611     {
612     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
613                                               SP_BUTTON_TYPE_TOGGLE,
614                                               NULL,
615                                               INKSCAPE_ICON_OBJECT_STROKE,
616                                               _("Create gradient in the stroke"),
617                                               tt);
618     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
619     g_object_set_data(G_OBJECT(tbl), "stroke", button);
620     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
621                                   !prefs->getBool("/tools/gradient/newfillorstroke", true));
622     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
623     }
625     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
626     gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), cvbox, "", "" );
627     }
630     sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
632     // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
634     {
635         GtkWidget *vectors = gr_change_widget (desktop);
636         gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), vectors, "", "" );
637     }
639     gtk_widget_show_all(tbl);
640     sp_set_font_size_smaller (tbl);
642     return tbl;
648 /*
649   Local Variables:
650   mode:c++
651   c-file-style:"stroustrup"
652   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
653   indent-tabs-mode:nil
654   fill-column:99
655   End:
656 */
657 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :