summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ui/dialog/clonetiler.cpp32
-rw-r--r--src/ui/dialog/clonetiler.h4
-rw-r--r--src/ui/tools/spray-tool.cpp475
-rw-r--r--src/ui/tools/spray-tool.h13
-rw-r--r--src/widgets/spray-toolbar.cpp256
-rw-r--r--src/widgets/spray-toolbar.h2
-rw-r--r--src/widgets/toolbox.cpp17
7 files changed, 756 insertions, 43 deletions
diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp
index da1c6d9fb..fbd050f8e 100644
--- a/src/ui/dialog/clonetiler.cpp
+++ b/src/ui/dialog/clonetiler.cpp
@@ -85,7 +85,7 @@ CloneTiler::CloneTiler () :
{
Gtk::Box *contents = _getContents();
contents->set_spacing(0);
-
+
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -101,7 +101,7 @@ CloneTiler::CloneTiler () :
contents->pack_start (*Gtk::manage(Glib::wrap(mainbox)), true, true, 0);
- GtkWidget *nb = gtk_notebook_new ();
+ nb = gtk_notebook_new ();
gtk_box_pack_start (GTK_BOX (mainbox), nb, FALSE, FALSE, 0);
@@ -662,7 +662,7 @@ CloneTiler::CloneTiler () :
gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0);
guint32 rgba = 0x000000ff | sp_svg_read_color (prefs->getString(prefs_path + "initial_color").data(), 0x000000ff);
- 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);
+ 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);
color_changed_connection = color_picker->connectChanged (sigc::ptr_fun(on_picker_color_changed));
gtk_box_pack_start (GTK_BOX (hb), reinterpret_cast<GtkWidget*>(color_picker->gobj()), FALSE, FALSE, 0);
@@ -776,8 +776,6 @@ CloneTiler::CloneTiler () :
// Trace
{
GtkWidget *vb = clonetiler_new_tab (nb, _("_Trace"));
-
-
{
#if GTK_CHECK_VERSION(3,0,0)
GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, VB_MARGIN);
@@ -787,11 +785,11 @@ CloneTiler::CloneTiler () :
#endif
gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0);
- GtkWidget *b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles"));
+ b = gtk_check_button_new_with_label (_("Trace the drawing under the clones/sprayed items"));
g_object_set_data (G_OBJECT(b), "uncheckable", GINT_TO_POINTER(TRUE));
bool old = prefs->getBool(prefs_path + "dotrace");
gtk_toggle_button_set_active ((GtkToggleButton *) b, old);
- 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"));
+ gtk_widget_set_tooltip_text (b, _("For each clone/sprayed item, pick a value from the drawing in its location and apply it"));
gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(b), "toggled",
@@ -1001,6 +999,18 @@ CloneTiler::CloneTiler () :
}
}
+ {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, VB_MARGIN);
+ gtk_box_set_homogeneous(GTK_BOX(hb), FALSE);
+#else
+ GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN);
+#endif
+ gtk_box_pack_start (GTK_BOX (mainbox), hb, FALSE, FALSE, 0);
+ GtkWidget *l = gtk_label_new(_(""));
+ gtk_label_set_markup (GTK_LABEL(l), _("Apply to tiled clones:"));
+ gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0);
+ }
// Rows/columns, width/height
{
#if GTK_CHECK_VERSION(3,0,0)
@@ -1289,7 +1299,6 @@ CloneTiler::CloneTiler () :
}
gtk_widget_show_all (mainbox);
-
}
show_all();
@@ -3005,6 +3014,13 @@ void CloneTiler::clonetiler_do_pick_toggled(GtkToggleButton *tb, GtkWidget *dlg)
}
}
+void CloneTiler::show_page_trace()
+{
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(nb),6);
+ gtk_toggle_button_set_active ((GtkToggleButton *) b, false);
+}
+
+
}
}
}
diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h
index e5f5638b2..a8f1df0a0 100644
--- a/src/ui/dialog/clonetiler.h
+++ b/src/ui/dialog/clonetiler.h
@@ -31,7 +31,7 @@ public:
virtual ~CloneTiler();
static CloneTiler &getInstance() { return *new CloneTiler(); }
-
+ void show_page_trace();
protected:
GtkWidget * clonetiler_new_tab(GtkWidget *nb, const gchar *label);
@@ -113,6 +113,8 @@ private:
CloneTiler& operator=(CloneTiler const &d);
GtkWidget *dlg;
+ GtkWidget *nb;
+ GtkWidget *b;
SPDesktop *desktop;
DesktopTracker deskTrack;
Inkscape::UI::Widget::ColorPicker *color_picker;
diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp
index e2be5ca4b..17b82fe1d 100644
--- a/src/ui/tools/spray-tool.cpp
+++ b/src/ui/tools/spray-tool.cpp
@@ -12,6 +12,7 @@
* Steren GIANNINI (steren.giannini@gmail.com)
* Jon A. Cruz <jon@joncruz.org>
* Abhishek Sharma
+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
*
* Copyright (C) 2009 authors
*
@@ -48,7 +49,15 @@
#include "sp-path.h"
#include "path-chemistry.h"
+// For color picking
+#include "display/drawing.h"
+#include "display/drawing-context.h"
+#include "display/cairo-utils.h"
+#include "desktop-style.h"
+#include "svg/svg-color.h"
+
#include "sp-text.h"
+#include "sp-root.h"
#include "sp-flowtext.h"
#include "display/sp-canvas.h"
#include "display/canvas-bpath.h"
@@ -88,6 +97,17 @@ namespace Inkscape {
namespace UI {
namespace Tools {
+enum {
+ PICK_COLOR,
+ PICK_OPACITY,
+ PICK_R,
+ PICK_G,
+ PICK_B,
+ PICK_H,
+ PICK_S,
+ PICK_L
+};
+
const std::string& SprayTool::getPrefsPath() {
return SprayTool::prefsPath;
}
@@ -133,7 +153,9 @@ SprayTool::SprayTool()
: ToolBase(cursor_spray_xpm, 4, 4, false)
, pressure(TC_DEFAULT_PRESSURE)
, dragging(false)
- , usepressure(false)
+ , usepressurewidth(false)
+ , usepressurepopulation(false)
+ , usepressurescale(false)
, usetilt(false)
, usetext(false)
, width(0.2)
@@ -151,6 +173,13 @@ SprayTool::SprayTool()
, is_dilating(false)
, has_dilated(false)
, dilate_area(NULL)
+ , nooverlap(false)
+ , picker(false)
+ , pickinversevalue(false)
+ , pickfill(false)
+ , pickstroke(false)
+ , visible(false)
+ , offset(0)
{
}
@@ -221,8 +250,17 @@ void SprayTool::setup() {
sp_event_context_read(this, "population");
sp_event_context_read(this, "mean");
sp_event_context_read(this, "standard_deviation");
- sp_event_context_read(this, "usepressure");
+ sp_event_context_read(this, "usepressurewidth");
+ sp_event_context_read(this, "usepressurepopulation");
+ sp_event_context_read(this, "usepressurescale");
sp_event_context_read(this, "Scale");
+ sp_event_context_read(this, "offset");
+ sp_event_context_read(this, "picker");
+ sp_event_context_read(this, "pickinversevalue");
+ sp_event_context_read(this, "pickfill");
+ sp_event_context_read(this, "pickstroke");
+ sp_event_context_read(this, "visible");
+ sp_event_context_read(this, "nooverlap");
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (prefs->getBool("/tools/spray/selcue")) {
@@ -241,8 +279,12 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) {
this->update_cursor(false);
} else if (path == "width") {
this->width = 0.01 * CLAMP(val.getInt(10), 1, 100);
- } else if (path == "usepressure") {
- this->usepressure = val.getBool();
+ } else if (path == "usepressurewidth") {
+ this->usepressurewidth = val.getBool();
+ } else if (path == "usepressurepopulation") {
+ this->usepressurepopulation = val.getBool();
+ } else if (path == "usepressurescale") {
+ this->usepressurescale = val.getBool();
} else if (path == "population") {
this->population = 0.01 * CLAMP(val.getInt(10), 1, 100);
} else if (path == "rotation_variation") {
@@ -260,6 +302,20 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) {
this->tilt = CLAMP(val.getDouble(0.1), 0, 1000.0);
} else if (path == "ratio") {
this->ratio = CLAMP(val.getDouble(), 0.0, 0.9);
+ } else if (path == "offset") {
+ this->offset = CLAMP(val.getDouble(), -1000.0, 1000.0);
+ } else if (path == "picker") {
+ this->picker = val.getBool();
+ } else if (path == "pickinversevalue") {
+ this->pickinversevalue = val.getBool();
+ } else if (path == "pickfill") {
+ this->pickfill = val.getBool();
+ } else if (path == "pickstroke") {
+ this->pickstroke = val.getBool();
+ } else if (path == "visible") {
+ this->visible = val.getBool();
+ } else if (path == "nooverlap") {
+ this->nooverlap = val.getBool();
}
}
@@ -272,9 +328,15 @@ static void sp_spray_extinput(SprayTool *tc, GdkEvent *event)
}
}
+static double get_width(SprayTool *tc)
+{
+ double pressure = (tc->usepressurewidth? tc->pressure / TC_DEFAULT_PRESSURE : 1);
+ return pressure * tc->width;
+}
+
static double get_dilate_radius(SprayTool *tc)
{
- return 250 * tc->width/SP_EVENT_CONTEXT(tc)->desktop->current_zoom();
+ return 250 * get_width(tc)/SP_EVENT_CONTEXT(tc)->desktop->current_zoom();
}
static double get_path_mean(SprayTool *tc)
@@ -289,11 +351,16 @@ static double get_path_standard_deviation(SprayTool *tc)
static double get_population(SprayTool *tc)
{
- double pressure = (tc->usepressure? tc->pressure / TC_DEFAULT_PRESSURE : 1);
- //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population);
+ double pressure = (tc->usepressurepopulation? tc->pressure / TC_DEFAULT_PRESSURE : 1);
return pressure * tc->population;
}
+static double get_pressure(SprayTool *tc)
+{
+ double pressure = tc->pressure / TC_DEFAULT_PRESSURE;
+ return pressure;
+}
+
static double get_move_mean(SprayTool *tc)
{
return tc->mean;
@@ -332,6 +399,317 @@ static void random_position(double &radius, double &angle, double &a, double &s,
}
+static void sp_spray_transform_path(SPItem * item, Geom::Path &path, Geom::Affine affine, Geom::Point center){
+ path *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL).inverse();
+ path *= item->transform.inverse();
+ Geom::Affine dt2p;
+ if (item->parent) {
+ dt2p = static_cast<SPItem *>(item->parent)->i2dt_affine().inverse();
+ } else {
+ SPDesktop *dt = SP_ACTIVE_DESKTOP;
+ dt2p = dt->dt2doc();
+ }
+ Geom::Affine i2dt = item->i2dt_affine() * Geom::Translate(center).inverse() * affine * Geom::Translate(center);
+ path *= i2dt * dt2p;
+ path *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL);
+}
+
+/**
+Randomizes \a val by \a rand, with 0 < val < 1 and all values (including 0, 1) having the same
+probability of being displaced.
+ */
+double randomize01(double val, double rand)
+{
+ double base = MIN (val - rand, 1 - 2*rand);
+ if (base < 0) {
+ base = 0;
+ }
+ val = base + g_random_double_range (0, MIN (2 * rand, 1 - base));
+ return CLAMP(val, 0, 1); // this should be unnecessary with the above provisions, but just in case...
+}
+
+static bool fit_item(SPDesktop *desktop,
+ SPItem *item,
+ Geom::OptRect bbox,
+ Geom::Point &move,
+ Geom::Point center,
+ double angle,
+ double &_scale,
+ double scale,
+ bool picker,
+ bool pickinversevalue,
+ bool pickfill,
+ bool pickstroke,
+ bool visible,
+ bool nooverlap,
+ double offset,
+ SPCSSAttr *css,
+ bool trace_scale)
+{
+ SPDocument *doc = item->document;
+ double width = bbox->width();
+ double height = bbox->height();
+ double size = std::min(width,height);
+ double offset_min = (offset * size)/100.0 - (size);
+ if(offset_min < 0 ){
+ offset_min = 0;
+ }
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool pick_to_size = prefs->getBool("/dialogs/clonetiler/pick_to_size");
+ bool trace = prefs->getBool("/dialogs/clonetiler/dotrace");
+ if(picker && pick_to_size && !trace_scale && trace){
+ _scale = 0.1;
+ }
+ 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));
+ Geom::Path path;
+ path.start(Geom::Point(bbox_procesed->left(), bbox_procesed->top()));
+ path.appendNew<Geom::LineSegment>(Geom::Point(bbox_procesed->right(), bbox_procesed->top()));
+ path.appendNew<Geom::LineSegment>(Geom::Point(bbox_procesed->right(), bbox_procesed->bottom()));
+ path.appendNew<Geom::LineSegment>(Geom::Point(bbox_procesed->left(), bbox_procesed->bottom()));
+ path.close(true);
+ sp_spray_transform_path(item, path, Geom::Scale(_scale), center);
+ sp_spray_transform_path(item, path, Geom::Scale(scale), center);
+ sp_spray_transform_path(item, path, Geom::Rotate(angle), center);
+ path *= Geom::Translate(move);
+ path *= desktop->doc2dt();
+ bbox_procesed = path.boundsFast();
+ double bbox_left_main = bbox_procesed->left();
+ double bbox_top_main = bbox_procesed->top();
+ double width_transformed = bbox_procesed->width();
+ double height_transformed = bbox_procesed->height();
+ Geom::Point mid_point = desktop->d2w(bbox_procesed->midpoint());
+ Geom::IntRect area = Geom::IntRect::from_xywh(floor(mid_point[Geom::X]), floor(mid_point[Geom::Y]), 1, 1);
+ double R = 0, G = 0, B = 0, A = 0;
+ cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
+ sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area);
+ ink_cairo_surface_average_color(s, R, G, B, A);
+ cairo_surface_destroy(s);
+ guint32 rgba = SP_RGBA32_F_COMPOSE(R, G, B, A);
+ if(nooverlap && visible && (A==0 || A < 1e-6)){
+ return false;
+ }
+ size = std::min(width_transformed,height_transformed);
+ if(offset < 100 ){
+ offset_min = ((99.0 - offset) * size)/100.0 - size;
+ } else {
+ offset_min = 0;
+ }
+ std::vector<SPItem*> items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox_procesed);
+ Inkscape::Selection *selection = desktop->getSelection();
+ if (selection->isEmpty()) {
+ return false;
+ }
+ std::vector<SPItem*> const items_selected(selection->itemList());
+ for (std::vector<SPItem*>::const_iterator i=items_down.begin(); i!=items_down.end(); i++) {
+ SPItem *item_down = *i;
+ Geom::OptRect bbox_down = item_down->documentVisualBounds();
+ width = bbox_down->width();
+ height = bbox_down->height();
+ double bbox_left = bbox_down->left();
+ double bbox_top = bbox_down->top();
+ gchar const * item_down_sharp = g_strdup_printf("#%s", item_down->getId());
+ for (std::vector<SPItem*>::const_iterator j=items_selected.begin(); j!=items_selected.end(); j++) {
+ SPItem *item_selected = *j;
+ gchar const * spray_origin;
+ if(!item_selected->getAttribute("inkscape:spray-origin")){
+ spray_origin = g_strdup_printf("#%s", item_selected->getId());
+ } else {
+ spray_origin = item_selected->getAttribute("inkscape:spray-origin");
+ }
+ if(strcmp(item_down_sharp, spray_origin) == 0 ||
+ (item_down->getAttribute("inkscape:spray-origin") &&
+ strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 ))
+ {
+ if(nooverlap){
+ if(!(offset_min < 0 && std::abs(bbox_left - bbox_left_main) > std::abs(offset_min) &&
+ std::abs(bbox_top - bbox_top_main) > std::abs(offset_min))){
+ return false;
+ }
+ } else if(picker || visible){
+ item_down->setHidden(true);
+ item_down->updateRepr();
+ }
+ }
+ }
+ }
+ if(picker || visible){
+ if(!nooverlap){
+ doc->ensureUpToDate();
+ }
+ int pick = prefs->getInt("/dialogs/clonetiler/pick");
+ bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence", false);
+ bool pick_to_color = prefs->getBool("/dialogs/clonetiler/pick_to_color");
+ bool pick_to_opacity = prefs->getBool("/dialogs/clonetiler/pick_to_opacity");
+ double rand_picked = 0.01 * prefs->getDoubleLimited("/dialogs/clonetiler/rand_picked", 0, 0, 100);
+ bool invert_picked = prefs->getBool("/dialogs/clonetiler/invert_picked");
+ double gamma_picked = prefs->getDoubleLimited("/dialogs/clonetiler/gamma_picked", 0, -10, 10);
+ double opacity = 1.0;
+ gchar color_string[32]; *color_string = 0;
+ float r = SP_RGBA32_R_F(rgba);
+ float g = SP_RGBA32_G_F(rgba);
+ float b = SP_RGBA32_B_F(rgba);
+ float a = SP_RGBA32_A_F(rgba);
+ //this can fix the bug #1511998 if confirmed
+ if( a == 0 || a < 1e-6){
+ r = 1;
+ g = 1;
+ b = 1;
+ }
+ if(visible && (a == 0 || a < 1e-6)){
+ return false;
+ }
+
+ if(picker && trace){
+ float hsl[3];
+ sp_color_rgb_to_hsl_floatv (hsl, r, g, b);
+
+ gdouble val = 0;
+ switch (pick) {
+ case PICK_COLOR:
+ val = 1 - hsl[2]; // inverse lightness; to match other picks where black = max
+ break;
+ case PICK_OPACITY:
+ val = a;
+ break;
+ case PICK_R:
+ val = r;
+ break;
+ case PICK_G:
+ val = g;
+ break;
+ case PICK_B:
+ val = b;
+ break;
+ case PICK_H:
+ val = hsl[0];
+ break;
+ case PICK_S:
+ val = hsl[1];
+ break;
+ case PICK_L:
+ val = 1 - hsl[2];
+ break;
+ default:
+ break;
+ }
+
+ if (rand_picked > 0) {
+ val = randomize01 (val, rand_picked);
+ r = randomize01 (r, rand_picked);
+ g = randomize01 (g, rand_picked);
+ b = randomize01 (b, rand_picked);
+ }
+
+ if (gamma_picked != 0) {
+ double power;
+ if (gamma_picked > 0)
+ power = 1/(1 + fabs(gamma_picked));
+ else
+ power = 1 + fabs(gamma_picked);
+
+ val = pow (val, power);
+ r = pow ((double)r, (double)power);
+ g = pow ((double)g, (double)power);
+ b = pow ((double)b, (double)power);
+ }
+
+ if (invert_picked) {
+ val = 1 - val;
+ r = 1 - r;
+ g = 1 - g;
+ b = 1 - b;
+ }
+
+ val = CLAMP (val, 0, 1);
+ r = CLAMP (r, 0, 1);
+ g = CLAMP (g, 0, 1);
+ b = CLAMP (b, 0, 1);
+
+ // recompose tweaked color
+ rgba = SP_RGBA32_F_COMPOSE(r, g, b, a);
+ if (pick_to_size) {
+ if(!trace_scale){
+ if(pickinversevalue) {
+ _scale = 1.0 - val;
+ } else {
+ _scale = val;
+ }
+ if(_scale == 0.0) {
+ return false;
+ }
+ if(!fit_item(desktop,
+ item,
+ bbox,
+ move,
+ center,
+ angle,
+ _scale,
+ scale,
+ picker,
+ pickinversevalue,
+ pickfill,
+ pickstroke,
+ visible,
+ nooverlap,
+ offset,
+ css,
+ true)){
+ return false;
+ }
+ }
+ }
+
+ if (pick_to_opacity) {
+ if(pickinversevalue) {
+ opacity *= 1.0 - val;
+ } else {
+ opacity *= val;
+ }
+ std::stringstream opacity_str;
+ opacity_str.imbue(std::locale::classic());
+ opacity_str << opacity;
+ sp_repr_css_set_property(css, "opacity", opacity_str.str().c_str());
+ }
+ if (pick_to_presence) {
+ if (g_random_double_range (0, 1) > val) {
+ //Hidding the element is a way to retain original
+ //behaviour of tiled clones for presence option.
+ sp_repr_css_set_property(css, "opacity", "0");
+ }
+ }
+ if (pick_to_color) {
+ sp_svg_write_color(color_string, sizeof(color_string), rgba);
+ if(pickfill){
+ sp_repr_css_set_property(css, "fill", color_string);
+ }
+ if(pickstroke){
+ sp_repr_css_set_property(css, "stroke", color_string);
+ }
+ }
+ if (opacity < 1e-6) { // invisibly transparent, skip
+ return false;
+ }
+ }
+ if(!trace){
+ sp_svg_write_color(color_string, sizeof(color_string), rgba);
+ if(pickfill){
+ sp_repr_css_set_property(css, "fill", color_string);
+ }
+ if(pickstroke){
+ sp_repr_css_set_property(css, "stroke", color_string);
+ }
+ }
+ if(!nooverlap && (picker || visible)){
+ for (std::vector<SPItem *>::const_iterator k=items_down.begin(); k!=items_down.end(); k++) {
+ SPItem *item_hidden = *k;
+ item_hidden->setHidden(false);
+ item_hidden->updateRepr();
+ }
+ }
+ }
+ return true;
+}
+
static bool sp_spray_recursive(SPDesktop *desktop,
Inkscape::Selection *selection,
SPItem *item,
@@ -348,7 +726,16 @@ static bool sp_spray_recursive(SPDesktop *desktop,
double ratio,
double tilt,
double rotation_variation,
- gint _distrib)
+ gint _distrib,
+ bool nooverlap,
+ bool picker,
+ bool pickinversevalue,
+ bool pickfill,
+ bool pickstroke,
+ bool visible,
+ double offset,
+ bool usepressurescale,
+ double pressure)
{
bool did = false;
@@ -364,6 +751,9 @@ static bool sp_spray_recursive(SPDesktop *desktop,
double _fid = g_random_double_range(0, 1);
double angle = g_random_double_range( - rotation_variation / 100.0 * M_PI , rotation_variation / 100.0 * M_PI );
double _scale = g_random_double_range( 1.0 - scale_variation / 100.0, 1.0 + scale_variation / 100.0 );
+ if(usepressurescale){
+ _scale = pressure;
+ }
double dr; double dp;
random_position( dr, dp, mean, standard_deviation, _distrib );
dr=dr*radius;
@@ -371,27 +761,44 @@ static bool sp_spray_recursive(SPDesktop *desktop,
if (mode == SPRAY_MODE_COPY) {
Geom::OptRect a = item->documentVisualBounds();
if (a) {
- SPItem *item_copied;
if(_fid <= population)
{
- // Duplicate
SPDocument *doc = item->document;
+ gchar const * spray_origin;
+ if(!item->getAttribute("inkscape:spray-origin")){
+ spray_origin = g_strdup_printf("#%s", item->getId());
+ } else {
+ spray_origin = item->getAttribute("inkscape:spray-origin");
+ }
+ Geom::Point center = item->getCenter();
+ 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());
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ if(nooverlap || picker || visible){
+ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, visible, nooverlap, offset, css, false)){
+ return false;
+ }
+ }
+ SPItem *item_copied;
+ // Duplicate
Inkscape::XML::Document* xml_doc = doc->getReprDoc();
Inkscape::XML::Node *old_repr = item->getRepr();
Inkscape::XML::Node *parent = old_repr->parent();
Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
+ if(!copy->attribute("inkscape:spray-origin")){
+ copy->setAttribute("inkscape:spray-origin", spray_origin);
+ }
parent->appendChild(copy);
-
SPObject *new_obj = doc->getObjectByRepr(copy);
item_copied = dynamic_cast<SPItem *>(new_obj); // Conversion object->item
- Geom::Point center=item->getCenter();
- sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale,_scale));
- sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale));
-
+ sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale));
+ sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale));
sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
// Move the cursor p
- 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());
sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
+ Inkscape::GC::release(copy);
+ if(picker){
+ sp_desktop_apply_css_recursive(item_copied, css, true);
+ }
did = true;
}
}
@@ -425,6 +832,13 @@ static bool sp_spray_recursive(SPDesktop *desktop,
if (_fid <= population) { // Rules the population of objects sprayed
// Duplicates the parent item
Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
+ gchar const * spray_origin;
+ if(!copy->attribute("inkscape:spray-origin")){
+ spray_origin = g_strdup_printf("#%s", old_repr->attribute("id"));
+ copy->setAttribute("inkscape:spray-origin", spray_origin);
+ } else {
+ spray_origin = copy->attribute("inkscape:spray-origin");
+ }
parent->appendChild(copy);
SPObject *new_obj = doc->getObjectByRepr(copy);
item_copied = dynamic_cast<SPItem *>(new_obj);
@@ -456,8 +870,22 @@ static bool sp_spray_recursive(SPDesktop *desktop,
Geom::OptRect a = item->documentVisualBounds();
if (a) {
if(_fid <= population) {
- SPItem *item_copied;
SPDocument *doc = item->document;
+ gchar const * spray_origin;
+ if(!item->getAttribute("inkscape:spray-origin")){
+ spray_origin = g_strdup_printf("#%s", item->getId());
+ } else {
+ spray_origin = item->getAttribute("inkscape:spray-origin");
+ }
+ Geom::Point center=item->getCenter();
+ 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());
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ if(nooverlap || picker || visible){
+ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, visible, nooverlap, offset, css, false)){
+ return false;
+ }
+ }
+ SPItem *item_copied;
Inkscape::XML::Document* xml_doc = doc->getReprDoc();
Inkscape::XML::Node *old_repr = item->getRepr();
Inkscape::XML::Node *parent = old_repr->parent();
@@ -467,6 +895,9 @@ static bool sp_spray_recursive(SPDesktop *desktop,
// Ad the clone to the list of the parent's children
parent->appendChild(clone);
// Generates the link between parent and child attributes
+ if(!clone->attribute("inkscape:spray-origin")){
+ clone->setAttribute("inkscape:spray-origin", spray_origin);
+ }
gchar *href_str = g_strdup_printf("#%s", old_repr->attribute("id"));
clone->setAttribute("xlink:href", href_str, false);
g_free(href_str);
@@ -474,15 +905,14 @@ static bool sp_spray_recursive(SPDesktop *desktop,
SPObject *clone_object = doc->getObjectByRepr(clone);
// Conversion object->item
item_copied = dynamic_cast<SPItem *>(clone_object);
- Geom::Point center = item->getCenter();
sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale));
sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale));
sp_spray_rotate_rel(center, desktop, item_copied, Geom::Rotate(angle));
- 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());
sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
-
+ if(picker){
+ sp_desktop_apply_css_recursive(item_copied, css, true);
+ }
Inkscape::GC::release(clone);
-
did = true;
}
}
@@ -529,8 +959,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point
for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
SPItem *item = *i;
g_assert(item != NULL);
-
- 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)) {
+ 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))) {
did = true;
}
}
diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h
index 8df730201..ca0c20375 100644
--- a/src/ui/tools/spray-tool.h
+++ b/src/ui/tools/spray-tool.h
@@ -12,6 +12,7 @@
* BenoƮt LAVORATA
* Vincent MONTAGNE
* Pierre BARBRY-BLOT
+ * Jabiertxo ARRAIZA
*
* Copyright (C) 2009 authors
*
@@ -62,7 +63,9 @@ public:
/* attributes */
bool dragging; /* mouse state: mouse is dragging */
- bool usepressure;
+ bool usepressurewidth;
+ bool usepressurepopulation;
+ bool usepressurescale;
bool usetilt;
bool usetext;
@@ -86,7 +89,13 @@ public:
bool has_dilated;
Geom::Point last_push;
SPCanvasItem *dilate_area;
-
+ bool nooverlap;
+ bool picker;
+ bool pickinversevalue;
+ bool pickfill;
+ bool pickstroke;
+ bool visible;
+ double offset;
sigc::connection style_set_connection;
static const std::string prefsPath;
diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp
index 183814b7e..5e0d81964 100644
--- a/src/widgets/spray-toolbar.cpp
+++ b/src/widgets/spray-toolbar.cpp
@@ -15,10 +15,11 @@
* Tavmjong Bah <tavmjong@free.fr>
* Abhishek Sharma
* Kris De Gussem <Kris.DeGussem@gmail.com>
+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
*
* Copyright (C) 2004 David Turner
* Copyright (C) 2003 MenTaLguY
- * Copyright (C) 1999-2011 authors
+ * Copyright (C) 1999-2015 authors
* Copyright (C) 2001-2002 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
@@ -28,18 +29,24 @@
# include "config.h"
#endif
-#include <glibmm/i18n.h>
+#include <gtkmm.h>
#include "spray-toolbar.h"
#include "desktop.h"
+#include "inkscape.h"
#include "document-undo.h"
#include "widgets/ege-adjustment-action.h"
#include "widgets/ege-select-one-action.h"
#include "widgets/ink-action.h"
#include "preferences.h"
#include "toolbox.h"
+#include "ui/dialog/clonetiler.h"
+#include "ui/dialog/dialog-manager.h"
+#include "ui/dialog/panel-dialog.h"
#include "ui/icon-names.h"
+#include <glibmm/i18n.h>
+
using Inkscape::DocumentUndo;
using Inkscape::UI::ToolboxFactory;
using Inkscape::UI::PrefPusher;
@@ -53,6 +60,55 @@ using Inkscape::UI::PrefPusher;
//## Spray ##
//########################
+static void sp_stb_sensitivize( GObject *tbl )
+{
+ GtkAction* offset = GTK_ACTION( g_object_get_data(tbl, "offset") );
+ GtkAction* spray_scale = GTK_ACTION( g_object_get_data(tbl, "spray_scale") );
+ GtkAdjustment *adj_offset = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(offset) );
+ GtkAdjustment *adj_scale = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(spray_scale) );
+ GtkToggleAction *nooverlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "nooverlap") );
+ GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") );
+ GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") );
+ GtkAction *pickfill = GTK_ACTION( g_object_get_data(tbl, "pickfill") );
+ GtkAction *pickstroke = GTK_ACTION( g_object_get_data(tbl, "pickstroke") );
+ GtkAction *pickinversevalue = GTK_ACTION( g_object_get_data(tbl, "pickinversevalue") );
+ gtk_adjustment_set_value( adj_offset, 100.0 );
+ if (gtk_toggle_action_get_active(nooverlap)) {
+ gtk_action_set_sensitive( offset, TRUE );
+ } else {
+ gtk_action_set_sensitive( offset, FALSE );
+ }
+ if (gtk_toggle_action_get_active(usepressurescale)) {
+ gtk_adjustment_set_value( adj_scale, 0.0 );
+ gtk_action_set_sensitive( spray_scale, FALSE );
+ } else {
+ gtk_action_set_sensitive( spray_scale, TRUE );
+ }
+ if(gtk_toggle_action_get_active(picker)){
+ gtk_action_set_sensitive( pickfill, TRUE );
+ gtk_action_set_sensitive( pickstroke, TRUE );
+ gtk_action_set_sensitive( pickinversevalue, TRUE );
+ } else {
+ gtk_action_set_sensitive( pickfill, FALSE );
+ gtk_action_set_sensitive( pickstroke, FALSE );
+ gtk_action_set_sensitive( pickinversevalue, FALSE );
+ }
+}
+
+Inkscape::UI::Dialog::CloneTiler *get_clone_tiler_panel(SPDesktop *desktop)
+{
+ if (Inkscape::UI::Dialog::PanelDialogBase *panel_dialog =
+ dynamic_cast<Inkscape::UI::Dialog::PanelDialogBase *>(desktop->_dlg_mgr->getDialog("CloneTiler"))) {
+ try {
+ Inkscape::UI::Dialog::CloneTiler &clone_tiler =
+ dynamic_cast<Inkscape::UI::Dialog::CloneTiler &>(panel_dialog->getPanel());
+ return &clone_tiler;
+ } catch (std::exception &e) { }
+ }
+
+ return 0;
+}
+
static void sp_spray_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ )
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -102,12 +158,83 @@ static void sp_spray_scale_value_changed( GtkAdjustment *adj, GObject * /*tbl*/
gtk_adjustment_get_value(adj));
}
+static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ )
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble( "/tools/spray/offset",
+ gtk_adjustment_get_value(adj));
+}
+
+static void sp_toggle_nooverlap( GtkToggleAction* act, gpointer data)
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gboolean active = gtk_toggle_action_get_active(act);
+ prefs->setBool("/tools/spray/nooverlap", active);
+ GObject *tbl = G_OBJECT(data);
+ sp_stb_sensitivize(tbl);
+}
+
+static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data)
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gboolean active = gtk_toggle_action_get_active(act);
+ prefs->setBool("/tools/spray/usepressurescale", active);
+ if(active == true){
+ prefs->setDouble("/tools/spray/scale_variation", 0);
+ }
+ GObject *tbl = G_OBJECT(data);
+ sp_stb_sensitivize( tbl );
+}
+
+static void sp_toggle_visible( GtkToggleAction* act, gpointer data)
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gboolean active = gtk_toggle_action_get_active(act);
+ prefs->setBool("/tools/spray/visible", active);
+}
+
+static void sp_toggle_picker( GtkToggleAction* act, gpointer data )
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gboolean active = gtk_toggle_action_get_active(act);
+ prefs->setBool("/tools/spray/picker", active);
+ if(active == true){
+ prefs->setBool("/dialogs/clonetiler/dotrace", true);
+ SPDesktop *dt = SP_ACTIVE_DESKTOP;
+ if (Inkscape::UI::Dialog::CloneTiler *ct = get_clone_tiler_panel(dt)){
+ dt->_dlg_mgr->showDialog("CloneTiler");
+ ct->show_page_trace();
+ }
+ }
+ GObject *tbl = G_OBJECT(data);
+ sp_stb_sensitivize(tbl);
+}
+
+static void sp_toggle_pick_fill( GtkToggleAction* act, gpointer data )
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gboolean active = gtk_toggle_action_get_active(act);
+ prefs->setBool("/tools/spray/pickfill", active);
+}
+
+static void sp_toggle_pick_inverse_value( GtkToggleAction* act, gpointer data )
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gboolean active = gtk_toggle_action_get_active(act);
+ prefs->setBool("/tools/spray/pickinversevalue", active);
+}
+
+static void sp_toggle_pick_stroke( GtkToggleAction* act, gpointer data )
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gboolean active = gtk_toggle_action_get_active(act);
+ prefs->setBool("/tools/spray/pickstroke", active);
+}
void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1);
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-
{
/* Width */
gchar const* labels[] = {_("(narrow spray)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad spray)")};
@@ -123,7 +250,20 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
}
+
+ /* Use Pressure Width button */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "SprayPressureWidthAction",
+ _("Pressure"),
+ _("Use the pressure of the input device to alter the width of spray area"),
+ INKSCAPE_ICON("draw-use-pressure"),
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressurewidth");
+ g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher);
+ }
+
{
/* Mean */
gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(maximum mean)")};
@@ -218,15 +358,15 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
g_object_set_data( holder, "spray_population", eact );
}
- /* Use Pressure button */
+ /* Use Pressure Population button */
{
- InkToggleAction* act = ink_toggle_action_new( "SprayPressureAction",
+ InkToggleAction* act = ink_toggle_action_new( "SprayPressurePopulationAction",
_("Pressure"),
_("Use the pressure of the input device to alter the amount of sprayed objects"),
INKSCAPE_ICON("draw-use-pressure"),
Inkscape::ICON_SIZE_DECORATION );
gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
- PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressure");
+ PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressurepopulation");
g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher);
}
@@ -267,8 +407,112 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
g_object_set_data( holder, "spray_scale", eact );
}
+ /* Use Pressure Scale button */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "SprayPressureScaleAction",
+ _("Pressure"),
+ _("Use the pressure of the input device to alter the scale of new items"),
+ INKSCAPE_ICON("draw-use-pressure"),
+ Inkscape::ICON_SIZE_DECORATION);
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/usepressurescale", false) );
+ g_object_set_data( holder, "usepressurescale", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pressure_scale), holder) ;
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ }
+
+ /* Picker */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction",
+ _("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."),
+ _("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."),
+ INKSCAPE_ICON("color-picker"),
+ secondarySize );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) );
+ g_object_set_data( holder, "picker", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_picker), holder) ;
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ }
+ /* Inverse Value Size */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "SprayOverPickInverseValueAction",
+ _("Inversed pick value retaining color"),
+ _("Inversed pick value retaining color"),
+ INKSCAPE_ICON("object-tweak-shrink"),
+ secondarySize );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickinversevalue", false) );
+ g_object_set_data( holder, "pickinversevalue", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_inverse_value), holder) ;
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ }
+
+ /* Pick Fill */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "SprayOverPickFillAction",
+ _("Apply picked color to fill"),
+ _("Apply picked color to fill"),
+ INKSCAPE_ICON("paint-solid"),
+ secondarySize );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickfill", false) );
+ g_object_set_data( holder, "pickfill", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_fill), holder) ;
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ }
+
+ /* Pick Stroke */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "SprayOverPickStrokeAction",
+ _("Apply picked color to stroke"),
+ _("Apply picked color to stroke"),
+ INKSCAPE_ICON("no-marker"),
+ secondarySize );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickstroke", false) );
+ g_object_set_data( holder, "pickstroke", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_stroke), holder) ;
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ }
+
+ /* Visible */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "SprayOverVisibleAction",
+ _("Apply only over non transparent areas"),
+ _("Apply only over non transparent areas"),
+ INKSCAPE_ICON("object-visible"),
+ secondarySize );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/visible", false) );
+ g_object_set_data( holder, "visible", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_visible), holder) ;
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ }
+
+ /* Overlap */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "SprayNoOverlapAction",
+ _("Prevent overlapping objects"),
+ _("Prevent overlapping objects"),
+ INKSCAPE_ICON("distribute-randomize"),
+ secondarySize );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/nooverlap", false) );
+ g_object_set_data( holder, "nooverlap", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_nooverlap), holder) ;
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ }
+
+ /* Offset */
+ {
+ EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction",
+ _("Offset %"), _("Offset %:"),
+ _("Increase to segregate objects more (value in percent)"),
+ "/tools/spray/offset", 100,
+ GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
+ 0, 10000, 1, 4,
+ 0, 0, 0,
+ sp_spray_offset_value_changed, NULL, 0 , 0);
+ g_object_set_data( holder, "offset", eact );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ }
+ sp_stb_sensitivize(holder);
}
diff --git a/src/widgets/spray-toolbar.h b/src/widgets/spray-toolbar.h
index d1d5c7b4c..30d8233ca 100644
--- a/src/widgets/spray-toolbar.h
+++ b/src/widgets/spray-toolbar.h
@@ -21,7 +21,7 @@
*
* Copyright (C) 2004 David Turner
* Copyright (C) 2003 MenTaLguY
- * Copyright (C) 1999-2011 authors
+ * Copyright (C) 1999-2015 authors
* Copyright (C) 2001-2002 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index 90103325a..cdb9e0d20 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -16,10 +16,11 @@
* Tavmjong Bah <tavmjong@free.fr>
* Abhishek Sharma
* Kris De Gussem <Kris.DeGussem@gmail.com>
+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
*
* Copyright (C) 2004 David Turner
* Copyright (C) 2003 MenTaLguY
- * Copyright (C) 1999-2011 authors
+ * Copyright (C) 1999-2015 authors
* Copyright (C) 2001-2002 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
@@ -309,14 +310,26 @@ static gchar const * ui_descr =
" <toolitem action='SprayModeAction' />"
" <separator />"
" <toolitem action='SprayWidthAction' />"
+ " <toolitem action='SprayPressureWidthAction' />"
" <toolitem action='SprayPopulationAction' />"
- " <toolitem action='SprayPressureAction' />"
+ " <toolitem action='SprayPressurePopulationAction' />"
" <separator />"
" <toolitem action='SprayRotationAction' />"
" <toolitem action='SprayScaleAction' />"
+ " <toolitem action='SprayPressureScaleAction' />"
" <separator />"
" <toolitem action='SprayStandard_deviationAction' />"
" <toolitem action='SprayMeanAction' />"
+ " <separator />"
+ " <toolitem action='SprayOverVisibleAction' />"
+ " <toolitem action='SprayNoOverlapAction' />"
+ " <toolitem action='SprayToolOffsetAction' />"
+ " <separator />"
+ " <toolitem action='SprayPickColorAction' />"
+ " <toolitem action='SprayOverPickInverseValueAction' />"
+ " <toolitem action='SprayOverPickFillAction' />"
+ " <toolitem action='SprayOverPickStrokeAction' />"
+
" </toolbar>"
" <toolbar name='ZoomToolbar'>"