summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2016-02-13 01:41:52 +0000
committerjabiertxof <info@marker.es>2016-02-13 01:41:52 +0000
commit710d4b83c310bd2fe9958aa22a9938b7ddb022a7 (patch)
treea68bdf637f98473ef955fb1c4c17d29c5b05032a /src
parentif viewbox does not exist, create it from page size, only if page size exists... (diff)
downloadinkscape-710d4b83c310bd2fe9958aa22a9938b7ddb022a7.tar.gz
inkscape-710d4b83c310bd2fe9958aa22a9938b7ddb022a7.zip
Improved eraser tool, now working on documents not pixels and with 0 width
(bzr r14648.1.1)
Diffstat (limited to 'src')
-rw-r--r--src/splivarot.cpp7
-rw-r--r--src/splivarot.h1
-rw-r--r--src/ui/tools/eraser-tool.cpp159
-rw-r--r--src/ui/tools/eraser-tool.h1
-rw-r--r--src/widgets/eraser-toolbar.cpp6
5 files changed, 92 insertions, 82 deletions
diff --git a/src/splivarot.cpp b/src/splivarot.cpp
index 9b2890bb8..461445ee0 100644
--- a/src/splivarot.cpp
+++ b/src/splivarot.cpp
@@ -105,6 +105,13 @@ sp_selected_path_cut(Inkscape::Selection *selection, SPDesktop *desktop)
{
sp_selected_path_boolop(selection, desktop, bool_op_cut, SP_VERB_SELECTION_CUT, _("Division"));
}
+
+void
+sp_selected_path_cut_skip_undo(Inkscape::Selection *selection, SPDesktop *desktop)
+{
+ sp_selected_path_boolop(selection, desktop, bool_op_cut, SP_VERB_NONE, _("Division"));
+}
+
void
sp_selected_path_slice(Inkscape::Selection *selection, SPDesktop *desktop)
{
diff --git a/src/splivarot.h b/src/splivarot.h
index ba314399f..421c9c4b8 100644
--- a/src/splivarot.h
+++ b/src/splivarot.h
@@ -33,6 +33,7 @@ void sp_selected_path_diff (Inkscape::Selection *selection, SPDesktop *desktop);
void sp_selected_path_diff_skip_undo (Inkscape::Selection *selection, SPDesktop *desktop);
void sp_selected_path_symdiff (Inkscape::Selection *selection, SPDesktop *desktop);
void sp_selected_path_cut (Inkscape::Selection *selection, SPDesktop *desktop);
+void sp_selected_path_cut_skip_undo (Inkscape::Selection *selection, SPDesktop *desktop);
void sp_selected_path_slice (Inkscape::Selection *selection, SPDesktop *desktop);
// offset/inset of a curve
diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp
index 83ecf7a0a..51068a3ae 100644
--- a/src/ui/tools/eraser-tool.cpp
+++ b/src/ui/tools/eraser-tool.cpp
@@ -96,6 +96,7 @@ const std::string EraserTool::prefsPath = "/tools/eraser";
EraserTool::EraserTool()
: DynamicBase(cursor_eraser_xpm, 4, 4)
+ , nowidth(false)
{
}
@@ -145,6 +146,7 @@ static ProfileFloatElement f_profile[PROFILE_FLOAT_SIZE] = {
sp_event_context_read(this, "cap_rounding");
this->is_drawing = false;
+ //TODO not sure why get 0.01 if slider width == 0, maybe a double/int problem
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (prefs->getBool("/tools/eraser/selcue", 0) != 0) {
@@ -339,7 +341,10 @@ void EraserTool::brush() {
this->point1[this->npoints] = brush + del_left;
this->point2[this->npoints] = brush - del_right;
-
+
+ if (this->nowidth) {
+ this->point1[this->npoints] = Geom::middle_point(this->point1[this->npoints],this->point2[this->npoints]);
+ }
this->del = 0.5*(del_left + del_right);
this->npoints++;
@@ -489,33 +494,32 @@ bool EraserTool::root_handler(GdkEvent* event) {
case GDK_KEY_PRESS:
switch (get_group0_keyval (&event->key)) {
- case GDK_KEY_Up:
- case GDK_KEY_KP_Up:
- if (!MOD__CTRL_ONLY(event)) {
- this->angle += 5.0;
-
- if (this->angle > 90.0) {
- this->angle = 90.0;
- }
-
- sp_erc_update_toolbox (desktop, "eraser-angle", this->angle);
- ret = TRUE;
- }
- break;
-
- case GDK_KEY_Down:
- case GDK_KEY_KP_Down:
- if (!MOD__CTRL_ONLY(event)) {
- this->angle -= 5.0;
-
- if (this->angle < -90.0) {
- this->angle = -90.0;
- }
-
- sp_erc_update_toolbox (desktop, "eraser-angle", this->angle);
- ret = TRUE;
- }
- break;
+// case GDK_KEY_Up:
+// case GDK_KEY_KP_Up:
+// if (!MOD__CTRL_ONLY(event)) {
+// this->angle += 5.0;
+
+// if (this->angle > 90.0) {
+// this->angle = 90.0;
+// }
+// sp_erc_update_toolbox (desktop, "eraser-angle", this->angle);
+// ret = TRUE;
+// }
+// break;
+
+// case GDK_KEY_Down:
+// case GDK_KEY_KP_Down:
+// if (!MOD__CTRL_ONLY(event)) {
+// this->angle -= 5.0;
+
+// if (this->angle < -90.0) {
+// this->angle = -90.0;
+// }
+
+// sp_erc_update_toolbox (desktop, "eraser-angle", this->angle);
+// ret = TRUE;
+// }
+// break;
case GDK_KEY_Right:
case GDK_KEY_KP_Right:
@@ -640,20 +644,16 @@ void EraserTool::set_to_accumulated() {
sp_desktop_apply_style_tool (desktop, repr, "/tools/eraser", false);
this->repr = repr;
-
- SPItem *item=SP_ITEM(desktop->currentLayer()->appendChildRepr(this->repr));
- Inkscape::GC::release(this->repr);
-
- item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
- item->updateRepr();
}
-
+ SPItem *item=SP_ITEM(desktop->currentLayer()->appendChildRepr(this->repr));
+ Inkscape::GC::release(this->repr);
+ item->updateRepr();
Geom::PathVector pathv = this->accumulated->get_pathvector() * desktop->dt2doc();
+ pathv *= item->i2doc_affine().inverse();
gchar *str = sp_svg_write_path(pathv);
g_assert( str != NULL );
this->repr->setAttribute("d", str);
g_free(str);
-
if ( this->repr ) {
bool wasSelection = false;
Inkscape::Selection *selection = desktop->getSelection();
@@ -663,13 +663,12 @@ void EraserTool::set_to_accumulated() {
Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
SPItem* acid = SP_ITEM(desktop->doc()->getObjectByRepr(this->repr));
- Geom::OptRect eraserBbox = acid->visualBounds();
- Geom::Rect bounds = (*eraserBbox) * desktop->doc2dt();
+ Geom::OptRect eraserBbox = acid->desktopVisualBounds();
std::vector<SPItem*> remainingItems;
std::vector<SPItem*> toWorkOn;
if (selection->isEmpty()) {
if ( eraserMode ) {
- toWorkOn = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, bounds);
+ toWorkOn = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *eraserBbox);
} else {
Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop);
toWorkOn = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints());
@@ -684,30 +683,30 @@ void EraserTool::set_to_accumulated() {
if ( eraserMode ) {
for (std::vector<SPItem*>::const_iterator i = toWorkOn.begin(); i != toWorkOn.end(); ++i){
SPItem *item = *i;
-
- if ( eraserMode ) {
- Geom::OptRect bbox = item->visualBounds();
-
- if (bbox && bbox->intersects(*eraserBbox)) {
- Inkscape::XML::Node* dup = this->repr->duplicate(xml_doc);
- this->repr->parent()->appendChild(dup);
- Inkscape::GC::release(dup); // parent takes over
-
- selection->set(item);
- selection->add(dup);
+ Geom::OptRect bbox = item->desktopVisualBounds();
+ if (bbox && bbox->intersects(*eraserBbox)) {
+ Inkscape::XML::Node* dup = this->repr->duplicate(xml_doc);
+ this->repr->parent()->appendChild(dup);
+ Inkscape::GC::release(dup); // parent takes over
+
+ selection->set(item);
+ selection->add(dup);
+ if (this->nowidth) {
+ sp_selected_path_cut_skip_undo(selection, desktop);
+ } else {
sp_selected_path_diff_skip_undo(selection, desktop);
- workDone = true; // TODO set this only if something was cut.
-
- if ( !selection->isEmpty() ) {
- // If the item was not completely erased, track the new remainder.
- std::vector<SPItem*> nowSel(selection->itemList());
- for (std::vector<SPItem*>::const_iterator i2 = nowSel.begin();i2!=nowSel.end();++i2) {
- remainingItems.push_back(*i2);
- }
+ }
+ workDone = true; // TODO set this only if something was cut.
+
+ if ( !selection->isEmpty() ) {
+ // If the item was not completely erased, track the new remainder.
+ std::vector<SPItem*> nowSel(selection->itemList());
+ for (std::vector<SPItem*>::const_iterator i2 = nowSel.begin();i2!=nowSel.end();++i2) {
+ remainingItems.push_back(*i2);
}
- } else {
- remainingItems.push_back(item);
}
+ } else {
+ remainingItems.push_back(item);
}
}
} else {
@@ -811,24 +810,25 @@ void EraserTool::accumulate() {
g_assert( rev_cal2_lastseg );
this->accumulated->append(this->cal1, FALSE);
-
- add_cap(this->accumulated,
- dc_cal1_lastseg->finalPoint() - dc_cal1_lastseg->unitTangentAt(1),
- dc_cal1_lastseg->finalPoint(),
- rev_cal2_firstseg->initialPoint(),
- rev_cal2_firstseg->initialPoint() + rev_cal2_firstseg->unitTangentAt(0),
- this->cap_rounding);
-
- this->accumulated->append(rev_cal2, TRUE);
-
- add_cap(this->accumulated,
- rev_cal2_lastseg->finalPoint() - rev_cal2_lastseg->unitTangentAt(1),
- rev_cal2_lastseg->finalPoint(),
- dc_cal1_firstseg->initialPoint(),
- dc_cal1_firstseg->initialPoint() + dc_cal1_firstseg->unitTangentAt(0),
- this->cap_rounding);
-
- this->accumulated->closepath();
+ if(!this->nowidth) {
+ add_cap(this->accumulated,
+ dc_cal1_lastseg->finalPoint() - dc_cal1_lastseg->unitTangentAt(1),
+ dc_cal1_lastseg->finalPoint(),
+ rev_cal2_firstseg->initialPoint(),
+ rev_cal2_firstseg->initialPoint() + rev_cal2_firstseg->unitTangentAt(0),
+ this->cap_rounding);
+
+ this->accumulated->append(rev_cal2, TRUE);
+
+ add_cap(this->accumulated,
+ rev_cal2_lastseg->finalPoint() - rev_cal2_lastseg->unitTangentAt(1),
+ rev_cal2_lastseg->finalPoint(),
+ dc_cal1_firstseg->initialPoint(),
+ dc_cal1_firstseg->initialPoint() + dc_cal1_firstseg->unitTangentAt(0),
+ this->cap_rounding);
+
+ this->accumulated->closepath();
+ }
rev_cal2->unref();
@@ -844,6 +844,8 @@ static double square(double const x)
void EraserTool::fit_and_split(bool release) {
double const tolerance_sq = square( desktop->w2d().descrim() * TOLERANCE_ERASER );
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ this->nowidth = prefs->getDouble( "/tools/eraser/width", 1) == 0;
#ifdef ERASER_VERBOSE
g_print("[F&S:R=%c]", release?'T':'F');
@@ -940,7 +942,6 @@ void EraserTool::fit_and_split(bool release) {
g_print("[%d]Yup\n", this->npoints);
#endif
if (!release) {
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0;
g_assert(!this->currentcurve->is_empty());
diff --git a/src/ui/tools/eraser-tool.h b/src/ui/tools/eraser-tool.h
index 110f57ba3..50ce6b6e3 100644
--- a/src/ui/tools/eraser-tool.h
+++ b/src/ui/tools/eraser-tool.h
@@ -58,6 +58,7 @@ private:
void accumulate();
void fit_and_split(bool release);
void draw_temporary_box();
+ bool nowidth;
};
}
diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp
index 1f79b50f2..f18a805b2 100644
--- a/src/widgets/eraser-toolbar.cpp
+++ b/src/widgets/eraser-toolbar.cpp
@@ -122,14 +122,14 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb
{
/* Width */
- gchar const* labels[] = {_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")};
- gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100};
+ gchar const* labels[] = {_("(no width)"),_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")};
+ gdouble values[] = {0, 1, 3, 5, 10, 15, 20, 30, 50, 75, 100};
EgeAdjustmentAction *eact = create_adjustment_action( "EraserWidthAction",
_("Pen Width"), _("Width:"),
_("The width of the eraser pen (relative to the visible canvas area)"),
"/tools/eraser/width", 15,
GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-eraser",
- 1, 100, 1.0, 10.0,
+ 0, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
sp_erc_width_value_changed, NULL /*unit tracker*/, 1, 0);
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );