~valavanisalex/ubuntu/oneiric/inkscape/inkscape_0.48.1-2ubuntu4

« back to all changes in this revision

Viewing changes to src/widgets/gradient-vector.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook, Ted Gould, Kees Cook
  • Date: 2009-06-24 14:00:43 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20090624140043-07stp20mry48hqup
Tags: 0.47~pre0-0ubuntu1
* New upstream release

[ Ted Gould ]
* debian/control: Adding libgsl0 and removing version specifics on boost

[ Kees Cook ]
* debian/watch: updated to run uupdate and mangle pre-release versions.
* Dropped patches that have been taken upstream:
  - 01_mips
  - 02-poppler-0.8.3
  - 03-chinese-inkscape
  - 05_fix_latex_patch
  - 06_gcc-4.4
  - 07_cdr2svg
  - 08_skip-bad-utf-on-pdf-import
  - 09_gtk-clist
  - 10_belarussian
  - 11_libpng
  - 12_desktop
  - 13_slider
  - 100_svg_import_improvements
  - 102_sp_pattern_painter_free
  - 103_bitmap_type_print

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#define __SP_GRADIENT_VECTOR_C__
2
 
 
3
1
/*
4
2
 * Gradient vector selection widget
5
3
 *
36
34
#include "xml/repr.h"
37
35
 
38
36
#include "../dialogs/dialog-events.h"
39
 
#include "../prefs-utils.h"
 
37
#include "../preferences.h"
40
38
#include "svg/css-ostringstream.h"
41
39
#include "sp-stop.h"
42
40
 
44
42
#include <sigc++/adaptors/bind.h>
45
43
 
46
44
enum {
47
 
        VECTOR_SET,
48
 
        LAST_SIGNAL
 
45
    VECTOR_SET,
 
46
    LAST_SIGNAL
49
47
};
50
48
 
51
49
static void sp_gradient_vector_selector_class_init (SPGradientVectorSelectorClass *klass);
62
60
static GtkVBoxClass *parent_class;
63
61
static guint signals[LAST_SIGNAL] = {0};
64
62
 
 
63
// TODO FIXME kill these globals!!!
65
64
static GtkWidget *dlg = NULL;
66
65
static win_data wd;
67
66
static gint x = -1000, y = -1000, w = 0, h = 0; // impossible original values to make sure they are read from prefs
68
 
static gchar const *prefs_path = "dialogs.gradienteditor";
 
67
static Glib::ustring const prefs_path = "/dialogs/gradienteditor/";
69
68
 
70
 
GtkType
71
 
sp_gradient_vector_selector_get_type (void)
 
69
GType sp_gradient_vector_selector_get_type(void)
72
70
{
73
 
        static GtkType type = 0;
74
 
        if (!type) {
75
 
                GtkTypeInfo info = {
76
 
                        "SPGradientVectorSelector",
77
 
                        sizeof (SPGradientVectorSelector),
78
 
                        sizeof (SPGradientVectorSelectorClass),
79
 
                        (GtkClassInitFunc) sp_gradient_vector_selector_class_init,
80
 
                        (GtkObjectInitFunc) sp_gradient_vector_selector_init,
81
 
                        NULL, NULL, NULL
82
 
                };
83
 
                type = gtk_type_unique (GTK_TYPE_VBOX, &info);
84
 
        }
85
 
        return type;
 
71
    static GType type = 0;
 
72
    if (!type) {
 
73
        static const GTypeInfo info = {
 
74
            sizeof(SPGradientVectorSelectorClass),
 
75
            NULL, /* base_init */
 
76
            NULL, /* base_finalize */
 
77
            (GClassInitFunc) sp_gradient_vector_selector_class_init,
 
78
            NULL, /* class_finalize */
 
79
            NULL, /* class_data */
 
80
            sizeof(SPGradientVectorSelector),
 
81
            0,    /* n_preallocs */
 
82
            (GInstanceInitFunc) sp_gradient_vector_selector_init,
 
83
            0,    /* value_table */
 
84
        };
 
85
 
 
86
        type = g_type_register_static( GTK_TYPE_VBOX,
 
87
                                       "SPGradientVectorSelector",
 
88
                                       &info,
 
89
                                       static_cast< GTypeFlags > (0) );
 
90
    }
 
91
    return type;
86
92
}
87
93
 
88
94
static void
89
95
sp_gradient_vector_selector_class_init (SPGradientVectorSelectorClass *klass)
90
96
{
91
 
        GtkObjectClass *object_class;
92
 
 
93
 
        object_class = GTK_OBJECT_CLASS (klass);
94
 
 
95
 
        parent_class = (GtkVBoxClass*)gtk_type_class (GTK_TYPE_VBOX);
96
 
 
97
 
        signals[VECTOR_SET] = gtk_signal_new ("vector_set",
98
 
                                              GTK_RUN_LAST,
99
 
                                              GTK_CLASS_TYPE(object_class),
100
 
                                              GTK_SIGNAL_OFFSET (SPGradientVectorSelectorClass, vector_set),
101
 
                                              gtk_marshal_NONE__POINTER,
102
 
                                              GTK_TYPE_NONE, 1,
103
 
                                              GTK_TYPE_POINTER);
104
 
 
105
 
        object_class->destroy = sp_gradient_vector_selector_destroy;
 
97
    GtkObjectClass *object_class;
 
98
 
 
99
    object_class = GTK_OBJECT_CLASS (klass);
 
100
 
 
101
    parent_class = (GtkVBoxClass*)gtk_type_class (GTK_TYPE_VBOX);
 
102
 
 
103
    signals[VECTOR_SET] = gtk_signal_new ("vector_set",
 
104
                                          GTK_RUN_LAST,
 
105
                                          GTK_CLASS_TYPE(object_class),
 
106
                                          GTK_SIGNAL_OFFSET (SPGradientVectorSelectorClass, vector_set),
 
107
                                          gtk_marshal_NONE__POINTER,
 
108
                                          GTK_TYPE_NONE, 1,
 
109
                                          GTK_TYPE_POINTER);
 
110
 
 
111
    object_class->destroy = sp_gradient_vector_selector_destroy;
106
112
}
107
113
 
108
114
static void
109
115
sp_gradient_vector_selector_init (SPGradientVectorSelector *gvs)
110
116
{
111
 
        gvs->idlabel = TRUE;
112
 
 
113
 
        gvs->doc = NULL;
114
 
        gvs->gr = NULL;
115
 
 
116
 
        new (&gvs->gradient_release_connection) sigc::connection();
117
 
        new (&gvs->defs_release_connection) sigc::connection();
118
 
        new (&gvs->defs_modified_connection) sigc::connection();
119
 
 
120
 
        gvs->menu = gtk_option_menu_new ();
121
 
        gtk_widget_show (gvs->menu);
122
 
        gtk_box_pack_start (GTK_BOX (gvs), gvs->menu, TRUE, TRUE, 0);
 
117
    gvs->idlabel = TRUE;
 
118
 
 
119
    gvs->doc = NULL;
 
120
    gvs->gr = NULL;
 
121
 
 
122
    new (&gvs->gradient_release_connection) sigc::connection();
 
123
    new (&gvs->defs_release_connection) sigc::connection();
 
124
    new (&gvs->defs_modified_connection) sigc::connection();
 
125
 
 
126
    gvs->menu = gtk_option_menu_new ();
 
127
    gtk_widget_show (gvs->menu);
 
128
    gtk_box_pack_start (GTK_BOX (gvs), gvs->menu, TRUE, TRUE, 0);
123
129
}
124
130
 
125
131
static void
126
132
sp_gradient_vector_selector_destroy (GtkObject *object)
127
133
{
128
 
        SPGradientVectorSelector *gvs;
129
 
 
130
 
        gvs = SP_GRADIENT_VECTOR_SELECTOR (object);
131
 
 
132
 
        if (gvs->gr) {
133
 
                gvs->gradient_release_connection.disconnect();
134
 
                gvs->gr = NULL;
135
 
        }
136
 
 
137
 
        if (gvs->doc) {
138
 
                gvs->defs_release_connection.disconnect();
139
 
                gvs->defs_modified_connection.disconnect();
140
 
                gvs->doc = NULL;
141
 
        }
142
 
 
143
 
        gvs->gradient_release_connection.~connection();
144
 
        gvs->defs_release_connection.~connection();
145
 
        gvs->defs_modified_connection.~connection();
146
 
 
147
 
        if (((GtkObjectClass *) (parent_class))->destroy)
148
 
                (* ((GtkObjectClass *) (parent_class))->destroy) (object);
 
134
    SPGradientVectorSelector *gvs;
 
135
 
 
136
    gvs = SP_GRADIENT_VECTOR_SELECTOR (object);
 
137
 
 
138
    if (gvs->gr) {
 
139
        gvs->gradient_release_connection.disconnect();
 
140
        gvs->gr = NULL;
 
141
    }
 
142
 
 
143
    if (gvs->doc) {
 
144
        gvs->defs_release_connection.disconnect();
 
145
        gvs->defs_modified_connection.disconnect();
 
146
        gvs->doc = NULL;
 
147
    }
 
148
 
 
149
    gvs->gradient_release_connection.~connection();
 
150
    gvs->defs_release_connection.~connection();
 
151
    gvs->defs_modified_connection.~connection();
 
152
 
 
153
    if (((GtkObjectClass *) (parent_class))->destroy)
 
154
        (* ((GtkObjectClass *) (parent_class))->destroy) (object);
149
155
}
150
156
 
151
157
GtkWidget *
152
158
sp_gradient_vector_selector_new (SPDocument *doc, SPGradient *gr)
153
159
{
154
 
        GtkWidget *gvs;
155
 
 
156
 
        g_return_val_if_fail (!gr || SP_IS_GRADIENT (gr), NULL);
157
 
        g_return_val_if_fail (!gr || (SP_OBJECT_DOCUMENT (gr) == doc), NULL);
158
 
 
159
 
        gvs = (GtkWidget*)gtk_type_new (SP_TYPE_GRADIENT_VECTOR_SELECTOR);
160
 
 
161
 
        if (doc) {
162
 
                sp_gradient_vector_selector_set_gradient (SP_GRADIENT_VECTOR_SELECTOR (gvs), doc, gr);
163
 
        } else {
164
 
                sp_gvs_rebuild_gui_full (SP_GRADIENT_VECTOR_SELECTOR (gvs));
165
 
        }
166
 
 
167
 
        return gvs;
 
160
    GtkWidget *gvs;
 
161
 
 
162
    g_return_val_if_fail (!gr || SP_IS_GRADIENT (gr), NULL);
 
163
    g_return_val_if_fail (!gr || (SP_OBJECT_DOCUMENT (gr) == doc), NULL);
 
164
 
 
165
    gvs = (GtkWidget*)gtk_type_new (SP_TYPE_GRADIENT_VECTOR_SELECTOR);
 
166
 
 
167
    if (doc) {
 
168
        sp_gradient_vector_selector_set_gradient (SP_GRADIENT_VECTOR_SELECTOR (gvs), doc, gr);
 
169
    } else {
 
170
        sp_gvs_rebuild_gui_full (SP_GRADIENT_VECTOR_SELECTOR (gvs));
 
171
    }
 
172
 
 
173
    return gvs;
168
174
}
169
175
 
170
176
void
171
177
sp_gradient_vector_selector_set_gradient (SPGradientVectorSelector *gvs, SPDocument *doc, SPGradient *gr)
172
178
{
173
 
        static gboolean suppress = FALSE;
174
 
 
175
 
        g_return_if_fail (gvs != NULL);
176
 
        g_return_if_fail (SP_IS_GRADIENT_VECTOR_SELECTOR (gvs));
177
 
        g_return_if_fail (!gr || (doc != NULL));
178
 
        g_return_if_fail (!gr || SP_IS_GRADIENT (gr));
179
 
        g_return_if_fail (!gr || (SP_OBJECT_DOCUMENT (gr) == doc));
180
 
        g_return_if_fail (!gr || SP_GRADIENT_HAS_STOPS (gr));
181
 
 
182
 
        if (doc != gvs->doc) {
183
 
                /* Disconnect signals */
184
 
                if (gvs->gr) {
185
 
                        gvs->gradient_release_connection.disconnect();
186
 
                        gvs->gr = NULL;
187
 
                }
188
 
                if (gvs->doc) {
189
 
                        gvs->defs_release_connection.disconnect();
190
 
                        gvs->defs_modified_connection.disconnect();
191
 
                        gvs->doc = NULL;
192
 
                }
193
 
                /* Connect signals */
194
 
                if (doc) {
195
 
                        gvs->defs_release_connection = SP_DOCUMENT_DEFS(doc)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gvs_defs_release), gvs));
196
 
                        gvs->defs_modified_connection = SP_DOCUMENT_DEFS(doc)->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_gvs_defs_modified), gvs));
197
 
                }
198
 
                if (gr) {
199
 
                        gvs->gradient_release_connection = gr->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gvs_gradient_release), gvs));
200
 
                }
201
 
                gvs->doc = doc;
202
 
                gvs->gr = gr;
203
 
                sp_gvs_rebuild_gui_full (gvs);
204
 
                if (!suppress) g_signal_emit (G_OBJECT (gvs), signals[VECTOR_SET], 0, gr);
205
 
        } else if (gr != gvs->gr) {
206
 
                /* Harder case - keep document, rebuild menus and stuff */
207
 
                /* fixme: (Lauris) */
208
 
                suppress = TRUE;
209
 
                sp_gradient_vector_selector_set_gradient (gvs, NULL, NULL);
210
 
                sp_gradient_vector_selector_set_gradient (gvs, doc, gr);
211
 
                suppress = FALSE;
212
 
                g_signal_emit (G_OBJECT (gvs), signals[VECTOR_SET], 0, gr);
213
 
        }
214
 
        /* The case of setting NULL -> NULL is not very interesting */
 
179
    static gboolean suppress = FALSE;
 
180
 
 
181
    g_return_if_fail (gvs != NULL);
 
182
    g_return_if_fail (SP_IS_GRADIENT_VECTOR_SELECTOR (gvs));
 
183
    g_return_if_fail (!gr || (doc != NULL));
 
184
    g_return_if_fail (!gr || SP_IS_GRADIENT (gr));
 
185
    g_return_if_fail (!gr || (SP_OBJECT_DOCUMENT (gr) == doc));
 
186
    g_return_if_fail (!gr || SP_GRADIENT_HAS_STOPS (gr));
 
187
 
 
188
    if (doc != gvs->doc) {
 
189
        /* Disconnect signals */
 
190
        if (gvs->gr) {
 
191
            gvs->gradient_release_connection.disconnect();
 
192
            gvs->gr = NULL;
 
193
        }
 
194
        if (gvs->doc) {
 
195
            gvs->defs_release_connection.disconnect();
 
196
            gvs->defs_modified_connection.disconnect();
 
197
            gvs->doc = NULL;
 
198
        }
 
199
        /* Connect signals */
 
200
        if (doc) {
 
201
            gvs->defs_release_connection = SP_DOCUMENT_DEFS(doc)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gvs_defs_release), gvs));
 
202
            gvs->defs_modified_connection = SP_DOCUMENT_DEFS(doc)->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_gvs_defs_modified), gvs));
 
203
        }
 
204
        if (gr) {
 
205
            gvs->gradient_release_connection = gr->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gvs_gradient_release), gvs));
 
206
        }
 
207
        gvs->doc = doc;
 
208
        gvs->gr = gr;
 
209
        sp_gvs_rebuild_gui_full (gvs);
 
210
        if (!suppress) g_signal_emit (G_OBJECT (gvs), signals[VECTOR_SET], 0, gr);
 
211
    } else if (gr != gvs->gr) {
 
212
        /* Harder case - keep document, rebuild menus and stuff */
 
213
        /* fixme: (Lauris) */
 
214
        suppress = TRUE;
 
215
        sp_gradient_vector_selector_set_gradient (gvs, NULL, NULL);
 
216
        sp_gradient_vector_selector_set_gradient (gvs, doc, gr);
 
217
        suppress = FALSE;
 
218
        g_signal_emit (G_OBJECT (gvs), signals[VECTOR_SET], 0, gr);
 
219
    }
 
220
    /* The case of setting NULL -> NULL is not very interesting */
215
221
}
216
222
 
217
223
SPDocument *
218
224
sp_gradient_vector_selector_get_document (SPGradientVectorSelector *gvs)
219
225
{
220
 
        g_return_val_if_fail (gvs != NULL, NULL);
221
 
        g_return_val_if_fail (SP_IS_GRADIENT_VECTOR_SELECTOR (gvs), NULL);
 
226
    g_return_val_if_fail (gvs != NULL, NULL);
 
227
    g_return_val_if_fail (SP_IS_GRADIENT_VECTOR_SELECTOR (gvs), NULL);
222
228
 
223
 
        return gvs->doc;
 
229
    return gvs->doc;
224
230
}
225
231
 
226
232
SPGradient *
227
233
sp_gradient_vector_selector_get_gradient (SPGradientVectorSelector *gvs)
228
234
{
229
 
        g_return_val_if_fail (gvs != NULL, NULL);
230
 
        g_return_val_if_fail (SP_IS_GRADIENT_VECTOR_SELECTOR (gvs), NULL);
 
235
    g_return_val_if_fail (gvs != NULL, NULL);
 
236
    g_return_val_if_fail (SP_IS_GRADIENT_VECTOR_SELECTOR (gvs), NULL);
231
237
 
232
 
        return gvs->gr;
 
238
    return gvs->gr;
233
239
}
234
240
 
235
241
static void
236
242
sp_gvs_rebuild_gui_full (SPGradientVectorSelector *gvs)
237
243
{
238
 
        /* Clear old menu, if there is any */
239
 
        if (gtk_option_menu_get_menu (GTK_OPTION_MENU (gvs->menu))) {
240
 
                gtk_option_menu_remove_menu (GTK_OPTION_MENU (gvs->menu));
241
 
        }
242
 
 
243
 
        /* Create new menu widget */
244
 
        GtkWidget *m = gtk_menu_new ();
245
 
        gtk_widget_show (m);
246
 
 
247
 
        /* Pick up all gradients with vectors */
248
 
        GSList *gl = NULL;
249
 
        if (gvs->gr) {
250
 
                const GSList *gradients = sp_document_get_resource_list (SP_OBJECT_DOCUMENT (gvs->gr), "gradient");
251
 
                for (const GSList *l = gradients; l != NULL; l = l->next) {
252
 
                        if (SP_GRADIENT_HAS_STOPS (l->data)) {
253
 
                                gl = g_slist_prepend (gl, l->data);
254
 
                        }
255
 
                }
256
 
        }
257
 
        gl = g_slist_reverse (gl);
258
 
 
259
 
        gint pos = 0;
260
 
        gint idx = 0;
261
 
 
262
 
        if (!gvs->doc) {
263
 
                GtkWidget *i;
264
 
                i = gtk_menu_item_new_with_label (_("No document selected"));
265
 
                gtk_widget_show (i);
266
 
                gtk_menu_append (GTK_MENU (m), i);
267
 
                gtk_widget_set_sensitive (gvs->menu, FALSE);
268
 
        } else if (!gl) {
269
 
                GtkWidget *i;
270
 
                i = gtk_menu_item_new_with_label (_("No gradients in document"));
271
 
                gtk_widget_show (i);
272
 
                gtk_menu_append (GTK_MENU (m), i);
273
 
                gtk_widget_set_sensitive (gvs->menu, FALSE);
274
 
        } else if (!gvs->gr) {
275
 
                GtkWidget *i;
276
 
                i = gtk_menu_item_new_with_label (_("No gradient selected"));
277
 
                gtk_widget_show (i);
278
 
                gtk_menu_append (GTK_MENU (m), i);
279
 
                gtk_widget_set_sensitive (gvs->menu, FALSE);
280
 
        } else {
281
 
                while (gl) {
282
 
                        SPGradient *gr;
283
 
                        GtkWidget *i, *w;
284
 
                        gr = SP_GRADIENT (gl->data);
285
 
                        gl = g_slist_remove (gl, gr);
286
 
 
287
 
                        /* We have to know: */
288
 
                        /* Gradient destroy */
289
 
                        /* Gradient name change */
290
 
                        i = gtk_menu_item_new ();
291
 
                        gtk_widget_show (i);
292
 
                        g_object_set_data (G_OBJECT (i), "gradient", gr);
293
 
                        g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (sp_gvs_gradient_activate), gvs);
294
 
 
295
 
                        w = sp_gradient_image_new (gr);
296
 
                        gtk_widget_show (w);
297
 
 
298
 
                        if (gvs->idlabel) {
299
 
                                GtkWidget *hb, *l;
300
 
                                hb = gtk_hbox_new (FALSE, 4);
301
 
                                gtk_widget_show (hb);
302
 
                                l = gtk_label_new (SP_OBJECT_ID (gr));
303
 
                                gtk_widget_show (l);
304
 
                                gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
305
 
                                gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
306
 
                                gtk_box_pack_start (GTK_BOX (hb), w, FALSE, FALSE, 0);
307
 
                                w = hb;
308
 
                        }
309
 
 
310
 
                        gtk_container_add (GTK_CONTAINER (i), w);
311
 
 
312
 
                        gtk_menu_append (GTK_MENU (m), i);
313
 
 
314
 
                        if (gr == gvs->gr) pos = idx;
315
 
                        idx += 1;
316
 
                }
317
 
                gtk_widget_set_sensitive (gvs->menu, TRUE);
318
 
        }
319
 
 
320
 
        gtk_option_menu_set_menu (GTK_OPTION_MENU (gvs->menu), m);
321
 
        /* Set history */
322
 
        gtk_option_menu_set_history (GTK_OPTION_MENU (gvs->menu), pos);
 
244
    /* Clear old menu, if there is any */
 
245
    if (gtk_option_menu_get_menu (GTK_OPTION_MENU (gvs->menu))) {
 
246
        gtk_option_menu_remove_menu (GTK_OPTION_MENU (gvs->menu));
 
247
    }
 
248
 
 
249
    /* Create new menu widget */
 
250
    GtkWidget *m = gtk_menu_new ();
 
251
    gtk_widget_show (m);
 
252
 
 
253
    /* Pick up all gradients with vectors */
 
254
    GSList *gl = NULL;
 
255
    if (gvs->gr) {
 
256
        const GSList *gradients = sp_document_get_resource_list (SP_OBJECT_DOCUMENT (gvs->gr), "gradient");
 
257
        for (const GSList *l = gradients; l != NULL; l = l->next) {
 
258
            if (SP_GRADIENT_HAS_STOPS (l->data)) {
 
259
                gl = g_slist_prepend (gl, l->data);
 
260
            }
 
261
        }
 
262
    }
 
263
    gl = g_slist_reverse (gl);
 
264
 
 
265
    gint pos = 0;
 
266
    gint idx = 0;
 
267
 
 
268
    if (!gvs->doc) {
 
269
        GtkWidget *i;
 
270
        i = gtk_menu_item_new_with_label (_("No document selected"));
 
271
        gtk_widget_show (i);
 
272
        gtk_menu_append (GTK_MENU (m), i);
 
273
        gtk_widget_set_sensitive (gvs->menu, FALSE);
 
274
    } else if (!gl) {
 
275
        GtkWidget *i;
 
276
        i = gtk_menu_item_new_with_label (_("No gradients in document"));
 
277
        gtk_widget_show (i);
 
278
        gtk_menu_append (GTK_MENU (m), i);
 
279
        gtk_widget_set_sensitive (gvs->menu, FALSE);
 
280
    } else if (!gvs->gr) {
 
281
        GtkWidget *i;
 
282
        i = gtk_menu_item_new_with_label (_("No gradient selected"));
 
283
        gtk_widget_show (i);
 
284
        gtk_menu_append (GTK_MENU (m), i);
 
285
        gtk_widget_set_sensitive (gvs->menu, FALSE);
 
286
    } else {
 
287
        while (gl) {
 
288
            SPGradient *gr;
 
289
            GtkWidget *i, *w;
 
290
            gr = SP_GRADIENT (gl->data);
 
291
            gl = g_slist_remove (gl, gr);
 
292
 
 
293
            /* We have to know: */
 
294
            /* Gradient destroy */
 
295
            /* Gradient name change */
 
296
            i = gtk_menu_item_new ();
 
297
            gtk_widget_show (i);
 
298
            g_object_set_data (G_OBJECT (i), "gradient", gr);
 
299
            g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (sp_gvs_gradient_activate), gvs);
 
300
 
 
301
            w = sp_gradient_image_new (gr);
 
302
            gtk_widget_show (w);
 
303
 
 
304
            if (gvs->idlabel) {
 
305
                GtkWidget *hb, *l;
 
306
                hb = gtk_hbox_new (FALSE, 4);
 
307
                gtk_widget_show (hb);
 
308
                l = gtk_label_new (SP_OBJECT_ID (gr));
 
309
                gtk_widget_show (l);
 
310
                gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
 
311
                gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
 
312
                gtk_box_pack_start (GTK_BOX (hb), w, FALSE, FALSE, 0);
 
313
                w = hb;
 
314
            }
 
315
 
 
316
            gtk_container_add (GTK_CONTAINER (i), w);
 
317
 
 
318
            gtk_menu_append (GTK_MENU (m), i);
 
319
 
 
320
            if (gr == gvs->gr) pos = idx;
 
321
            idx += 1;
 
322
        }
 
323
        gtk_widget_set_sensitive (gvs->menu, TRUE);
 
324
    }
 
325
 
 
326
    gtk_option_menu_set_menu (GTK_OPTION_MENU (gvs->menu), m);
 
327
    /* Set history */
 
328
    gtk_option_menu_set_history (GTK_OPTION_MENU (gvs->menu), pos);
323
329
}
324
330
 
325
331
static void
326
332
sp_gvs_gradient_activate (GtkMenuItem *mi, SPGradientVectorSelector *gvs)
327
333
{
328
 
        SPGradient *gr, *norm;
329
 
 
330
 
        gr = (SPGradient*)g_object_get_data (G_OBJECT (mi), "gradient");
331
 
        /* Hmmm... bad things may happen here, if actual gradient is something new */
332
 
        /* Namely - menuitems etc. will be fucked up */
333
 
        /* Hmmm - probably we can just re-set it as menuitem data (Lauris) */
334
 
 
335
 
        //g_print ("SPGradientVectorSelector: gradient %s activated\n", SP_OBJECT_ID (gr));
336
 
 
337
 
        norm = sp_gradient_ensure_vector_normalized (gr);
338
 
        if (norm != gr) {
339
 
                //g_print ("SPGradientVectorSelector: become %s after normalization\n", SP_OBJECT_ID (norm));
340
 
                /* But be careful that we do not have gradient saved anywhere else */
341
 
                g_object_set_data (G_OBJECT (mi), "gradient", norm);
342
 
        }
343
 
 
344
 
        /* fixme: Really we would want to use _set_vector */
345
 
        /* Detach old */
346
 
        if (gvs->gr) {
347
 
                gvs->gradient_release_connection.disconnect();
348
 
                gvs->gr = NULL;
349
 
        }
350
 
        /* Attach new */
351
 
        if (norm) {
352
 
                gvs->gradient_release_connection = norm->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gvs_gradient_release), gvs));
