1 /*
2 * Gradient aux toolbar
3 *
4 * Authors:
5 * bulia byak <bulia@dr.com>
6 *
7 * Copyright (C) 2005 authors
8 *
9 * Released under GNU GPL, read the file 'COPYING' for more information
10 */
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
16 #include <gtk/gtk.h>
18 #include "macros.h"
19 #include "widgets/button.h"
20 #include "widgets/widget-sizes.h"
21 #include "widgets/spw-utilities.h"
22 #include "widgets/spinbutton-events.h"
23 #include "widgets/gradient-vector.h"
24 #include "widgets/gradient-image.h"
25 #include "style.h"
27 #include "prefs-utils.h"
28 #include "document-private.h"
29 #include "desktop.h"
30 #include "desktop-handles.h"
31 #include <glibmm/i18n.h>
33 #include "gradient-context.h"
34 #include "gradient-drag.h"
35 #include "sp-linear-gradient.h"
36 #include "sp-radial-gradient.h"
37 #include "gradient-chemistry.h"
38 #include "selection.h"
40 #include "toolbox.h"
43 //########################
44 //## Gradient ##
45 //########################
47 static void gr_toggle_type (GtkWidget *button, gpointer data) {
48 GtkWidget *linear = (GtkWidget *) g_object_get_data (G_OBJECT(data), "linear");
49 GtkWidget *radial = (GtkWidget *) g_object_get_data (G_OBJECT(data), "radial");
50 if (button == linear && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (linear))) {
51 prefs_set_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
52 if (radial) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radial), FALSE);
53 } else if (button == radial && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radial))) {
54 prefs_set_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_RADIAL);
55 if (linear) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear), FALSE);
56 }
57 }
59 static void gr_toggle_fillstroke (GtkWidget *button, gpointer data) {
60 GtkWidget *fill = (GtkWidget *) g_object_get_data (G_OBJECT(data), "fill");
61 GtkWidget *stroke = (GtkWidget *) g_object_get_data (G_OBJECT(data), "stroke");
62 if (button == fill && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fill))) {
63 prefs_set_int_attribute ("tools.gradient", "newfillorstroke", 1);
64 if (stroke) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (stroke), FALSE);
65 } else if (button == stroke && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (stroke))) {
66 prefs_set_int_attribute ("tools.gradient", "newfillorstroke", 0);
67 if (fill) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fill), FALSE);
68 }
69 }
71 void
72 gr_apply_gradient_to_item (SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke)
73 {
74 SPStyle *style = SP_OBJECT_STYLE (item);
76 if (do_fill) {
77 if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER) &&
78 SP_IS_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (item))) {
79 SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
80 if (SP_IS_LINEARGRADIENT (server)) {
81 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, true);
82 } else if (SP_IS_RADIALGRADIENT (server)) {
83 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, true);
84 }
85 } else if (new_fill) {
86 sp_item_set_gradient(item, gr, new_type, true);
87 }
88 }
90 if (do_stroke) {
91 if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER) &&
92 SP_IS_GRADIENT (SP_OBJECT_STYLE_STROKE_SERVER (item))) {
93 SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
94 if (SP_IS_LINEARGRADIENT (server)) {
95 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, false);
96 } else if (SP_IS_RADIALGRADIENT (server)) {
97 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, false);
98 }
99 } else if (!new_fill) {
100 sp_item_set_gradient(item, gr, new_type, false);
101 }
102 }
103 }
105 /**
106 Applies gradient vector gr to the gradients attached to the selected dragger of drag, or if none,
107 to all objects in selection. If there was no previous gradient on an item, uses gradient type and
108 fill/stroke setting from preferences to create new default (linear: left/right; radial: centered)
109 gradient.
110 */
111 void
112 gr_apply_gradient (Inkscape::Selection *selection, GrDrag *drag, SPGradient *gr)
113 {
114 SPGradientType new_type = (SPGradientType) prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
115 guint new_fill = prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1);
117 // First try selected dragger
118 if (drag && drag->selected) {
119 GrDragger *dragger = drag->selected;
120 for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
121 GrDraggable *draggable = (GrDraggable *) i->data;
122 gr_apply_gradient_to_item (draggable->item, gr, new_type, new_fill, draggable->fill_or_stroke, !draggable->fill_or_stroke);
123 }
124 return;
125 }
127 // If no drag or no dragger selected, act on selection
128 for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
129 gr_apply_gradient_to_item (SP_ITEM(i->data), gr, new_type, new_fill, true, true);
130 }
131 }
133 void
134 gr_item_activate (GtkMenuItem *menuitem, gpointer data)
135 {
136 SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT (menuitem), "gradient");
137 gr = sp_gradient_ensure_vector_normalized(gr);
139 SPDesktop *desktop = (SPDesktop *) data;
140 Inkscape::Selection *selection = sp_desktop_selection (desktop);
141 SPEventContext *ev = sp_desktop_event_context (desktop);
143 gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
145 sp_document_done (sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
146 /* TODO: annotate */ "gradient-toolbar.cpp:146");
147 }
149 gchar *
150 gr_prepare_label (SPObject *obj)
151 {
152 const gchar *id = obj->defaultLabel();
153 if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15)))
154 return g_strdup_printf ("<small>#%s</small>", id+15);
155 return g_strdup_printf ("<small>%s</small>", id);
156 }
158 GtkWidget *
159 gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
160 {
161 SPDocument *document = sp_desktop_document (desktop);
163 GtkWidget *om = gtk_option_menu_new ();
164 GtkWidget *m = gtk_menu_new ();
166 GSList *gl = NULL;
167 const GSList *gradients = sp_document_get_resource_list (document, "gradient");
168 for (const GSList *i = gradients; i != NULL; i = i->next) {
169 if (SP_GRADIENT_HAS_STOPS (i->data)) {
170 gl = g_slist_prepend (gl, i->data);
171 }
172 }
173 gl = g_slist_reverse (gl);
175 guint pos = 0;
176 guint idx = 0;
178 if (!gl) {
179 GtkWidget *l = gtk_label_new("");
180 gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients</small>"));
181 GtkWidget *i = gtk_menu_item_new ();
182 gtk_container_add (GTK_CONTAINER (i), l);
184 gtk_widget_show (i);
185 gtk_menu_append (GTK_MENU (m), i);
186 gtk_widget_set_sensitive (om, FALSE);
187 } else if (selection_empty) {
188 GtkWidget *l = gtk_label_new("");
189 gtk_label_set_markup (GTK_LABEL(l), _("<small>Nothing selected</small>"));
190 GtkWidget *i = gtk_menu_item_new ();
191 gtk_container_add (GTK_CONTAINER (i), l);
193 gtk_widget_show (i);
194 gtk_menu_append (GTK_MENU (m), i);
195 gtk_widget_set_sensitive (om, FALSE);
196 } else {
198 if (gr_selected == NULL) {
199 GtkWidget *l = gtk_label_new("");
200 gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients in selection</small>"));
201 GtkWidget *i = gtk_menu_item_new ();
202 gtk_container_add (GTK_CONTAINER (i), l);
204 gtk_widget_show (i);
205 gtk_menu_append (GTK_MENU (m), i);
206 }
208 if (gr_multi) {
209 GtkWidget *l = gtk_label_new("");
210 gtk_label_set_markup (GTK_LABEL(l), _("<small>Multiple gradients</small>"));
211 GtkWidget *i = gtk_menu_item_new ();
212 gtk_container_add (GTK_CONTAINER (i), l);
214 gtk_widget_show (i);
215 gtk_menu_append (GTK_MENU (m), i);
216 }
218 while (gl) {
219 SPGradient *gradient = SP_GRADIENT (gl->data);
220 gl = g_slist_remove (gl, gradient);
222 GtkWidget *i = gtk_menu_item_new ();
223 g_object_set_data (G_OBJECT (i), "gradient", gradient);
224 g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (gr_item_activate), desktop);
226 GtkWidget *image = sp_gradient_image_new (gradient);
228 GtkWidget *hb = gtk_hbox_new (FALSE, 4);
229 GtkWidget *l = gtk_label_new ("");
230 gchar *label = gr_prepare_label (SP_OBJECT(gradient));
231 gtk_label_set_markup (GTK_LABEL(l), label);
232 g_free (label);
233 gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
234 gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
235 gtk_box_pack_start (GTK_BOX (hb), image, FALSE, FALSE, 0);
237 gtk_widget_show_all (i);
239 gtk_container_add (GTK_CONTAINER (i), hb);
241 gtk_menu_append (GTK_MENU (m), i);
243 if (gradient == gr_selected) {
244 pos = idx;
245 }
246 idx ++;
247 }
248 gtk_widget_set_sensitive (om, TRUE);
249 }
251 gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m);
252 /* Select the current gradient, or the Multi/Nothing line */
253 if (gr_multi || gr_selected == NULL)
254 gtk_option_menu_set_history (GTK_OPTION_MENU (om), 0);
255 else
256 gtk_option_menu_set_history (GTK_OPTION_MENU (om), pos);
258 return om;
259 }
262 void
263 gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi)
264 {
265 if (drag && drag->selected) {
266 GrDragger *dragger = drag->selected;
267 for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
268 GrDraggable *draggable = (GrDraggable *) i->data;
269 SPGradient *gradient = sp_item_gradient_get_vector (draggable->item, draggable->fill_or_stroke);
270 SPGradientSpread spread = sp_item_gradient_get_spread (draggable->item, draggable->fill_or_stroke);
272 if (gradient != *gr_selected) {
273 if (*gr_selected != NULL) {
274 *gr_multi = true;
275 } else {
276 *gr_selected = gradient;
277 }
278 }
279 if (spread != *spr_selected) {
280 if (*spr_selected != INT_MAX) {
281 *spr_multi = true;
282 } else {
283 *spr_selected = spread;
284 }
285 }
286 }
287 return;
288 }
290 // If no selected dragger, read desktop selection
291 for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
292 SPItem *item = SP_ITEM(i->data);
293 SPStyle *style = SP_OBJECT_STYLE (item);
295 if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) {
296 SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
297 if (SP_IS_GRADIENT (server)) {
298 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
299 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
300 if (gradient != *gr_selected) {
301 if (*gr_selected != NULL) {
302 *gr_multi = true;
303 } else {
304 *gr_selected = gradient;
305 }
306 }
307 if (spread != *spr_selected) {
308 if (*spr_selected != INT_MAX) {
309 *spr_multi = true;
310 } else {
311 *spr_selected = spread;
312 }
313 }
314 }
315 }
316 if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) {
317 SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
318 if (SP_IS_GRADIENT (server)) {
319 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
320 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
321 if (gradient != *gr_selected) {
322 if (*gr_selected != NULL) {
323 *gr_multi = true;
324 } else {
325 *gr_selected = gradient;
326 }
327 }
328 if (spread != *spr_selected) {
329 if (*spr_selected != INT_MAX) {
330 *spr_multi = true;
331 } else {
332 *spr_selected = spread;
333 }
334 }
335 }
336 }
337 }
338 }
340 static void
341 gr_tb_selection_changed (Inkscape::Selection *, gpointer data)
342 {
343 GtkWidget *widget = (GtkWidget *) data;
345 SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
346 if (!desktop)
347 return;
349 Inkscape::Selection *selection = sp_desktop_selection (desktop); // take from desktop, not from args
350 if (!selection)
351 return;
353 SPEventContext *ev = sp_desktop_event_context (desktop);
355 GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "menu");
356 if (om) gtk_widget_destroy (om);
358 SPGradient *gr_selected = NULL;
359 bool gr_multi = false;
361 SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
362 bool spr_multi = false;
364 gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
366 om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
367 g_object_set_data (G_OBJECT (widget), "menu", om);
369 GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "buttons");
370 gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
372 gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
374 gtk_widget_show_all (widget);
375 }
377 static void
378 gr_tb_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
379 {
380 gr_tb_selection_changed (selection, data);
381 }
383 static void
384 gr_drag_selection_changed (gpointer dragger, gpointer data)
385 {
386 gr_tb_selection_changed (NULL, data);
387 }
389 static void
390 gr_defs_release (SPObject *defs, GtkWidget *widget)
391 {
392 gr_tb_selection_changed (NULL, (gpointer) widget);
393 }
395 static void
396 gr_defs_modified (SPObject *defs, guint flags, GtkWidget *widget)
397 {
398 gr_tb_selection_changed (NULL, (gpointer) widget);
399 }
401 static void
402 gr_fork (GtkWidget *button, GtkWidget *widget)
403 {
404 SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
405 SPDocument *document = sp_desktop_document (desktop);
406 Inkscape::Selection *selection = sp_desktop_selection (desktop);
407 SPEventContext *ev = sp_desktop_event_context (desktop);
408 GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
410 if (om && document) {
411 GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
412 SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
414 if (gr) {
415 SPGradient *gr_new = sp_gradient_fork_vector_if_necessary (gr);
416 if (gr_new != gr) {
417 gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr_new);
418 sp_document_done (document, SP_VERB_CONTEXT_GRADIENT,
419 /* TODO: annotate */ "gradient-toolbar.cpp:419");
420 }
421 }
422 }
424 spinbutton_defocus(GTK_OBJECT(widget));
425 }
427 static void gr_disconnect_sigc (GObject *obj, sigc::connection *connection) {
428 connection->disconnect();
429 delete connection;
430 }
432 static void gr_disconnect_gsignal (GObject *widget, gpointer defs) {
433 if (defs && G_IS_OBJECT(defs))
434 sp_signal_disconnect_by_data (defs, widget);
435 }
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 g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (document)), "release", G_CALLBACK (gr_defs_release), widget);
537 g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (document)), "modified", G_CALLBACK (gr_defs_modified), widget);
539 // when widget is destroyed, disconnect
540 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_gsignal), G_OBJECT (SP_DOCUMENT_DEFS (document)));
541 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_gsignal), G_OBJECT (SP_DOCUMENT_DEFS (document)));
543 gtk_widget_show_all (widget);
544 return widget;
545 }
547 GtkWidget *
548 sp_gradient_toolbox_new(SPDesktop *desktop)
549 {
550 GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
552 gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
553 gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
555 GtkTooltips *tt = gtk_tooltips_new();
557 sp_toolbox_add_label(tbl, _("<b>New:</b>"));
559 aux_toolbox_space(tbl, AUX_SPACING);
561 {
562 GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
563 GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
565 {
566 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
567 SP_BUTTON_TYPE_TOGGLE,
568 NULL,
569 "fill_gradient",
570 _("Create linear gradient"),
571 tt);
572 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
573 g_object_set_data(G_OBJECT(tbl), "linear", button);
574 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
575 prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
576 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
577 }
579 {
580 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
581 SP_BUTTON_TYPE_TOGGLE,
582 NULL,
583 "fill_radial",
584 _("Create radial (elliptic or circular) gradient"),
585 tt);
586 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
587 g_object_set_data(G_OBJECT(tbl), "radial", button);
588 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
589 prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
590 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
591 }
593 gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
594 gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
595 }
597 aux_toolbox_space(tbl, AUX_SPACING);
599 sp_toolbox_add_label(tbl, _("on"), false);
601 aux_toolbox_space(tbl, AUX_SPACING);
603 {
604 GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
605 GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
607 {
608 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
609 SP_BUTTON_TYPE_TOGGLE,
610 NULL,
611 "controls_fill",
612 _("Create gradient in the fill"),
613 tt);
614 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
615 g_object_set_data(G_OBJECT(tbl), "fill", button);
616 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
617 prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 1);
618 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
619 }
621 {
622 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
623 SP_BUTTON_TYPE_TOGGLE,
624 NULL,
625 "controls_stroke",
626 _("Create gradient in the stroke"),
627 tt);
628 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
629 g_object_set_data(G_OBJECT(tbl), "stroke", button);
630 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
631 prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 0);
632 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
633 }
635 gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
636 gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
637 }
640 sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
642 aux_toolbox_space(tbl, AUX_SPACING);
644 {
645 GtkWidget *vectors = gr_change_widget (desktop);
646 gtk_box_pack_start (GTK_BOX (tbl), vectors, FALSE, FALSE, 0);
647 }
649 gtk_widget_show_all(tbl);
650 sp_set_font_size_smaller (tbl);
652 return tbl;
653 }
658 /*
659 Local Variables:
660 mode:c++
661 c-file-style:"stroustrup"
662 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
663 indent-tabs-mode:nil
664 fill-column:99
665 End:
666 */
667 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :