Merge lp:~inkscape.dev/inkscape/spraytool-no-overlap into lp:~inkscape.dev/inkscape/trunk

Proposed by Jabiertxof
Status: Merged
Merged at revision: 14452
Proposed branch: lp:~inkscape.dev/inkscape/spraytool-no-overlap
Merge into: lp:~inkscape.dev/inkscape/trunk
Diff against target: 1189 lines (+758/-45)
7 files modified
src/ui/dialog/clonetiler.cpp (+24/-8)
src/ui/dialog/clonetiler.h (+3/-1)
src/ui/tools/spray-tool.cpp (+452/-23)
src/ui/tools/spray-tool.h (+11/-2)
src/widgets/spray-toolbar.cpp (+252/-8)
src/widgets/spray-toolbar.h (+1/-1)
src/widgets/toolbox.cpp (+15/-2)
To merge this branch: bzr merge lp:~inkscape.dev/inkscape/spraytool-no-overlap
Reviewer Review Type Date Requested Status
Inkscape Developers Pending
Review via email: mp+275643@code.launchpad.net

Description of the change

The feature I added is optionaly no overlap with offsets for spray tool.

To post a comment you must log in.
Revision history for this message
Mc (mc...) wrote :

I read it, and just saw two very minor things to change.

I did not test it yet.

14434. By jabiertxof<email address hidden>

Fixed typos from Mc
Removed unnecesary added headers
Put overlap default to false

Revision history for this message
Jabiertxof (jabiertxof) wrote :

Thanks Mc for the review! I hope you can test it soon.

14435. By jabiertxof<email address hidden>

Add option to not overlap if multiple elements are selected to spray

14436. By Jabiertxof <email address hidden>

Added a option to pick down color

14437. By Jabiertxof <email address hidden>

update to trunk

14438. By Jabiertxof <email address hidden>

removed dead code

14439. By Jabiertxof <email address hidden>

Fixed some typos pointed by Mc

14440. By jabiertxof<email address hidden>

Now the picker work with alphas and also in no overlap mode
Offset dropdown disabled if no overlap
Changed offset to percent based

14441. By jabiertxof<email address hidden>

little tweak

14442. By jabiertxof<email address hidden>

Fix the problems on transformed layers

14443. By jabiertxof<email address hidden>

add a ignore transparent areas option

14444. By jabiertxof<email address hidden>

Improvement to the css stored on change colors

14445. By jabiertxof<email address hidden>

Increase recursion levels

14446. By Jabiertxof <email address hidden>

Fix a regression updating CSS data

14447. By Jabiertxof <email address hidden>

Removed recursion from code because no speed improvements
Added swith to 100 on toogle no overlap button pointed by Mc.
Fixed crash pointed by Mc selecting all+no overlap+click

14448. By Jabiertxof <email address hidden>

update to trunk

14449. By Jabiertxof <email address hidden>

Add optional presure to width and to size
Start showing trace dialog

14450. By Jabiertxof <email address hidden>

update to trunk

14451. By jabiertxof<email address hidden>

Some fixes to new pressure options

14452. By jabiertxof<email address hidden>

Open trace dialog on click on pick toogle

14453. By jabiertxof<email address hidden>

Now picker use all features of trace clones

14454. By Jabiertxof <email address hidden>

Fix a bug compiling on pow

14455. By Jabiertxof <email address hidden>

Working on picker

14456. By Jabiertxof <email address hidden>

update to trunk

14457. By Jabiertxof <email address hidden>

'End' of picker work

14458. By Jabiertxof <email address hidden>

update to trunk

14459. By Jabiertxof <email address hidden>

Order disposition of icons
Add inverse also to opacity

14460. By Jabiertxof <email address hidden>

improve apply value to clones in scale mode

14461. By Jabiertxof <email address hidden>

update to trunk

14462. By Jabiertxof <email address hidden>

update to trunk

14463. By Jabiertxof <email address hidden>

update to trunk

14464. By Jabiertxof <email address hidden>

update to trunk

14465. By Jabiertxof <email address hidden>

Use color if trace dialog is disabled

14466. By Jabiertxof <email address hidden>

update to trunk

14467. By Jabiertxof <email address hidden>

Fix for scale bug pointed by Mc-

Revision history for this message
Mc (mc...) wrote :

comments inline

14468. By Jabiertxof <email address hidden>

Fixes from review form Mc-

14469. By Jabiertxof <email address hidden>