353
 
                gvs->gr = norm;
354
 
        }
355
 
 
356
 
        g_signal_emit (G_OBJECT (gvs), signals[VECTOR_SET], 0, norm);
357
 
 
358
 
        if (norm != gr) {
359
 
                /* We do extra undo push here */
360
 
                /* If handler has already done it, it is just NOP */
361
 
                // FIXME: looks like this is never a valid undo step, consider removing this
362
 
            sp_document_done (SP_OBJECT_DOCUMENT (norm), SP_VERB_CONTEXT_GRADIENT,
363
 
                              /* TODO: annotate */ "gradient-vector.cpp:350");
364
 
        }
365
 
}
366
 
 
367
 
static void
368
 
sp_gvs_gradient_release (SPObject *obj, SPGradientVectorSelector *gvs)
369
 
{
370
 
        /* Disconnect gradient */
371
 
        if (gvs->gr) {
372
 
                gvs->gradient_release_connection.disconnect();
373
 
                gvs->gr = NULL;
374
 
        }
375
 
 
376
 
        /* Rebuild GUI */
377
 
        sp_gvs_rebuild_gui_full (gvs);
378
 
}
379
 
 
380
 
static void
381
 
sp_gvs_defs_release (SPObject *defs, SPGradientVectorSelector *gvs)
382
 
{
383
 
        gvs->doc = NULL;
384
 
 
385
 
        gvs->defs_release_connection.disconnect();
386
 
        gvs->defs_modified_connection.disconnect();
387
 
 
388
 
        /* Disconnect gradient as well */
389
 
        if (gvs->gr) {
390
 
                gvs->gradient_release_connection.disconnect();
391
 
                gvs->gr = NULL;
392
 
        }
393
 
 
394
 
        /* Rebuild GUI */
395
 
        sp_gvs_rebuild_gui_full (gvs);
396
 
}
397
 
 
398
 
static void
399
 
sp_gvs_defs_modified (SPObject *defs, guint flags, SPGradientVectorSelector *gvs)
400
 
{
401
 
        /* fixme: We probably have to check some flags here (Lauris) */
402
 
 
403
 
        sp_gvs_rebuild_gui_full (gvs);
 
334
    SPGradient *gr, *norm;
 
335
 
 
336
    gr = (SPGradient*)g_object_get_data (G_OBJECT (mi), "gradient");
 
337
    /* Hmmm... bad things may happen here, if actual gradient is something new */
 
338
    /* Namely - menuitems etc. will be fucked up */
 
339
    /* Hmmm - probably we can just re-set it as menuitem data (Lauris) */
 
340
 
 
341
    //g_print ("SPGradientVectorSelector: gradient %s activated\n", SP_OBJECT_ID (gr));
 
342
 
 
343
    norm = sp_gradient_ensure_vector_normalized (gr);
 
344
    if (norm != gr) {
 
345
        //g_print ("SPGradientVectorSelector: become %s after normalization\n", SP_OBJECT_ID (norm));
 
346
        /* But be careful that we do not have gradient saved anywhere else */
 
347
        g_object_set_data (G_OBJECT (mi), "gradient", norm);
 
348
    }
 
349
 
 
350
    /* fixme: Really we would want to use _set_vector */
 
351
    /* Detach old */
 
352
    if (gvs->gr) {
 
353
        gvs->gradient_release_connection.disconnect();
 
354
        gvs->gr = NULL;
 
355
    }
 
356
    /* Attach new */
 
357
    if (norm) {
 
358
        gvs->gradient_release_connection = norm->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gvs_gradient_release), gvs));
 
359
        gvs->gr = norm;
 
360
    }
 
361
 
 
362
    g_signal_emit (G_OBJECT (gvs), signals[VECTOR_SET], 0, norm);
 
363
 
 
364
    if (norm != gr) {
 
365
        /* We do extra undo push here */
 
366
        /* If handler has already done it, it is just NOP */
 
367
        // FIXME: looks like this is never a valid undo step, consider removing this
 
368
        sp_document_done (SP_OBJECT_DOCUMENT (norm), SP_VERB_CONTEXT_GRADIENT,
 
369
                          /* TODO: annotate */ "gradient-vector.cpp:350");
 
370
    }
 
371
}
 
372
 
 
373
static void
 
374
sp_gvs_gradient_release (SPObject */*obj*/, SPGradientVectorSelector *gvs)
 
375
{
 
376
    /* Disconnect gradient */
 
377
    if (gvs->gr) {
 
378
        gvs->gradient_release_connection.disconnect();
 
379
        gvs->gr = NULL;
 
380
    }
 
381
 
 
382
    /* Rebuild GUI */
 
383
    sp_gvs_rebuild_gui_full (gvs);
 
384
}
 
385
 
 
386
static void
 
387
sp_gvs_defs_release (SPObject */*defs*/, SPGradientVectorSelector *gvs)
 
388
{
 
389
    gvs->doc = NULL;
 
390
 
 
391
    gvs->defs_release_connection.disconnect();
 
392
    gvs->defs_modified_connection.disconnect();
 
393
 
 
394
    /* Disconnect gradient as well */
 
395
    if (gvs->gr) {
 
396
        gvs->gradient_release_connection.disconnect();
 
397
        gvs->gr = NULL;
 
398
    }
 
399
 
 
400
    /* Rebuild GUI */
 
401
    sp_gvs_rebuild_gui_full (gvs);
 
402
}
 
403
 
 
404
static void
 
405
sp_gvs_defs_modified (SPObject */*defs*/, guint /*flags*/, SPGradientVectorSelector *gvs)
 
406
{
 
407
    /* fixme: We probably have to check some flags here (Lauris) */
 
408
 
 
409
    sp_gvs_rebuild_gui_full (gvs);
404
410
}
405
411
 
406
412
/*##################################################################
407
 
###                 Vector Editing Widget
408
 
##################################################################*/
 
413
  ###                 Vector Editing Widget
 
414
  ##################################################################*/
409
415
 
410
416
#include "../widgets/sp-color-notebook.h"
411
417
#include "../widgets/sp-color-preview.h"
431
437
 
432
438
static gboolean blocked = FALSE;
433
439
 
434
 
static void grad_edit_dia_stop_added_or_removed (Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data)
 
440
static void grad_edit_dia_stop_added_or_removed (Inkscape::XML::Node */*repr*/, Inkscape::XML::Node */*child*/, Inkscape::XML::Node */*ref*/, gpointer data)
435
441
{
436
 
   GtkWidget *vb = GTK_WIDGET(data);
437
 
   GtkWidget *mnu = (GtkWidget *)g_object_get_data (G_OBJECT(vb), "stopmenu");
438
 
   SPGradient *gradient = (SPGradient *)g_object_get_data (G_OBJECT(vb), "gradient");
439
 
   update_stop_list (mnu, gradient, NULL);
 
442
    GtkWidget *vb = GTK_WIDGET(data);
 
443
    GtkWidget *mnu = (GtkWidget *)g_object_get_data (G_OBJECT(vb), "stopmenu");
 
444
    SPGradient *gradient = (SPGradient *)g_object_get_data (G_OBJECT(vb), "gradient");
 
445
    update_stop_list (mnu, gradient, NULL);
440
446
}
441
447
 
442
448
//FIXME!!! We must also listen to attr changes on all children (i.e. stops) too,
454
460
static void
455
461
verify_grad(SPGradient *gradient)
456
462
{
457
 
        int i = 0;
458
 
        SPStop *stop = NULL;
459
 
        /* count stops */
460
 
        for ( SPObject *ochild = sp_object_first_child(SP_OBJECT(gradient)) ; ochild != NULL ; ochild = SP_OBJECT_NEXT(ochild) ) {
461
 
                if (SP_IS_STOP (ochild)) {
462
 
                        i++;
463
 
                        stop = SP_STOP(ochild);
464
 
                }
465
 
        }
466
 
 
467
 
        Inkscape::XML::Document *xml_doc;
468
 
        xml_doc = SP_OBJECT_REPR(gradient)->document();
469
 
 
470
 
        if (i < 1) {
471
 
                gchar c[64];
472
 
                sp_svg_write_color (c, sizeof(c), 0x00000000);
473
 
 
474
 
                Inkscape::CSSOStringStream os;
475
 
                os << "stop-color:" << c << ";stop-opacity:" << 1.0 << ";";
476
 
 
477
 
                Inkscape::XML::Node *child;
478
 
 
479
 
                child = xml_doc->createElement("svg:stop");
480
 
                sp_repr_set_css_double(child, "offset", 0.0);
481
 
                child->setAttribute("style", os.str().c_str());
482
 
                SP_OBJECT_REPR (gradient)->addChild(child, NULL);
483
 
 
484
 
                child = xml_doc->createElement("svg:stop");
485
 
                sp_repr_set_css_double(child, "offset", 1.0);
486
 
                child->setAttribute("style", os.str().c_str());
487
 
                SP_OBJECT_REPR (gradient)->addChild(child, NULL);
488
 
        }
489
 
        if (i < 2) {
490
 
                sp_repr_set_css_double(SP_OBJECT_REPR(stop), "offset", 0.0);
491
 
                Inkscape::XML::Node *child = SP_OBJECT_REPR(stop)->duplicate(SP_OBJECT_REPR(gradient)->document());
492
 
                sp_repr_set_css_double(child, "offset", 1.0);
493
 
                SP_OBJECT_REPR(gradient)->addChild(child, SP_OBJECT_REPR (stop));
494
 
        }
 
463
    int i = 0;
 
464
    SPStop *stop = NULL;
 
465
    /* count stops */
 
466
    for ( SPObject *ochild = sp_object_first_child(SP_OBJECT(gradient)) ; ochild != NULL ; ochild = SP_OBJECT_NEXT(ochild) ) {
 
467
        if (SP_IS_STOP (ochild)) {
 
468
            i++;
 
469
            stop = SP_STOP(ochild);
 
470
        }
 
471
    }
 
472
 
 
473
    Inkscape::XML::Document *xml_doc;
 
474
    xml_doc = SP_OBJECT_REPR(gradient)->document();
 
475
 
 
476
    if (i < 1) {
 
477
        gchar c[64];
 
478
        sp_svg_write_color (c, sizeof(c), 0x00000000);
 
479
 
 
480
        Inkscape::CSSOStringStream os;
 
481
        os << "stop-color:" << c << ";stop-opacity:" << 1.0 << ";";
 
482
 
 
483
        Inkscape::XML::Node *child;
 
484
 
 
485
        child = xml_doc->createElement("svg:stop");
 
486
        sp_repr_set_css_double(child, "offset", 0.0);
 
487
        child->setAttribute("style", os.str().c_str());
 
488
        SP_OBJECT_REPR (gradient)->addChild(child, NULL);
 
489
        Inkscape::GC::release(child);
 
490
 
 
491
        child = xml_doc->createElement("svg:stop");
 
492
        sp_repr_set_css_double(child, "offset", 1.0);
 
493
        child->setAttribute("style", os.str().c_str());
 
494
        SP_OBJECT_REPR (gradient)->addChild(child, NULL);
 
495
        Inkscape::GC::release(child);
 
496
    }
 
497
    if (i < 2) {
 
498
        sp_repr_set_css_double(SP_OBJECT_REPR(stop), "offset", 0.0);
 
499
        Inkscape::XML::Node *child = SP_OBJECT_REPR(stop)->duplicate(SP_OBJECT_REPR(gradient)->document());
 
500
        sp_repr_set_css_double(child, "offset", 1.0);
 
501
        SP_OBJECT_REPR(gradient)->addChild(child, SP_OBJECT_REPR (stop));
 
502
        Inkscape::GC::release(child);
 
503
    }
495
504
}
496
505
 
497
506
static void
498
507
select_stop_in_list( GtkWidget *mnu, SPGradient *gradient, SPStop *new_stop)
499
508
{
500
 
        int i = 0;
501
 
        for ( SPObject *ochild = sp_object_first_child(SP_OBJECT(gradient)) ; ochild != NULL ; ochild = SP_OBJECT_NEXT(ochild) ) {
502
 
                if (SP_IS_STOP (ochild)) {
503
 
                        if (SP_OBJECT (ochild) == SP_OBJECT(new_stop)) {
504
 
                                gtk_option_menu_set_history (GTK_OPTION_MENU (mnu), i);
505
 
                                break;
506
 
                        }
507
 
                        i++;
508
 
                }
509
 
        }
 
509
    int i = 0;
 
510
    for ( SPObject *ochild = sp_object_first_child(SP_OBJECT(gradient)) ; ochild != NULL ; ochild = SP_OBJECT_NEXT(ochild) ) {
 
511
        if (SP_IS_STOP (ochild)) {
 
512
            if (SP_OBJECT (ochild) == SP_OBJECT(new_stop)) {
 
513
                gtk_option_menu_set_history (GTK_OPTION_MENU (mnu), i);
 
514
                break;
 
515
            }
 
516
            i++;
 
517
        }
 
518
    }
510
519
}
511
520
 
