32
38
#include "sp-radial-gradient.h"
34
40
#include "widgets/paint-selector.h"
35
#include "widgets/sp-widget.h"
36
41
#include "xml/repr.h"
38
#include "widgets/fill-style.h"
43
#include "fill-style.h"
44
#include "fill-n-stroke-factory.h"
41
47
// These can be deleted once we sort out the libart dependence.
43
49
#define ART_WIND_RULE_NONZERO 0
45
static void sp_fill_style_widget_construct ( SPWidget *spw,
46
SPPaintSelector *psel );
48
static void sp_fill_style_widget_modify_selection ( SPWidget *spw,
49
Inkscape::Selection *selection,
51
SPPaintSelector *psel );
53
static void sp_fill_style_widget_change_subselection ( Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw );
55
static void sp_fill_style_widget_change_selection ( SPWidget *spw,
56
Inkscape::Selection *selection,
57
SPPaintSelector *psel );
59
static void sp_fill_style_widget_update (SPWidget *spw);
61
static void sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel,
62
SPPaintSelectorMode mode,
64
static void sp_fill_style_widget_fillrule_changed ( SPPaintSelector *psel,
65
SPPaintSelectorFillRule mode,
68
static void sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw );
69
static void sp_fill_style_widget_paint_changed (SPPaintSelector *psel, SPWidget *spw );
72
sp_fill_style_widget_new (void)
74
GtkWidget *spw = sp_widget_new_global (INKSCAPE);
76
GtkWidget *vb = gtk_vbox_new (FALSE, 0);
78
gtk_container_add (GTK_CONTAINER (spw), vb);
80
GtkWidget *psel = sp_paint_selector_new (true); // with fillrule selector
81
gtk_widget_show (psel);
82
gtk_box_pack_start (GTK_BOX (vb), psel, TRUE, TRUE, 0);
83
g_object_set_data (G_OBJECT (spw), "paint-selector", psel);
85
g_signal_connect ( G_OBJECT (psel), "mode_changed",
86
G_CALLBACK (sp_fill_style_widget_paint_mode_changed),
89
g_signal_connect ( G_OBJECT (psel), "dragged",
90
G_CALLBACK (sp_fill_style_widget_paint_dragged),
93
g_signal_connect ( G_OBJECT (psel), "changed",
94
G_CALLBACK (sp_fill_style_widget_paint_changed),
97
g_signal_connect ( G_OBJECT (psel), "fillrule_changed",
98
G_CALLBACK (sp_fill_style_widget_fillrule_changed),
102
g_signal_connect ( G_OBJECT (spw), "construct",
103
G_CALLBACK (sp_fill_style_widget_construct), psel);
105
//FIXME: switch these from spw signals to global inkscape object signals; spw just retranslates
106
//those anyway; then eliminate spw
107
g_signal_connect ( G_OBJECT (spw), "modify_selection",
108
G_CALLBACK (sp_fill_style_widget_modify_selection), psel);
110
g_signal_connect ( G_OBJECT (spw), "change_selection",
111
G_CALLBACK (sp_fill_style_widget_change_selection), psel);
113
g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_fill_style_widget_change_subselection), spw);
115
sp_fill_style_widget_update (SP_WIDGET (spw));
119
} // end of sp_fill_style_widget_new()
124
sp_fill_style_widget_construct( SPWidget *spw, SPPaintSelector */*psel*/ )
127
g_print ( "Fill style widget constructed: inkscape %p repr %p\n",
128
spw->inkscape, spw->repr );
131
sp_fill_style_widget_update (spw);
134
} // end of sp_fill_style_widget_construct()
137
sp_fill_style_widget_modify_selection( SPWidget *spw,
138
Inkscape::Selection */*selection*/,
140
SPPaintSelector */*psel*/ )
54
Gtk::Widget *sp_fill_style_widget_new(void)
56
return Inkscape::Widgets::createStyleWidget( FILL );
62
class FillNStroke : public Gtk::VBox
65
FillNStroke( FillOrStroke kind );
68
void setFillrule( SPPaintSelector::FillRule mode );
70
void setDesktop(SPDesktop *desktop);
73
static void paintModeChangeCB(SPPaintSelector *psel, SPPaintSelector::Mode mode, FillNStroke *self);
74
static void paintChangedCB(SPPaintSelector *psel, FillNStroke *self);
75
static void paintDraggedCB(SPPaintSelector *psel, FillNStroke *self);
76
static gboolean dragDelayCB(gpointer data);
78
static void fillruleChangedCB( SPPaintSelector *psel, SPPaintSelector::FillRule mode, FillNStroke *self );
80
void selectionModifiedCB(guint flags);
83
void updateFromPaint();
89
SPPaintSelector *psel;
93
sigc::connection selectChangedConn;
94
sigc::connection subselChangedConn;
95
sigc::connection selectModifiedConn;
98
} // namespace Inkscape
100
void sp_fill_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop)
102
Inkscape::FillNStroke *fs = dynamic_cast<Inkscape::FillNStroke*>(widget);
104
fs->setDesktop(desktop);
111
* Create the fill or stroke style widget, and hook up all the signals.
113
Gtk::Widget *Inkscape::Widgets::createStyleWidget( FillOrStroke kind )
115
FillNStroke *filler = new FillNStroke(kind);
120
FillNStroke::FillNStroke( FillOrStroke kind ) :
132
// Add and connect up the paint selector widget:
133
psel = sp_paint_selector_new(kind);
134
gtk_widget_show(GTK_WIDGET(psel));
135
gtk_container_add(GTK_CONTAINER(gobj()), GTK_WIDGET(psel));
136
g_signal_connect( G_OBJECT(psel), "mode_changed",
137
G_CALLBACK(paintModeChangeCB),
140
g_signal_connect( G_OBJECT(psel), "dragged",
141
G_CALLBACK(paintDraggedCB),
144
g_signal_connect( G_OBJECT(psel), "changed",
145
G_CALLBACK(paintChangedCB),
148
g_signal_connect( G_OBJECT(psel), "fillrule_changed",
149
G_CALLBACK(fillruleChangedCB),
156
FillNStroke::~FillNStroke()
159
g_source_remove(dragId);
163
selectModifiedConn.disconnect();
164
subselChangedConn.disconnect();
165
selectChangedConn.disconnect();
169
* On signal modified, invokes an update of the fill or stroke style paint object.
171
void FillNStroke::selectionModifiedCB( guint flags )
142
173
if (flags & ( SP_OBJECT_MODIFIED_FLAG |
143
SP_OBJECT_PARENT_MODIFIED_FLAG |
144
SP_OBJECT_STYLE_MODIFIED_FLAG) )
146
sp_fill_style_widget_update (spw);
151
sp_fill_style_widget_change_subselection( Inkscape::Application */*inkscape*/,
152
SPDesktop */*desktop*/,
155
sp_fill_style_widget_update (spw);
159
sp_fill_style_widget_change_selection( SPWidget *spw,
160
Inkscape::Selection */*selection*/,
161
SPPaintSelector */*psel*/ )
163
sp_fill_style_widget_update (spw);
174
SP_OBJECT_PARENT_MODIFIED_FLAG |
175
SP_OBJECT_STYLE_MODIFIED_FLAG) ) {
177
g_message("selectionModifiedCB(%d) on %p", flags, this);
183
void FillNStroke::setDesktop(SPDesktop *desktop)
185
if (this->desktop != desktop) {
187
g_source_remove(dragId);
191
selectModifiedConn.disconnect();
192
subselChangedConn.disconnect();
193
selectChangedConn.disconnect();
195
this->desktop = desktop;
196
if (desktop && desktop->selection) {
197
selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &FillNStroke::performUpdate)));
198
subselChangedConn = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &FillNStroke::performUpdate)));
200
// Must check flags, so can't call performUpdate() directly.
201
selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &FillNStroke::selectionModifiedCB)));
167
* \param sel Selection to use, or NULL.
170
sp_fill_style_widget_update (SPWidget *spw)
208
* Gets the active fill or stroke style property, then sets the appropriate
209
* color, alpha, gradient, pattern, etc. for the paint-selector.
211
* @param sel Selection to use, or NULL.
213
void FillNStroke::performUpdate()
172
if (g_object_get_data (G_OBJECT (spw), "update"))
175
if (g_object_get_data (G_OBJECT (spw), "local")) {
176
g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (FALSE)); // local change; do nothing, but reset the flag
180
g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
182
SPPaintSelector *psel = SP_PAINT_SELECTOR (g_object_get_data (G_OBJECT (spw), "paint-selector"));
215
if ( update || !desktop ) {
220
// local change; do nothing, but reset the flag
221
g_source_remove(dragId);
184
228
// create temporary style
185
SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
229
SPStyle *query = sp_style_new(desktop->doc());
186
231
// query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
187
int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FILL);
232
int result = sp_desktop_query_style(desktop, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE);
234
SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
235
SPIScale24 &targOpacity = (kind == FILL) ? query->fill_opacity : query->stroke_opacity;
189
237
switch (result) {
190
238
case QUERY_STYLE_NOTHING:
192
240
/* No paint at all */
193
sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY);
241
psel->setMode(SPPaintSelector::MODE_EMPTY);
197
245
case QUERY_STYLE_SINGLE:
198
246
case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector
199
case QUERY_STYLE_MULTIPLE_SAME:
247
case QUERY_STYLE_MULTIPLE_SAME:
201
SPPaintSelectorMode pselmode = sp_style_determine_paint_selector_mode (query, true);
202
sp_paint_selector_set_mode (psel, pselmode);
204
sp_paint_selector_set_fillrule (psel, query->fill_rule.computed == ART_WIND_RULE_NONZERO?
205
SP_PAINT_SELECTOR_FILLRULE_NONZERO : SP_PAINT_SELECTOR_FILLRULE_EVENODD);
207
if (query->fill.set && query->fill.isColor()) {
208
sp_paint_selector_set_color_alpha (psel, &query->fill.value.color, SP_SCALE24_TO_FLOAT (query->fill_opacity.value));
209
} else if (query->fill.set && query->fill.isPaintserver()) {
211
SPPaintServer *server = SP_STYLE_FILL_SERVER (query);
213
if (SP_IS_LINEARGRADIENT (server)) {
214
SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
215
sp_paint_selector_set_gradient_linear (psel, vector);
217
SPLinearGradient *lg = SP_LINEARGRADIENT (server);
218
sp_paint_selector_set_gradient_properties (psel,
219
SP_GRADIENT_UNITS (lg),
220
SP_GRADIENT_SPREAD (lg));
221
} else if (SP_IS_RADIALGRADIENT (server)) {
222
SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
223
sp_paint_selector_set_gradient_radial (psel, vector);
225
SPRadialGradient *rg = SP_RADIALGRADIENT (server);
226
sp_paint_selector_set_gradient_properties (psel,
227
SP_GRADIENT_UNITS (rg),
228
SP_GRADIENT_SPREAD (rg));
229
} else if (SP_IS_PATTERN (server)) {
230
SPPattern *pat = pattern_getroot (SP_PATTERN (server));
231
sp_update_pattern_list (psel, pat);
249
SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, kind);
250
psel->setMode(pselmode);
253
psel->setFillrule(query->fill_rule.computed == ART_WIND_RULE_NONZERO?
254
SPPaintSelector::FILLRULE_NONZERO : SPPaintSelector::FILLRULE_EVENODD);
257
if (targPaint.set && targPaint.isColor()) {
258
psel->setColorAlpha(targPaint.value.color, SP_SCALE24_TO_FLOAT(targOpacity.value));
259
} else if (targPaint.set && targPaint.isPaintserver()) {
261
SPPaintServer *server = (kind == FILL) ? query->getFillPaintServer() : query->getStrokePaintServer();
263
if (server && SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector()->isSwatch()) {
264
SPGradient *vector = SP_GRADIENT(server)->getVector();
265
psel->setSwatch( vector );
266
} else if (SP_IS_LINEARGRADIENT(server)) {
267
SPGradient *vector = SP_GRADIENT(server)->getVector();
268
psel->setGradientLinear( vector );
270
SPLinearGradient *lg = SP_LINEARGRADIENT(server);
271
psel->setGradientProperties( lg->getUnits(),
273
} else if (SP_IS_RADIALGRADIENT(server)) {
274
SPGradient *vector = SP_GRADIENT(server)->getVector();
275
psel->setGradientRadial( vector );
277
SPRadialGradient *rg = SP_RADIALGRADIENT(server);
278
psel->setGradientProperties( rg->getUnits(),
280
} else if (SP_IS_PATTERN(server)) {
281
SPPattern *pat = pattern_getroot(SP_PATTERN(server));
282
psel->updatePatternList( pat );
237
288
case QUERY_STYLE_MULTIPLE_DIFFERENT:
239
sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
290
psel->setMode(SPPaintSelector::MODE_MULTIPLE);
244
295
sp_style_unref(query);
246
g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
252
sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel,
253
SPPaintSelectorMode /*mode*/,
256
if (g_object_get_data (G_OBJECT (spw), "update"))
259
/* TODO: Does this work? */
260
/* TODO: Not really, here we have to get old color back from object */
261
/* Instead of relying on paint widget having meaningful colors set */
262
sp_fill_style_widget_paint_changed (psel, spw);
266
sp_fill_style_widget_fillrule_changed ( SPPaintSelector */*psel*/,
267
SPPaintSelectorFillRule mode,
270
if (g_object_get_data (G_OBJECT (spw), "update"))
273
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
275
SPCSSAttr *css = sp_repr_css_attr_new ();
276
sp_repr_css_set_property (css, "fill-rule", mode == SP_PAINT_SELECTOR_FILLRULE_EVENODD? "evenodd":"nonzero");
278
sp_desktop_set_style (desktop, css);
280
sp_repr_css_attr_unref (css);
282
sp_document_done (SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILL_STROKE,
283
_("Change fill rule"));
286
static gchar const *undo_label_1 = "fill:flatcolor:1";
287
static gchar const *undo_label_2 = "fill:flatcolor:2";
288
static gchar const *undo_label = undo_label_1;
291
This is called repeatedly while you are dragging a color slider, only for flat color
292
modes. Previously it set the color in style but did not update the repr for efficiency, however
293
this was flakey and didn't buy us almost anything. So now it does the same as _changed, except
294
lumps all its changes for undo.
297
sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw)
299
if (!spw->inkscape) {
303
if (g_object_get_data (G_OBJECT (spw), "update")) {
307
if (g_object_get_data (G_OBJECT (spw), "local")) {
308
// previous local flag not cleared yet;
309
// this means dragged events come too fast, so we better skip this one to speed up display
301
* When the mode is changed, invoke a regular changed handler.
303
void FillNStroke::paintModeChangeCB( SPPaintSelector * /*psel*/,
304
SPPaintSelector::Mode /*mode*/,
308
g_message("paintModeChangeCB(psel, mode, self:%p)", self);
310
if (self && !self->update) {
311
self->updateFromPaint();
315
void FillNStroke::fillruleChangedCB( SPPaintSelector * /*psel*/,
316
SPPaintSelector::FillRule mode,
320
self->setFillrule(mode);
324
void FillNStroke::setFillrule( SPPaintSelector::FillRule mode )
326
if (!update && desktop) {
327
SPCSSAttr *css = sp_repr_css_attr_new();
328
sp_repr_css_set_property(css, "fill-rule", (mode == SPPaintSelector::FILLRULE_EVENODD) ? "evenodd":"nonzero");
330
sp_desktop_set_style(desktop, css);
332
sp_repr_css_attr_unref(css);
335
sp_document_done(desktop->doc(), SP_VERB_DIALOG_FILL_STROKE,
336
_("Change fill rule"));
340
static gchar const *undo_F_label_1 = "fill:flatcolor:1";
341
static gchar const *undo_F_label_2 = "fill:flatcolor:2";
343
static gchar const *undo_S_label_1 = "stroke:flatcolor:1";
344
static gchar const *undo_S_label_2 = "stroke:flatcolor:2";
346
static gchar const *undo_F_label = undo_F_label_1;
347
static gchar const *undo_S_label = undo_S_label_1;
350
void FillNStroke::paintDraggedCB(SPPaintSelector * /*psel*/, FillNStroke *self)
353
g_message("paintDraggedCB(psel, spw:%p)", self);
355
if (self && !self->update) {
356
self->dragFromPaint();
361
gboolean FillNStroke::dragDelayCB(gpointer data)
363
gboolean keepGoing = TRUE;
365
FillNStroke *self = reinterpret_cast<FillNStroke*>(data);
368
g_source_remove(self->dragId);
371
self->dragFromPaint();
372
self->performUpdate();
383
* This is called repeatedly while you are dragging a color slider, only for flat color
384
* modes. Previously it set the color in style but did not update the repr for efficiency, however
385
* this was flakey and didn't buy us almost anything. So now it does the same as _changed, except
386
* lumps all its changes for undo.
388
void FillNStroke::dragFromPaint()
390
if (!desktop || update) {
394
guint32 when = gtk_get_current_event_time();
396
// Don't attempt too many updates per second.
397
// Assume a base 15.625ms resolution on the timer.
398
if (!dragId && lastDrag && when && ((when - lastDrag) < 32)) {
399
// local change, do not update from selection
400
dragId = g_timeout_add_full(G_PRIORITY_DEFAULT, 33, dragDelayCB, this, 0);
404
// previous local flag not cleared yet;
405
// this means dragged events come too fast, so we better skip this one to speed up display
310
406
// (it's safe to do this in any case)
314
g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
316
413
switch (psel->mode) {
318
case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
319
case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
414
case SPPaintSelector::MODE_COLOR_RGB:
415
case SPPaintSelector::MODE_COLOR_CMYK:
321
sp_paint_selector_set_flat_color (psel, SP_ACTIVE_DESKTOP, "fill", "fill-opacity");
322
sp_document_maybe_done (sp_desktop_document(SP_ACTIVE_DESKTOP), undo_label, SP_VERB_DIALOG_FILL_STROKE,
323
_("Set fill color"));
324
g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (TRUE)); // local change, do not update from selection
417
// local change, do not update from selection
418
dragId = g_timeout_add_full(G_PRIORITY_DEFAULT, 100, dragDelayCB, this, 0);
419
psel->setFlatColor( desktop, (kind == FILL) ? "fill" : "stroke", (kind == FILL) ? "fill-opacity" : "stroke-opacity" );
420
sp_document_maybe_done(desktop->doc(), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE,
421
(kind == FILL) ? _("Set fill color") : _("Set stroke color"));
329
g_warning ( "file %s: line %d: Paint %d should not emit 'dragged'",
330
__FILE__, __LINE__, psel->mode );
426
g_warning( "file %s: line %d: Paint %d should not emit 'dragged'",
427
__FILE__, __LINE__, psel->mode );
334
g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
339
434
This is called (at least) when:
340
435
1 paint selector mode is switched (e.g. flat color -> gradient)
342
437
3 you changed a gradient selector parameter (e.g. spread)
343
438
Must update repr.
346
sp_fill_style_widget_paint_changed ( SPPaintSelector *psel,
440
void FillNStroke::paintChangedCB( SPPaintSelector * /*psel*/, FillNStroke *self )
349
if (g_object_get_data (G_OBJECT (spw), "update")) {
443
g_message("paintChangedCB(psel, spw:%p)", self);
445
if (self && !self->update) {
446
self->updateFromPaint();
352
g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
354
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
450
void FillNStroke::updateFromPaint()
358
SPDocument *document = sp_desktop_document (desktop);
359
Inkscape::Selection *selection = sp_desktop_selection (desktop);
457
SPDocument *document = sp_desktop_document(desktop);
458
Inkscape::Selection *selection = sp_desktop_selection(desktop);
361
460
GSList const *items = selection->itemList();
363
462
switch (psel->mode) {
365
case SP_PAINT_SELECTOR_MODE_EMPTY:
463
case SPPaintSelector::MODE_EMPTY:
366
464
// This should not happen.
367
g_warning ( "file %s: line %d: Paint %d should not emit 'changed'",
368
__FILE__, __LINE__, psel->mode);
465
g_warning( "file %s: line %d: Paint %d should not emit 'changed'",
466
__FILE__, __LINE__, psel->mode);
370
case SP_PAINT_SELECTOR_MODE_MULTIPLE:
468
case SPPaintSelector::MODE_MULTIPLE:
371
469
// This happens when you switch multiple objects with different gradients to flat color;
372
470
// nothing to do here.
375
case SP_PAINT_SELECTOR_MODE_NONE:
473
case SPPaintSelector::MODE_NONE:
377
SPCSSAttr *css = sp_repr_css_attr_new ();
378
sp_repr_css_set_property (css, "fill", "none");
380
sp_desktop_set_style (desktop, css);
382
sp_repr_css_attr_unref (css);
384
sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
475
SPCSSAttr *css = sp_repr_css_attr_new();
476
sp_repr_css_set_property(css, (kind == FILL) ? "fill" : "stroke", "none");
478
sp_desktop_set_style(desktop, css);
480
sp_repr_css_attr_unref(css);
483
sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
484
(kind == FILL) ? _("Remove fill") : _("Remove stroke"));
389
case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
390
case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
488
case SPPaintSelector::MODE_COLOR_RGB:
489
case SPPaintSelector::MODE_COLOR_CMYK:
392
// FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events
393
sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0);
395
sp_paint_selector_set_flat_color (psel, desktop, "fill", "fill-opacity");
396
sp_document_maybe_done (sp_desktop_document(desktop), undo_label, SP_VERB_DIALOG_FILL_STROKE,
397
_("Set fill color"));
398
// resume interruptibility
399
sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop));
492
// FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events
493
sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0);
496
psel->setFlatColor( desktop,
497
(kind == FILL) ? "fill" : "stroke",
498
(kind == FILL) ? "fill-opacity" : "stroke-opacity" );
499
sp_document_maybe_done(sp_desktop_document(desktop), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE,
500
(kind == FILL) ? _("Set fill color") : _("Set stroke color"));
503
// resume interruptibility
504
sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop));
401
507
// on release, toggle undo_label so that the next drag will not be lumped with this one
402
if (undo_label == undo_label_1)
403
undo_label = undo_label_2;
405
undo_label = undo_label_1;
508
if (undo_F_label == undo_F_label_1) {
509
undo_F_label = undo_F_label_2;
510
undo_S_label = undo_S_label_2;
512
undo_F_label = undo_F_label_1;
513
undo_S_label = undo_S_label_1;
410
case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
411
case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
519
case SPPaintSelector::MODE_GRADIENT_LINEAR:
520
case SPPaintSelector::MODE_GRADIENT_RADIAL:
521
case SPPaintSelector::MODE_SWATCH:
413
SPGradientType const gradient_type = ( psel->mode == SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR
523
SPGradientType const gradient_type = ( psel->mode != SPPaintSelector::MODE_GRADIENT_RADIAL
414
524
? SP_GRADIENT_TYPE_LINEAR
415
525
: SP_GRADIENT_TYPE_RADIAL );
417
// HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
418
SPCSSAttr *css = sp_repr_css_attr_new();
419
sp_repr_css_set_property(css, "fill-opacity", "1.0");
421
SPGradient *vector = sp_paint_selector_get_gradient_vector(psel);
526
bool createSwatch = (psel->mode == SPPaintSelector::MODE_SWATCH);
530
// HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
531
css = sp_repr_css_attr_new();
532
sp_repr_css_set_property(css, "fill-opacity", "1.0");
535
SPGradient *vector = psel->getGradientVector();
423
537
/* No vector in paint selector should mean that we just changed mode */
425
SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
426
int result = objects_query_fillstroke ((GSList *) items, query, true);
427
guint32 common_rgb = 0;
539
SPStyle *query = sp_style_new(desktop->doc());
540
int result = objects_query_fillstroke(const_cast<GSList *>(items), query, kind == FILL);
428
541
if (result == QUERY_STYLE_MULTIPLE_SAME) {
429
if (!query->fill.isColor()) {
430
common_rgb = sp_desktop_get_color(desktop, true);
542
SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
544
if (!targPaint.isColor()) {
545
common = sp_desktop_get_color(desktop, kind == FILL);
432
common_rgb = query->fill.value.color.toRGBA32( 0xff );
434
vector = sp_document_default_gradient_vector(document, common_rgb);
547
common = targPaint.value.color;
549
vector = sp_document_default_gradient_vector( document, common, createSwatch );
550
if ( vector && createSwatch ) {
436
554
sp_style_unref(query);
438
556
for (GSList const *i = items; i != NULL; i = i->next) {
439
557
//FIXME: see above
440
sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style");
559
sp_repr_css_change_recursive(reinterpret_cast<SPObject*>(i->data)->repr, css, "style");
563
SPGradient *gr = sp_gradient_vector_for_object( document, desktop, reinterpret_cast<SPObject*>(i->data), kind == FILL, createSwatch );
564
if ( gr && createSwatch ) {
443
567
sp_item_set_gradient(SP_ITEM(i->data),
444
sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), true),
445
gradient_type, true);
569
gradient_type, kind == FILL);
447
sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true);
571
sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL);
451
/* We have changed from another gradient type, or modified spread/units within
452
* this gradient type. */
453
vector = sp_gradient_ensure_vector_normalized (vector);
575
// We have changed from another gradient type, or modified spread/units within
576
// this gradient type.
577
vector = sp_gradient_ensure_vector_normalized(vector);
454
578
for (GSList const *i = items; i != NULL; i = i->next) {
455
579
//FIXME: see above
456
sp_repr_css_change_recursive (SP_OBJECT_REPR (i->data), css, "style");
581
sp_repr_css_change_recursive(reinterpret_cast<SPObject*>(i->data)->repr, css, "style");
458
SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true);
459
sp_gradient_selector_attrs_to_gradient (gr, psel);
584
SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL);
585
psel->pushAttrsToGradient( gr );
463
sp_repr_css_attr_unref (css);
590
sp_repr_css_attr_unref(css);
465
sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
466
_("Set gradient on fill"));
594
sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
595
(kind == FILL) ? _("Set gradient on fill") : _("Set gradient on stroke"));
470
case SP_PAINT_SELECTOR_MODE_PATTERN:
599
case SPPaintSelector::MODE_PATTERN:
474
SPPattern *pattern = sp_paint_selector_get_pattern (psel);
603
SPPattern *pattern = psel->getPattern();
477
606
/* No Pattern in paint selector should mean that we just
482
Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern);
483
SPCSSAttr *css = sp_repr_css_attr_new ();
484
gchar *urltext = g_strdup_printf ("url(#%s)", patrepr->attribute("id"));
485
sp_repr_css_set_property (css, "fill", urltext);
611
Inkscape::XML::Node *patrepr = pattern->repr;
612
SPCSSAttr *css = sp_repr_css_attr_new();
613
gchar *urltext = g_strdup_printf("url(#%s)", patrepr->attribute("id"));
614
sp_repr_css_set_property(css, (kind == FILL) ? "fill" : "stroke", urltext);
487
616
// HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
488
sp_repr_css_set_property(css, "fill-opacity", "1.0");
618
sp_repr_css_set_property(css, "fill-opacity", "1.0");
490
621
// cannot just call sp_desktop_set_style, because we don't want to touch those
491
622
// objects who already have the same root pattern but through a different href
492
623
// chain. FIXME: move this to a sp_item_set_pattern
493
624
for (GSList const *i = items; i != NULL; i = i->next) {
494
SPObject *selobj = SP_OBJECT (i->data);
625
Inkscape::XML::Node *selrepr = reinterpret_cast<SPObject*>(i->data)->repr;
626
if ( (kind == STROKE) && !selrepr) {
629
SPObject *selobj = reinterpret_cast<SPObject*>(i->data);
496
SPStyle *style = SP_OBJECT_STYLE (selobj);
497
if (style && style->fill.isPaintserver()) {
498
SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (selobj);
499
if (SP_IS_PATTERN (server) && pattern_getroot (SP_PATTERN(server)) == pattern)
631
SPStyle *style = selobj->style;
632
if (style && ((kind == FILL) ? style->fill : style->stroke).isPaintserver()) {
633
SPPaintServer *server = (kind == FILL) ?
634
selobj->style->getFillPaintServer() :
635
selobj->style->getStrokePaintServer();
636
if (SP_IS_PATTERN(server) && pattern_getroot(SP_PATTERN(server)) == pattern)
500
637
// only if this object's pattern is not rooted in our selected pattern, apply
504
sp_desktop_apply_css_recursive (selobj, css, true);
507
sp_repr_css_attr_unref (css);
642
sp_desktop_apply_css_recursive(selobj, css, true);
644
sp_repr_css_change_recursive(selrepr, css, "style");
648
sp_repr_css_attr_unref(css);
512
sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
513
_("Set pattern on fill"));
654
sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
655
(kind == FILL) ? _("Set pattern on fill") :
656
_("Set pattern on stroke"));
519
case SP_PAINT_SELECTOR_MODE_UNSET:
661
case SPPaintSelector::MODE_UNSET:
521
SPCSSAttr *css = sp_repr_css_attr_new ();
522
sp_repr_css_unset_property (css, "fill");
524
sp_desktop_set_style (desktop, css);
525
sp_repr_css_attr_unref (css);
527
sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
663
SPCSSAttr *css = sp_repr_css_attr_new();
665
sp_repr_css_unset_property(css, "fill");
667
sp_repr_css_unset_property(css, "stroke");
668
sp_repr_css_unset_property(css, "stroke-opacity");
669
sp_repr_css_unset_property(css, "stroke-width");
670
sp_repr_css_unset_property(css, "stroke-miterlimit");
671
sp_repr_css_unset_property(css, "stroke-linejoin");
672
sp_repr_css_unset_property(css, "stroke-linecap");
673
sp_repr_css_unset_property(css, "stroke-dashoffset");
674
sp_repr_css_unset_property(css, "stroke-dasharray");
677
sp_desktop_set_style(desktop, css);
678
sp_repr_css_attr_unref(css);
681
sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
682
(kind == FILL) ? _("Unset fill") : _("Unset stroke"));
533
g_warning ( "file %s: line %d: Paint selector should not be in "
535
__FILE__, __LINE__, psel->mode );
687
g_warning( "file %s: line %d: Paint selector should not be in "
539
g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
697
} // namespace Inkscape