Fix a typo

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/ui/dialog/clonetiler.cpp'
2--- src/ui/dialog/clonetiler.cpp 2015-10-04 15:42:12 +0000
3+++ src/ui/dialog/clonetiler.cpp 2015-11-08 09:50:32 +0000
4@@ -85,7 +85,7 @@
5 {
6 Gtk::Box *contents = _getContents();
7 contents->set_spacing(0);
8-
9+
10 {
11 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
12
13@@ -101,7 +101,7 @@
14
15 contents->pack_start (*Gtk::manage(Glib::wrap(mainbox)), true, true, 0);
16
17- GtkWidget *nb = gtk_notebook_new ();
18+ nb = gtk_notebook_new ();
19 gtk_box_pack_start (GTK_BOX (mainbox), nb, FALSE, FALSE, 0);
20
21
22@@ -662,7 +662,7 @@
23 gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0);
24
25 guint32 rgba = 0x000000ff | sp_svg_read_color (prefs->getString(prefs_path + "initial_color").data(), 0x000000ff);
26- color_picker = new Inkscape::UI::Widget::ColorPicker (*new Glib::ustring(_("Initial color of tiled clones")), *new Glib::ustring(_("Initial color for clones (works only if the original has unset fill or stroke)")), rgba, false);
27+ color_picker = new Inkscape::UI::Widget::ColorPicker (*new Glib::ustring(_("Initial color of tiled clones")), *new Glib::ustring(_("Initial color for clones (works only if the original has unset fill or stroke or on spray tool in copy mode)")), rgba, false);
28 color_changed_connection = color_picker->connectChanged (sigc::ptr_fun(on_picker_color_changed));
29
30 gtk_box_pack_start (GTK_BOX (hb), reinterpret_cast<GtkWidget*>(color_picker->gobj()), FALSE, FALSE, 0);
31@@ -776,8 +776,6 @@
32 // Trace
33 {
34 GtkWidget *vb = clonetiler_new_tab (nb, _("_Trace"));
35-
36-
37 {
38 #if GTK_CHECK_VERSION(3,0,0)
39 GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, VB_MARGIN);
40@@ -787,11 +785,11 @@
41 #endif
42 gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0);
43
44- GtkWidget *b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles"));
45+ b = gtk_check_button_new_with_label (_("Trace the drawing under the clones/sprayed items"));
46 g_object_set_data (G_OBJECT(b), "uncheckable", GINT_TO_POINTER(TRUE));
47 bool old = prefs->getBool(prefs_path + "dotrace");
48 gtk_toggle_button_set_active ((GtkToggleButton *) b, old);
49- gtk_widget_set_tooltip_text (b, _("For each clone, pick a value from the drawing in that clone's location and apply it to the clone"));
50+ gtk_widget_set_tooltip_text (b, _("For each clone/sprayed item, pick a value from the drawing in its location and apply it"));
51 gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0);
52
53 g_signal_connect(G_OBJECT(b), "toggled",
54@@ -1001,6 +999,18 @@
55 }
56 }
57
58+ {
59+#if GTK_CHECK_VERSION(3,0,0)
60+ GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, VB_MARGIN);
61+ gtk_box_set_homogeneous(GTK_BOX(hb), FALSE);
62+#else
63+ GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN);
64+#endif
65+ gtk_box_pack_start (GTK_BOX (mainbox), hb, FALSE, FALSE, 0);
66+ GtkWidget *l = gtk_label_new(_(""));
67+ gtk_label_set_markup (GTK_LABEL(l), _("Apply to tiled clones:"));
68+ gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0);
69+ }
70 // Rows/columns, width/height
71 {
72 #if GTK_CHECK_VERSION(3,0,0)
73@@ -1289,7 +1299,6 @@
74 }
75
76 gtk_widget_show_all (mainbox);
77-
78 }
79
80 show_all();
81@@ -3005,6 +3014,13 @@
82 }
83 }
84
85+void CloneTiler::show_page_trace()
86+{
87+ gtk_notebook_set_current_page(GTK_NOTEBOOK(nb),6);
88+ gtk_toggle_button_set_active ((GtkToggleButton *) b, false);
89+}
90+
91+
92 }
93 }
94 }
95
96=== modified file 'src/ui/dialog/clonetiler.h'
97--- src/ui/dialog/clonetiler.h 2014-10-08 02:22:03 +0000
98+++ src/ui/dialog/clonetiler.h 2015-11-08 09:50:32 +0000
99@@ -31,7 +31,7 @@
100 virtual ~CloneTiler();
101
102 static CloneTiler &getInstance() { return *new CloneTiler(); }
103-
104+ void show_page_trace();
105 protected:
106
107 GtkWidget * clonetiler_new_tab(GtkWidget *nb, const gchar *label);
108@@ -113,6 +113,8 @@
109 CloneTiler& operator=(CloneTiler const &d);
110
111 GtkWidget *dlg;
112+ GtkWidget *nb;
113+ GtkWidget *b;
114 SPDesktop *desktop;
115 DesktopTracker deskTrack;
116 Inkscape::UI::Widget::ColorPicker *color_picker;
117
118=== modified file 'src/ui/tools/spray-tool.cpp'
119--- src/ui/tools/spray-tool.cpp 2015-07-04 16:15:46 +0000
120+++ src/ui/tools/spray-tool.cpp 2015-11-08 09:50:32 +0000
121@@ -12,6 +12,7 @@
122 * Steren GIANNINI (steren.giannini@gmail.com)
123 * Jon A. Cruz <jon@joncruz.org>
124 * Abhishek Sharma
125+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
126 *
127 * Copyright (C) 2009 authors
128 *
129@@ -48,7 +49,15 @@
130 #include "sp-path.h"
131 #include "path-chemistry.h"
132
133+// For color picking
134+#include "display/drawing.h"
135+#include "display/drawing-context.h"
136+#include "display/cairo-utils.h"
137+#include "desktop-style.h"
138+#include "svg/svg-color.h"
139+
140 #include "sp-text.h"
141+#include "sp-root.h"
142 #include "sp-flowtext.h"
143 #include "display/sp-canvas.h"
144 #include "display/canvas-bpath.h"
145@@ -88,6 +97,17 @@
146 namespace UI {
147 namespace Tools {
148
149+enum {
150+ PICK_COLOR,
151+ PICK_OPACITY,
152+ PICK_R,
153+ PICK_G,
154+ PICK_B,
155+ PICK_H,
156+ PICK_S,
157+ PICK_L
158+};
159+
160 const std::string& SprayTool::getPrefsPath() {
161 return SprayTool::prefsPath;
162 }
163@@ -133,7 +153,9 @@
164 : ToolBase(cursor_spray_xpm, 4, 4, false)
165 , pressure(TC_DEFAULT_PRESSURE)
166 , dragging(false)
167- , usepressure(false)
168+ , usepressurewidth(false)
169+ , usepressurepopulation(false)
170+ , usepressurescale(false)
171 , usetilt(false)
172 , usetext(false)
173 , width(0.2)
174@@ -151,6 +173,13 @@
175 , is_dilating(false)
176 , has_dilated(false)
177 , dilate_area(NULL)
178+ , nooverlap(false)
179+ , picker(false)
180+ , pickinversevalue(false)
181+ , pickfill(false)
182+ , pickstroke(false)
183+ , visible(false)
184+ , offset(0)
185 {
186 }
187
188@@ -221,8 +250,17 @@
189 sp_event_context_read(this, "population");
190 sp_event_context_read(this, "mean");
191 sp_event_context_read(this, "standard_deviation");
192- sp_event_context_read(this, "usepressure");
193+ sp_event_context_read(this, "usepressurewidth");
194+ sp_event_context_read(this, "usepressurepopulation");
195+ sp_event_context_read(this, "usepressurescale");
196 sp_event_context_read(this, "Scale");
197+ sp_event_context_read(this, "offset");
198+ sp_event_context_read(this, "picker");
199+ sp_event_context_read(this, "pickinversevalue");
200+ sp_event_context_read(this, "pickfill");
201+ sp_event_context_read(this, "pickstroke");
202+ sp_event_context_read(this, "visible");
203+ sp_event_context_read(this, "nooverlap");
204
205 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
206 if (prefs->getBool("/tools/spray/selcue")) {
207@@ -241,8 +279,12 @@
208 this->update_cursor(false);
209 } else if (path == "width") {
210 this->width = 0.01 * CLAMP(val.getInt(10), 1, 100);
211- } else if (path == "usepressure") {
212- this->usepressure = val.getBool();
213+ } else if (path == "usepressurewidth") {
214+ this->usepressurewidth = val.getBool();
215+ } else if (path == "usepressurepopulation") {
216+ this->usepressurepopulation = val.getBool();
217+ } else if (path == "usepressurescale") {
218+ this->usepressurescale = val.getBool();
219 } else if (path == "population") {
220 this->population = 0.01 * CLAMP(val.getInt(10), 1, 100);
221 } else if (path == "rotation_variation") {
222@@ -260,6 +302,20 @@
223 this->tilt = CLAMP(val.getDouble(0.1), 0, 1000.0);
224 } else if (path == "ratio") {
225 this->ratio = CLAMP(val.getDouble(), 0.0, 0.9);
226+ } else if (path == "offset") {
227+ this->offset = CLAMP(val.getDouble(), -1000.0, 1000.0);
228+ } else if (path == "picker") {
229+ this->picker = val.getBool();
230+ } else if (path == "pickinversevalue") {
231+ this->pickinversevalue = val.getBool();
232+ } else if (path == "pickfill") {
233+ this->pickfill = val.getBool();
234+ } else if (path == "pickstroke") {
235+ this->pickstroke = val.getBool();
236+ } else if (path == "visible") {
237+ this->visible = val.getBool();
238+ } else if (path == "nooverlap") {
239+ this->nooverlap = val.getBool();
240 }
241 }
242
243@@ -272,9 +328,15 @@
244 }
245 }
246
247+static double get_width(SprayTool *tc)
248+{
249+ double pressure = (tc->usepressurewidth? tc->pressure / TC_DEFAULT_PRESSURE : 1);
250+ return pressure * tc->width;
251+}
252+
253 static double get_dilate_radius(SprayTool *tc)
254 {
255- return 250 * tc->width/SP_EVENT_CONTEXT(tc)->desktop->current_zoom();
256+ return 250 * get_width(tc)/SP_EVENT_CONTEXT(tc)->desktop->current_zoom();
257 }
258
259 static double get_path_mean(SprayTool *tc)
260@@ -289,11 +351,16 @@
261
262 static double get_population(SprayTool *tc)
263 {
264- double pressure = (tc->usepressure? tc->pressure / TC_DEFAULT_PRESSURE : 1);
265- //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population);
266+ double pressure = (tc->usepressurepopulation? tc->pressure / TC_DEFAULT_PRESSURE : 1);
267 return pressure * tc->population;
268 }
269
270+static double get_pressure(SprayTool *tc)
271+{
272+ double pressure = tc->pressure / TC_DEFAULT_PRESSURE;
273+ return pressure;
274+}
275+
276 static double get_move_mean(SprayTool *tc)
277 {
278 return tc->mean;
279@@ -332,6 +399,317 @@
280
281 }
282
283+static void sp_spray_transform_path(SPItem * item, Geom::Path &path, Geom::Affine affine, Geom::Point center){
284+ path *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL).inverse();
285+ path *= item->transform.inverse();
286+ Geom::Affine dt2p;
287+ if (item->parent) {
288+ dt2p = static_cast<SPItem *>(item->parent)->i2dt_affine().inverse();
289+ } else {
290+ SPDesktop *dt = SP_ACTIVE_DESKTOP;
291+ dt2p = dt->dt2doc();
292+ }
293+ Geom::Affine i2dt = item->i2dt_affine() * Geom::Translate(center).inverse() * affine * Geom::Translate(center);
294+ path *= i2dt * dt2p;
295+ path *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL);
296+}
297+
298+/**
299+Randomizes \a val by \a rand, with 0 < val < 1 and all values (including 0, 1) having the same
300+probability of being displaced.
301+ */
302+double randomize01(double val, double rand)
303+{
304+ double base = MIN (val - rand, 1 - 2*rand);
305+ if (base < 0) {
306+ base = 0;
307+ }
308+ val = base + g_random_double_range (0, MIN (2 * rand, 1 - base));
309+ return CLAMP(val, 0, 1); // this should be unnecessary with the above provisions, but just in case...
310+}
311+
312+static bool fit_item(SPDesktop *desktop,
313+ SPItem *item,
314+ Geom::OptRect bbox,
315+ Geom::Point &move,
316+ Geom::Point center,
317+ double angle,
318+ double &_scale,
319+ double scale,
320+ bool picker,
321+ bool pickinversevalue,
322+ bool pickfill,
323+ bool pickstroke,
324+ bool visible,
325+ bool nooverlap,
326+ double offset,
327+ SPCSSAttr *css,
328+ bool trace_scale)
329+{
330+ SPDocument *doc = item->document;
331+ double width = bbox->width();
332+ double height = bbox->height();
333+ double size = std::min(width,height);
334+ double offset_min = (offset * size)/100.0 - (size);
335+ if(offset_min < 0 ){
336+ offset_min = 0;
337+ }
338+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
339+ bool pick_to_size = prefs->getBool("/dialogs/clonetiler/pick_to_size");
340+ bool trace = prefs->getBool("/dialogs/clonetiler/dotrace");
341+ if(picker && pick_to_size && !trace_scale && trace){
342+ _scale = 0.1;
343+ }
344+ Geom::OptRect bbox_procesed = Geom::Rect(Geom::Point(bbox->left() - offset_min, bbox->top() - offset_min),Geom::Point(bbox->right() + offset_min, bbox->bottom() + offset_min));
345+ Geom::Path path;
346+ path.start(Geom::Point(bbox_procesed->left(), bbox_procesed->top()));
347+ path.appendNew<Geom::LineSegment>(Geom::Point(bbox_procesed->right(), bbox_procesed->top()));
348+ path.appendNew<Geom::LineSegment>(Geom::Point(bbox_procesed->right(), bbox_procesed->bottom()));
349+ path.appendNew<Geom::LineSegment>(Geom::Point(bbox_procesed->left(), bbox_procesed->bottom()));
350+ path.close(true);
351+ sp_spray_transform_path(item, path, Geom::Scale(_scale), center);
352+ sp_spray_transform_path(item, path, Geom::Scale(scale), center);
353+ sp_spray_transform_path(item, path, Geom::Rotate(angle), center);
354+ path *= Geom::Translate(move);
355+ path *= desktop->doc2dt();
356+ bbox_procesed = path.boundsFast();
357+ double bbox_left_main = bbox_procesed->left();
358+ double bbox_top_main = bbox_procesed->top();
359+ double width_transformed = bbox_procesed->width();
360+ double height_transformed = bbox_procesed->height();
361+ Geom::Point mid_point = desktop->d2w(bbox_procesed->midpoint());
362+ Geom::IntRect area = Geom::IntRect::from_xywh(floor(mid_point[Geom::X]), floor(mid_point[Geom::Y]), 1, 1);
363+ double R = 0, G = 0, B = 0, A = 0;
364+ cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
365+ sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area);
366+ ink_cairo_surface_average_color(s, R, G, B, A);
367+ cairo_surface_destroy(s);
368+ guint32 rgba = SP_RGBA32_F_COMPOSE(R, G, B, A);
369+ if(nooverlap && visible && (A==0 || A < 1e-6)){
370+ return false;
371+ }
372+ size = std::min(width_transformed,height_transformed);
373+ if(offset < 100 ){
374+ offset_min = ((99.0 - offset) * size)/100.0 - size;
375+ } else {
376+ offset_min = 0;
377+ }
378+ std::vector<SPItem*> items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox_procesed);
379+ Inkscape::Selection *selection = desktop->getSelection();
380+ if (selection->isEmpty()) {
381+ return false;
382+ }
383+ std::vector<SPItem*> const items_selected(selection->itemList());
384+ for (std::vector<SPItem*>::const_iterator i=items_down.begin(); i!=items_down.end(); i++) {
385+ SPItem *item_down = *i;
386+ Geom::OptRect bbox_down = item_down->documentVisualBounds();
387+ width = bbox_down->width();
388+ height = bbox_down->height();
389+ double bbox_left = bbox_down->left();
390+ double bbox_top = bbox_down->top();
391+ gchar const * item_down_sharp = g_strdup_printf("#%s", item_down->getId());
392+ for (std::vector<SPItem*>::const_iterator j=items_selected.begin(); j!=items_selected.end(); j++) {
393+ SPItem *item_selected = *j;
394+ gchar const * spray_origin;
395+ if(!item_selected->getAttribute("inkscape:spray-origin")){
396+ spray_origin = g_strdup_printf("#%s", item_selected->getId());
397+ } else {
398+ spray_origin = item_selected->getAttribute("inkscape:spray-origin");
399+ }
400+ if(strcmp(item_down_sharp, spray_origin) == 0 ||
401+ (item_down->getAttribute("inkscape:spray-origin") &&
402+ strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 ))
403+ {
404+ if(nooverlap){
405+ if(!(offset_min < 0 && std::abs(bbox_left - bbox_left_main) > std::abs(offset_min) &&
406+ std::abs(bbox_top - bbox_top_main) > std::abs(offset_min))){
407+ return false;
408+ }
409+ } else if(picker || visible){
410+ item_down->setHidden(true);
411+ item_down->updateRepr();
412+ }
413+ }
414+ }
415+ }
416+ if(picker || visible){
417+ if(!nooverlap){
418+ doc->ensureUpToDate();
419+ }
420+ int pick = prefs->getInt("/dialogs/clonetiler/pick");
421+ bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence", false);
422+ bool pick_to_color = prefs->getBool("/dialogs/clonetiler/pick_to_color");
423+ bool pick_to_opacity = prefs->getBool("/dialogs/clonetiler/pick_to_opacity");
424+ double rand_picked = 0.01 * prefs->getDoubleLimited("/dialogs/clonetiler/rand_picked", 0, 0, 100);
425+ bool invert_picked = prefs->getBool("/dialogs/clonetiler/invert_picked");
426+ double gamma_picked = prefs->getDoubleLimited("/dialogs/clonetiler/gamma_picked", 0, -10, 10);
427+ double opacity = 1.0;
428+ gchar color_string[32]; *color_string = 0;
429+ float r = SP_RGBA32_R_F(rgba);
430+ float g = SP_RGBA32_G_F(rgba);
431+ float b = SP_RGBA32_B_F(rgba);
432+ float a = SP_RGBA32_A_F(rgba);
433+ //this can fix the bug #1511998 if confirmed
434+ if( a == 0 || a < 1e-6){
435+ r = 1;
436+ g = 1;
437+ b = 1;
438+ }
439+ if(visible && (a == 0 || a < 1e-6)){
440+ return false;
441+ }
442+
443+ if(picker && trace){
444+ float hsl[3];
445+ sp_color_rgb_to_hsl_floatv (hsl, r, g, b);
446+
447+ gdouble val = 0;
448+ switch (pick) {
449+ case PICK_COLOR:
450+ val = 1 - hsl[2]; // inverse lightness; to match other picks where black = max
451+ break;
452+ case PICK_OPACITY:
453+ val = a;
454+ break;
455+ case PICK_R:
456+ val = r;
457+ break;
458+ case PICK_G:
459+ val = g;
460+ break;
461+ case PICK_B:
462+ val = b;
463+ break;
464+ case PICK_H:
465+ val = hsl[0];
466+ break;
467+ case PICK_S:
468+ val = hsl[1];
469+ break;
470+ case PICK_L:
471+ val = 1 - hsl[2];
472+ break;
473+ default:
474+ break;
475+ }
476+
477+ if (rand_picked > 0) {
478+ val = randomize01 (val, rand_picked);
479+ r = randomize01 (r, rand_picked);
480+ g = randomize01 (g, rand_picked);
481+ b = randomize01 (b, rand_picked);
482+ }
483+
484+ if (gamma_picked != 0) {
485+ double power;
486+ if (gamma_picked > 0)
487+ power = 1/(1 + fabs(gamma_picked));
488+ else
489+ power = 1 + fabs(gamma_picked);
490+
491+ val = pow (val, power);
492+ r = pow ((double)r, (double)power);
493+ g = pow ((double)g, (double)power);
494+ b = pow ((double)b, (double)power);
495+ }
496+
497+ if (invert_picked) {
498+ val = 1 - val;
499+ r = 1 - r;
500+ g = 1 - g;
501+ b = 1 - b;
502+ }
503+
504+ val = CLAMP (val, 0, 1);
505+ r = CLAMP (r, 0, 1);
506+ g = CLAMP (g, 0, 1);
507+ b = CLAMP (b, 0, 1);
508+
509+ // recompose tweaked color
510+ rgba = SP_RGBA32_F_COMPOSE(r, g, b, a);
511+ if (pick_to_size) {
512+ if(!trace_scale){
513+ if(pickinversevalue) {
514+ _scale = 1.0 - val;
515+ } else {
516+ _scale = val;
517+ }
518+ if(_scale == 0.0) {
519+ return false;
520+ }
521+ if(!fit_item(desktop,
522+ item,
523+ bbox,
524+ move,
525+ center,
526+ angle,
527+ _scale,
528+ scale,
529+ picker,
530+ pickinversevalue,
531+ pickfill,
532+ pickstroke,
533+ visible,
534+ nooverlap,
535+ offset,
536+ css,
537+ true)){
538+ return false;
539+ }
540+ }
541+ }
542+
543+ if (pick_to_opacity) {
544+ if(pickinversevalue) {
545+ opacity *= 1.0 - val;
546+ } else {
547+ opacity *= val;
548+ }
549+ std::stringstream opacity_str;
550+ opacity_str.imbue(std::locale::classic());
551+ opacity_str << opacity;
552+ sp_repr_css_set_property(css, "opacity", opacity_str.str().c_str());
553+ }
554+ if (pick_to_presence) {
555+ if (g_random_double_range (0, 1) > val) {
556+ //Hidding the element is a way to retain original
557+ //behaviour of tiled clones for presence option.
558+ sp_repr_css_set_property(css, "opacity", "0");
559+ }
560+ }
561+ if (pick_to_color) {
562+ sp_svg_write_color(color_string, sizeof(color_string), rgba);
563+ if(pickfill){
564+ sp_repr_css_set_property(css, "fill", color_string);
565+ }
566+ if(pickstroke){
567+ sp_repr_css_set_property(css, "stroke", color_string);
568+ }
569+ }
570+ if (opacity < 1e-6) { // invisibly transparent, skip
571+ return false;
572+ }
573+ }
574+ if(!trace){
575+ sp_svg_write_color(color_string, sizeof(color_string), rgba);
576+ if(pickfill){
577+ sp_repr_css_set_property(css, "fill", color_string);
578+ }
579+ if(pickstroke){
580+ sp_repr_css_set_property(css, "stroke", color_string);
581+ }
582+ }
583+ if(!nooverlap && (picker || visible)){
584+ for (std::vector<SPItem *>::const_iterator k=items_down.begin(); k!=items_down.end(); k++) {
585+ SPItem *item_hidden = *k;
586+ item_hidden->setHidden(false);
587+ item_hidden->updateRepr();
588+ }
589+ }
590+ }
591+ return true;
592+}
593+
594 static bool sp_spray_recursive(SPDesktop *desktop,
595 Inkscape::Selection *selection,
596 SPItem *item,
597@@ -348,7 +726,16 @@
598 double ratio,
599 double tilt,
600 double rotation_variation,
601- gint _distrib)
602+ gint _distrib,
603+ bool nooverlap,
604+ bool picker,
605+ bool pickinversevalue,
606+ bool pickfill,
607+ bool pickstroke,
608+ bool visible,
609+ double offset,
610+ bool usepressurescale,
611+ double pressure)
612 {
613 bool did = false;
614
615@@ -364,6 +751,9 @@
616 double _fid = g_random_double_range(0, 1);
617 double angle = g_random_double_range( - rotation_variation / 100.0 * M_PI , rotation_variation / 100.0 * M_PI );
618 double _scale = g_random_double_range( 1.0 - scale_variation / 100.0, 1.0 + scale_variation / 100.0 );
619+ if(usepressurescale){
620+ _scale = pressure;
621+ }
622 double dr; double dp;
623 random_position( dr, dp, mean, standard_deviation, _distrib );
624 dr=dr*radius;
625@@ -371,27 +761,44 @@
626 if (mode == SPRAY_MODE_COPY) {
627 Geom::OptRect a = item->documentVisualBounds();
628 if (a) {
629- SPItem *item_copied;
630 if(_fid <= population)
631 {
632+ SPDocument *doc = item->document;
633+ gchar const * spray_origin;
634+ if(!item->getAttribute("inkscape:spray-origin")){
635+ spray_origin = g_strdup_printf("#%s", item->getId());
636+ } else {
637+ spray_origin = item->getAttribute("inkscape:spray-origin");
638+ }
639+ Geom::Point center = item->getCenter();
640+ Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
641+ SPCSSAttr *css = sp_repr_css_attr_new();
642+ if(nooverlap || picker || visible){
643+ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, visible, nooverlap, offset, css, false)){
644+ return false;
645+ }
646+ }
647+ SPItem *item_copied;
648 // Duplicate
649- SPDocument *doc = item->document;
650 Inkscape::XML::Document* xml_doc = doc->getReprDoc();
651 Inkscape::XML::Node *old_repr = item->getRepr();
652 Inkscape::XML::Node *parent = old_repr->parent();
653 Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
654+ if(!copy->attribute("inkscape:spray-origin")){
655+ copy->setAttribute("inkscape:spray-origin", spray_origin);
656+ }
657 parent->appendChild(copy);
658-
659 SPObject *new_obj = doc->getObjectByRepr(copy);
660 item_copied = dynamic_cast<SPItem *>(new_obj); // Conversion object->item
661- Geom::Point center=item->getCenter();
662- sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale,_scale));
663- sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale));
664-
665+ sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale));
666+ sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale));
667 sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
668 // Move the cursor p
669- Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
670 sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
671+ Inkscape::GC::release(copy);
672+ if(picker){
673+ sp_desktop_apply_css_recursive(item_copied, css, true);
674+ }
675 did = true;
676 }
677 }
678@@ -425,6 +832,13 @@
679 if (_fid <= population) { // Rules the population of objects sprayed
680 // Duplicates the parent item
681 Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
682+ gchar const * spray_origin;
683+ if(!copy->attribute("inkscape:spray-origin")){
684+ spray_origin = g_strdup_printf("#%s", old_repr->attribute("id"));
685+ copy->setAttribute("inkscape:spray-origin", spray_origin);
686+ } else {
687+ spray_origin = copy->attribute("inkscape:spray-origin");
688+ }
689 parent->appendChild(copy);
690 SPObject *new_obj = doc->getObjectByRepr(copy);
691 item_copied = dynamic_cast<SPItem *>(new_obj);
692@@ -456,8 +870,22 @@
693 Geom::OptRect a = item->documentVisualBounds();
694 if (a) {
695 if(_fid <= population) {
696+ SPDocument *doc = item->document;
697+ gchar const * spray_origin;
698+ if(!item->getAttribute("inkscape:spray-origin")){
699+ spray_origin = g_strdup_printf("#%s", item->getId());
700+ } else {
701+ spray_origin = item->getAttribute("inkscape:spray-origin");
702+ }
703+ Geom::Point center=item->getCenter();
704+ Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
705+ SPCSSAttr *css = sp_repr_css_attr_new();
706+ if(nooverlap || picker || visible){
707+ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, visible, nooverlap, offset, css, false)){
708+ return false;
709+ }
710+ }
711 SPItem *item_copied;
712- SPDocument *doc = item->document;
713 Inkscape::XML::Document* xml_doc = doc->getReprDoc();
714 Inkscape::XML::Node *old_repr = item->getRepr();
715 Inkscape::XML::Node *parent = old_repr->parent();
716@@ -467,6 +895,9 @@
717 // Ad the clone to the list of the parent's children
718 parent->appendChild(clone);
719 // Generates the link between parent and child attributes
720+ if(!clone->attribute("inkscape:spray-origin")){
721+ clone->setAttribute("inkscape:spray-origin", spray_origin);
722+ }
723 gchar *href_str = g_strdup_printf("#%s", old_repr->attribute("id"));
724 clone->setAttribute("xlink:href", href_str, false);
725 g_free(href_str);
726@@ -474,15 +905,14 @@
727 SPObject *clone_object = doc->getObjectByRepr(clone);
728 // Conversion object->item
729 item_copied = dynamic_cast<SPItem *>(clone_object);
730- Geom::Point center = item->getCenter();
731 sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale));
732 sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale));
733 sp_spray_rotate_rel(center, desktop, item_copied, Geom::Rotate(angle));
734- Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
735 sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
736-
737+ if(picker){
738+ sp_desktop_apply_css_recursive(item_copied, css, true);
739+ }
740 Inkscape::GC::release(clone);
741-
742 did = true;
743 }
744 }
745@@ -529,8 +959,7 @@
746 for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
747 SPItem *item = *i;
748 g_assert(item != NULL);
749-
750- if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) {
751+ if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib, tc->nooverlap, tc->picker, tc->pickinversevalue, tc->pickfill, tc->pickstroke, tc->visible, tc->offset, tc->usepressurescale, get_pressure(tc))) {
752 did = true;
753 }
754 }
755
756=== modified file 'src/ui/tools/spray-tool.h'
757--- src/ui/tools/spray-tool.h 2015-06-22 19:20:23 +0000
758+++ src/ui/tools/spray-tool.h 2015-11-08 09:50:32 +0000
759@@ -12,6 +12,7 @@
760 * Benoît LAVORATA
761 * Vincent MONTAGNE
762 * Pierre BARBRY-BLOT
763+ * Jabiertxo ARRAIZA
764 *
765 * Copyright (C) 2009 authors
766 *
767@@ -62,7 +63,9 @@
768
769 /* attributes */
770 bool dragging; /* mouse state: mouse is dragging */
771- bool usepressure;
772+ bool usepressurewidth;
773+ bool usepressurepopulation;
774+ bool usepressurescale;
775 bool usetilt;
776 bool usetext;
777
778@@ -86,7 +89,13 @@
779 bool has_dilated;
780 Geom::Point last_push;
781 SPCanvasItem *dilate_area;
782-
783+ bool nooverlap;
784+ bool picker;
785+ bool pickinversevalue;
786+ bool pickfill;
787+ bool pickstroke;
788+ bool visible;
789+ double offset;
790 sigc::connection style_set_connection;
791
792 static const std::string prefsPath;
793
794=== modified file 'src/widgets/spray-toolbar.cpp'
795--- src/widgets/spray-toolbar.cpp 2014-10-05 18:14:01 +0000
796+++ src/widgets/spray-toolbar.cpp 2015-11-08 09:50:32 +0000
797@@ -15,10 +15,11 @@
798 * Tavmjong Bah <tavmjong@free.fr>
799 * Abhishek Sharma
800 * Kris De Gussem <Kris.DeGussem@gmail.com>
801+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
802 *
803 * Copyright (C) 2004 David Turner
804 * Copyright (C) 2003 MenTaLguY
805- * Copyright (C) 1999-2011 authors
806+ * Copyright (C) 1999-2015 authors
807 * Copyright (C) 2001-2002 Ximian, Inc.
808 *
809 * Released under GNU GPL, read the file 'COPYING' for more information
810@@ -28,18 +29,24 @@
811 # include "config.h"
812 #endif
813
814-#include <glibmm/i18n.h>
815+#include <gtkmm.h>
816
817 #include "spray-toolbar.h"
818 #include "desktop.h"
819+#include "inkscape.h"
820 #include "document-undo.h"
821 #include "widgets/ege-adjustment-action.h"
822 #include "widgets/ege-select-one-action.h"
823 #include "widgets/ink-action.h"
824 #include "preferences.h"
825 #include "toolbox.h"
826+#include "ui/dialog/clonetiler.h"
827+#include "ui/dialog/dialog-manager.h"
828+#include "ui/dialog/panel-dialog.h"
829 #include "ui/icon-names.h"
830
831+#include <glibmm/i18n.h>
832+
833 using Inkscape::DocumentUndo;
834 using Inkscape::UI::ToolboxFactory;
835 using Inkscape::UI::PrefPusher;
836@@ -53,6 +60,55 @@
837 //## Spray ##
838 //########################
839
840+static void sp_stb_sensitivize( GObject *tbl )
841+{
842+ GtkAction* offset = GTK_ACTION( g_object_get_data(tbl, "offset") );
843+ GtkAction* spray_scale = GTK_ACTION( g_object_get_data(tbl, "spray_scale") );
844+ GtkAdjustment *adj_offset = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(offset) );
845+ GtkAdjustment *adj_scale = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(spray_scale) );
846+ GtkToggleAction *nooverlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "nooverlap") );
847+ GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") );
848+ GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") );
849+ GtkAction *pickfill = GTK_ACTION( g_object_get_data(tbl, "pickfill") );
850+ GtkAction *pickstroke = GTK_ACTION( g_object_get_data(tbl, "pickstroke") );
851+ GtkAction *pickinversevalue = GTK_ACTION( g_object_get_data(tbl, "pickinversevalue") );
852+ gtk_adjustment_set_value( adj_offset, 100.0 );
853+ if (gtk_toggle_action_get_active(nooverlap)) {
854+ gtk_action_set_sensitive( offset, TRUE );
855+ } else {
856+ gtk_action_set_sensitive( offset, FALSE );
857+ }
858+ if (gtk_toggle_action_get_active(usepressurescale)) {
859+ gtk_adjustment_set_value( adj_scale, 0.0 );
860+ gtk_action_set_sensitive( spray_scale, FALSE );
861+ } else {
862+ gtk_action_set_sensitive( spray_scale, TRUE );
863+ }
864+ if(gtk_toggle_action_get_active(picker)){
865+ gtk_action_set_sensitive( pickfill, TRUE );
866+ gtk_action_set_sensitive( pickstroke, TRUE );
867+ gtk_action_set_sensitive( pickinversevalue, TRUE );
868+ } else {
869+ gtk_action_set_sensitive( pickfill, FALSE );
870+ gtk_action_set_sensitive( pickstroke, FALSE );
871+ gtk_action_set_sensitive( pickinversevalue, FALSE );
872+ }
873+}
874+
875+Inkscape::UI::Dialog::CloneTiler *get_clone_tiler_panel(SPDesktop *desktop)
876+{
877+ if (Inkscape::UI::Dialog::PanelDialogBase *panel_dialog =
878+ dynamic_cast<Inkscape::UI::Dialog::PanelDialogBase *>(desktop->_dlg_mgr->getDialog("CloneTiler"))) {
879+ try {
880+ Inkscape::UI::Dialog::CloneTiler &clone_tiler =
881+ dynamic_cast<Inkscape::UI::Dialog::CloneTiler &>(panel_dialog->getPanel());
882+ return &clone_tiler;
883+ } catch (std::exception &e) { }
884+ }
885+
886+ return 0;
887+}
888+
889 static void sp_spray_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ )
890 {
891 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
892@@ -102,12 +158,83 @@
893 gtk_adjustment_get_value(adj));
894 }
895
896+static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ )
897+{
898+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
899+ prefs->setDouble( "/tools/spray/offset",
900+ gtk_adjustment_get_value(adj));
901+}
902+
903+static void sp_toggle_nooverlap( GtkToggleAction* act, gpointer data)
904+{
905+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
906+ gboolean active = gtk_toggle_action_get_active(act);
907+ prefs->setBool("/tools/spray/nooverlap", active);
908+ GObject *tbl = G_OBJECT(data);
909+ sp_stb_sensitivize(tbl);
910+}
911+
912+static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data)
913+{
914+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
915+ gboolean active = gtk_toggle_action_get_active(act);
916+ prefs->setBool("/tools/spray/usepressurescale", active);
917+ if(active == true){
918+ prefs->setDouble("/tools/spray/scale_variation", 0);
919+ }
920+ GObject *tbl = G_OBJECT(data);
921+ sp_stb_sensitivize( tbl );
922+}
923+
924+static void sp_toggle_visible( GtkToggleAction* act, gpointer data)
925+{
926+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
927+ gboolean active = gtk_toggle_action_get_active(act);
928+ prefs->setBool("/tools/spray/visible", active);
929+}
930+
931+static void sp_toggle_picker( GtkToggleAction* act, gpointer data )
932+{
933+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
934+ gboolean active = gtk_toggle_action_get_active(act);
935+ prefs->setBool("/tools/spray/picker", active);
936+ if(active == true){
937+ prefs->setBool("/dialogs/clonetiler/dotrace", true);
938+ SPDesktop *dt = SP_ACTIVE_DESKTOP;
939+ if (Inkscape::UI::Dialog::CloneTiler *ct = get_clone_tiler_panel(dt)){
940+ dt->_dlg_mgr->showDialog("CloneTiler");
941+ ct->show_page_trace();
942+ }
943+ }
944+ GObject *tbl = G_OBJECT(data);
945+ sp_stb_sensitivize(tbl);
946+}
947+
948+static void sp_toggle_pick_fill( GtkToggleAction* act, gpointer data )
949+{
950+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
951+ gboolean active = gtk_toggle_action_get_active(act);
952+ prefs->setBool("/tools/spray/pickfill", active);
953+}
954+
955+static void sp_toggle_pick_inverse_value( GtkToggleAction* act, gpointer data )
956+{
957+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
958+ gboolean active = gtk_toggle_action_get_active(act);
959+ prefs->setBool("/tools/spray/pickinversevalue", active);
960+}
961+
962+static void sp_toggle_pick_stroke( GtkToggleAction* act, gpointer data )
963+{
964+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
965+ gboolean active = gtk_toggle_action_get_active(act);
966+ prefs->setBool("/tools/spray/pickstroke", active);
967+}
968
969 void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
970 {
971 Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1);
972 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
973-
974 {
975 /* Width */
976 gchar const* labels[] = {_("(narrow spray)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad spray)")};
977@@ -123,7 +250,20 @@
978 gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
979 gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
980 }
981+
982+ /* Use Pressure Width button */
983+ {
984+ InkToggleAction* act = ink_toggle_action_new( "SprayPressureWidthAction",
985+ _("Pressure"),
986+ _("Use the pressure of the input device to alter the width of spray area"),
987+ INKSCAPE_ICON("draw-use-pressure"),
988+ Inkscape::ICON_SIZE_DECORATION );
989+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
990+ PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressurewidth");
991+ g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher);
992
993+ }
994+
995 {
996 /* Mean */
997 gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(maximum mean)")};
998@@ -218,15 +358,15 @@
999 g_object_set_data( holder, "spray_population", eact );
1000 }
1001
1002- /* Use Pressure button */
1003+ /* Use Pressure Population button */
1004 {
1005- InkToggleAction* act = ink_toggle_action_new( "SprayPressureAction",
1006+ InkToggleAction* act = ink_toggle_action_new( "SprayPressurePopulationAction",
1007 _("Pressure"),
1008 _("Use the pressure of the input device to alter the amount of sprayed objects"),
1009 INKSCAPE_ICON("draw-use-pressure"),
1010 Inkscape::ICON_SIZE_DECORATION );
1011 gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
1012- PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressure");
1013+ PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressurepopulation");
1014 g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher);
1015
1016 }
1017@@ -267,8 +407,112 @@
1018 g_object_set_data( holder, "spray_scale", eact );
1019 }
1020
1021-
1022-
1023+ /* Use Pressure Scale button */
1024+ {
1025+ InkToggleAction* act = ink_toggle_action_new( "SprayPressureScaleAction",
1026+ _("Pressure"),
1027+ _("Use the pressure of the input device to alter the scale of new items"),
1028+ INKSCAPE_ICON("draw-use-pressure"),
1029+ Inkscape::ICON_SIZE_DECORATION);
1030+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/usepressurescale", false) );
1031+ g_object_set_data( holder, "usepressurescale", act );
1032+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pressure_scale), holder) ;
1033+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
1034+ }
1035+
1036+
1037+ /* Picker */
1038+ {
1039+ InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction",
1040+ _("Pick color from the drawing. You can use clonetiler trace dialog for avanced effects. In clone mode original fill or stroke colors must be unset."),
1041+ _("Pick color from the drawing. You can use clonetiler trace dialog for avanced effects. In clone mode original fill or stroke colors must be unset."),
1042+ INKSCAPE_ICON("color-picker"),
1043+ secondarySize );
1044+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) );
1045+ g_object_set_data( holder, "picker", act );
1046+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_picker), holder) ;
1047+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
1048+ }
1049+
1050+ /* Inverse Value Size */
1051+ {
1052+ InkToggleAction* act = ink_toggle_action_new( "SprayOverPickInverseValueAction",
1053+ _("Inversed pick value retaining color"),
1054+ _("Inversed pick value retaining color"),
1055+ INKSCAPE_ICON("object-tweak-shrink"),
1056+ secondarySize );
1057+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickinversevalue", false) );
1058+ g_object_set_data( holder, "pickinversevalue", act );
1059+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_inverse_value), holder) ;
1060+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
1061+ }
1062+
1063+ /* Pick Fill */
1064+ {
1065+ InkToggleAction* act = ink_toggle_action_new( "SprayOverPickFillAction",
1066+ _("Apply picked color to fill"),
1067+ _("Apply picked color to fill"),
1068+ INKSCAPE_ICON("paint-solid"),
1069+ secondarySize );
1070+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickfill", false) );
1071+ g_object_set_data( holder, "pickfill", act );
1072+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_fill), holder) ;
1073+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
1074+ }
1075+
1076+ /* Pick Stroke */
1077+ {
1078+ InkToggleAction* act = ink_toggle_action_new( "SprayOverPickStrokeAction",
1079+ _("Apply picked color to stroke"),
1080+ _("Apply picked color to stroke"),
1081+ INKSCAPE_ICON("no-marker"),
1082+ secondarySize );
1083+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickstroke", false) );
1084+ g_object_set_data( holder, "pickstroke", act );
1085+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_stroke), holder) ;
1086+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
1087+ }
1088+
1089+ /* Visible */
1090+ {
1091+ InkToggleAction* act = ink_toggle_action_new( "SprayOverVisibleAction",
1092+ _("Apply only over non transparent areas"),
1093+ _("Apply only over non transparent areas"),
1094+ INKSCAPE_ICON("object-visible"),
1095+ secondarySize );
1096+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/visible", false) );
1097+ g_object_set_data( holder, "visible", act );
1098+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_visible), holder) ;
1099+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
1100+ }
1101+
1102+ /* Overlap */
1103+ {
1104+ InkToggleAction* act = ink_toggle_action_new( "SprayNoOverlapAction",
1105+ _("Prevent overlapping objects"),
1106+ _("Prevent overlapping objects"),
1107+ INKSCAPE_ICON("distribute-randomize"),
1108+ secondarySize );
1109+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/nooverlap", false) );
1110+ g_object_set_data( holder, "nooverlap", act );
1111+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_nooverlap), holder) ;
1112+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
1113+ }
1114+
1115+ /* Offset */
1116+ {
1117+ EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction",
1118+ _("Offset %"), _("Offset %:"),
1119+ _("Increase to segregate objects more (value in percent)"),
1120+ "/tools/spray/offset", 100,
1121+ GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
1122+ 0, 10000, 1, 4,
1123+ 0, 0, 0,
1124+ sp_spray_offset_value_changed, NULL, 0 , 0);
1125+ g_object_set_data( holder, "offset", eact );
1126+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
1127+ }
1128+ sp_stb_sensitivize(holder);
1129 }
1130
1131
1132
1133=== modified file 'src/widgets/spray-toolbar.h'
1134--- src/widgets/spray-toolbar.h 2014-03-02 22:58:28 +0000
1135+++ src/widgets/spray-toolbar.h 2015-11-08 09:50:32 +0000
1136@@ -21,7 +21,7 @@
1137 *
1138 * Copyright (C) 2004 David Turner
1139 * Copyright (C) 2003 MenTaLguY
1140- * Copyright (C) 1999-2011 authors
1141+ * Copyright (C) 1999-2015 authors
1142 * Copyright (C) 2001-2002 Ximian, Inc.
1143 *
1144 * Released under GNU GPL, read the file 'COPYING' for more information
1145
1146=== modified file 'src/widgets/toolbox.cpp'
1147--- src/widgets/toolbox.cpp 2015-10-22 17:29:20 +0000
1148+++ src/widgets/toolbox.cpp 2015-11-08 09:50:32 +0000
1149@@ -16,10 +16,11 @@
1150 * Tavmjong Bah <tavmjong@free.fr>
1151 * Abhishek Sharma
1152 * Kris De Gussem <Kris.DeGussem@gmail.com>
1153+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
1154 *
1155 * Copyright (C) 2004 David Turner
1156 * Copyright (C) 2003 MenTaLguY
1157- * Copyright (C) 1999-2011 authors
1158+ * Copyright (C) 1999-2015 authors
1159 * Copyright (C) 2001-2002 Ximian, Inc.
1160 *
1161 * Released under GNU GPL, read the file 'COPYING' for more information
1162@@ -309,14 +310,26 @@
1163 " <toolitem action='SprayModeAction' />"
1164 " <separator />"
1165 " <toolitem action='SprayWidthAction' />"
1166+ " <toolitem action='SprayPressureWidthAction' />"
1167 " <toolitem action='SprayPopulationAction' />"
1168- " <toolitem action='SprayPressureAction' />"
1169+ " <toolitem action='SprayPressurePopulationAction' />"
1170 " <separator />"
1171 " <toolitem action='SprayRotationAction' />"
1172 " <toolitem action='SprayScaleAction' />"
1173+ " <toolitem action='SprayPressureScaleAction' />"
1174 " <separator />"
1175 " <toolitem action='SprayStandard_deviationAction' />"
1176 " <toolitem action='SprayMeanAction' />"
1177+ " <separator />"
1178+ " <toolitem action='SprayOverVisibleAction' />"
1179+ " <toolitem action='SprayNoOverlapAction' />"
1180+ " <toolitem action='SprayToolOffsetAction' />"
1181+ " <separator />"
1182+ " <toolitem action='SprayPickColorAction' />"
1183+ " <toolitem action='SprayOverPickInverseValueAction' />"
1184+ " <toolitem action='SprayOverPickFillAction' />"
1185+ " <toolitem action='SprayOverPickStrokeAction' />"
1186+
1187 " </toolbar>"
1188
1189 " <toolbar name='ZoomToolbar'>"