512
521
static void
513
522
update_stop_list( GtkWidget *mnu, SPGradient *gradient, SPStop *new_stop)
514
523
{
515
524
 
516
 
        if (!SP_IS_GRADIENT (gradient))
517
 
                return;
518
 
 
519
 
        blocked = TRUE;
520
 
 
521
 
        /* Clear old menu, if there is any */
522
 
        if (gtk_option_menu_get_menu (GTK_OPTION_MENU (mnu))) {
523
 
                gtk_option_menu_remove_menu (GTK_OPTION_MENU (mnu));
524
 
        }
525
 
 
526
 
        /* Create new menu widget */
527
 
        GtkWidget *m = gtk_menu_new ();
528
 
        gtk_widget_show (m);
529
 
        GSList *sl = NULL;
530
 
        if (gradient->has_stops) {
531
 
                for ( SPObject *ochild = sp_object_first_child (SP_OBJECT(gradient)) ; ochild != NULL ; ochild = SP_OBJECT_NEXT(ochild) ) {
532
 
                        if (SP_IS_STOP (ochild)) {
533
 
                                sl = g_slist_append (sl, ochild);
534
 
                        }
535
 
                }
536
 
        }
537
 
        if (!sl) {
538
 
                GtkWidget *i = gtk_menu_item_new_with_label (_("No stops in gradient"));
539
 
                gtk_widget_show (i);
540
 
                gtk_menu_append (GTK_MENU (m), i);
541
 
                gtk_widget_set_sensitive (mnu, FALSE);
542
 
        } else {
543
 
 
544
 
                for (; sl != NULL; sl = sl->next){
545
 
                        SPStop *stop;
546
 
                        GtkWidget *i;
547
 
                        if (SP_IS_STOP(sl->data)){
548
 
                                stop = SP_STOP (sl->data);
549
 
                                i = gtk_menu_item_new ();
550
 
                                gtk_widget_show (i);
551
 
                                g_object_set_data (G_OBJECT (i), "stop", stop);
552
 
                                GtkWidget *hb = gtk_hbox_new (FALSE, 4);
553
 
                                GtkWidget *cpv = sp_color_preview_new(sp_stop_get_rgba32(stop));
554
 
                                gtk_widget_show (cpv);
555
 
                                gtk_container_add ( GTK_CONTAINER (hb), cpv );
556
 
                                g_object_set_data ( G_OBJECT (i), "preview", cpv );
557
 
                                Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) sl->data);
558
 
                                GtkWidget *l = gtk_label_new (repr->attribute("id"));
559
 
                                gtk_widget_show (l);
560
 
                                gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
561
 
                                gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
562
 
                                gtk_widget_show (hb);
563
 
                                gtk_container_add (GTK_CONTAINER (i), hb);
564
 
                                gtk_menu_append (GTK_MENU (m), i);
565
 
                        }
566
 
                }
567
 
 
568
 
                gtk_widget_set_sensitive (mnu, TRUE);
569
 
        }
570
 
        gtk_option_menu_set_menu (GTK_OPTION_MENU (mnu), m);
571
 
 
572
 
        /* Set history */
573
 
        if (new_stop == NULL) {
574
 
                gtk_option_menu_set_history (GTK_OPTION_MENU (mnu), 0);
575
 
        } else {
576
 
                select_stop_in_list (mnu, gradient, new_stop);
577
 
        }
578
 
 
579
 
        blocked = FALSE;
 
525
    if (!SP_IS_GRADIENT (gradient))
 
526
        return;
 
527
 
 
528
    blocked = TRUE;
 
529
 
 
530
    /* Clear old menu, if there is any */
 
531
    if (gtk_option_menu_get_menu (GTK_OPTION_MENU (mnu))) {
 
532
        gtk_option_menu_remove_menu (GTK_OPTION_MENU (mnu));
 
533
    }
 
534
 
 
535
    /* Create new menu widget */
 
536
    GtkWidget *m = gtk_menu_new ();
 
537
    gtk_widget_show (m);
 
538
    GSList *sl = NULL;
 
539
    if (gradient->has_stops) {
 
540
        for ( SPObject *ochild = sp_object_first_child (SP_OBJECT(gradient)) ; ochild != NULL ; ochild = SP_OBJECT_NEXT(ochild) ) {
 
541
            if (SP_IS_STOP (ochild)) {
 
542
                sl = g_slist_append (sl, ochild);
 
543
            }
 
544
        }
 
545
    }
 
546
    if (!sl) {
 
547
        GtkWidget *i = gtk_menu_item_new_with_label (_("No stops in gradient"));
 
548
        gtk_widget_show (i);
 
549
        gtk_menu_append (GTK_MENU (m), i);
 
550
        gtk_widget_set_sensitive (mnu, FALSE);
 
551
    } else {
 
552
 
 
553
        for (; sl != NULL; sl = sl->next){
 
554
            SPStop *stop;
 
555
            GtkWidget *i;
 
556
            if (SP_IS_STOP(sl->data)){
 
557
                stop = SP_STOP (sl->data);
 
558
                i = gtk_menu_item_new ();
 
559
                gtk_widget_show (i);
 
560
                g_object_set_data (G_OBJECT (i), "stop", stop);
 
561
                GtkWidget *hb = gtk_hbox_new (FALSE, 4);
 
562
                GtkWidget *cpv = sp_color_preview_new(sp_stop_get_rgba32(stop));
 
563
                gtk_widget_show (cpv);
 
564
                gtk_container_add ( GTK_CONTAINER (hb), cpv );
 
565
                g_object_set_data ( G_OBJECT (i), "preview", cpv );
 
566
                Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) sl->data);
 
567
                GtkWidget *l = gtk_label_new (repr->attribute("id"));
 
568
                gtk_widget_show (l);
 
569
                gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
 
570
                gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
 
571
                gtk_widget_show (hb);
 
572
                gtk_container_add (GTK_CONTAINER (i), hb);
 
573
                gtk_menu_append (GTK_MENU (m), i);
 
574
            }
 
575
        }
 
576
 
 
577
        gtk_widget_set_sensitive (mnu, TRUE);
 
578
    }
 
579
    gtk_option_menu_set_menu (GTK_OPTION_MENU (mnu), m);
 
580
 
 
581
    /* Set history */
 
582
    if (new_stop == NULL) {
 
583
        gtk_option_menu_set_history (GTK_OPTION_MENU (mnu), 0);
 
584
    } else {
 
585
        select_stop_in_list (mnu, gradient, new_stop);
 
586
    }
 
587
 
 
588
    blocked = FALSE;
580
589
}
581
590
 
582
591
 
584
593
static void
585
594
sp_grad_edit_select (GtkOptionMenu *mnu,  GtkWidget *tbl)
586
595
{
587
 
        SPGradient *gradient = (SPGradient *)g_object_get_data (G_OBJECT(tbl), "gradient");
588
 
 
589
 
        GObject *item = G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu))));
590
 
        SPStop *stop = SP_STOP (g_object_get_data (item, "stop"));
591
 
        if (!stop) return;
592
 
 
593
 
        blocked = TRUE;
594
 
 
595
 
        SPColorSelector *csel = (SPColorSelector*)g_object_get_data (G_OBJECT (tbl), "cselector");
596
 
        guint32 const c = sp_stop_get_rgba32(stop);
597
 
        csel->base->setAlpha(SP_RGBA32_A_F (c));
598
 
        SPColor color( SP_RGBA32_R_F (c), SP_RGBA32_G_F (c), SP_RGBA32_B_F (c) );
599
 
        // set its color, from the stored array
600
 
        csel->base->setColor( color );
601
 
        GtkWidget *offspin = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "offspn"));
602
 
        GtkWidget *offslide =GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "offslide"));
603
 
 
604
 
        GtkAdjustment *adj = (GtkAdjustment*)gtk_object_get_data (GTK_OBJECT (tbl), "offset");
605
 
 
606
 
        bool isEndStop = false;
607
 
 
608
 
        SPStop *prev = NULL;
609
 
        prev = sp_prev_stop(stop, gradient);
610
 
        if (prev != NULL )  {
611
 
          adj->lower = prev->offset;
612
 
        } else {
613
 
          isEndStop = true;
614
 
          adj->lower = 0;
615
 
        }
616
 
 
617
 
        SPStop *next = NULL;
618
 
        next = sp_next_stop(stop);
619
 
        if (next != NULL ) {
620
 
          adj->upper = next->offset;
621
 
        } else {
622
 
          isEndStop = true;
623
 
          adj->upper = 1.0;
624
 
        }
625
 
 
626
 
        //fixme: does this work on all possible input gradients?
627
 
        if (!isEndStop) {
628
 
                gtk_widget_set_sensitive (offslide, TRUE);
629
 
                gtk_widget_set_sensitive (GTK_WIDGET (offspin), TRUE);
630
 
        } else {
631
 
                gtk_widget_set_sensitive (offslide, FALSE);
632
 
                gtk_widget_set_sensitive (GTK_WIDGET (offspin), FALSE);
633
 
        }
634
 
 
635
 
        gtk_adjustment_set_value (adj, stop->offset);
636
 
 
637
 
        gtk_adjustment_changed (adj);
638
 
 
639
 
        blocked = FALSE;
 
596
    SPGradient *gradient = (SPGradient *)g_object_get_data (G_OBJECT(tbl), "gradient");
 
597
 
 
598
    GObject *item = G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu))));
 
599
    SPStop *stop = SP_STOP (g_object_get_data (item, "stop"));
 
600
    if (!stop) return;
 
601
 
 
602
    blocked = TRUE;
 
603
 
 
604
    SPColorSelector *csel = (SPColorSelector*)g_object_get_data (G_OBJECT (tbl), "cselector");
 
605
    guint32 const c = sp_stop_get_rgba32(stop);
 
606
    csel->base->setAlpha(SP_RGBA32_A_F (c));
 
607
    SPColor color( SP_RGBA32_R_F (c), SP_RGBA32_G_F (c), SP_RGBA32_B_F (c) );
 
608
    // set its color, from the stored array
 
609
    csel->base->setColor( color );
 
610
    GtkWidget *offspin = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "offspn"));
 
611
    GtkWidget *offslide =GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "offslide"));
 
612
 
 
613
    GtkAdjustment *adj = (GtkAdjustment*)gtk_object_get_data (GTK_OBJECT (tbl), "offset");
 
614
 
 
615
    bool isEndStop = false;
 
616
 
 
617
    SPStop *prev = NULL;
 
618
    prev = sp_prev_stop(stop, gradient);
 
619
    if (prev != NULL )  {
 
620
        adj->lower = prev->offset;
 
621
    } else {
 
622
        isEndStop = true;
 
623
        adj->lower = 0;
 
624
    }
 
625
 
 
626
    SPStop *next = NULL;
 
627
    next = sp_next_stop(stop);
 
628
    if (next != NULL ) {
 
629
        adj->upper = next->offset;
 
630
    } else {
 
631
        isEndStop = true;
 
632
        adj->upper = 1.0;
 
633
    }
 
634
 
 
635
    //fixme: does this work on all possible input gradients?
 
636
    if (!isEndStop) {
 
637
        gtk_widget_set_sensitive (offslide, TRUE);
 
638
        gtk_widget_set_sensitive (GTK_WIDGET (offspin), TRUE);
 
639
    } else {
 
640
        gtk_widget_set_sensitive (offslide, FALSE);
 
641
        gtk_widget_set_sensitive (GTK_WIDGET (offspin), FALSE);
 
642
    }
 
643
 
 
644
    gtk_adjustment_set_value (adj, stop->offset);
 
645
 
 
646
    gtk_adjustment_changed (adj);
 
647
 
 
648
    blocked = FALSE;
640
649
}
641
650
 
642
651
 
645
654
static void
646
655
offadjustmentChanged( GtkAdjustment *adjustment, GtkWidget *vb)
647
656
{
648
 
        if (blocked)
649
 
                return;
 
657
    if (blocked)
 
658
        return;
650
659
 
651
 
        blocked = TRUE;
 
660
    blocked = TRUE;
652
661
 
653
662
    GtkOptionMenu *mnu = (GtkOptionMenu *)g_object_get_data (G_OBJECT(vb), "stopmenu");
654
663
    if (!g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop")) return;
658
667
    sp_repr_set_css_double(SP_OBJECT_REPR(stop), "offset", stop->offset);
659
668
 
660
669
    sp_document_done (SP_OBJECT_DOCUMENT (stop), SP_VERB_CONTEXT_GRADIENT,
661
 
                                                        _("Change gradient stop offset"));
 
670
                      _("Change gradient stop offset"));
662
671
 
663
 
        blocked = FALSE;
 
672
    blocked = FALSE;
664
673
}
665
674
 
666
675
guint32
667
676
sp_average_color (guint32 c1, guint32 c2, gdouble p = 0.5)
668
677
{
669
 
        guint32 r = (guint32) (SP_RGBA32_R_U (c1) * p + SP_RGBA32_R_U (c2) * (1 - p));
670
 
        guint32 g = (guint32) (SP_RGBA32_G_U (c1) * p + SP_RGBA32_G_U (c2) * (1 - p));
671
 
        guint32 b = (guint32) (SP_RGBA32_B_U (c1) * p + SP_RGBA32_B_U (c2) * (1 - p));
672
 
        guint32 a = (guint32) (SP_RGBA32_A_U (c1) * p + SP_RGBA32_A_U (c2) * (1 - p));
 
678
    guint32 r = (guint32) (SP_RGBA32_R_U (c1) * p + SP_RGBA32_R_U (c2) * (1 - p));
 
679
    guint32 g = (guint32) (SP_RGBA32_G_U (c1) * p + SP_RGBA32_G_U (c2) * (1 - p));
 
680
    guint32 b = (guint32) (SP_RGBA32_B_U (c1) * p + SP_RGBA32_B_U (c2) * (1 - p));
 
681
    guint32 a = (guint32) (SP_RGBA32_A_U (c1) * p + SP_RGBA32_A_U (c2) * (1 - p));
673
682
 
674
 
        return SP_RGBA32_U_COMPOSE (r, g, b, a);
 
683
    return SP_RGBA32_U_COMPOSE (r, g, b, a);
675
684
}
676
685
 
677
686
 
678
687
static void
679
 
sp_grd_ed_add_stop (GtkWidget *widget,  GtkWidget *vb)
 
688
sp_grd_ed_add_stop (GtkWidget */*widget*/,  GtkWidget *vb)
680
689
{
681
 
        SPGradient *gradient = (SPGradient *) g_object_get_data (G_OBJECT(vb), "gradient");
682
 
        verify_grad (gradient);
683
 
        GtkOptionMenu *mnu = (GtkOptionMenu *)g_object_get_data (G_OBJECT(vb), "stopmenu");
684
 
 
685
 
        SPStop *stop = (SPStop *) g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop");
686
 
 
687
 
        if (stop == NULL)
688
 
                return;
689
 
 
690
 
        Inkscape::XML::Node *new_stop_repr = NULL;
691
 
 
692
 
        SPStop *next = sp_next_stop (stop);
693
 
 
694
 
        if (next == NULL) {
695
 
                SPStop *prev = sp_prev_stop (stop, gradient);
696
 
                if (prev != NULL) {
697
 
                        next = stop;
698
 
                        stop = prev;
699
 
                }
700
 
        }
701
 
 
702
 
        if (next != NULL) {
703
 
                new_stop_repr = SP_OBJECT_REPR(stop)->duplicate(SP_OBJECT_REPR(gradient)->document());
704
 
                SP_OBJECT_REPR(gradient)->addChild(new_stop_repr, SP_OBJECT_REPR(stop));
705
 
        } else {
706
 
                next = stop;
707
 
                new_stop_repr = SP_OBJECT_REPR(sp_prev_stop(stop, gradient))->duplicate(SP_OBJECT_REPR(gradient)->document());
708
 
                SP_OBJECT_REPR(gradient)->addChild(new_stop_repr, SP_OBJECT_REPR(sp_prev_stop(stop, gradient)));
709
 
        }
710
 
 
711
 
        SPStop *newstop = (SPStop *) SP_OBJECT_DOCUMENT(gradient)->getObjectByRepr(new_stop_repr);
712
 
 
713
 
        newstop->offset = (stop->offset + next->offset) * 0.5 ;
714
 
 
715
 
        guint32 const c1 = sp_stop_get_rgba32(stop);
716
 
        guint32 const c2 = sp_stop_get_rgba32(next);
717
 
        guint32 cnew = sp_average_color (c1, c2);
718
 
 
719
 
        Inkscape::CSSOStringStream os;
720
 
        gchar c[64];
721
 
        sp_svg_write_color (c, sizeof(c), cnew);
722
 
        gdouble opacity = (gdouble) SP_RGBA32_A_F (cnew);
723
 
        os << "stop-color:" << c << ";stop-opacity:" << opacity <<";";
724
 
        SP_OBJECT_REPR (newstop)->setAttribute("style", os.str().c_str());
 
690
    SPGradient *gradient = (SPGradient *) g_object_get_data (G_OBJECT(vb), "gradient");
 
691
    verify_grad (gradient);
 
692
    GtkOptionMenu *mnu = (GtkOptionMenu *)g_object_get_data (G_OBJECT(vb), "stopmenu");
 
693
 
 
694
    SPStop *stop = (SPStop *) g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop");
 
695
 
 
696
    if (stop == NULL)
 
697
        return;
 
698
 
 
699
    Inkscape::XML::Node *new_stop_repr = NULL;
 
700
 
 
701
    SPStop *next = sp_next_stop (stop);
 
702
 
 
703
    if (next == NULL) {
 
704
        SPStop *prev = sp_prev_stop (stop, gradient);
 
705
        if (prev != NULL) {
 
706
            next = stop;
 
707
            stop = prev;
 
708
        }
 
709
    }
 
710
 
 
711
    if (next != NULL) {
 
712
        new_stop_repr = SP_OBJECT_REPR(stop)->duplicate(SP_OBJECT_REPR(gradient)->document());
 
713
        SP_OBJECT_REPR(gradient)->addChild(new_stop_repr, SP_OBJECT_REPR(stop));
 
714
    } else {
 
715
        next = stop;
 
716
        new_stop_repr = SP_OBJECT_REPR(sp_prev_stop(stop, gradient))->duplicate(SP_OBJECT_REPR(gradient)->document());
 
717
        SP_OBJECT_REPR(gradient)->addChild(new_stop_repr, SP_OBJECT_REPR(sp_prev_stop(stop, gradient)));
 
718
    }
 
719
 
 
720
    SPStop *newstop = (SPStop *) SP_OBJECT_DOCUMENT(gradient)->getObjectByRepr(new_stop_repr);
 
721
 
 
722
    newstop->offset = (stop->offset + next->offset) * 0.5 ;
 
723
 
 
724
    guint32 const c1 = sp_stop_get_rgba32(stop);
 
725
    guint32 const c2 = sp_stop_get_rgba32(next);
 
726
    guint32 cnew = sp_average_color (c1, c2);
 
727
 
 
728
    Inkscape::CSSOStringStream os;
 
729
    gchar c[64];
 
730
    sp_svg_write_color (c, sizeof(c), cnew);
 
731
    gdouble opacity = (gdouble) SP_RGBA32_A_F (cnew);
 
732
    os << "stop-color:" << c << ";stop-opacity:" << opacity <<";";
 
733
    SP_OBJECT_REPR (newstop)->setAttribute("style", os.str().c_str());
725
734
    sp_repr_set_css_double( SP_OBJECT_REPR(newstop), "offset", (double)newstop->offset);
726
735
 
727
 
        sp_gradient_vector_widget_load_gradient (vb, gradient);
728
 
        Inkscape::GC::release(new_stop_repr);
729
 
        update_stop_list(GTK_WIDGET(mnu), gradient, newstop);
730
 
        GtkWidget *offspin = GTK_WIDGET (g_object_get_data (G_OBJECT (vb), "offspn"));
731
 
        GtkWidget *offslide =GTK_WIDGET (g_object_get_data (G_OBJECT (vb), "offslide"));
732
 
        gtk_widget_set_sensitive (offslide, TRUE);
733
 
        gtk_widget_set_sensitive (GTK_WIDGET (offspin), TRUE);
734
 
        sp_document_done (SP_OBJECT_DOCUMENT (gradient), SP_VERB_CONTEXT_GRADIENT, 
735
 
                          _("Add gradient stop"));
 
736
    sp_gradient_vector_widget_load_gradient (vb, gradient);
 
737
    Inkscape::GC::release(new_stop_repr);
 
738
    update_stop_list(GTK_WIDGET(mnu), gradient, newstop);
 
739
    GtkWidget *offspin = GTK_WIDGET (g_object_get_data (G_OBJECT (vb), "offspn"));
 
740
    GtkWidget *offslide =GTK_WIDGET (g_object_get_data (G_OBJECT (vb), "offslide"));
 
741
    gtk_widget_set_sensitive (offslide, TRUE);
 
742
    gtk_widget_set_sensitive (GTK_WIDGET (offspin), TRUE);
 
743
    sp_document_done (SP_OBJECT_DOCUMENT (gradient), SP_VERB_CONTEXT_GRADIENT,
 
744
                      _("Add gradient stop"));
736
745
}
737
746
 
738
747
static void
739
 
sp_grd_ed_del_stop (GtkWidget *widget,  GtkWidget *vb)
 
748
sp_grd_ed_del_stop (GtkWidget */*widget*/,  GtkWidget *vb)
740
749
{
741
 
        SPGradient *gradient = (SPGradient *)g_object_get_data (G_OBJECT(vb), "gradient");
742
 
 
743
 
        GtkOptionMenu *mnu = (GtkOptionMenu *)g_object_get_data (G_OBJECT(vb), "stopmenu");
744
 
        if (!g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop")) return;
745
 
        SPStop *stop = SP_STOP(g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop"));
746
 
        if (gradient->vector.stops.size() > 2) { // 2 is the minimum
747
 
 
748
 
                // if we delete first or last stop, move the next/previous to the edge
749
 
                if (stop->offset == 0) {
750
 
                        SPStop *next = sp_next_stop (stop);
751
 
                        if (next) {
752
 
                                next->offset = 0;
753
 
                                sp_repr_set_css_double (SP_OBJECT_REPR (next), "offset", 0);
754
 
                        }
755
 
                } else if (stop->offset == 1) {
756
 
                        SPStop *prev = sp_prev_stop (stop, gradient);
757
 
                        if (prev) {
758
 
                                prev->offset = 1;
759
 
                                sp_repr_set_css_double (SP_OBJECT_REPR (prev), "offset", 1);
760
 
                        }
761
 
                }
762
 
 
763
 
                SP_OBJECT_REPR(gradient)->removeChild(SP_OBJECT_REPR(stop));
764
 
                sp_gradient_vector_widget_load_gradient (vb, gradient);
765
 
                update_stop_list(GTK_WIDGET(mnu), gradient, NULL);
766
 
                sp_document_done (SP_OBJECT_DOCUMENT (gradient), SP_VERB_CONTEXT_GRADIENT, 
767
 
                                  _("Delete gradient stop"));
768
 
        }
 
750
    SPGradient *gradient = (SPGradient *)g_object_get_data (G_OBJECT(vb), "gradient");
 
751
 
 
752
    GtkOptionMenu *mnu = (GtkOptionMenu *)g_object_get_data (G_OBJECT(vb), "stopmenu");
 
753
    if (!g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop")) return;
 
754
    SPStop *stop = SP_STOP(g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop"));
 
755
    if (gradient->vector.stops.size() > 2) { // 2 is the minimum
 
756
 
 
757
        // if we delete first or last stop, move the next/previous to the edge
 
758
        if (stop->offset == 0) {
 
759
            SPStop *next = sp_next_stop (stop);
 
760
            if (next) {
 
761
                next->offset = 0;
 
762
                sp_repr_set_css_double (SP_OBJECT_REPR (next), "offset", 0);
 
763
            }
 
764
        } else if (stop->offset == 1) {
 
765
            SPStop *prev = sp_prev_stop (stop, gradient);
 
766
            if (prev) {
 
767
                prev->offset = 1;
 
768
                sp_repr_set_css_double (SP_OBJECT_REPR (prev), "offset", 1);
 
769
            }
 
770
        }
 
771
 
 
772
        SP_OBJECT_REPR(gradient)->removeChild(SP_OBJECT_REPR(stop));
 
773
        sp_gradient_vector_widget_load_gradient (vb, gradient);
 
774
        update_stop_list(GTK_WIDGET(mnu), gradient, NULL);
 
775
        sp_document_done (SP_OBJECT_DOCUMENT (gradient), SP_VERB_CONTEXT_GRADIENT,
 
776
                          _("Delete gradient stop"));
 
777
    }
769
778
 
770
779
}
771
780
 
772
781
static GtkWidget *
773
782
sp_gradient_vector_widget_new (SPGradient *gradient, SPStop *select_stop)
774
783
{
775
 
        GtkWidget *vb, *w, *f, *csel;
776
 
 
777
 
        g_return_val_if_fail (!gradient || SP_IS_GRADIENT (gradient), NULL);
778
 
 
779
 
        vb = gtk_vbox_new (FALSE, PAD);
780
 
        g_signal_connect (G_OBJECT (vb), "destroy", G_CALLBACK (sp_gradient_vector_widget_destroy), NULL);
781
 
 
782
 
        w = sp_gradient_image_new (gradient);
783
 
        g_object_set_data (G_OBJECT (vb), "preview", w);
784
 
        gtk_widget_show (w);
785
 
        gtk_box_pack_start (GTK_BOX (vb), w, TRUE, TRUE, PAD);
786
 
 
787
 
        gtk_object_set_data (GTK_OBJECT (vb), "gradient", gradient);
788
 
        sp_repr_add_listener (SP_OBJECT_REPR(gradient), &grad_edit_dia_repr_events, vb);
789
 
        GtkTooltips *tt = gtk_tooltips_new ();
790
 
 
791
 
        /* Stop list */
792
 
        GtkWidget *mnu = gtk_option_menu_new ();
793
 
        /* Create new menu widget */
794
 
        update_stop_list (GTK_WIDGET(mnu), gradient, NULL);
795
 
        gtk_signal_connect (GTK_OBJECT (mnu), "changed", GTK_SIGNAL_FUNC (sp_grad_edit_select), vb);
796
 
        gtk_widget_show (mnu);
797
 
        gtk_object_set_data (GTK_OBJECT (vb), "stopmenu", mnu);
798
 
        gtk_box_pack_start (GTK_BOX (vb), mnu, FALSE, FALSE, 0);
799
 
 
800
 
        /* Add and Remove buttons */
801
 
        GtkWidget *hb = gtk_hbox_new (FALSE, 1);
802
 
        // TRANSLATORS: "Stop" means: a "phase" of a gradient
803
 
        GtkWidget *b = gtk_button_new_with_label (_("Add stop"));
804
 
        gtk_widget_show (b);
805
 
        gtk_container_add (GTK_CONTAINER (hb), b);
806
 
        gtk_tooltips_set_tip (tt, b, _("Add another control stop to gradient"), NULL);
807
 
        gtk_signal_connect (GTK_OBJECT (b), "clicked", GTK_SIGNAL_FUNC (sp_grd_ed_add_stop), vb);
808
 
        b = gtk_button_new_with_label (_("Delete stop"));
809
 
        gtk_widget_show (b);
810
 
        gtk_container_add (GTK_CONTAINER (hb), b);
811
 
        gtk_tooltips_set_tip (tt, b, _("Delete current control stop from gradient"), NULL);
812
 
        gtk_signal_connect (GTK_OBJECT (b), "clicked", GTK_SIGNAL_FUNC (sp_grd_ed_del_stop), vb);
813
 
 
814
 
        gtk_widget_show (hb);
815
 
        gtk_box_pack_start (GTK_BOX (vb),hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
816
 
 
817
 
 
818
 
        /*  Offset Slider and stuff   */
819
 
        hb = gtk_hbox_new (FALSE, 0);
820
 
 
821
 
        /* Label */
822
 
        GtkWidget *l = gtk_label_new (_("Offset:"));
823
 
        gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
824
 
        gtk_box_pack_start (GTK_BOX (hb),l, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
825
 
        gtk_widget_show (l);
826
 
 
827
 
        /* Adjustment */
828
 
        GtkAdjustment *Offset_adj = NULL;
829
 
        Offset_adj= (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 1.0, 0.01, 0.01, 0.0);
830
 
        gtk_object_set_data (GTK_OBJECT (vb), "offset", Offset_adj);
831
 
        GtkMenu *m = GTK_MENU(gtk_option_menu_get_menu (GTK_OPTION_MENU(mnu)));
832
 
        SPStop *stop = SP_STOP (g_object_get_data (G_OBJECT (gtk_menu_get_active (m)), "stop"));
833
 
        gtk_adjustment_set_value (Offset_adj, stop->offset);
834
 
 
835
 
        /* Slider */
836
 
        GtkWidget *slider = gtk_hscale_new(Offset_adj);
837
 
        gtk_scale_set_draw_value( GTK_SCALE(slider), FALSE );
838
 
        gtk_widget_show (slider);
839
 
        gtk_box_pack_start (GTK_BOX (hb),slider, TRUE, TRUE, AUX_BETWEEN_BUTTON_GROUPS);
840
 
        gtk_object_set_data (GTK_OBJECT (vb), "offslide", slider);
841
 
 
842
 
        /* Spinbutton */
843
 
        GtkWidget *sbtn = gtk_spin_button_new (GTK_ADJUSTMENT (Offset_adj), 0.01, 2);
844
 
        sp_dialog_defocus_on_enter (sbtn);
845
 
        gtk_widget_show (sbtn);
846
 
        gtk_box_pack_start (GTK_BOX (hb),sbtn, FALSE, TRUE, AUX_BETWEEN_BUTTON_GROUPS);
847
 
        gtk_object_set_data (GTK_OBJECT (vb), "offspn", sbtn);
848
 
 
849
 
        if (stop->offset>0 && stop->offset<1) {
850
 
                gtk_widget_set_sensitive (slider, TRUE);
851
 
                gtk_widget_set_sensitive (GTK_WIDGET (sbtn), TRUE);
852
 
        } else {
853
 
                gtk_widget_set_sensitive (slider, FALSE);
854
 
                gtk_widget_set_sensitive (GTK_WIDGET (sbtn), FALSE);
855
 
        }
856
 
 
857
 
 
858
 
        /* Signals */
859
 
        gtk_signal_connect (GTK_OBJECT (Offset_adj), "value_changed", 
860
 
                            GTK_SIGNAL_FUNC (offadjustmentChanged), vb);
861
 
 
862
 
        // gtk_signal_connect (GTK_OBJECT (slider), "changed",  GTK_SIGNAL_FUNC (offsliderChanged), vb);
863
 
        gtk_widget_show (hb);
864
 
        gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, PAD);
865
 
 
866
 
        // TRANSLATORS: "Stop" means: a "phase" of a gradient
867
 
        f = gtk_frame_new (_("Stop Color"));
868
 
        gtk_widget_show (f);
869
 
        gtk_box_pack_start (GTK_BOX (vb), f, TRUE, TRUE, PAD);
870
 
        csel = (GtkWidget*)sp_color_selector_new (SP_TYPE_COLOR_NOTEBOOK);
871
 
        g_object_set_data (G_OBJECT (vb), "cselector", csel);
872
 
        gtk_widget_show (csel);
873
 
        gtk_container_add (GTK_CONTAINER (f), csel);
874
 
        g_signal_connect (G_OBJECT (csel), "dragged", G_CALLBACK (sp_gradient_vector_color_dragged), vb);
875
 
        g_signal_connect (G_OBJECT (csel), "changed", G_CALLBACK (sp_gradient_vector_color_changed), vb);
876
 
 
877
 
        gtk_widget_show (vb);
878
 
 
879
 
        sp_gradient_vector_widget_load_gradient (vb, gradient);
880
 
 
881
 
        if (select_stop)
882
 
                select_stop_in_list (GTK_WIDGET(mnu), gradient, select_stop);
883
 
 
884
 
        return vb;
 
784
    GtkWidget *vb, *w, *f, *csel;
 
785
 
 
786
    g_return_val_if_fail (!gradient || SP_IS_GRADIENT (gradient), NULL);
 
787
 
 
788
    vb = gtk_vbox_new (FALSE, PAD);
 
789
    g_signal_connect (G_OBJECT (vb), "destroy", G_CALLBACK (sp_gradient_vector_widget_destroy), NULL);
 
790
 
 
791
    w = sp_gradient_image_new (gradient);
 
792
    g_object_set_data (G_OBJECT (vb), "preview", w);
 
793
    gtk_widget_show (w);
 
794
    gtk_box_pack_start (GTK_BOX (vb), w, TRUE, TRUE, PAD);
 
795
 
 
796
    gtk_object_set_data (GTK_OBJECT (vb), "gradient", gradient);
 
797
    sp_repr_add_listener (SP_OBJECT_REPR(gradient), &grad_edit_dia_repr_events, vb);
 
798
    GtkTooltips *tt = gtk_tooltips_new ();
 
799
 
 
800
    /* Stop list */
 
801
    GtkWidget *mnu = gtk_option_menu_new ();
 
802
    /* Create new menu widget */
 
803
    update_stop_list (GTK_WIDGET(mnu), gradient, NULL);
 
804
    gtk_signal_connect (GTK_OBJECT (mnu), "changed", GTK_SIGNAL_FUNC (sp_grad_edit_select), vb);
 
805
    gtk_widget_show (mnu);
 
806
    gtk_object_set_data (GTK_OBJECT (vb), "stopmenu", mnu);
 
807
    gtk_box_pack_start (GTK_BOX (vb), mnu, FALSE, FALSE, 0);
 
808
 
 
809
    /* Add and Remove buttons */
 
810
    GtkWidget *hb = gtk_hbox_new (FALSE, 1);
 
811
    // TRANSLATORS: "Stop" means: a "phase" of a gradient
 
812
    GtkWidget *b = gtk_button_new_with_label (_("Add stop"));
 
813
    gtk_widget_show (b);
 
814
    gtk_container_add (GTK_CONTAINER (hb), b);
 
815
    gtk_tooltips_set_tip (tt, b, _("Add another control stop to gradient"), NULL);
 
816
    gtk_signal_connect (GTK_OBJECT (b), "clicked", GTK_SIGNAL_FUNC (sp_grd_ed_add_stop), vb);
 
817
    b = gtk_button_new_with_label (_("Delete stop"));
 
818
    gtk_widget_show (b);
 
819
    gtk_container_add (GTK_CONTAINER (hb), b);
 
820
    gtk_tooltips_set_tip (tt, b, _("Delete current control stop from gradient"), NULL);
 
821
    gtk_signal_connect (GTK_OBJECT (b), "clicked", GTK_SIGNAL_FUNC (sp_grd_ed_del_stop), vb);
 
822
 
 
823
    gtk_widget_show (hb);
 
824
    gtk_box_pack_start (GTK_BOX (vb),hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
825
 
 
826
 
 
827
    /*  Offset Slider and stuff   */
 
828
    hb = gtk_hbox_new (FALSE, 0);
 
829
 
 
830
    /* Label */
 
831
    GtkWidget *l = gtk_label_new (_("Offset:"));
 
832
    gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
 
833
    gtk_box_pack_start (GTK_BOX (hb),l, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
834
    gtk_widget_show (l);
 
835
 
 
836
    /* Adjustment */
 
837
    GtkAdjustment *Offset_adj = NULL;
 
838
    Offset_adj= (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 1.0, 0.01, 0.01, 0.0);
 
839
    gtk_object_set_data (GTK_OBJECT (vb), "offset", Offset_adj);
 
840
    GtkMenu *m = GTK_MENU(gtk_option_menu_get_menu (GTK_OPTION_MENU(mnu)));
 
841
    SPStop *stop = SP_STOP (g_object_get_data (G_OBJECT (gtk_menu_get_active (m)), "stop"));
 
842
    gtk_adjustment_set_value (Offset_adj, stop->offset);
 
843
 
 
844
    /* Slider */
 
845
    GtkWidget *slider = gtk_hscale_new(Offset_adj);
 
846
    gtk_scale_set_draw_value( GTK_SCALE(slider), FALSE );
 
847
    gtk_widget_show (slider);
 
848
    gtk_box_pack_start (GTK_BOX (hb),slider, TRUE, TRUE, AUX_BETWEEN_BUTTON_GROUPS);
 
849
    gtk_object_set_data (GTK_OBJECT (vb), "offslide", slider);
 
850
 
 
851
    /* Spinbutton */
 
852
    GtkWidget *sbtn = gtk_spin_button_new (GTK_ADJUSTMENT (Offset_adj), 0.01, 2);
 
853
    sp_dialog_defocus_on_enter (sbtn);
 
854
    gtk_widget_show (sbtn);
 
855
    gtk_box_pack_start (GTK_BOX (hb),sbtn, FALSE, TRUE, AUX_BETWEEN_BUTTON_GROUPS);
 
856
    gtk_object_set_data (GTK_OBJECT (vb), "offspn", sbtn);
 
857
 
 
858
    if (stop->offset>0 && stop->offset<1) {
 
859
        gtk_widget_set_sensitive (slider, TRUE);
 
860
        gtk_widget_set_sensitive (GTK_WIDGET (sbtn), TRUE);
 
861
    } else {
 
862
        gtk_widget_set_sensitive (slider, FALSE);
 
863
        gtk_widget_set_sensitive (GTK_WIDGET (sbtn), FALSE);
 
864
    }
 
865
 
 
866
 
 
867
    /* Signals */
 
868
    gtk_signal_connect (GTK_OBJECT (Offset_adj), "value_changed",
 
869
                        GTK_SIGNAL_FUNC (offadjustmentChanged), vb);
 
870
 
 
871
    // gtk_signal_connect (GTK_OBJECT (slider), "changed",  GTK_SIGNAL_FUNC (offsliderChanged), vb);
 
872
    gtk_widget_show (hb);
 
873
    gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, PAD);
 
874
 
 
875
    // TRANSLATORS: "Stop" means: a "phase" of a gradient
 
876
    f = gtk_frame_new (_("Stop Color"));
 
877
    gtk_widget_show (f);
 
878
    gtk_box_pack_start (GTK_BOX (vb), f, TRUE, TRUE, PAD);
 
879
    csel = (GtkWidget*)sp_color_selector_new (SP_TYPE_COLOR_NOTEBOOK);
 
880
    g_object_set_data (G_OBJECT (vb), "cselector", csel);
 
881
    gtk_widget_show (csel);
 
882
    gtk_container_add (GTK_CONTAINER (f), csel);
 
883
    g_signal_connect (G_OBJECT (csel), "dragged", G_CALLBACK (sp_gradient_vector_color_dragged), vb);
 
884
    g_signal_connect (G_OBJECT (csel), "changed", G_CALLBACK (sp_gradient_vector_color_changed), vb);
 
885
 
 
886
    gtk_widget_show (vb);
 
887
 
 
888
    sp_gradient_vector_widget_load_gradient (vb, gradient);
 
889
 
 
890
    if (select_stop)
 
891
        select_stop_in_list (GTK_WIDGET(mnu), gradient, select_stop);
 
892
 
 
893
    return vb;
885
894
}
886
895
 
887
896
 
889
898
GtkWidget *
890
899
sp_gradient_vector_editor_new (SPGradient *gradient, SPStop *stop)
891
900
{
892
 
        GtkWidget *wid;
893
 
 
894
 
        if (dlg == NULL) {
895
 
 
896
 
                dlg = sp_window_new (_("Gradient editor"), TRUE);
897
 
                if (x == -1000 || y == -1000) {
898
 
                        x = prefs_get_int_attribute (prefs_path, "x", 0);
899
 
                        y = prefs_get_int_attribute (prefs_path, "y", 0);
900
 
                }
901
 
                if (w ==0 || h == 0) {
902
 
                        w = prefs_get_int_attribute (prefs_path, "w", 0);
903
 
                        h = prefs_get_int_attribute (prefs_path, "h", 0);
904
 
                }
905
 
 
906
 
                if (x<0) x=0;
907
 
                if (y<0) y=0;
908
 
 
909
 
                if (x != 0 || y != 0)
910
 
                        gtk_window_move ((GtkWindow *) dlg, x, y);
911
 
                else
912
 
                        gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
913
 
                if (w && h) gtk_window_resize ((GtkWindow *) dlg, w, h);
914
 
                sp_transientize (dlg);
915
 
                wd.win = dlg;
916
 
                wd.stop = 0;
917
 
                g_signal_connect (G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd);
918
 
                gtk_signal_connect (GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg);
919
 
                gtk_signal_connect (GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_gradient_vector_dialog_destroy), dlg);
920
 
                gtk_signal_connect (GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_gradient_vector_dialog_delete), dlg);
921
 
                g_signal_connect (G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_gradient_vector_dialog_delete), dlg);
922
 
                g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg );
923
 
                g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg );
924
 
 
925
 
                gtk_container_set_border_width (GTK_CONTAINER (dlg), PAD);
926
 
 
927
 
                wid = (GtkWidget*)sp_gradient_vector_widget_new (gradient, stop);
928
 
                g_object_set_data (G_OBJECT (dlg), "gradient-vector-widget", wid);
929
 
                /* Connect signals */
930
 
                gtk_widget_show (wid);
931
 
                gtk_container_add (GTK_CONTAINER (dlg), wid);
932
 
        } else {
933
 
                // FIXME: temp fix for 0.38
934
 
                // Simply load_gradient into the editor does not work for multi-stop gradients,
935
 
                // as the stop list and other widgets are in a wrong state and crash readily.
936
 
                // Instead we just delete the window (by sending the delete signal)
937
 
                // and call sp_gradient_vector_editor_new again, so it creates the window anew.
938
 
 
939
 
                GdkEventAny event;
940
 
                GtkWidget *widget = (GtkWidget *) dlg;
941
 
                event.type = GDK_DELETE;
942
 
                event.window = widget->window;
943
 
                event.send_event = TRUE;
944
 
                g_object_ref (G_OBJECT (event.window));
945
 
                gtk_main_do_event ((GdkEvent*)&event);
946
 
                g_object_unref (G_OBJECT (event.window));
947
 
 
948
 
                g_assert (dlg == NULL);
949
 
                sp_gradient_vector_editor_new (gradient, stop);
950
 
        }
951
 
 
952
 
        return dlg;
 
901
    GtkWidget *wid;
 
902
 
 
903
    if (dlg == NULL) {
 
904
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
905
 
 
906
        dlg = sp_window_new (_("Gradient editor"), TRUE);
 
907
        if (x == -1000 || y == -1000) {
 
908
            x = prefs->getInt(prefs_path + "x", -1000);
 
909
            y = prefs->getInt(prefs_path + "y", -1000);
 
910
        }
 
911
        if (w ==0 || h == 0) {
 
912
            w = prefs->getInt(prefs_path + "w", 0);
 
913
            h = prefs->getInt(prefs_path + "h", 0);
 
914
        }
 
915
 
 
916
        if (x<0) x=0;
 
917
        if (y<0) y=0;
 
918
 
 
919
        if (x != 0 || y != 0)
 
920
            gtk_window_move ((GtkWindow *) dlg, x, y);
 
921
        else
 
922
            gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
 
923
        if (w && h) gtk_window_resize ((GtkWindow *) dlg, w, h);
 
924
        sp_transientize (dlg);
 
925
        wd.win = dlg;
 
926
        wd.stop = 0;
 
927
        g_signal_connect (G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd);
 
928
        gtk_signal_connect (GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg);
 
929
        gtk_signal_connect (GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_gradient_vector_dialog_destroy), dlg);
 
930
        gtk_signal_connect (GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_gradient_vector_dialog_delete), dlg);
 
931
        g_signal_connect (G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_gradient_vector_dialog_delete), dlg);
 
932
        g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg );
 
933
        g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg );
 
934
 
 
935
        gtk_container_set_border_width (GTK_CONTAINER (dlg), PAD);
 
936
 
 
937
        wid = (GtkWidget*)sp_gradient_vector_widget_new (gradient, stop);
 
938
        g_object_set_data (G_OBJECT (dlg), "gradient-vector-widget", wid);
 
939
        /* Connect signals */
 
940
        gtk_widget_show (wid);
 
941
        gtk_container_add (GTK_CONTAINER (dlg), wid);
 
942
    } else {
 
943
        // FIXME: temp fix for 0.38
 
944
        // Simply load_gradient into the editor does not work for multi-stop gradients,
 
945
        // as the stop list and other widgets are in a wrong state and crash readily.
 
946
        // Instead we just delete the window (by sending the delete signal)
 
947
        // and call sp_gradient_vector_editor_new again, so it creates the window anew.
 
948
 
 
949
        GdkEventAny event;
 
950
        GtkWidget *widget = (GtkWidget *) dlg;
 
951
        event.type = GDK_DELETE;
 
952
        event.window = widget->window;
 
953
        event.send_event = TRUE;
 
954
        g_object_ref (G_OBJECT (event.window));
 
955
        gtk_main_do_event ((GdkEvent*)&event);
 
956
        g_object_unref (G_OBJECT (event.window));
 
957
 
 
958
        g_assert (dlg == NULL);
 
959
        sp_gradient_vector_editor_new (gradient, stop);
 
960
    }
 
961
 
 
962
    return dlg;
953
963
}
954
964
 
955
965
static void
956
966
sp_gradient_vector_widget_load_gradient (GtkWidget *widget, SPGradient *gradient)
957
967
{
958
 
        blocked = TRUE;
959
 
 
960
 
        SPGradient *old;
961
 
 
962
 
        old = (SPGradient*)g_object_get_data (G_OBJECT (widget), "gradient");
963
 
 
964
 
        if (old != gradient) {
965
 
                sigc::connection *release_connection;
966
 
                sigc::connection *modified_connection;
967
 
 
968
 
                release_connection = (sigc::connection *)g_object_get_data(G_OBJECT(widget), "gradient_release_connection");
969
 
                modified_connection = (sigc::connection *)g_object_get_data(G_OBJECT(widget), "gradient_modified_connection");
970
 
 
971
 
                if (old) {
972
 
                        g_assert( release_connection != NULL );
973
 
                        g_assert( modified_connection != NULL );
974
 
                        release_connection->disconnect();
975
 
                        modified_connection->disconnect();
976
 
                        sp_signal_disconnect_by_data (old, widget);
977
 
                }
978
 
 
979
 
                if (gradient) {
980
 
                        if (!release_connection) {
981
 
                                release_connection = new sigc::connection();
982
 
                        }
983
 
                        if (!modified_connection) {
984
 
                                modified_connection = new sigc::connection();
985
 
                        }
986
 
                        *release_connection = gradient->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gradient_vector_gradient_release), widget));
987
 
                        *modified_connection = gradient->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_gradient_vector_gradient_modified), widget));
988
 
                } else {
989
 
                        if (release_connection) {
990
 
                                delete release_connection;
991
 
                                release_connection = NULL;
992
 
                        }
993
 
                        if (modified_connection) {
994
 
                                delete modified_connection;
995
 
                                modified_connection = NULL;
996
 
                        }
997
 
                }
998
 
 
999
 
                g_object_set_data(G_OBJECT(widget), "gradient_release_connection", release_connection);
1000
 
                g_object_set_data(G_OBJECT(widget), "gradient_modified_connection", modified_connection);
1001
 
        }
1002
 
 
1003
 
        g_object_set_data (G_OBJECT (widget), "gradient", gradient);
1004
 
 
1005
 
        if (gradient) {
1006
 
                sp_gradient_ensure_vector (gradient);
1007
 
 
1008
 
                GtkOptionMenu *mnu = (GtkOptionMenu *)g_object_get_data (G_OBJECT(widget), "stopmenu");
1009
 
                SPStop *stop = SP_STOP(g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop"));
1010
 
                guint32 const c = sp_stop_get_rgba32(stop);
1011
 
 
1012
 
                /// get the color selector
1013
 
                SPColorSelector *csel = SP_COLOR_SELECTOR(g_object_get_data (G_OBJECT (widget), "cselector"));
1014
 
                // set alpha
1015
 
                csel->base->setAlpha(SP_RGBA32_A_F (c));
1016
 
                SPColor color( SP_RGBA32_R_F (c), SP_RGBA32_G_F (c), SP_RGBA32_B_F (c) );
1017
 
                // set color
1018
 
                csel->base->setColor( color );
1019
 
        }
1020
 
 
1021
 
        /* Fill preview */
1022
 
        GtkWidget *w = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(widget), "preview"));
1023
 
        sp_gradient_image_set_gradient (SP_GRADIENT_IMAGE (w), gradient);
1024
 
 
1025
 
        GtkWidget *mnu = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(widget), "stopmenu"));
1026
 
        update_stop_list (GTK_WIDGET(mnu), gradient, NULL);
1027
 
 
1028
 
        // Once the user edits a gradient, it stops being auto-collectable
1029
 
        if (SP_OBJECT_REPR(gradient)->attribute("inkscape:collect")) {
1030
 
                SPDocument *document = SP_OBJECT_DOCUMENT (gradient);
1031
 
                bool saved = sp_document_get_undo_sensitive(document);
1032
 
                sp_document_set_undo_sensitive (document, false);
1033
 
                SP_OBJECT_REPR(gradient)->setAttribute("inkscape:collect", NULL);
1034
 
                sp_document_set_undo_sensitive (document, saved);
1035
 
        }
1036
 
 
1037
 
        blocked = FALSE;
 
968
    blocked = TRUE;
 
969
 
 
970
    SPGradient *old;
 
971
 
 
972
    old = (SPGradient*)g_object_get_data (G_OBJECT (widget), "gradient");
 
973
 
 
974
    if (old != gradient) {
 
975
        sigc::connection *release_connection;
 
976
        sigc::connection *modified_connection;
 
977
 
 
978
        release_connection = (sigc::connection *)g_object_get_data(G_OBJECT(widget), "gradient_release_connection");
 
979
        modified_connection = (sigc::connection *)g_object_get_data(G_OBJECT(widget), "gradient_modified_connection");
 
980
 
 
981
        if (old) {
 
982
            g_assert( release_connection != NULL );
 
983
            g_assert( modified_connection != NULL );
 
984
            release_connection->disconnect();
 
985
            modified_connection->disconnect();
 
986
            sp_signal_disconnect_by_data (old, widget);
 
987
        }
 
988
 
 
989
        if (gradient) {
 
990
            if (!release_connection) {
 
991
                release_connection = new sigc::connection();
 
992
            }
 
993
            if (!modified_connection) {
 
994
                modified_connection = new sigc::connection();
 
995
            }
 
996
            *release_connection = gradient->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gradient_vector_gradient_release), widget));
 
997
            *modified_connection = gradient->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_gradient_vector_gradient_modified), widget));
 
998
        } else {
 
999
            if (release_connection) {
 
1000
                delete release_connection;
 
1001
                release_connection = NULL;
 
1002
            }
 
1003
            if (modified_connection) {
 
1004
                delete modified_connection;
 
1005
                modified_connection = NULL;
 
1006
            }
 
1007
        }
 
1008
 
 
1009
        g_object_set_data(G_OBJECT(widget), "gradient_release_connection", release_connection);
 
1010
        g_object_set_data(G_OBJECT(widget), "gradient_modified_connection", modified_connection);
 
1011
    }
 
1012
 
 
1013
    g_object_set_data (G_OBJECT (widget), "gradient", gradient);
 
1014
 
 
1015
    if (gradient) {
 
1016
        sp_gradient_ensure_vector (gradient);
 
1017
 
 
1018
        GtkOptionMenu *mnu = (GtkOptionMenu *)g_object_get_data (G_OBJECT(widget), "stopmenu");
 
1019
        SPStop *stop = SP_STOP(g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop"));
 
1020
        guint32 const c = sp_stop_get_rgba32(stop);
 
1021
 
 
1022
        /// get the color selector
 
1023
        SPColorSelector *csel = SP_COLOR_SELECTOR(g_object_get_data (G_OBJECT (widget), "cselector"));
 
1024
        // set alpha
 
1025
        csel->base->setAlpha(SP_RGBA32_A_F (c));
 
1026
        SPColor color( SP_RGBA32_R_F (c), SP_RGBA32_G_F (c), SP_RGBA32_B_F (c) );
 
1027
        // set color
 
1028
        csel->base->setColor( color );
 
1029
    }
 
1030
 
 
1031
    /* Fill preview */
 
1032
    GtkWidget *w = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(widget), "preview"));
 
1033
    sp_gradient_image_set_gradient (SP_GRADIENT_IMAGE (w), gradient);
 
1034
 
 
1035
    GtkWidget *mnu = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(widget), "stopmenu"));
 
1036
    update_stop_list (GTK_WIDGET(mnu), gradient, NULL);
 
1037
 
 
1038
    // Once the user edits a gradient, it stops being auto-collectable
 
1039
    if (SP_OBJECT_REPR(gradient)->attribute("inkscape:collect")) {
 
1040
        SPDocument *document = SP_OBJECT_DOCUMENT (gradient);
 
1041
        bool saved = sp_document_get_undo_sensitive(document);
 
1042
        sp_document_set_undo_sensitive (document, false);
 
1043
        SP_OBJECT_REPR(gradient)->setAttribute("inkscape:collect", NULL);
 
1044
        sp_document_set_undo_sensitive (document, saved);
 
1045
    }
 
1046
 
 
1047
    blocked = FALSE;
1038
1048
}
1039
1049
 
1040
1050
static void
1041
 
sp_gradient_vector_dialog_destroy (GtkObject *object, gpointer data)
 
1051
sp_gradient_vector_dialog_destroy (GtkObject */*object*/, gpointer /*data*/)
1042
1052
{
1043
 
        sp_signal_disconnect_by_data (INKSCAPE, dlg);
1044
 
        wd.win = dlg = NULL;
1045
 
        wd.stop = 0;
 
1053
    sp_signal_disconnect_by_data (INKSCAPE, dlg);
 
1054
    wd.win = dlg = NULL;
 
1055
    wd.stop = 0;
1046
1056
}
1047
1057
 
1048
1058
static gboolean
1049
 
sp_gradient_vector_dialog_delete (GtkWidget *widget, GdkEvent *event, GtkWidget *dialog)
 
1059
sp_gradient_vector_dialog_delete (GtkWidget */*widget*/, GdkEvent */*event*/, GtkWidget */*dialog*/)
1050
1060
{
1051
 
        gtk_window_get_position ((GtkWindow *) dlg, &x, &y);
1052
 
        gtk_window_get_size ((GtkWindow *) dlg, &w, &h);
 
1061
    gtk_window_get_position ((GtkWindow *) dlg, &x, &y);
 
1062
    gtk_window_get_size ((GtkWindow *) dlg, &w, &h);
1053
1063
 
1054
1064
    if (x<0) x=0;
1055
1065
    if (y<0) y=0;
1056
1066
 
1057
 
        prefs_set_int_attribute (prefs_path, "x", x);
1058
 
        prefs_set_int_attribute (prefs_path, "y", y);
1059
 
        prefs_set_int_attribute (prefs_path, "w", w);
1060
 
        prefs_set_int_attribute (prefs_path, "h", h);
 
1067
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
1068
    prefs->setInt(prefs_path + "x", x);
 
1069
    prefs->setInt(prefs_path + "y", y);
 
1070
    prefs->setInt(prefs_path + "w", w);
 
1071
    prefs->setInt(prefs_path + "h", h);
1061
1072
 
1062
 
        return FALSE; // which means, go ahead and destroy it
 
1073
    return FALSE; // which means, go ahead and destroy it
1063
1074
}
1064
1075
 
1065
1076
/* Widget destroy handler */
1066
1077
 
1067
1078
static void
1068
 
sp_gradient_vector_widget_destroy (GtkObject *object, gpointer data)
1069
 
{
1070
 
        GObject *gradient;
1071
 
 
1072
 
        gradient = (GObject*)g_object_get_data (G_OBJECT (object), "gradient");
1073
 
 
1074
 
        if (gradient && SP_OBJECT_REPR(gradient)) {
1075
 
                /* Remove signals connected to us */
1076
 
                /* fixme: may use _connect_while_alive as well */
1077
 
                sp_signal_disconnect_by_data (gradient, object);
1078
 
                sp_repr_remove_listener_by_data (SP_OBJECT_REPR(gradient), object);
1079
 
        }
1080
 
}
1081
 
 
1082
 
static void
1083
 
sp_gradient_vector_gradient_release (SPObject *object, GtkWidget *widget)
1084
 
{
1085
 
        sp_gradient_vector_widget_load_gradient (widget, NULL);
1086
 
}
1087
 
 
1088
 
static void
1089
 
sp_gradient_vector_gradient_modified (SPObject *object, guint flags, GtkWidget *widget)
1090
 
{
1091
 
        SPGradient *gradient=SP_GRADIENT(object);
1092
 
        if (!blocked) {
1093
 
                blocked = TRUE;
1094
 
                sp_gradient_vector_widget_load_gradient (widget, gradient);
1095
 
                blocked = FALSE;
1096
 
        }
 
1079
sp_gradient_vector_widget_destroy (GtkObject *object, gpointer /*data*/)
 
1080
{
 
1081
    GObject *gradient;
 
1082
 
 
1083
    gradient = (GObject*)g_object_get_data (G_OBJECT (object), "gradient");
 
1084
 
 
1085
    if (gradient && SP_OBJECT_REPR(gradient)) {
 
1086
        /* Remove signals connected to us */
 
1087
        /* fixme: may use _connect_while_alive as well */
 
1088
        sp_signal_disconnect_by_data (gradient, object);
 
1089
        sp_repr_remove_listener_by_data (SP_OBJECT_REPR(gradient), object);
 
1090
    }
 
1091
}
 
1092
 
 
1093
static void
 
1094
sp_gradient_vector_gradient_release (SPObject */*object*/, GtkWidget *widget)
 
1095
{
 
1096
    sp_gradient_vector_widget_load_gradient (widget, NULL);
 
1097
}
 
1098
 
 
1099
static void
 
1100
sp_gradient_vector_gradient_modified (SPObject *object, guint /*flags*/, GtkWidget *widget)
 
1101
{
 
1102
    SPGradient *gradient=SP_GRADIENT(object);
 
1103
    if (!blocked) {
 
1104
        blocked = TRUE;
 
1105
        sp_gradient_vector_widget_load_gradient (widget, gradient);
 
1106
        blocked = FALSE;
 
1107
    }
1097
1108
}
1098
1109
 
1099
1110
static void sp_gradient_vector_color_dragged(SPColorSelector *csel, GtkObject *object)
1100
1111
{
1101
 
        SPGradient *gradient, *ngr;
1102
 
 
1103
 
        if (blocked) return;
1104
 
 
1105
 
        gradient = (SPGradient*)g_object_get_data (G_OBJECT (object), "gradient");
1106
 
        if (!gradient) return;
1107
 
 
1108
 
        blocked = TRUE;
1109
 
 
1110
 
        ngr = sp_gradient_ensure_vector_normalized (gradient);
1111
 
        if (ngr != gradient) {
1112
 
                /* Our master gradient has changed */
1113
 
                sp_gradient_vector_widget_load_gradient (GTK_WIDGET (object), ngr);
1114
 
        }
1115
 
 
1116
 
        sp_gradient_ensure_vector (ngr);
 
1112
    SPGradient *gradient, *ngr;
 
1113
 
 
1114
    if (blocked) return;
 
1115
 
 
1116
    gradient = (SPGradient*)g_object_get_data (G_OBJECT (object), "gradient");
 
1117
    if (!gradient) return;
 
1118
 
 
1119
    blocked = TRUE;
 
1120
 
 
1121
    ngr = sp_gradient_ensure_vector_normalized (gradient);
 
1122
    if (ngr != gradient) {
 
1123
        /* Our master gradient has changed */
 
1124
        sp_gradient_vector_widget_load_gradient (GTK_WIDGET (object), ngr);
 
1125
    }
 
1126
 
 
1127
    sp_gradient_ensure_vector (ngr);
1117
1128
 
1118
1129
    GtkOptionMenu *mnu = (GtkOptionMenu *)g_object_get_data (G_OBJECT(object), "stopmenu");
1119
1130
    SPStop *stop = SP_STOP(g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop"));
1128
1139
static void
1129
1140
sp_gradient_vector_color_changed (SPColorSelector *csel, GtkObject *object)
1130
1141
{
1131
 
        SPColor color;
1132
 
        float alpha;
1133
 
        guint32 rgb;
1134
 
 
1135
 
        if (blocked) return;
1136
 
 
1137
 
        SPGradient *gradient = (SPGradient*)g_object_get_data (G_OBJECT (object), "gradient");
1138
 
        if (!gradient) return;
1139
 
 
1140
 
        blocked = TRUE;
1141
 
 
1142
 
        SPGradient *ngr = sp_gradient_ensure_vector_normalized (gradient);
1143
 
        if (ngr != gradient) {
1144
 
                /* Our master gradient has changed */
1145
 
                sp_gradient_vector_widget_load_gradient (GTK_WIDGET (object), ngr);
1146
 
        }
1147
 
 
1148
 
        sp_gradient_ensure_vector (ngr);
1149
 
 
1150
 
        /* Set start parameters */
1151
 
        /* We rely on normalized vector, i.e. stops HAVE to exist */
1152
 
        g_return_if_fail (sp_first_stop(ngr) != NULL);
1153
 
 
1154
 
        GtkOptionMenu *mnu = (GtkOptionMenu *)g_object_get_data (G_OBJECT(object), "stopmenu");
1155
 
        SPStop *stop = SP_STOP(g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop"));
1156
 
 
1157
 
        csel = (SPColorSelector*)g_object_get_data (G_OBJECT (object), "cselector");
1158
 
        csel->base->getColorAlpha( color, &alpha );
1159
 
        rgb = color.toRGBA32( 0x00 );
1160
 
 
1161
 
        sp_repr_set_css_double (SP_OBJECT_REPR (stop), "offset", stop->offset);
1162
 
        Inkscape::CSSOStringStream os;
1163
 
        gchar c[64];
1164
 
        sp_svg_write_color (c, sizeof(c), rgb);
1165
 
        os << "stop-color:" << c << ";stop-opacity:" << (gdouble) alpha <<";";
1166
 
        SP_OBJECT_REPR (stop)->setAttribute("style", os.str().c_str());
1167
 
                //      g_snprintf (c, 256, "stop-color:#%06x;stop-opacity:%g;", rgb >> 8, (gdouble) alpha);
1168
 
                //SP_OBJECT_REPR (stop)->setAttribute("style", c);
1169
 
 
1170
 
        sp_document_done (SP_OBJECT_DOCUMENT (ngr), SP_VERB_CONTEXT_GRADIENT,
1171
 
                          _("Change gradient stop color"));
1172
 
 
1173
 
        blocked = FALSE;
1174
 
 
1175
 
        SPColorPreview *cpv = (SPColorPreview *)g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "preview");
1176
 
        sp_color_preview_set_rgba32(cpv, sp_stop_get_rgba32(stop));
 
1142
    SPColor color;
 
1143
    float alpha;
 
1144
    guint32 rgb;
 
1145
 
 
1146
    if (blocked) return;
 
1147
 
 
1148
    SPGradient *gradient = (SPGradient*)g_object_get_data (G_OBJECT (object), "gradient");
 
1149
    if (!gradient) return;
 
1150
 
 
1151
    blocked = TRUE;
 
1152
 
 
1153
    SPGradient *ngr = sp_gradient_ensure_vector_normalized (gradient);
 
1154
    if (ngr != gradient) {
 
1155
        /* Our master gradient has changed */
 
1156
        sp_gradient_vector_widget_load_gradient (GTK_WIDGET (object), ngr);
 
1157
    }
 
1158
 
 
1159
    sp_gradient_ensure_vector (ngr);
 
1160
 
 
1161
    /* Set start parameters */
 
1162
    /* We rely on normalized vector, i.e. stops HAVE to exist */
 
1163
    g_return_if_fail (sp_first_stop(ngr) != NULL);
 
1164
 
 
1165
    GtkOptionMenu *mnu = (GtkOptionMenu *)g_object_get_data (G_OBJECT(object), "stopmenu");
 
1166
    SPStop *stop = SP_STOP(g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "stop"));
 
1167
 
 
1168
    csel = (SPColorSelector*)g_object_get_data (G_OBJECT (object), "cselector");
 
1169
    csel->base->getColorAlpha( color, &alpha );
 
1170
    rgb = color.toRGBA32( 0x00 );
 
1171
 
 
1172
    sp_repr_set_css_double (SP_OBJECT_REPR (stop), "offset", stop->offset);
 
1173
    Inkscape::CSSOStringStream os;
 
1174
    gchar c[64];
 
1175
    sp_svg_write_color (c, sizeof(c), rgb);
 
1176
    os << "stop-color:" << c << ";stop-opacity:" << (gdouble) alpha <<";";
 
1177
    SP_OBJECT_REPR (stop)->setAttribute("style", os.str().c_str());
 
1178
    // g_snprintf (c, 256, "stop-color:#%06x;stop-opacity:%g;", rgb >> 8, (gdouble) alpha);
 
1179
    //SP_OBJECT_REPR (stop)->setAttribute("style", c);
 
1180
 
 
1181
    sp_document_done (SP_OBJECT_DOCUMENT (ngr), SP_VERB_CONTEXT_GRADIENT,
 
1182
                      _("Change gradient stop color"));
 
1183
 
 
1184
    blocked = FALSE;
 
1185
 
 
1186
    SPColorPreview *cpv = (SPColorPreview *)g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "preview");
 
1187
    sp_color_preview_set_rgba32(cpv, sp_stop_get_rgba32(stop));
1177
1188
}
1178
1189
 
1179
1190
/*