diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2016-03-01 01:39:05 +0000 |
|---|---|---|
| committer | jabiertxof <info@marker.es> | 2016-03-01 01:39:05 +0000 |
| commit | 5234acfed2a47dc2445475ec7a9e245f0f8dc729 (patch) | |
| tree | a501b1be76ed3cf492f50d0031c313d18227999a /src | |
| parent | Improved eraser tool, now working on documents not pixels and with 0 width (diff) | |
| download | inkscape-5234acfed2a47dc2445475ec7a9e245f0f8dc729.tar.gz inkscape-5234acfed2a47dc2445475ec7a9e245f0f8dc729.zip | |
Improve fill rule and add mass option
(bzr r14648.1.2)
Diffstat (limited to 'src')
| -rw-r--r-- | src/ui/tools/eraser-tool.cpp | 62 | ||||
| -rw-r--r-- | src/widgets/eraser-toolbar.cpp | 69 | ||||
| -rw-r--r-- | src/widgets/toolbox.cpp | 3 |
3 files changed, 111 insertions, 23 deletions
diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index 51068a3ae..698415480 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -64,8 +64,11 @@ #include "livarot/Shape.h" #include "document-undo.h" #include "verbs.h" +#include "style.h" +#include "style-enums.h" #include <2geom/math-utils.h> #include <2geom/pathvector.h> +#include "path-chemistry.h" #include "display/curve.h" #include "ui/tools/eraser-tool.h" @@ -376,7 +379,8 @@ void EraserTool::cancel() { bool EraserTool::root_handler(GdkEvent* event) { gint ret = FALSE; - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; switch (event->type) { case GDK_BUTTON_PRESS: if (event->button.button == 1 && !this->space_panning) { @@ -396,10 +400,10 @@ bool EraserTool::root_handler(GdkEvent* event) { if (this->repr) { this->repr = NULL; } - - Inkscape::Rubberband::get(desktop)->start(desktop, button_dt); - Inkscape::Rubberband::get(desktop)->setMode(RUBBERBAND_MODE_TOUCHPATH); - + if ( ! eraserMode ) { + Inkscape::Rubberband::get(desktop)->start(desktop, button_dt); + Inkscape::Rubberband::get(desktop)->setMode(RUBBERBAND_MODE_TOUCHPATH); + } /* initialize first point */ this->npoints = 0; @@ -444,8 +448,9 @@ bool EraserTool::root_handler(GdkEvent* event) { ret = TRUE; } - - Inkscape::Rubberband::get(desktop)->move(motion_dt); + if ( !eraserMode ) { + Inkscape::Rubberband::get(desktop)->move(motion_dt); + } } break; @@ -485,7 +490,7 @@ bool EraserTool::root_handler(GdkEvent* event) { ret = TRUE; } - if (Inkscape::Rubberband::get(desktop)->is_started()) { + if (!eraserMode && Inkscape::Rubberband::get(desktop)->is_started()) { Inkscape::Rubberband::get(desktop)->stop(); } @@ -572,8 +577,9 @@ bool EraserTool::root_handler(GdkEvent* event) { break; case GDK_KEY_Escape: - Inkscape::Rubberband::get(desktop)->stop(); - + if ( !eraserMode ) { + Inkscape::Rubberband::get(desktop)->stop(); + } if (this->is_drawing) { // if drawing, cancel, otherwise pass it up for deselecting this->cancel(); @@ -645,7 +651,7 @@ void EraserTool::set_to_accumulated() { this->repr = repr; } - SPItem *item=SP_ITEM(desktop->currentLayer()->appendChildRepr(this->repr)); + 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(); @@ -654,11 +660,11 @@ void EraserTool::set_to_accumulated() { g_assert( str != NULL ); this->repr->setAttribute("d", str); g_free(str); + if ( this->repr ) { bool wasSelection = false; Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); @@ -675,32 +681,50 @@ void EraserTool::set_to_accumulated() { } toWorkOn.erase(std::remove(toWorkOn.begin(), toWorkOn.end(), acid), toWorkOn.end()); } else { - toWorkOn= selection->itemList(); + toWorkOn = selection->itemList(); wasSelection = true; } if ( !toWorkOn.empty() ) { if ( eraserMode ) { for (std::vector<SPItem*>::const_iterator i = toWorkOn.begin(); i != toWorkOn.end(); ++i){ - SPItem *item = *i; + SPItem *item = *i; + SPUse *use = dynamic_cast<SPUse *>(item); + if (SP_IS_GROUP(item) || use ) { + continue; + } 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); + selection->set(dup); + sp_selected_path_union(selection, desktop); + selection->add(item); + if(item->style->fill_rule.value == SP_WIND_RULE_EVENODD){ + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "fill-rule", "evenodd"); + sp_desktop_set_style(desktop, css); + sp_repr_css_attr_unref(css); + css = 0; + } 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. - + bool break_apart = prefs->getBool("/tools/eraser/break_apart", false); + if(!break_apart){ + sp_selected_path_combine(desktop); + } else { + if(!this->nowidth){ + sp_selected_path_break_apart(desktop); + } + } if ( !selection->isEmpty() ) { // If the item was not completely erased, track the new remainder. - std::vector<SPItem*> nowSel(selection->itemList()); + std::vector<SPItem*> nowSel(selection->itemList()); for (std::vector<SPItem*>::const_iterator i2 = nowSel.begin();i2!=nowSel.end();++i2) { remainingItems.push_back(*i2); } diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp index f18a805b2..1fc520185 100644 --- a/src/widgets/eraser-toolbar.cpp +++ b/src/widgets/eraser-toolbar.cpp @@ -57,6 +57,13 @@ static void sp_erc_width_value_changed( GtkAdjustment *adj, GObject *tbl ) update_presets_list(tbl); } +static void sp_erc_mass_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/eraser/mass", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); @@ -65,7 +72,15 @@ static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool( "/tools/eraser/mode", eraserMode ); } - + GtkAction *split = GTK_ACTION( g_object_get_data(tbl, "split") ); + GtkAction *mass = GTK_ACTION( g_object_get_data(tbl, "mass") ); + if(eraserMode == TRUE){ + gtk_action_set_visible( split, TRUE ); + gtk_action_set_visible( mass, TRUE ); + } else { + gtk_action_set_visible( split, FALSE ); + gtk_action_set_visible( mass, FALSE ); + } // only take action if run by the attr_changed listener if (!g_object_get_data( tbl, "freeze" )) { // in turn, prevent listener from responding @@ -82,11 +97,20 @@ static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) } } +static void sp_toogle_break_apart( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/eraser/break_apart", active); +} + void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { + Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint eraserMode = FALSE; { GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); - GtkTreeIter iter; gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, @@ -113,9 +137,8 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb ege_select_one_action_set_icon_column( act, 2 ); ege_select_one_action_set_tooltip_column( act, 1 ); - /// @todo Convert to boolean? Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; + eraserMode = prefs->getBool("/tools/eraser/mode") ? TRUE : FALSE; ege_select_one_action_set_active( act, eraserMode ); g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_erasertb_mode_changed), holder ); } @@ -136,6 +159,44 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); } + { + /* Mass */ + gchar const* labels[] = {_("(no inertia)"), _("(slight smoothing, default)"), _("(noticeable lagging)"), 0, 0, _("(maximum inertia)")}; + gdouble values[] = {0.0, 2, 10, 20, 50, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "EraserMassAction", + _("Eraser Mass"), _("Mass:"), + _("Increase to make the eraser drag behind, as if slowed by inertia"), + "/tools/eraser/mass", 10.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_erc_mass_value_changed, NULL /*unit tracker*/, 1, 0); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + g_object_set_data( holder, "mass", eact ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + /* Overlap */ + { + InkToggleAction* act = ink_toggle_action_new( "EraserBreakAppart", + _("Break appart cutted items"), + _("Break appart cutted itemss"), + INKSCAPE_ICON("distribute-randomize"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/eraser/break_apart", false) ); + g_object_set_data( holder, "split", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toogle_break_apart), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + GtkAction *split = GTK_ACTION( g_object_get_data(holder, "split") ); + GtkAction *mass = GTK_ACTION( g_object_get_data(holder, "mass") ); + if(eraserMode == TRUE){ + gtk_action_set_visible( split, TRUE ); + gtk_action_set_visible( mass, TRUE ); + } else { + gtk_action_set_visible( split, FALSE ); + gtk_action_set_visible( mass, FALSE ); + } } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 6787ef6cc..72537f727 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -497,6 +497,9 @@ static gchar const * ui_descr = " <toolitem action='EraserModeAction' />" " <separator />" " <toolitem action='EraserWidthAction' />" + " <toolitem action='EraserBreakAppart' />" + " <separator />" + " <toolitem action='EraserMassAction' />" " </toolbar>" " <toolbar name='TextToolbar'>" |
