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);
118 // GRADIENTFIXME: make this work for multiple selected draggers.
120 // First try selected dragger
121 if (drag && drag->selected) {
122 GrDragger *dragger = (GrDragger*) drag->selected->data;
123 for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
124 GrDraggable *draggable = (GrDraggable *) i->data;
125 gr_apply_gradient_to_item (draggable->item, gr, new_type, new_fill, draggable->fill_or_stroke, !draggable->fill_or_stroke);
126 }
127 return;
128 }
130 // If no drag or no dragger selected, act on selection
131 for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
132 gr_apply_gradient_to_item (SP_ITEM(i->data), gr, new_type, new_fill, new_fill, !new_fill);
133 }
134 }
136 void
137 gr_item_activate (GtkMenuItem *menuitem, gpointer data)
138 {
139 SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT (menuitem), "gradient");
140 gr = sp_gradient_ensure_vector_normalized(gr);
142 SPDesktop *desktop = (SPDesktop *) data;
143 Inkscape::Selection *selection = sp_desktop_selection (desktop);
144 SPEventContext *ev = sp_desktop_event_context (desktop);
146 gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
148 sp_document_done (sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
149 _("Assign gradient to object"));
150 }
152 gchar *
153 gr_prepare_label (SPObject *obj)
154 {
155 const gchar *id = obj->defaultLabel();
156 if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15)))
157 return g_strdup_printf ("<small>#%s</small>", id+15);
158 return g_strdup_printf ("<small>%s</small>", id);
159 }
161 GtkWidget *
162 gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
163 {
164 SPDocument *document = sp_desktop_document (desktop);
166 GtkWidget *om = gtk_option_menu_new ();
167 GtkWidget *m = gtk_menu_new ();
169 GSList *gl = NULL;
170 const GSList *gradients = sp_document_get_resource_list (document, "gradient");
171 for (const GSList *i = gradients; i != NULL; i = i->next) {
172 if (SP_GRADIENT_HAS_STOPS (i->data)) {
173 gl = g_slist_prepend (gl, i->data);
174 }
175 }
176 gl = g_slist_reverse (gl);
178 guint pos = 0;
179 guint idx = 0;
181 if (!gl) {
182 GtkWidget *l = gtk_label_new("");
183 gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients</small>"));
184 GtkWidget *i = gtk_menu_item_new ();
185 gtk_container_add (GTK_CONTAINER (i), l);
187 gtk_widget_show (i);
188 gtk_menu_append (GTK_MENU (m), i);
189 gtk_widget_set_sensitive (om, FALSE);
190 } else if (selection_empty) {
191 GtkWidget *l = gtk_label_new("");
192 gtk_label_set_markup (GTK_LABEL(l), _("<small>Nothing selected</small>"));
193 GtkWidget *i = gtk_menu_item_new ();
194 gtk_container_add (GTK_CONTAINER (i), l);
196 gtk_widget_show (i);
197 gtk_menu_append (GTK_MENU (m), i);
198 gtk_widget_set_sensitive (om, FALSE);
199 } else {
201 if (gr_selected == NULL) {
202 GtkWidget *l = gtk_label_new("");
203 gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients in selection</small>"));
204 GtkWidget *i = gtk_menu_item_new ();
205 gtk_container_add (GTK_CONTAINER (i), l);
207 gtk_widget_show (i);
208 gtk_menu_append (GTK_MENU (m), i);
209 }
211 if (gr_multi) {
212 GtkWidget *l = gtk_label_new("");
213 gtk_label_set_markup (GTK_LABEL(l), _("<small>Multiple gradients</small>"));
214 GtkWidget *i = gtk_menu_item_new ();
215 gtk_container_add (GTK_CONTAINER (i), l);
217 gtk_widget_show (i);
218 gtk_menu_append (GTK_MENU (m), i);
219 }
221 while (gl) {
222 SPGradient *gradient = SP_GRADIENT (gl->data);
223 gl = g_slist_remove (gl, gradient);
225 GtkWidget *i = gtk_menu_item_new ();
226 g_object_set_data (G_OBJECT (i), "gradient", gradient);
227 g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (gr_item_activate), desktop);
229 GtkWidget *image = sp_gradient_image_new (gradient);
231 GtkWidget *hb = gtk_hbox_new (FALSE, 4);
232 GtkWidget *l = gtk_label_new ("");
233 gchar *label = gr_prepare_label (SP_OBJECT(gradient));
234 gtk_label_set_markup (GTK_LABEL(l), label);
235 g_free (label);
236 gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
237 gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
238 gtk_box_pack_start (GTK_BOX (hb), image, FALSE, FALSE, 0);
240 gtk_widget_show_all (i);
242 gtk_container_add (GTK_CONTAINER (i), hb);
244 gtk_menu_append (GTK_MENU (m), i);
246 if (gradient == gr_selected) {
247 pos = idx;
248 }
249 idx ++;
250 }
251 gtk_widget_set_sensitive (om, TRUE);
252 }
254 gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m);
255 /* Select the current gradient, or the Multi/Nothing line */
256 if (gr_multi || gr_selected == NULL)
257 gtk_option_menu_set_history (GTK_OPTION_MENU (om), 0);
258 else
259 gtk_option_menu_set_history (GTK_OPTION_MENU (om), pos);
261 return om;
262 }
265 void
266 gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi)
267 {
268 if (drag && drag->selected) {
269 // GRADIENTFIXME: make this work for more than one selected dragger?
270 GrDragger *dragger = (GrDragger*) drag->selected->data;
271 for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
272 GrDraggable *draggable = (GrDraggable *) i->data;
273 SPGradient *gradient = sp_item_gradient_get_vector (draggable->item, draggable->fill_or_stroke);
274 SPGradientSpread spread = sp_item_gradient_get_spread (draggable->item, draggable->fill_or_stroke);
276 if (gradient != *gr_selected) {
277 if (*gr_selected != NULL) {
278 *gr_multi = true;
279 } else {
280 *gr_selected = gradient;
281 }
282 }
283 if (spread != *spr_selected) {
284 if (*spr_selected != INT_MAX) {
285 *spr_multi = true;
286 } else {
287 *spr_selected = spread;
288 }
289 }
290 }
291 return;
292 }
294 // If no selected dragger, read desktop selection
295 for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
296 SPItem *item = SP_ITEM(i->data);
297 SPStyle *style = SP_OBJECT_STYLE (item);
299 if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) {
300 SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
301 if (SP_IS_GRADIENT (server)) {
302 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
303 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
304 if (gradient != *gr_selected) {
305 if (*gr_selected != NULL) {
306 *gr_multi = true;
307 } else {
308 *gr_selected = gradient;
309 }
310 }
311 if (spread != *spr_selected) {
312 if (*spr_selected != INT_MAX) {
313 *spr_multi = true;
314 } else {
315 *spr_selected = spread;
316 }
317 }
318 }
319 }
320 if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) {
321 SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
322 if (SP_IS_GRADIENT (server)) {
323 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
324 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
325 if (gradient != *gr_selected) {
326 if (*gr_selected != NULL) {
327 *gr_multi = true;
328 } else {
329 *gr_selected = gradient;
330 }
331 }
332 if (spread != *spr_selected) {
333 if (*spr_selected != INT_MAX) {
334 *spr_multi = true;
335 } else {
336 *spr_selected = spread;
337 }
338 }
339 }
340 }
341 }
342 }
344 static void
345 gr_tb_selection_changed (Inkscape::Selection *, gpointer data)
346 {
347 GtkWidget *widget = (GtkWidget *) data;
349 SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
350 if (!desktop)
351 return;
353 Inkscape::Selection *selection = sp_desktop_selection (desktop); // take from desktop, not from args
354 if (!selection)
355 return;
357 SPEventContext *ev = sp_desktop_event_context (desktop);
359 GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "menu");
360 if (om) gtk_widget_destroy (om);
362 SPGradient *gr_selected = NULL;
363 bool gr_multi = false;
365 SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
366 bool spr_multi = false;
368 gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
370 om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
371 g_object_set_data (G_OBJECT (widget), "menu", om);
373 GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "buttons");
374 gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
376 gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
378 gtk_widget_show_all (widget);
379 }
381 static void
382 gr_tb_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
383 {
384 gr_tb_selection_changed (selection, data);
385 }
387 static void
388 gr_drag_selection_changed (gpointer dragger, gpointer data)
389 {
390 gr_tb_selection_changed (NULL, data);
391 }
393 static void
394 gr_defs_release (SPObject *defs, GtkWidget *widget)
395 {
396 gr_tb_selection_changed (NULL, (gpointer) widget);
397 }
399 static void
400 gr_defs_modified (SPObject *defs, guint flags, GtkWidget *widget)
401 {
402 gr_tb_selection_changed (NULL, (gpointer) widget);
403 }
405 static void
406 gr_fork (GtkWidget *button, GtkWidget *widget)
407 {
408 SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
409 SPDocument *document = sp_desktop_document (desktop);
410 Inkscape::Selection *selection = sp_desktop_selection (desktop);
411 SPEventContext *ev = sp_desktop_event_context (desktop);
412 GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
414 if (om && document) {
415 GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
416 SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
418 if (gr) {
419 SPGradient *gr_new = sp_gradient_fork_vector_if_necessary (gr);
420 if (gr_new != gr) {
421 gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr_new);
422 sp_document_done (document, SP_VERB_CONTEXT_GRADIENT,
423 _("Duplicate gradient"));
424 }
425 }
426 }
428 spinbutton_defocus(GTK_OBJECT(widget));
429 }
431 static void gr_disconnect_sigc (GObject *obj, sigc::connection *connection) {
432 connection->disconnect();
433 delete connection;
434 }
436 static void
437 gr_edit (GtkWidget *button, GtkWidget *widget)
438 {
439 GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
441 spinbutton_defocus(GTK_OBJECT(widget));
443 if (om) {
444 GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
445 SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
447 if (gr) {
448 GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
449 gtk_widget_show (dialog);
450 }
451 }
452 }
454 GtkWidget *
455 gr_change_widget (SPDesktop *desktop)
456 {
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() : NULL, &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 /* Fork */
484 {
485 GtkWidget *hb = gtk_hbox_new(FALSE, 1);
486 GtkWidget *b = gtk_button_new_with_label(_("Duplicate"));
487 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);
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_fork), widget);
491 gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
492 }
494 /* Edit... */
495 {
496 GtkWidget *hb = gtk_hbox_new(FALSE, 1);
497 GtkWidget *b = gtk_button_new_with_label(_("Edit..."));
498 gtk_tooltips_set_tip(tt, b, _("Edit the stops of the gradient"), NULL);
499 gtk_widget_show(b);
500 gtk_container_add(GTK_CONTAINER(hb), b);
501 gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_edit), widget);
502 gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
503 }
505 gtk_box_pack_end (GTK_BOX(widget), buttons, FALSE, FALSE, 0);
506 g_object_set_data (G_OBJECT(widget), "buttons", buttons);
507 gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
508 }
510 // connect to selection modified and changed signals
511 sigc::connection *conn1 = new sigc::connection (selection->connectChanged(
512 sigc::bind (
513 sigc::ptr_fun(&gr_tb_selection_changed),
514 (gpointer)widget )
515 ));
516 sigc::connection *conn2 = new sigc::connection (selection->connectModified(
517 sigc::bind (
518 sigc::ptr_fun(&gr_tb_selection_modified),
519 (gpointer)widget )
520 ));
522 sigc::connection *conn3 = new sigc::connection (desktop->connectToolSubselectionChanged(
523 sigc::bind (
524 sigc::ptr_fun(&gr_drag_selection_changed),
525 (gpointer)widget )
526 ));
528 // when widget is destroyed, disconnect
529 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
530 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
531 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
533 // connect to release and modified signals of the defs (i.e. when someone changes gradient)
534 sigc::connection *release_connection = new sigc::connection();
535 *release_connection = SP_DOCUMENT_DEFS(document)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), widget));
536 sigc::connection *modified_connection = new sigc::connection();
537 *modified_connection = SP_DOCUMENT_DEFS(document)->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), widget));
539 // when widget is destroyed, disconnect
540 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
541 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
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 :