~vaifrax/inkscape/bugfix170049

« back to all changes in this revision

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

  • Committer: mental
  • Date: 2006-01-16 02:36:01 UTC
  • Revision ID: mental@users.sourceforge.net-20060116023601-wkr0h7edl5veyudq
moving trunk for module inkscape

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define __SP_GRADIENT_SELECTOR_C__
 
2
 
 
3
/*
 
4
 * Gradient vector widget
 
5
 *
 
6
 * Authors:
 
7
 *   Lauris Kaplinski <lauris@kaplinski.com>
 
8
 *   bulia byak <buliabyak@users.sf.net>
 
9
 *
 
10
 * Copyright (C) 2001-2002 Lauris Kaplinski
 
11
 * Copyright (C) 2001 Ximian, Inc.
 
12
 *
 
13
 * Released under GNU GPL, read the file 'COPYING' for more information
 
14
 */
 
15
 
 
16
#ifdef HAVE_CONFIG_H
 
17
# include "config.h"
 
18
#endif
 
19
#include <gtk/gtkhbox.h>
 
20
#include <gtk/gtklabel.h>
 
21
#include <gtk/gtkoptionmenu.h>
 
22
#include <gtk/gtkmenuitem.h>
 
23
#include <gtk/gtktooltips.h>
 
24
 
 
25
#include "../document-private.h"
 
26
#include "../gradient-chemistry.h"
 
27
 
 
28
#include <glibmm/i18n.h>
 
29
#include <xml/repr.h>
 
30
 
 
31
#include "gradient-vector.h"
 
32
 
 
33
#include "gradient-selector.h"
 
34
 
 
35
enum {
 
36
        GRABBED,
 
37
        DRAGGED,
 
38
        RELEASED,
 
39
        CHANGED,
 
40
        LAST_SIGNAL
 
41
};
 
42
 
 
43
static void sp_gradient_selector_class_init (SPGradientSelectorClass *klass);
 
44
static void sp_gradient_selector_init (SPGradientSelector *selector);
 
45
static void sp_gradient_selector_destroy (GtkObject *object);
 
46
 
 
47
/* Signal handlers */
 
48
static void sp_gradient_selector_vector_set (SPGradientVectorSelector *gvs, SPGradient *gr, SPGradientSelector *sel);
 
49
static void sp_gradient_selector_edit_vector_clicked (GtkWidget *w, SPGradientSelector *sel);
 
50
static void sp_gradient_selector_add_vector_clicked (GtkWidget *w, SPGradientSelector *sel);
 
51
 
 
52
static void sp_gradient_selector_spread_activate (GtkWidget *widget, SPGradientSelector *sel);
 
53
 
 
54
static GtkVBoxClass *parent_class;
 
55
static guint signals[LAST_SIGNAL] = {0};
 
56
 
 
57
GtkType
 
58
sp_gradient_selector_get_type (void)
 
59
{
 
60
        static GtkType type = 0;
 
61
        if (!type) {
 
62
                GtkTypeInfo info = {
 
63
                        "SPGradientSelector",
 
64
                        sizeof (SPGradientSelector),
 
65
                        sizeof (SPGradientSelectorClass),
 
66
                        (GtkClassInitFunc) sp_gradient_selector_class_init,
 
67
                        (GtkObjectInitFunc) sp_gradient_selector_init,
 
68
                        NULL, NULL, NULL
 
69
                };
 
70
                type = gtk_type_unique (GTK_TYPE_VBOX, &info);
 
71
        }
 
72
        return type;
 
73
}
 
74
 
 
75
static void
 
76
sp_gradient_selector_class_init (SPGradientSelectorClass *klass)
 
