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.type == SP_PAINT_TYPE_PAINTSERVER) &&
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.type == SP_PAINT_TYPE_PAINTSERVER) &&
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.type == SP_PAINT_TYPE_PAINTSERVER)) {
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.type == SP_PAINT_TYPE_PAINTSERVER)) {
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
408 gr_fork (GtkWidget *button, GtkWidget *widget)
409 {
410 SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
411 SPDocument *document = sp_desktop_document (desktop);
412 Inkscape::Selection *selection = sp_desktop_selection (desktop);
413 SPEventContext *ev = sp_desktop_event_context (desktop);
414 GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
416 if (om && document) {
417 GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
418 SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
420 if (gr) {
421 SPGradient *gr_new = sp_gradient_fork_vector_if_necessary (gr);
422 if (gr_new != gr) {
423 gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr_new);
424 sp_document_done (document, SP_VERB_CONTEXT_GRADIENT,
425 _("Duplicate gradient"));
426 }
427 }
428 }
430 spinbutton_defocus(GTK_OBJECT(widget));
431 }
433 static void gr_disconnect_sigc (GObject *obj, sigc::connection *connection) {
434 connection->disconnect();
435 delete connection;
436 }
438 static void
439 gr_edit (GtkWidget *button, GtkWidget *widget)
440 {
441 GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
443 spinbutton_defocus(GTK_OBJECT(widget));
445 if (om) {
446 GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
447 SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
449 if (gr) {
450 GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
451 gtk_widget_show (dialog);
452 }
453 }
454 }
456 GtkWidget *
457 gr_change_widget (SPDesktop *desktop)
458 {
459 Inkscape::Selection *selection = sp_desktop_selection (desktop);
460 SPDocument *document = sp_desktop_document (desktop);
461 SPEventContext *ev = sp_desktop_event_context (desktop);
463 SPGradient *gr_selected = NULL;
464 bool gr_multi = false;
466 SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
467 bool spr_multi = false;
469 GtkTooltips *tt = gtk_tooltips_new();
471 gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
473 GtkWidget *widget = gtk_hbox_new(FALSE, FALSE);
474 gtk_object_set_data(GTK_OBJECT(widget), "dtw", desktop->canvas);
475 g_object_set_data (G_OBJECT (widget), "desktop", desktop);
477 GtkWidget *om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
478 g_object_set_data (G_OBJECT (widget), "menu", om);
480 gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
482 {
483 GtkWidget *buttons = gtk_hbox_new(FALSE, 1);
485 /* Fork */
486 {
487 GtkWidget *hb = gtk_hbox_new(FALSE, 1);
488 GtkWidget *b = gtk_button_new_with_label(_("Duplicate"));
489 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);
490 gtk_widget_show(b);
491 gtk_container_add(GTK_CONTAINER(hb), b);
492 gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_fork), widget);
493 gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
494 }
496 /* Edit... */
497 {
498 GtkWidget *hb = gtk_hbox_new(FALSE, 1);
499 GtkWidget *b = gtk_button_new_with_label(_("Edit..."));
500 gtk_tooltips_set_tip(tt, b, _("Edit the stops of the gradient"), NULL);
501 gtk_widget_show(b);
502 gtk_container_add(GTK_CONTAINER(hb), b);
503 gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_edit), widget);
504 gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
505 }
507 gtk_box_pack_end (GTK_BOX(widget), buttons, FALSE, FALSE, 0);
508 g_object_set_data (G_OBJECT(widget), "buttons", buttons);
509 gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
510 }
512 // connect to selection modified and changed signals
513 sigc::connection *conn1 = new sigc::connection (selection->connectChanged(
514 sigc::bind (
515 sigc::ptr_fun(&gr_tb_selection_changed),
516 (gpointer)widget )
517 ));
518 sigc::connection *conn2 = new sigc::connection (selection->connectModified(
519 sigc::bind (
520 sigc::ptr_fun(&gr_tb_selection_modified),
521 (gpointer)widget )
522 ));
524 sigc::connection *conn3 = new sigc::connection (desktop->connectToolSubselectionChanged(
525 sigc::bind (
526 sigc::ptr_fun(&gr_drag_selection_changed),
527 (gpointer)widget )
528 ));
530 // when widget is destroyed, disconnect
531 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
532 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
533 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
535 // connect to release and modified signals of the defs (i.e. when someone changes gradient)
536 sigc::connection *release_connection = new sigc::connection();
537 *release_connection = SP_DOCUMENT_DEFS(document)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), widget));
538 sigc::connection *modified_connection = new sigc::connection();
539 *modified_connection = SP_DOCUMENT_DEFS(document)->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), widget));
541 // when widget is destroyed, disconnect
542 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
543 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
545 gtk_widget_show_all (widget);
546 return widget;
547 }
549 GtkWidget *
550 sp_gradient_toolbox_new(SPDesktop *desktop)
551 {
552 GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
554 gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
555 gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
557 GtkTooltips *tt = gtk_tooltips_new();
559 sp_toolbox_add_label(tbl, _("<b>New:</b>"));
561 aux_toolbox_space(tbl, AUX_SPACING);
563 {
564 GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
565 GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
567 {
568 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
569 SP_BUTTON_TYPE_TOGGLE,
570 NULL,
571 "fill_gradient",
572 _("Create linear gradient"),
573 tt);
574 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
575 g_object_set_data(G_OBJECT(tbl), "linear", button);
576 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
577 prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
578 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
579 }
581 {
582 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
583 SP_BUTTON_TYPE_TOGGLE,
584 NULL,
585 "fill_radial",
586 _("Create radial (elliptic or circular) gradient"),
587 tt);
588 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
589 g_object_set_data(G_OBJECT(tbl), "radial", button);
590 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
591 prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
592 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
593 }
595 gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
596 gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
597 }
599 aux_toolbox_space(tbl, AUX_SPACING);
601 sp_toolbox_add_label(tbl, _("on"), false);
603 aux_toolbox_space(tbl, AUX_SPACING);
605 {
606 GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
607 GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
609 {
610 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
611 SP_BUTTON_TYPE_TOGGLE,
612 NULL,
613 "controls_fill",
614 _("Create gradient in the fill"),
615 tt);
616 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
617 g_object_set_data(G_OBJECT(tbl), "fill", button);
618 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
619 prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 1);
620 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
621 }
623 {
624 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
625 SP_BUTTON_TYPE_TOGGLE,
626 NULL,
627 "controls_stroke",
628 _("Create gradient in the stroke"),
629 tt);
630 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
631 g_object_set_data(G_OBJECT(tbl), "stroke", button);
632 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
633 prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 0);
634 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
635 }
637 gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
638 gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
639 }
642 sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
644 aux_toolbox_space(tbl, AUX_SPACING);
646 {
647 GtkWidget *vectors = gr_change_widget (desktop);
648 gtk_box_pack_start (GTK_BOX (tbl), vectors, FALSE, FALSE, 0);
649 }
651 gtk_widget_show_all(tbl);
652 sp_set_font_size_smaller (tbl);
654 return tbl;
655 }
660 /*
661 Local Variables:
662 mode:c++
663 c-file-style:"stroustrup"
664 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
665 indent-tabs-mode:nil
666 fill-column:99
667 End:
668 */
669 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :