summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-10-27 19:10:06 +0000
committerjabiertxof <jabier.arraiza@marker.es>2015-10-27 19:10:06 +0000
commitb0de24888aea4410596e237f947a201b349b0097 (patch)
tree9b0e11063b9d255d44deaccdcb8897ea06b272a1 /src
parentFixed some typos pointed by Mc (diff)
downloadinkscape-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.cpp78
-rw-r--r--src/widgets/spray-toolbar.cpp70
-rw-r--r--src/widgets/toolbox.cpp2
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>"