77
{
 
78
        GtkObjectClass *object_class;
 
79
 
 
80
        object_class = (GtkObjectClass *) klass;
 
81
 
 
82
        parent_class = (GtkVBoxClass*)gtk_type_class (GTK_TYPE_VBOX);
 
83
 
 
84
        signals[GRABBED] =  gtk_signal_new ("grabbed",
 
85
                                            (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
 
86
                                            GTK_CLASS_TYPE(object_class),
 
87
                                            GTK_SIGNAL_OFFSET (SPGradientSelectorClass, grabbed),
 
88
                                            gtk_marshal_NONE__NONE,
 
89
                                            GTK_TYPE_NONE, 0);
 
90
        signals[DRAGGED] =  gtk_signal_new ("dragged",
 
91
                                            (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
 
92
                                            GTK_CLASS_TYPE(object_class),
 
93
                                            GTK_SIGNAL_OFFSET (SPGradientSelectorClass, dragged),
 
94
                                            gtk_marshal_NONE__NONE,
 
95
                                            GTK_TYPE_NONE, 0);
 
96
        signals[RELEASED] = gtk_signal_new ("released",
 
97
                                            (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
 
98
                                            GTK_CLASS_TYPE(object_class),
 
99
                                            GTK_SIGNAL_OFFSET (SPGradientSelectorClass, released),
 
100
                                            gtk_marshal_NONE__NONE,
 
101
                                            GTK_TYPE_NONE, 0);
 
102
        signals[CHANGED] =  gtk_signal_new ("changed",
 
103
                                            (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
 
104
                                            GTK_CLASS_TYPE(object_class),
 
105
                                            GTK_SIGNAL_OFFSET (SPGradientSelectorClass, changed),
 
106
                                            gtk_marshal_NONE__NONE,
 
107
                                            GTK_TYPE_NONE, 0);
 
108
 
 
109
        object_class->destroy = sp_gradient_selector_destroy;
 
110
}
 
111
 
 
112
static void
 
113
sp_gradient_selector_init (SPGradientSelector *sel)
 
114
{
 
115
        GtkWidget *hb, *l, *m, *mi;
 
116
 
 
117
        sel->mode = SP_GRADIENT_SELECTOR_MODE_LINEAR;
 
118
 
 
119
        sel->gradientUnits = SP_GRADIENT_UNITS_USERSPACEONUSE;
 
120
        sel->gradientSpread = SP_GRADIENT_SPREAD_PAD;
 
121
 
 
122
        /* Vectors */
 
123
        sel->vectors = sp_gradient_vector_selector_new (NULL, NULL);
 
124
        gtk_widget_show (sel->vectors);
 
125
        gtk_box_pack_start (GTK_BOX (sel), sel->vectors, FALSE, FALSE, 0);
 
126
        g_signal_connect (G_OBJECT (sel->vectors), "vector_set", G_CALLBACK (sp_gradient_selector_vector_set), sel);
 
127
 
 
128
        /* Create box for buttons */
 
129
        hb = gtk_hbox_new (FALSE, 0);
 
130
        gtk_box_pack_start (GTK_BOX (sel), hb, FALSE, FALSE, 0);
 
131
        GtkTooltips *ttips = gtk_tooltips_new ();
 
132
 
 
133
        sel->add = gtk_button_new_with_label (_("Duplicate"));
 
134
        gtk_box_pack_start (GTK_BOX (hb), sel->add, TRUE, TRUE, 0);
 
135
        g_signal_connect (G_OBJECT (sel->add), "clicked", G_CALLBACK (sp_gradient_selector_add_vector_clicked), sel);
 
136
        gtk_widget_set_sensitive (sel->add, FALSE);
 
137
 
 
138
        sel->edit = gtk_button_new_with_label (_("Edit..."));
 
139
        gtk_box_pack_start (GTK_BOX (hb), sel->edit, TRUE, TRUE, 0);
 
140
        g_signal_connect (G_OBJECT (sel->edit), "clicked", G_CALLBACK (sp_gradient_selector_edit_vector_clicked), sel);
 
141
        gtk_widget_set_sensitive (sel->edit, FALSE);
 
142
 
 
143
        gtk_widget_show_all (hb);
 
144
 
 
145
        /* Spread selector */
 
146
        hb = gtk_hbox_new (FALSE, 0);
 
147
        gtk_widget_show (hb);
 
148
        gtk_box_pack_start (GTK_BOX (sel), hb, FALSE, FALSE, 0);
 
149
 
 
150
        sel->spread = gtk_option_menu_new ();
 
151
        gtk_widget_show (sel->spread);
 
152
        gtk_box_pack_end (GTK_BOX (hb), sel->spread, FALSE, FALSE, 0);
 
153
        gtk_tooltips_set_tip (ttips, sel->spread,
 
154
        // TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute
 
155
                                        _("Whether to fill with flat color beyond the ends of the gradient vector "
 
156
                                        "(spreadMethod=\"pad\"), or repeat the gradient in the same direction "
 
157
                                        "(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite "
 
158
                                        "directions (spreadMethod=\"reflect\")"), NULL);
 
159
 
 
160
        m = gtk_menu_new ();
 
161
        mi = gtk_menu_item_new_with_label (_("none"));
 
162
        gtk_menu_append (GTK_MENU (m), mi);
 
163
        g_object_set_data (G_OBJECT (mi), "gradientSpread", GUINT_TO_POINTER (SP_GRADIENT_SPREAD_PAD));
 
164
        g_signal_connect (G_OBJECT (mi), "activate", G_CALLBACK (sp_gradient_selector_spread_activate), sel);
 
165
        mi = gtk_menu_item_new_with_label (_("reflected"));
 
166
        g_object_set_data (G_OBJECT (mi), "gradientSpread", GUINT_TO_POINTER (SP_GRADIENT_SPREAD_REFLECT));
 
167
        g_signal_connect (G_OBJECT (mi), "activate", G_CALLBACK (sp_gradient_selector_spread_activate), sel);
 
168
        gtk_menu_append (GTK_MENU (m), mi);
 
169
        mi = gtk_menu_item_new_with_label (_("direct"));
 
170
        g_object_set_data (G_OBJECT (mi), "gradientSpread", GUINT_TO_POINTER (SP_GRADIENT_SPREAD_REPEAT));
 
171
        g_signal_connect (G_OBJECT (mi), "activate", G_CALLBACK (sp_gradient_selector_spread_activate), sel);
 
172
        gtk_menu_append (GTK_MENU (m), mi);
 
173
        gtk_widget_show_all (m);
 
174
 
 
175
        gtk_option_menu_set_menu (GTK_OPTION_MENU (sel->spread), m);
 
176
 
 
177
        l = gtk_label_new (_("Repeat:"));
 
178
        gtk_widget_show (l);
 
179
        gtk_box_pack_end (GTK_BOX (hb), l, FALSE, FALSE, 4);
 
180
}
 
181
 
 
182
static void
 
183
sp_gradient_selector_destroy (GtkObject *object)
 
184
{
 
185
        SPGradientSelector *sel;
 
186
 
 
187
        sel = SP_GRADIENT_SELECTOR (object);
 
188
 
 
189
        if (((GtkObjectClass *) (parent_class))->destroy)
 
190
                (* ((GtkObjectClass *) (parent_class))->destroy) (object);
 
191
}
 
192
 
 
193
GtkWidget *
 
194
sp_gradient_selector_new (void)
 
195
{
 
196
        SPGradientSelector *sel;
 
197
 
 
198
        sel = (SPGradientSelector*)gtk_type_new (SP_TYPE_GRADIENT_SELECTOR);
 
199
 
 
200
        return (GtkWidget *) sel;
 
201
}
 
202
 
 
203
void
 
204
sp_gradient_selector_set_mode (SPGradientSelector *sel, guint mode)
 
205
{
 
206
        g_return_if_fail (sel != NULL);
 
207
        g_return_if_fail (SP_IS_GRADIENT_SELECTOR (sel));
 
208
 
 
209
        sel->mode = mode;
 
210
}
 
211
 
 
212
void
 
213
sp_gradient_selector_set_units (SPGradientSelector *sel, guint units)
 
214
{
 
215
        g_return_if_fail (sel != NULL);
 
216
        g_return_if_fail (SP_IS_GRADIENT_SELECTOR (sel));
 
217
 
 
218
        sel->gradientUnits = (SPGradientUnits)units;
 
219
}
 
220
 
 
221
void
 
222
sp_gradient_selector_set_spread (SPGradientSelector *sel, guint spread)
 
223
{
 
224
        g_return_if_fail (sel != NULL);
 
225
        g_return_if_fail (SP_IS_GRADIENT_SELECTOR (sel));
 
226
 
 
227
        sel->gradientSpread = (SPGradientSpread)spread;
 
228
 
 
229
        gtk_option_menu_set_history (GTK_OPTION_MENU (sel->spread), sel->gradientSpread);
 
230
}
 
231
 
 
232
SPGradientUnits
 
233
sp_gradient_selector_get_units (SPGradientSelector *sel)
 
234
{
 
235
        return (SPGradientUnits) sel->gradientUnits;
 
236
}
 
237
 
 
238
SPGradientSpread
 
239
sp_gradient_selector_get_spread (SPGradientSelector *sel)
 
240
{
 
241
        return (SPGradientSpread) sel->gradientSpread;
 
242
}
 
243
 
 
244
void
 
245
sp_gradient_selector_set_vector (SPGradientSelector *sel, SPDocument *doc, SPGradient *vector)
 
246
{
 
247
        g_return_if_fail (sel != NULL);
 
248
        g_return_if_fail (SP_IS_GRADIENT_SELECTOR (sel));
 
249
        g_return_if_fail (!vector || SP_IS_GRADIENT (vector));
 
250
        g_return_if_fail (!vector || (SP_OBJECT_DOCUMENT (vector) == doc));
 
251
 
 
252
        if (vector && !SP_GRADIENT_HAS_STOPS (vector))
 
253
                return; 
 
254
 
 
255
        sp_gradient_vector_selector_set_gradient (SP_GRADIENT_VECTOR_SELECTOR (sel->vectors), doc, vector);
 
256
 
 
257
        if (vector) {
 
258
                gtk_widget_set_sensitive (sel->edit, TRUE);
 
259
                gtk_widget_set_sensitive (sel->add, TRUE);
 
260
        } else {
 
261
                gtk_widget_set_sensitive (sel->edit, FALSE);
 
262
                gtk_widget_set_sensitive (sel->add, (doc != NULL));
 
263
        }
 
264
}
 
265
 
 
266
SPGradient *
 
267
sp_gradient_selector_get_vector (SPGradientSelector *sel)
 
268
{
 
269
        if (sel == NULL || !SP_IS_GRADIENT_SELECTOR (sel))
 
270
                return NULL;
 
271
 
 
272
        /* fixme: */
 
273
        return SP_GRADIENT_VECTOR_SELECTOR (sel->vectors)->gr;
 
274
}
 
275
 
 
276
static void
 
277
sp_gradient_selector_vector_set (SPGradientVectorSelector *gvs, SPGradient *gr, SPGradientSelector *sel)
 
278
{
 
279
        static gboolean blocked = FALSE;
 
280
 
 
281
        if (!blocked) {
 
282
                blocked = TRUE;
 
283
                gr = sp_gradient_ensure_vector_normalized (gr);
 
284
                sp_gradient_selector_set_vector (sel, (gr) ? SP_OBJECT_DOCUMENT (gr) : NULL, gr);
 
285
                g_signal_emit (G_OBJECT (sel), signals[CHANGED], 0, gr);
 
286
                blocked = FALSE;
 
287
        }
 
288
}
 
289
 
 
290
static void
 
291
sp_gradient_selector_edit_vector_clicked (GtkWidget *w, SPGradientSelector *sel)
 
292
{
 
293
        GtkWidget *dialog;
 
294
 
 
295
        /* fixme: */
 
296
        dialog = sp_gradient_vector_editor_new (SP_GRADIENT_VECTOR_SELECTOR (sel->vectors)->gr);
 
297
 
 
298
        gtk_widget_show (dialog);
 
299
}
 
300
 
 
301
static void
 
302
sp_gradient_selector_add_vector_clicked (GtkWidget *w, SPGradientSelector *sel)
 
303
{
 
304
        SPDocument *doc;
 
305
        SPGradient *gr;
 
306
        Inkscape::XML::Node *repr;
 
307
 
 
308
        doc = sp_gradient_vector_selector_get_document (SP_GRADIENT_VECTOR_SELECTOR (sel->vectors));
 
309
        if (!doc) return;
 
310
        gr = sp_gradient_vector_selector_get_gradient (SP_GRADIENT_VECTOR_SELECTOR (sel->vectors));
 
311
 
 
312
        if (gr) {
 
313
                repr = SP_OBJECT_REPR (gr)->duplicate();
 
314
        } else {
 
315
                Inkscape::XML::Node *stop;
 
316
                repr = sp_repr_new ("svg:linearGradient");
 
317
                stop = sp_repr_new ("svg:stop");
 
318
                stop->setAttribute("offset", "0");
 
319
                stop->setAttribute("style", "stop-color:#000;stop-opacity:1;");
 
320
                repr->appendChild(stop);
 
321
                Inkscape::GC::release(stop);
 
322
                stop = sp_repr_new ("svg:stop");
 
323
                stop->setAttribute("offset", "1");
 
324
                stop->setAttribute("style", "stop-color:#fff;stop-opacity:1;");
 
325
                repr->appendChild(stop);
 
326
                Inkscape::GC::release(stop);
 
327
        }
 
328
 
 
329
        SP_OBJECT_REPR (SP_DOCUMENT_DEFS (doc))->addChild(repr, NULL);
 
330
        Inkscape::GC::release(repr);
 
331
 
 
332
        gr = (SPGradient *) doc->getObjectByRepr(repr);
 
333
        sp_gradient_vector_selector_set_gradient (SP_GRADIENT_VECTOR_SELECTOR (sel->vectors), doc, gr);
 
334
}
 
335
 
 
336
static void
 
337
sp_gradient_selector_spread_activate (GtkWidget *widget, SPGradientSelector *sel)
 
338
{
 
339
        sel->gradientSpread = (SPGradientSpread)GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget), "gradientSpread"));
 
340
 
 
341
        g_signal_emit (G_OBJECT (sel), signals[CHANGED], 0);
 
342
}