gradient-toolbar.cpp revision ef9d155a8149d4793471047b3836db719b9e0292
469N/A/*
469N/A * Gradient aux toolbar
469N/A *
1068N/A * Authors:
1068N/A * bulia byak <bulia@dr.com>
1068N/A *
1068N/A * Copyright (C) 2005 authors
1068N/A *
1068N/A * Released under GNU GPL, read the file 'COPYING' for more information
1068N/A */
1068N/A
1068N/A#ifdef HAVE_CONFIG_H
1068N/A# include "config.h"
469N/A#endif
919N/A
919N/A#include <gtk/gtk.h>
919N/A
919N/A#include "macros.h"
919N/A#include "widgets/button.h"
919N/A#include "widgets/widget-sizes.h"
919N/A#include "widgets/spw-utilities.h"
919N/A#include "widgets/spinbutton-events.h"
919N/A#include "widgets/gradient-vector.h"
919N/A#include "widgets/gradient-image.h"
469N/A#include "style.h"
919N/A
919N/A#include "prefs-utils.h"
919N/A#include "document-private.h"
919N/A#include "desktop.h"
919N/A#include "desktop-handles.h"
919N/A#include <glibmm/i18n.h>
919N/A
469N/A#include "gradient-context.h"
469N/A#include "gradient-drag.h"
1068N/A#include "sp-linear-gradient.h"
469N/A#include "sp-radial-gradient.h"
469N/A#include "gradient-chemistry.h"
469N/A#include "selection.h"
469N/A
469N/A#include "toolbox.h"
469N/A
469N/A
1233N/A//########################
1233N/A//## Gradient ##
1233N/A//########################
1233N/A
1233N/Astatic void gr_toggle_type (GtkWidget *button, gpointer data) {
469N/A GtkWidget *linear = (GtkWidget *) g_object_get_data (G_OBJECT(data), "linear");
469N/A GtkWidget *radial = (GtkWidget *) g_object_get_data (G_OBJECT(data), "radial");
469N/A if (button == linear && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (linear))) {
469N/A prefs_set_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
469N/A if (radial) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radial), FALSE);
469N/A } else if (button == radial && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radial))) {
469N/A prefs_set_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_RADIAL);
469N/A if (linear) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear), FALSE);
469N/A }
469N/A}
469N/A
469N/Astatic void gr_toggle_fillstroke (GtkWidget *button, gpointer data) {
469N/A GtkWidget *fill = (GtkWidget *) g_object_get_data (G_OBJECT(data), "fill");
469N/A GtkWidget *stroke = (GtkWidget *) g_object_get_data (G_OBJECT(data), "stroke");
469N/A if (button == fill && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fill))) {
469N/A prefs_set_int_attribute ("tools.gradient", "newfillorstroke", 1);
469N/A if (stroke) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (stroke), FALSE);
469N/A } else if (button == stroke && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (stroke))) {
469N/A prefs_set_int_attribute ("tools.gradient", "newfillorstroke", 0);
469N/A if (fill) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fill), FALSE);
469N/A }
469N/A}
469N/A
469N/Avoid
469N/Agr_apply_gradient_to_item (SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke)
469N/A{
469N/A SPStyle *style = SP_OBJECT_STYLE (item);
469N/A
469N/A if (do_fill) {
469N/A if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER) &&
469N/A SP_IS_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (item))) {
469N/A SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
469N/A if (SP_IS_LINEARGRADIENT (server)) {
1233N/A sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, true);
1233N/A } else if (SP_IS_RADIALGRADIENT (server)) {
1233N/A sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, true);
1233N/A }
1233N/A } else if (new_fill) {
1233N/A sp_item_set_gradient(item, gr, new_type, true);
1233N/A }
469N/A }
1233N/A
1233N/A if (do_stroke) {
1233N/A if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER) &&
1233N/A SP_IS_GRADIENT (SP_OBJECT_STYLE_STROKE_SERVER (item))) {
1233N/A SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
469N/A if (SP_IS_LINEARGRADIENT (server)) {
469N/A sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, false);
469N/A } else if (SP_IS_RADIALGRADIENT (server)) {
469N/A sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, false);
469N/A }
469N/A } else if (!new_fill) {
469N/A sp_item_set_gradient(item, gr, new_type, false);
469N/A }
469N/A }
469N/A}
469N/A
469N/A/**
469N/AApplies gradient vector gr to the gradients attached to the selected dragger of drag, or if none,
469N/Ato all objects in selection. If there was no previous gradient on an item, uses gradient type and
469N/Afill/stroke setting from preferences to create new default (linear: left/right; radial: centered)
469N/Agradient.
469N/A*/
469N/Avoid
469N/Agr_apply_gradient (Inkscape::Selection *selection, GrDrag *drag, SPGradient *gr)
469N/A{
469N/A SPGradientType new_type = (SPGradientType) prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
469N/A guint new_fill = prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1);
469N/A
469N/A // First try selected dragger
469N/A if (drag && drag->selected) {
469N/A GrDragger *dragger = drag->selected;
469N/A for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
469N/A GrDraggable *draggable = (GrDraggable *) i->data;
469N/A gr_apply_gradient_to_item (draggable->item, gr, new_type, new_fill, draggable->fill_or_stroke, !draggable->fill_or_stroke);
469N/A }
1233N/A return;
469N/A }
469N/A
469N/A // If no drag or no dragger selected, act on selection
469N/A for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
469N/A gr_apply_gradient_to_item (SP_ITEM(i->data), gr, new_type, new_fill, true, true);
469N/A }
469N/A}
469N/A
469N/Avoid
469N/Agr_item_activate (GtkMenuItem *menuitem, gpointer data)
469N/A{
469N/A SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT (menuitem), "gradient");
469N/A gr = sp_gradient_ensure_vector_normalized(gr);
469N/A
469N/A SPDesktop *desktop = (SPDesktop *) data;
469N/A Inkscape::Selection *selection = sp_desktop_selection (desktop);
469N/A SPEventContext *ev = sp_desktop_event_context (desktop);
1233N/A
469N/A gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
469N/A
469N/A sp_document_done (sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
469N/A _("Assign gradient to object"));
469N/A}
469N/A
469N/Agchar *
469N/Agr_prepare_label (SPObject *obj)
469N/A{
469N/A const gchar *id = obj->defaultLabel();
469N/A if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15)))
469N/A return g_strdup_printf ("<small>#%s</small>", id+15);
469N/A return g_strdup_printf ("<small>%s</small>", id);
469N/A}
469N/A
469N/AGtkWidget *
469N/Agr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
469N/A{
469N/A SPDocument *document = sp_desktop_document (desktop);
469N/A
469N/A GtkWidget *om = gtk_option_menu_new ();
469N/A GtkWidget *m = gtk_menu_new ();
469N/A
469N/A GSList *gl = NULL;
469N/A const GSList *gradients = sp_document_get_resource_list (document, "gradient");
469N/A for (const GSList *i = gradients; i != NULL; i = i->next) {
469N/A if (SP_GRADIENT_HAS_STOPS (i->data)) {
469N/A gl = g_slist_prepend (gl, i->data);
469N/A }
469N/A }
469N/A gl = g_slist_reverse (gl);
469N/A
469N/A guint pos = 0;
469N/A guint idx = 0;
469N/A
469N/A if (!gl) {
469N/A GtkWidget *l = gtk_label_new("");
469N/A gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients</small>"));
1233N/A GtkWidget *i = gtk_menu_item_new ();
1233N/A gtk_container_add (GTK_CONTAINER (i), l);
1233N/A
1233N/A gtk_widget_show (i);
1233N/A gtk_menu_append (GTK_MENU (m), i);
469N/A gtk_widget_set_sensitive (om, FALSE);
1233N/A } else if (selection_empty) {
1233N/A GtkWidget *l = gtk_label_new("");
469N/A gtk_label_set_markup (GTK_LABEL(l), _("<small>Nothing selected</small>"));
1233N/A GtkWidget *i = gtk_menu_item_new ();
469N/A gtk_container_add (GTK_CONTAINER (i), l);
469N/A
469N/A gtk_widget_show (i);
469N/A gtk_menu_append (GTK_MENU (m), i);
469N/A gtk_widget_set_sensitive (om, FALSE);
469N/A } else {
469N/A
469N/A if (gr_selected == NULL) {
469N/A GtkWidget *l = gtk_label_new("");
469N/A gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients in selection</small>"));
469N/A GtkWidget *i = gtk_menu_item_new ();
469N/A gtk_container_add (GTK_CONTAINER (i), l);
469N/A
469N/A gtk_widget_show (i);
469N/A gtk_menu_append (GTK_MENU (m), i);
469N/A }
469N/A
469N/A if (gr_multi) {
469N/A GtkWidget *l = gtk_label_new("");
469N/A gtk_label_set_markup (GTK_LABEL(l), _("<small>Multiple gradients</small>"));
469N/A GtkWidget *i = gtk_menu_item_new ();
469N/A gtk_container_add (GTK_CONTAINER (i), l);
469N/A
469N/A gtk_widget_show (i);
469N/A gtk_menu_append (GTK_MENU (m), i);
469N/A }
469N/A
469N/A while (gl) {
469N/A SPGradient *gradient = SP_GRADIENT (gl->data);
469N/A gl = g_slist_remove (gl, gradient);
469N/A
469N/A GtkWidget *i = gtk_menu_item_new ();
469N/A g_object_set_data (G_OBJECT (i), "gradient", gradient);
469N/A g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (gr_item_activate), desktop);
469N/A
469N/A GtkWidget *image = sp_gradient_image_new (gradient);
469N/A
469N/A GtkWidget *hb = gtk_hbox_new (FALSE, 4);
469N/A GtkWidget *l = gtk_label_new ("");
469N/A gchar *label = gr_prepare_label (SP_OBJECT(gradient));
469N/A gtk_label_set_markup (GTK_LABEL(l), label);
469N/A g_free (label);
469N/A gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
469N/A gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
469N/A gtk_box_pack_start (GTK_BOX (hb), image, FALSE, FALSE, 0);
469N/A
469N/A gtk_widget_show_all (i);
469N/A
469N/A gtk_container_add (GTK_CONTAINER (i), hb);
469N/A
469N/A gtk_menu_append (GTK_MENU (m), i);
469N/A
469N/A if (gradient == gr_selected) {
469N/A pos = idx;
469N/A }
469N/A idx ++;
469N/A }
469N/A gtk_widget_set_sensitive (om, TRUE);
469N/A }
469N/A
469N/A gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m);
469N/A /* Select the current gradient, or the Multi/Nothing line */
469N/A if (gr_multi || gr_selected == NULL)
469N/A gtk_option_menu_set_history (GTK_OPTION_MENU (om), 0);
469N/A else
469N/A gtk_option_menu_set_history (GTK_OPTION_MENU (om), pos);
469N/A
469N/A return om;
469N/A}
469N/A
469N/A
469N/Avoid
469N/Agr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi)
469N/A{
469N/A if (drag && drag->selected) {
469N/A GrDragger *dragger = drag->selected;
469N/A for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
469N/A GrDraggable *draggable = (GrDraggable *) i->data;
469N/A SPGradient *gradient = sp_item_gradient_get_vector (draggable->item, draggable->fill_or_stroke);
469N/A SPGradientSpread spread = sp_item_gradient_get_spread (draggable->item, draggable->fill_or_stroke);
469N/A
469N/A if (gradient != *gr_selected) {
469N/A if (*gr_selected != NULL) {
469N/A *gr_multi = true;
469N/A } else {
469N/A *gr_selected = gradient;
469N/A }
469N/A }
469N/A if (spread != *spr_selected) {
469N/A if (*spr_selected != INT_MAX) {
469N/A *spr_multi = true;
469N/A } else {
469N/A *spr_selected = spread;
469N/A }
469N/A }
469N/A }
469N/A return;
469N/A }
469N/A
469N/A // If no selected dragger, read desktop selection
469N/A for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
469N/A SPItem *item = SP_ITEM(i->data);
469N/A SPStyle *style = SP_OBJECT_STYLE (item);
469N/A
469N/A if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) {
469N/A SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
469N/A if (SP_IS_GRADIENT (server)) {
469N/A SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
469N/A SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
469N/A if (gradient != *gr_selected) {
469N/A if (*gr_selected != NULL) {
469N/A *gr_multi = true;
469N/A } else {
469N/A *gr_selected = gradient;
469N/A }
469N/A }
469N/A if (spread != *spr_selected) {
469N/A if (*spr_selected != INT_MAX) {
469N/A *spr_multi = true;
469N/A } else {
469N/A *spr_selected = spread;
469N/A }
469N/A }
469N/A }
469N/A }
469N/A if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) {
469N/A SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
469N/A if (SP_IS_GRADIENT (server)) {
469N/A SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
469N/A SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
469N/A if (gradient != *gr_selected) {
469N/A if (*gr_selected != NULL) {
469N/A *gr_multi = true;
469N/A } else {
469N/A *gr_selected = gradient;
469N/A }
469N/A }
469N/A if (spread != *spr_selected) {
469N/A if (*spr_selected != INT_MAX) {
469N/A *spr_multi = true;
469N/A } else {
469N/A *spr_selected = spread;
469N/A }
469N/A }
469N/A }
469N/A }
469N/A }
469N/A }
469N/A
469N/Astatic void
469N/Agr_tb_selection_changed (Inkscape::Selection *, gpointer data)
469N/A{
469N/A GtkWidget *widget = (GtkWidget *) data;
1233N/A
469N/A SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
469N/A if (!desktop)
469N/A return;
469N/A
469N/A Inkscape::Selection *selection = sp_desktop_selection (desktop); // take from desktop, not from args
469N/A if (!selection)
469N/A return;
469N/A
469N/A SPEventContext *ev = sp_desktop_event_context (desktop);
469N/A
469N/A GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "menu");
469N/A if (om) gtk_widget_destroy (om);
469N/A
469N/A SPGradient *gr_selected = NULL;
469N/A bool gr_multi = false;
469N/A
469N/A SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
469N/A bool spr_multi = false;
469N/A
469N/A gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
469N/A
469N/A om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
469N/A g_object_set_data (G_OBJECT (widget), "menu", om);
469N/A
469N/A GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "buttons");
469N/A gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
469N/A
469N/A gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
469N/A
1233N/A gtk_widget_show_all (widget);
469N/A}
469N/A
469N/Astatic void
469N/Agr_tb_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
469N/A{
469N/A gr_tb_selection_changed (selection, data);
469N/A}
469N/A
469N/Astatic void
469N/Agr_drag_selection_changed (gpointer dragger, gpointer data)
469N/A{
469N/A gr_tb_selection_changed (NULL, data);
469N/A}
469N/A
469N/Astatic void
469N/Agr_defs_release (SPObject *defs, GtkWidget *widget)
469N/A{
469N/A gr_tb_selection_changed (NULL, (gpointer) widget);
469N/A}
469N/A
469N/Astatic void
469N/Agr_defs_modified (SPObject *defs, guint flags, GtkWidget *widget)
469N/A{
469N/A gr_tb_selection_changed (NULL, (gpointer) widget);
469N/A}
469N/A
469N/Astatic void
469N/Agr_fork (GtkWidget *button, GtkWidget *widget)
469N/A{
469N/A SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
469N/A SPDocument *document = sp_desktop_document (desktop);
469N/A Inkscape::Selection *selection = sp_desktop_selection (desktop);
469N/A SPEventContext *ev = sp_desktop_event_context (desktop);
469N/A GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
469N/A
469N/A if (om && document) {
469N/A GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
469N/A SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
469N/A
469N/A if (gr) {
469N/A SPGradient *gr_new = sp_gradient_fork_vector_if_necessary (gr);
469N/A if (gr_new != gr) {
469N/A gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr_new);
469N/A sp_document_done (document, SP_VERB_CONTEXT_GRADIENT,
469N/A _("Duplicate gradient"));
469N/A }
469N/A }
469N/A }
469N/A
469N/A spinbutton_defocus(GTK_OBJECT(widget));
469N/A}
469N/A
469N/Astatic void gr_disconnect_sigc (GObject *obj, sigc::connection *connection) {
469N/A connection->disconnect();
469N/A delete connection;
469N/A}
469N/A
469N/Astatic void
469N/Agr_edit (GtkWidget *button, GtkWidget *widget)
469N/A{
469N/A GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
469N/A
469N/A spinbutton_defocus(GTK_OBJECT(widget));
469N/A
469N/A if (om) {
469N/A GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
469N/A SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
469N/A
469N/A if (gr) {
469N/A GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
469N/A gtk_widget_show (dialog);
1233N/A }
469N/A }
469N/A}
469N/A
469N/AGtkWidget *
469N/Agr_change_widget (SPDesktop *desktop)
469N/A{
469N/A Inkscape::Selection *selection = sp_desktop_selection (desktop);
469N/A SPDocument *document = sp_desktop_document (desktop);
469N/A SPEventContext *ev = sp_desktop_event_context (desktop);
469N/A
469N/A SPGradient *gr_selected = NULL;
469N/A bool gr_multi = false;
469N/A
469N/A SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
469N/A bool spr_multi = false;
469N/A
469N/A GtkTooltips *tt = gtk_tooltips_new();
469N/A
469N/A gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
469N/A
469N/A GtkWidget *widget = gtk_hbox_new(FALSE, FALSE);
469N/A gtk_object_set_data(GTK_OBJECT(widget), "dtw", desktop->canvas);
469N/A g_object_set_data (G_OBJECT (widget), "desktop", desktop);
469N/A
469N/A GtkWidget *om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
469N/A g_object_set_data (G_OBJECT (widget), "menu", om);
469N/A
469N/A gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
469N/A
469N/A {
469N/A GtkWidget *buttons = gtk_hbox_new(FALSE, 1);
469N/A
469N/A /* Fork */
469N/A {
469N/A GtkWidget *hb = gtk_hbox_new(FALSE, 1);
1233N/A GtkWidget *b = gtk_button_new_with_label(_("Duplicate"));
469N/A 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);
469N/A gtk_widget_show(b);
469N/A gtk_container_add(GTK_CONTAINER(hb), b);
469N/A gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_fork), widget);
469N/A gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
469N/A }
469N/A
469N/A /* Edit... */
469N/A {
469N/A GtkWidget *hb = gtk_hbox_new(FALSE, 1);
469N/A GtkWidget *b = gtk_button_new_with_label(_("Edit..."));
469N/A gtk_tooltips_set_tip(tt, b, _("Edit the stops of the gradient"), NULL);
469N/A gtk_widget_show(b);
469N/A gtk_container_add(GTK_CONTAINER(hb), b);
469N/A gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_edit), widget);
469N/A gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
469N/A }
1233N/A
469N/A gtk_box_pack_end (GTK_BOX(widget), buttons, FALSE, FALSE, 0);
469N/A g_object_set_data (G_OBJECT(widget), "buttons", buttons);
469N/A gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
469N/A }
469N/A
469N/A // connect to selection modified and changed signals
469N/A sigc::connection *conn1 = new sigc::connection (selection->connectChanged(
469N/A sigc::bind (
469N/A sigc::ptr_fun(&gr_tb_selection_changed),
469N/A (gpointer)widget )
469N/A ));
469N/A sigc::connection *conn2 = new sigc::connection (selection->connectModified(
469N/A sigc::bind (
469N/A sigc::ptr_fun(&gr_tb_selection_modified),
469N/A (gpointer)widget )
1233N/A ));
469N/A
469N/A sigc::connection *conn3 = new sigc::connection (desktop->connectToolSubselectionChanged(
469N/A sigc::bind (
469N/A sigc::ptr_fun(&gr_drag_selection_changed),
469N/A (gpointer)widget )
469N/A ));
469N/A
469N/A // when widget is destroyed, disconnect
469N/A g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
469N/A g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
469N/A g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
469N/A
469N/A // connect to release and modified signals of the defs (i.e. when someone changes gradient)
469N/A sigc::connection *release_connection = new sigc::connection();
469N/A *release_connection = SP_DOCUMENT_DEFS(document)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), widget));
469N/A sigc::connection *modified_connection = new sigc::connection();
469N/A *modified_connection = SP_DOCUMENT_DEFS(document)->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), widget));
469N/A
469N/A // when widget is destroyed, disconnect
469N/A g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
469N/A g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
469N/A
469N/A gtk_widget_show_all (widget);
469N/A return widget;
469N/A}
1233N/A
469N/AGtkWidget *
469N/Asp_gradient_toolbox_new(SPDesktop *desktop)
469N/A{
469N/A GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
469N/A
469N/A gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
469N/A gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
469N/A
469N/A GtkTooltips *tt = gtk_tooltips_new();
469N/A
469N/A sp_toolbox_add_label(tbl, _("<b>New:</b>"));
469N/A
1233N/A aux_toolbox_space(tbl, AUX_SPACING);
469N/A
469N/A {
469N/A GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
469N/A GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
469N/A
469N/A {
469N/A GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
469N/A SP_BUTTON_TYPE_TOGGLE,
469N/A NULL,
469N/A "fill_gradient",
469N/A _("Create linear gradient"),
469N/A tt);
469N/A g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
469N/A g_object_set_data(G_OBJECT(tbl), "linear", button);
469N/A gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
469N/A prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
469N/A gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
469N/A }
1233N/A
469N/A {
469N/A GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
469N/A SP_BUTTON_TYPE_TOGGLE,
469N/A NULL,
469N/A "fill_radial",
469N/A _("Create radial (elliptic or circular) gradient"),
469N/A tt);
469N/A g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
469N/A g_object_set_data(G_OBJECT(tbl), "radial", button);
469N/A gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
469N/A prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
469N/A gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
469N/A }
469N/A
469N/A gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
469N/A gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
469N/A }
469N/A
469N/A aux_toolbox_space(tbl, AUX_SPACING);
469N/A
469N/A sp_toolbox_add_label(tbl, _("on"), false);
469N/A
469N/A aux_toolbox_space(tbl, AUX_SPACING);
1233N/A
469N/A {
469N/A GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
469N/A GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
469N/A
469N/A {
469N/A GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
469N/A SP_BUTTON_TYPE_TOGGLE,
469N/A NULL,
469N/A "controls_fill",
469N/A _("Create gradient in the fill"),
469N/A tt);
469N/A g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
469N/A g_object_set_data(G_OBJECT(tbl), "fill", button);
469N/A gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
469N/A prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 1);
469N/A gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
469N/A }
469N/A
469N/A {
469N/A GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
SP_BUTTON_TYPE_TOGGLE,
NULL,
"controls_stroke",
_("Create gradient in the stroke"),
tt);
g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
g_object_set_data(G_OBJECT(tbl), "stroke", button);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 0);
gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
}
gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
}
sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
aux_toolbox_space(tbl, AUX_SPACING);
{
GtkWidget *vectors = gr_change_widget (desktop);
gtk_box_pack_start (GTK_BOX (tbl), vectors, FALSE, FALSE, 0);
}
gtk_widget_show_all(tbl);
sp_set_font_size_smaller (tbl);
return tbl;
}
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :