diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2015-10-27 19:10:06 +0000 |
|---|---|---|
| committer | jabiertxof <jabier.arraiza@marker.es> | 2015-10-27 19:10:06 +0000 |
| commit | b0de24888aea4410596e237f947a201b349b0097 (patch) | |
| tree | 9b0e11063b9d255d44deaccdcb8897ea06b272a1 /src | |
| parent | Fixed some typos pointed by Mc (diff) | |
| download | inkscape-b0de24888aea4410596e237f947a201b349b0097.tar.gz inkscape-b0de24888aea4410596e237f947a201b349b0097.zip | |
Now the picker work with alphas and also in no overlap mode
Offset dropdown disabled if no overlap
Changed offset to percent based
(bzr r14422.1.18)
Diffstat (limited to 'src')
| -rw-r--r-- | src/ui/tools/spray-tool.cpp | 78 | ||||
| -rw-r--r-- | src/widgets/spray-toolbar.cpp | 70 | ||||
| -rw-r--r-- | src/widgets/toolbox.cpp | 2 |
3 files changed, 102 insertions, 48 deletions
diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index bacb1105c..25e9dbd73 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -378,13 +378,19 @@ static bool fit_item(SPDesktop *desktop, double _scale, double scale, bool picker, + bool overlap, double offset, SPCSSAttr *css) { - if(offset < 0){ - offset = std::min(std::min(std::abs(offset), bbox->width()/2.0),std::min(std::abs(offset), bbox->height()/2.0)) * -1; + 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; } - bbox = Geom::Rect(Geom::Point(bbox->left() - offset, bbox->top() - offset),Geom::Point(bbox->right() + offset, bbox->bottom() + offset)); + bbox = 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->left(), bbox->top())); path.appendNew<Geom::LineSegment>(Geom::Point(bbox->right(), bbox->top())); @@ -397,6 +403,16 @@ static bool fit_item(SPDesktop *desktop, path *= Geom::Translate(move[Geom::X], move[Geom::Y]); path *= desktop->doc2dt(); bbox = path.boundsFast(); + double bbox_left_main = bbox->left(); + double bbox_top_main = bbox->top(); + double width_transformed = bbox->width(); + double height_transformed = bbox->height(); + 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); Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { @@ -405,6 +421,11 @@ static bool fit_item(SPDesktop *desktop, 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; @@ -415,27 +436,56 @@ static bool fit_item(SPDesktop *desktop, 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 )) + (item_down->getAttribute("inkscape:spray-origin") && + strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) { - return false; + if(overlap){ + 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){ + item_down->setHidden(true); + item_down->updateRepr(); + } } } } if(picker){ - Geom::IntRect area = Geom::IntRect::from_xywh(floor(desktop->d2w(bbox->midpoint())[Geom::X]), floor(desktop->d2w(bbox->midpoint())[Geom::Y]), 1, 1); + if(!overlap){ + doc->ensureUpToDate(); + } + Geom::Point mid_point = bbox->midpoint(); + Geom::IntRect area = Geom::IntRect::from_xywh(floor(desktop->d2w(mid_point)[Geom::X]), floor(desktop->d2w(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_premul(s, R, G, B, A); cairo_surface_destroy(s); + if (fabs(A) < 1e-4) { + A = 0; // suppress exponentials, CSS does not allow that + } + if (A > 0) { + R /= A; + G /= A; + B /= A; + } guint32 c32 = SP_RGBA32_F_COMPOSE(R, G, B, A); gchar c[64]; sp_svg_write_color(c, sizeof(c), c32); sp_repr_css_set_property(css, "fill", c); - gchar const * fill_opacity = g_strdup_printf("%f", A); - sp_repr_css_set_property(css, "fill-opacity", fill_opacity); - if(R == 1 && G == 1 && B == 1 && A == 0){ + std::stringstream fill_opacity; + fill_opacity.imbue(std::locale::classic()); + fill_opacity << float(A); + sp_repr_css_set_property(css, "fill-opacity", fill_opacity.str().c_str()); + if(!overlap){ + 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(); + } + } + if(A == 0){ return false; } } @@ -497,8 +547,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, offset, css)){ + if(overlap || picker){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, overlap, offset, css)){ limit += 1; //Limit recursion to 10 levels //Seems enough to chech if there is place to put new copie @@ -631,8 +681,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, offset, css)){ + if(overlap || picker){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, overlap, offset, css)){ limit += 1; if(limit < 11){ return sp_spray_recursive(desktop, diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 57b582903..9f7a7cb1d 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -54,6 +54,17 @@ using Inkscape::UI::PrefPusher; //## Spray ## //######################## +static void sp_stb_sensitivize( GObject *tbl ) +{ + GtkAction* offset = GTK_ACTION( g_object_get_data(tbl, "offset") ); + GtkToggleAction *overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "overlap") ); + if (gtk_toggle_action_get_active(overlap)) { + gtk_action_set_sensitive( offset, TRUE ); + } else { + gtk_action_set_sensitive( offset, FALSE ); + } +} + static void sp_spray_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -110,11 +121,14 @@ static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ gtk_adjustment_get_value(adj)); } -static void sp_toggle_not_overlap( GtkToggleAction* act, gpointer data ) +static void sp_toggle_not_overlap( GtkToggleAction* act, gpointer data) { + + GObject *tbl = G_OBJECT(data); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); prefs->setBool("/tools/spray/overlap", active); + sp_stb_sensitivize(tbl); } static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) @@ -128,9 +142,6 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj { Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool overlap = prefs->getBool("/tools/spray/overlap", false); - { /* Width */ gchar const* labels[] = {_("(narrow spray)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad spray)")}; @@ -290,18 +301,6 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_object_set_data( holder, "spray_scale", eact ); } - /* Overlap */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", - _("Prevent overlapping objects"), - _("Prevent overlapping objects"), - INKSCAPE_ICON("distribute-randomize"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overlap", false) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_not_overlap), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* Picker */ { InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", @@ -310,35 +309,40 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj 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), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } - //if ( offset ) { - // gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - //} else { - // gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - //} + /* Overlap */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", + _("Prevent overlapping objects"), + _("Prevent overlapping objects"), + INKSCAPE_ICON("distribute-randomize"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overlap", false) ); + g_object_set_data( holder, "overlap", act ); + //g_object_set_data (context_object, "holder", holder); + //g_object_set_data (context_object, "desktop", desktop); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_not_overlap), 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 px)"), - "/tools/spray/offset", 0.0, + _("Offset precent"), _("Offset percent:"), + _("Increase to segregate objects more (value in percent)"), + "/tools/spray/offset", 100, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - -1000.0, 1000.0, 1.0, 4.0, + 0, 10000, 1, 4, 0, 0, 0, - sp_spray_offset_value_changed, NULL, 0 , 2); + sp_spray_offset_value_changed, NULL, 0 , 0); + g_object_set_data( holder, "offset", eact ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - - //if ( offset ) { - // gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - //} else { - // gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - //} } - + sp_stb_sensitivize(holder); } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 57f804d99..f4bc367d0 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -319,8 +319,8 @@ static gchar const * ui_descr = " <toolitem action='SprayStandard_deviationAction' />" " <toolitem action='SprayMeanAction' />" " <separator />" - " <toolitem action='SprayNotOverlapAction' />" " <toolitem action='SprayPickColorAction' />" + " <toolitem action='SprayNotOverlapAction' />" " <toolitem action='SprayToolOffsetAction' />" " </toolbar>" |
