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 }
105 }
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)
115 {
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 }
136 }
138 void
139 gr_item_activate (GtkMenuItem *menuitem, gpointer data)
140 {
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"));
152 }
154 gchar *
155 gr_prepare_label (SPObject *obj)
156 {
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);
161 }
163 GtkWidget *
164 gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
165 {
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;
264 }
267 void
268 gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi)
269 {
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)
348 {
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);
381 }
383 static void
384 gr_tb_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
385 {
386 gr_tb_selection_changed (selection, data);
387 }
389 static void
390 gr_drag_selection_changed (gpointer dragger, gpointer data)
391 {
392 gr_tb_selection_changed (NULL, data);
393 }
395 static void
396 gr_defs_release (SPObject *defs, GtkWidget *widget)
397 {
398 gr_tb_selection_changed (NULL, (gpointer) widget);
399 }
401 static void
402 gr_defs_modified (SPObject *defs, guint flags, GtkWidget *widget)
403 {
404 gr_tb_selection_changed (NULL, (gpointer) widget);
405 }
407 static void gr_disconnect_sigc (GObject *obj, sigc::connection *connection) {
408 connection->disconnect();
409 delete connection;
410 }
412 static void
413 gr_edit (GtkWidget *button, GtkWidget *widget)
414 {
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 }
428 }
430 GtkWidget *
431 gr_change_widget (SPDesktop *desktop)
432 {
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;
510 }
512 GtkWidget *
513 sp_gradient_toolbox_new(SPDesktop *desktop)
514 {
515 GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
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 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_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
560 }
562 aux_toolbox_space(tbl, AUX_SPACING);
564 sp_toolbox_add_label(tbl, _("on"), false);
566 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_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
602 }
605 sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
607 aux_toolbox_space(tbl, AUX_SPACING);
609 {
610 GtkWidget *vectors = gr_change_widget (desktop);
611 gtk_box_pack_start (GTK_BOX (tbl), vectors, FALSE, FALSE, 0);
612 }
614 gtk_widget_show_all(tbl);
615 sp_set_font_size_smaller (tbl);
617 return tbl;
618 }
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 :