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_DT_SELECTION (desktop);
141 SPEventContext *ev = SP_DT_EVENTCONTEXT (desktop);
143 gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
145 sp_document_done (SP_DT_DOCUMENT (desktop));
146 }
148 gchar *
149 gr_prepare_label (SPObject *obj)
150 {
151 const gchar *id = obj->defaultLabel();
152 if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15)))
153 return g_strdup_printf ("<small>#%s</small>", id+15);
154 return g_strdup_printf ("<small>%s</small>", id);
155 }
157 GtkWidget *
158 gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
159 {
160 SPDocument *document = SP_DT_DOCUMENT (desktop);
162 GtkWidget *om = gtk_option_menu_new ();
163 GtkWidget *m = gtk_menu_new ();
165 GSList *gl = NULL;
166 const GSList *gradients = sp_document_get_resource_list (document, "gradient");
167 for (const GSList *i = gradients; i != NULL; i = i->next) {
168 if (SP_GRADIENT_HAS_STOPS (i->data)) {
169 gl = g_slist_prepend (gl, i->data);
170 }
171 }
172 gl = g_slist_reverse (gl);
174 guint pos = 0;
175 guint idx = 0;
177 if (!gl) {
178 GtkWidget *l = gtk_label_new("");
179 gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients</small>"));
180 GtkWidget *i = gtk_menu_item_new ();
181 gtk_container_add (GTK_CONTAINER (i), l);
183 gtk_widget_show (i);
184 gtk_menu_append (GTK_MENU (m), i);
185 gtk_widget_set_sensitive (om, FALSE);
186 } else if (selection_empty) {
187 GtkWidget *l = gtk_label_new("");
188 gtk_label_set_markup (GTK_LABEL(l), _("<small>Nothing selected</small>"));
189 GtkWidget *i = gtk_menu_item_new ();
190 gtk_container_add (GTK_CONTAINER (i), l);
192 gtk_widget_show (i);
193 gtk_menu_append (GTK_MENU (m), i);
194 gtk_widget_set_sensitive (om, FALSE);
195 } else {
197 if (gr_selected == NULL) {
198 GtkWidget *l = gtk_label_new("");
199 gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients in selection</small>"));
200 GtkWidget *i = gtk_menu_item_new ();
201 gtk_container_add (GTK_CONTAINER (i), l);
203 gtk_widget_show (i);
204 gtk_menu_append (GTK_MENU (m), i);
205 }
207 if (gr_multi) {
208 GtkWidget *l = gtk_label_new("");
209 gtk_label_set_markup (GTK_LABEL(l), _("<small>Multiple gradients</small>"));
210 GtkWidget *i = gtk_menu_item_new ();
211 gtk_container_add (GTK_CONTAINER (i), l);
213 gtk_widget_show (i);
214 gtk_menu_append (GTK_MENU (m), i);
215 }
217 while (gl) {
218 SPGradient *gradient = SP_GRADIENT (gl->data);
219 gl = g_slist_remove (gl, gradient);
221 GtkWidget *i = gtk_menu_item_new ();
222 g_object_set_data (G_OBJECT (i), "gradient", gradient);
223 g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (gr_item_activate), desktop);
225 GtkWidget *image = sp_gradient_image_new (gradient);
227 GtkWidget *hb = gtk_hbox_new (FALSE, 4);
228 GtkWidget *l = gtk_label_new ("");
229 gchar *label = gr_prepare_label (SP_OBJECT(gradient));
230 gtk_label_set_markup (GTK_LABEL(l), label);
231 g_free (label);
232 gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
233 gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
234 gtk_box_pack_start (GTK_BOX (hb), image, FALSE, FALSE, 0);
236 gtk_widget_show_all (i);
238 gtk_container_add (GTK_CONTAINER (i), hb);
240 gtk_menu_append (GTK_MENU (m), i);
242 if (gradient == gr_selected) {
243 pos = idx;
244 }
245 idx ++;
246 }
247 gtk_widget_set_sensitive (om, TRUE);
248 }
250 gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m);
251 /* Select the current gradient, or the Multi/Nothing line */
252 if (gr_multi || gr_selected == NULL)
253 gtk_option_menu_set_history (GTK_OPTION_MENU (om), 0);
254 else
255 gtk_option_menu_set_history (GTK_OPTION_MENU (om), pos);
257 return om;
258 }
261 void
262 gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi)
263 {
264 if (drag && drag->selected) {
265 GrDragger *dragger = drag->selected;
266 for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
267 GrDraggable *draggable = (GrDraggable *) i->data;
268 SPGradient *gradient = sp_item_gradient_get_vector (draggable->item, draggable->fill_or_stroke);
269 SPGradientSpread spread = sp_item_gradient_get_spread (draggable->item, draggable->fill_or_stroke);
271 if (gradient != *gr_selected) {
272 if (*gr_selected != NULL) {
273 *gr_multi = true;
274 } else {
275 *gr_selected = gradient;
276 }
277 }
278 if (spread != *spr_selected) {
279 if (*spr_selected != INT_MAX) {
280 *spr_multi = true;
281 } else {
282 *spr_selected = spread;
283 }
284 }
285 }
286 return;
287 }
289 // If no selected dragger, read desktop selection
290 for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
291 SPItem *item = SP_ITEM(i->data);
292 SPStyle *style = SP_OBJECT_STYLE (item);
294 if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) {
295 SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
296 if (SP_IS_GRADIENT (server)) {
297 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
298 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
299 if (gradient != *gr_selected) {
300 if (*gr_selected != NULL) {
301 *gr_multi = true;
302 } else {
303 *gr_selected = gradient;
304 }
305 }
306 if (spread != *spr_selected) {
307 if (*spr_selected != INT_MAX) {
308 *spr_multi = true;
309 } else {
310 *spr_selected = spread;
311 }
312 }
313 }
314 }
315 if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) {
316 SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
317 if (SP_IS_GRADIENT (server)) {
318 SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
319 SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
320 if (gradient != *gr_selected) {
321 if (*gr_selected != NULL) {
322 *gr_multi = true;
323 } else {
324 *gr_selected = gradient;
325 }
326 }
327 if (spread != *spr_selected) {
328 if (*spr_selected != INT_MAX) {
329 *spr_multi = true;
330 } else {
331 *spr_selected = spread;
332 }
333 }
334 }
335 }
336 }
337 }
339 static void
340 gr_tb_selection_changed (Inkscape::Selection *, gpointer data)
341 {
342 GtkWidget *widget = (GtkWidget *) data;
344 SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
345 if (!desktop)
346 return;
348 Inkscape::Selection *selection = SP_DT_SELECTION (desktop); // take from desktop, not from args
349 if (!selection)
350 return;
352 SPEventContext *ev = SP_DT_EVENTCONTEXT (desktop);
354 GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "menu");
355 if (om) gtk_widget_destroy (om);
357 SPGradient *gr_selected = NULL;
358 bool gr_multi = false;
360 SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
361 bool spr_multi = false;
363 gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
365 om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
366 g_object_set_data (G_OBJECT (widget), "menu", om);
368 GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "buttons");
369 gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
371 gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
373 gtk_widget_show_all (widget);
374 }
376 static void
377 gr_tb_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
378 {
379 gr_tb_selection_changed (selection, data);
380 }
382 static void
383 gr_drag_selection_changed (gpointer dragger, gpointer data)
384 {
385 gr_tb_selection_changed (NULL, data);
386 }
388 static void
389 gr_defs_release (SPObject *defs, GtkWidget *widget)
390 {
391 gr_tb_selection_changed (NULL, (gpointer) widget);
392 }
394 static void
395 gr_defs_modified (SPObject *defs, guint flags, GtkWidget *widget)
396 {
397 gr_tb_selection_changed (NULL, (gpointer) widget);
398 }
400 static void
401 gr_fork (GtkWidget *button, GtkWidget *widget)
402 {
403 SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
404 SPDocument *document = SP_DT_DOCUMENT (desktop);
405 Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
406 SPEventContext *ev = SP_DT_EVENTCONTEXT (desktop);
407 GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
409 if (om && document) {
410 GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
411 SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
413 if (gr) {
414 SPGradient *gr_new = sp_gradient_fork_vector_if_necessary (gr);
415 if (gr_new != gr) {
416 gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr_new);
417 sp_document_done (document);
418 }
419 }
420 }
422 spinbutton_defocus(GTK_OBJECT(widget));
423 }
425 static void gr_disconnect_sigc (GObject *obj, sigc::connection *connection) {
426 connection->disconnect();
427 delete connection;
428 }
430 static void gr_disconnect_gsignal (GObject *widget, gpointer defs) {
431 if (defs && G_IS_OBJECT(defs))
432 sp_signal_disconnect_by_data (defs, widget);
433 }
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_DT_SELECTION (desktop);
458 SPDocument *document = SP_DT_DOCUMENT (desktop);
459 SPEventContext *ev = SP_DT_EVENTCONTEXT (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 g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (document)), "release", G_CALLBACK (gr_defs_release), widget);
535 g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (document)), "modified", G_CALLBACK (gr_defs_modified), widget);
537 // when widget is destroyed, disconnect
538 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_gsignal), G_OBJECT (SP_DOCUMENT_DEFS (document)));
539 g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_gsignal), G_OBJECT (SP_DOCUMENT_DEFS (document)));
541 gtk_widget_show_all (widget);
542 return widget;
543 }
545 GtkWidget *
546 sp_gradient_toolbox_new(SPDesktop *desktop)
547 {
548 GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
550 gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
551 gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
553 GtkTooltips *tt = gtk_tooltips_new();
555 sp_toolbox_add_label(tbl, _("<b>New:</b>"));
557 aux_toolbox_space(tbl, AUX_SPACING);
559 {
560 GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
561 GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
563 {
564 GtkWidget *button = sp_button_new_from_data( GTK_ICON_SIZE_SMALL_TOOLBAR,
565 SP_BUTTON_TYPE_TOGGLE,
566 NULL,
567 "fill_gradient",
568 _("Create linear gradient"),
569 tt);
570 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
571 g_object_set_data(G_OBJECT(tbl), "linear", button);
572 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
573 prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
574 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
575 }
577 {
578 GtkWidget *button = sp_button_new_from_data( GTK_ICON_SIZE_SMALL_TOOLBAR,
579 SP_BUTTON_TYPE_TOGGLE,
580 NULL,
581 "fill_radial",
582 _("Create radial (elliptic or circular) gradient"),
583 tt);
584 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
585 g_object_set_data(G_OBJECT(tbl), "radial", button);
586 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
587 prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
588 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
589 }
591 gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
592 gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
593 }
595 aux_toolbox_space(tbl, AUX_SPACING);
597 sp_toolbox_add_label(tbl, _("on"), false);
599 aux_toolbox_space(tbl, AUX_SPACING);
601 {
602 GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
603 GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
605 {
606 GtkWidget *button = sp_button_new_from_data( GTK_ICON_SIZE_SMALL_TOOLBAR,
607 SP_BUTTON_TYPE_TOGGLE,
608 NULL,
609 "controls_fill",
610 _("Create gradient in the fill"),
611 tt);
612 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
613 g_object_set_data(G_OBJECT(tbl), "fill", button);
614 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
615 prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 1);
616 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
617 }
619 {
620 GtkWidget *button = sp_button_new_from_data( GTK_ICON_SIZE_SMALL_TOOLBAR,
621 SP_BUTTON_TYPE_TOGGLE,
622 NULL,
623 "controls_stroke",
624 _("Create gradient in the stroke"),
625 tt);
626 g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
627 g_object_set_data(G_OBJECT(tbl), "stroke", button);
628 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
629 prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 0);
630 gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
631 }
633 gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
634 gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
635 }
638 sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
640 aux_toolbox_space(tbl, AUX_SPACING);
642 {
643 GtkWidget *vectors = gr_change_widget (desktop);
644 gtk_box_pack_start (GTK_BOX (tbl), vectors, FALSE, FALSE, 0);
645 }
647 gtk_widget_show_all(tbl);
648 sp_set_font_size_smaller (tbl);
650 return tbl;
651 }
656 /*
657 Local Variables:
658 mode:c++
659 c-file-style:"stroustrup"
660 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
661 indent-tabs-mode:nil
662 fill-column:99
663 End:
664 */
665 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :