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
433 gr_edit (GtkWidget *button, GtkWidget *widget)
434 {
435 GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
437 spinbutton_defocus(GTK_OBJECT(widget));
439 if (om) {
440 GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
441 SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
443 if (gr) {
444 GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
445 gtk_widget_show (dialog);
446 }
447 }
448 }
450 GtkWidget *
451 gr_change_widget (SPDesktop *desktop)
452 {
453 Inkscape::Selection *selection = sp_desktop_selection (desktop);
454 SPDocument *document = sp_desktop_document (desktop);
455 SPEventContext *ev = sp_desktop_event_context (desktop);
457 SPGradient *gr_selected = NULL;
458 bool gr_multi = false;
460 SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
461 bool spr_multi = false;
463 GtkTooltips *tt = gtk_tooltips_new();
465 gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
467 GtkWidget *widget = gtk_hbox_new(FALSE, FALSE);
468 gtk_object_set_data(GTK_OBJECT(widget), "dtw", desktop->canvas);
469 g_object_set_data (G_OBJECT (widget), "desktop", desktop);
471 GtkWidget *om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
472 g_object_set_data (G_OBJECT (widget), "menu", om);
474 gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
476 {
477 GtkWidget *buttons = gtk_hbox_new(FALSE, 1);
479 /* Fork */
480 {
481 GtkWidget *hb = gtk_hbox_new(FALSE, 1);
482 GtkWidget *b = gtk_button_new_with_label(_("Duplicate"));
483 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);
484 gtk_widget_show(b);
485 gtk_container_add(GTK_CONTAINER(hb), b);
486 gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_fork), widget);
487 gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
488 }
490 /* Edit... */
491 {
492 GtkWidget *hb = gtk_hbox_new(FALSE, 1);
493 GtkWidget *b = gtk_button_new_with_label(_("Edit..."));
494 gtk_tooltips_set_tip(tt, b, _("Edit the stops of the gradient"), NULL);
495 gtk_widget_show(b);
496 gtk_container_add(GTK_CONTAINER(hb), b);
497 gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_edit), widget);
498 gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
499 }
501 gtk_box_pack_end (GTK_BOX(widget), buttons, FALSE, FALSE, 0);
502 g_object_set_data (G_OBJECT(widget), "buttons", buttons);
503 gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
504 }
506 // connect to selection modified and changed signals
507 sigc::connection *conn1 = new sigc::connection (selection->connectChanged(
508 sigc::bind (
509 sigc::ptr_fun(&gr_tb_selection_changed),
510 (gpointer)widget )
511 ));
512 sigc::connection *conn2 = new sigc::connection (selection->connectModified(
513 sigc::bind (
514 sigc::ptr_fun(&gr_tb_selection_modified),
515 (gpointer)widget )
516 ));
518 sigc::connection *conn3 = new sigc::connection (desktop->connectToolSubselectionChanged(
519 sigc::bind (
520 sigc::ptr_fun(&gr_drag_selection_changed),
521 (gpointer)widget )
522 ));
524 // when widget is destroyed, disconnect
525 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
526 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
527 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
529 // connect to release and modified signals of the defs (i.e. when someone changes gradient)
530 sigc::connection *release_connection = new sigc::connection();
531 *release_connection = SP_DOCUMENT_DEFS(document)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), widget));
532 sigc::connection *modified_connection = new sigc::connection();
533 *modified_connection = SP_DOCUMENT_DEFS(document)->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), widget));
535 // when widget is destroyed, disconnect
536 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
537 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
539 gtk_widget_show_all (widget);
540 return widget;
541 }
543 GtkWidget *
544 sp_gradient_toolbox_new(SPDesktop *desktop)
545 {
546 GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
548 gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
549 gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
551 GtkTooltips *tt = gtk_tooltips_new();
553 sp_toolbox_add_label(tbl, _("<b>New:</b>"));
555 aux_toolbox_space(tbl, AUX_SPACING);
557 {
558 GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
559 GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
561 {
562 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
563 SP_BUTTON_TYPE_TOGGLE,
564 NULL,
565 "fill_gradient",
566 _("Create linear gradient"),
567 tt);
568 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
569 g_object_set_data(G_OBJECT(tbl), "linear", button);
570 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
571 prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
572 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
573 }
575 {
576 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
577 SP_BUTTON_TYPE_TOGGLE,
578 NULL,
579 "fill_radial",
580 _("Create radial (elliptic or circular) gradient"),
581 tt);
582 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
583 g_object_set_data(G_OBJECT(tbl), "radial", button);
584 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
585 prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
586 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
587 }
589 gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
590 gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
591 }
593 aux_toolbox_space(tbl, AUX_SPACING);
595 sp_toolbox_add_label(tbl, _("on"), false);
597 aux_toolbox_space(tbl, AUX_SPACING);
599 {
600 GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
601 GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
603 {
604 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
605 SP_BUTTON_TYPE_TOGGLE,
606 NULL,
607 "controls_fill",
608 _("Create gradient in the fill"),
609 tt);
610 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
611 g_object_set_data(G_OBJECT(tbl), "fill", button);
612 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
613 prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 1);
614 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
615 }
617 {
618 GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
619 SP_BUTTON_TYPE_TOGGLE,
620 NULL,
621 "controls_stroke",
622 _("Create gradient in the stroke"),
623 tt);
624 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
625 g_object_set_data(G_OBJECT(tbl), "stroke", button);
626 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
627 prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 0);
628 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
629 }
631 gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
632 gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
633 }
636 sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
638 aux_toolbox_space(tbl, AUX_SPACING);
640 {
641 GtkWidget *vectors = gr_change_widget (desktop);
642 gtk_box_pack_start (GTK_BOX (tbl), vectors, FALSE, FALSE, 0);
643 }
645 gtk_widget_show_all(tbl);
646 sp_set_font_size_smaller (tbl);
648 return tbl;
649 }
654 /*
655 Local Variables:
656 mode:c++
657 c-file-style:"stroustrup"
658 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
659 indent-tabs-mode:nil
660 fill-column:99
661 End:
662 */
663 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :