From b1fd9e5520ba0578f3b1dbfa53a806bfdb74f3a3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 3 Oct 2016 00:48:49 +0200 Subject: Doc rotate start (bzr r15142.1.1) --- src/attributes.cpp | 1 + src/attributes.h | 1 + src/document.cpp | 6 ++++ src/sp-namedview.cpp | 47 ++++++++++++++++++++++++++- src/sp-namedview.h | 1 + src/ui/dialog/export.cpp | 12 ++++++- src/viewbox.cpp | 82 +++++++++++++++++++++++++++++++++++++++++------- src/viewbox.h | 12 +++++++ 8 files changed, 148 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index b06ff6048..cc75d94c6 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -89,6 +89,7 @@ static SPStyleProp const props[] = { {SP_ATTR_INKSCAPE_ZOOM, "inkscape:zoom"}, {SP_ATTR_INKSCAPE_CX, "inkscape:cx"}, {SP_ATTR_INKSCAPE_CY, "inkscape:cy"}, + {SP_ATTR_INKSCAPE_DOCUMENT_ROTATION, "inkscape:document-rotation"}, {SP_ATTR_INKSCAPE_WINDOW_WIDTH, "inkscape:window-width"}, {SP_ATTR_INKSCAPE_WINDOW_HEIGHT, "inkscape:window-height"}, {SP_ATTR_INKSCAPE_WINDOW_X, "inkscape:window-x"}, diff --git a/src/attributes.h b/src/attributes.h index ff426e8cf..ba82c18f1 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -97,6 +97,7 @@ enum SPAttributeEnum { SP_ATTR_INKSCAPE_ZOOM, SP_ATTR_INKSCAPE_CX, SP_ATTR_INKSCAPE_CY, + SP_ATTR_INKSCAPE_DOCUMENT_ROTATION, SP_ATTR_INKSCAPE_WINDOW_WIDTH, SP_ATTR_INKSCAPE_WINDOW_HEIGHT, SP_ATTR_INKSCAPE_WINDOW_X, diff --git a/src/document.cpp b/src/document.cpp index 920e47cb8..a371fe1e5 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -386,6 +386,7 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, if (!bordercolor.empty()) { rnew->setAttribute("bordercolor", bordercolor.data()); } + sp_repr_set_svg_double(rnew, "inkscape:document-rotation", 0.); sp_repr_set_svg_double(rnew, "borderopacity", prefs->getDouble("/template/base/borderopacity", 1.0)); sp_repr_set_svg_double(rnew, "objecttolerance", @@ -407,6 +408,11 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, rroot->addChild(rnew, NULL); // clean up Inkscape::GC::release(rnew); + } else { + Inkscape::XML::Node *nv_repr = sp_item_group_get_child_by_name(document->root, NULL, "sodipodi:namedview")->getRepr(); + if (!nv_repr->attribute("inkscape:document-rotation")) { + sp_repr_set_svg_double(nv_repr, "inkscape:document-rotation", 0.); + } } // Defs diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index b9526433f..69fc78b33 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -29,12 +29,14 @@ #include "desktop-events.h" #include "sp-guide.h" +#include "sp-root.h" #include "sp-item-group.h" #include "sp-namedview.h" #include "preferences.h" #include "desktop.h" +#include "selection.h" +#include "inkscape.h" #include "conn-avoid-ref.h" // for defaultConnSpacing. -#include "sp-root.h" #include using Inkscape::DocumentUndo; @@ -49,6 +51,7 @@ using Inkscape::Util::unit_table; #define DEFAULTPAGECOLOR 0xffffff00 static void sp_namedview_setup_guides(SPNamedView * nv); +static void sp_namedview_set_document_rotation(SPDocument * doc, SPNamedView * nv); static void sp_namedview_lock_guides(SPNamedView * nv); static void sp_namedview_show_single_guide(SPGuide* guide, bool show); static void sp_namedview_lock_single_guide(SPGuide* guide, bool show); @@ -72,6 +75,7 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) { this->pagecolor = 0; this->cx = 0; this->pageshadow = 0; + this->document_rotation = 0; this->window_width = 0; this->window_height = 0; this->window_maximized = 0; @@ -212,6 +216,7 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "inkscape:zoom" ); this->readAttr( "inkscape:cx" ); this->readAttr( "inkscape:cy" ); + this->readAttr( "inkscape:document-rotation" ); this->readAttr( "inkscape:window-width" ); this->readAttr( "inkscape:window-height" ); this->readAttr( "inkscape:window-x" ); @@ -409,6 +414,13 @@ void SPNamedView::set(unsigned int key, const gchar* value) { this->cy = value ? g_ascii_strtod(value, NULL) : HUGE_VAL; // HUGE_VAL means not set this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_INKSCAPE_DOCUMENT_ROTATION: + this->document_rotation = value ? g_ascii_strtod(value, NULL) : 0; // zero means not set + if (value && document) { + sp_namedview_set_document_rotation(document, this); + } + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; case SP_ATTR_INKSCAPE_WINDOW_WIDTH: this->window_width = value? atoi(value) : -1; // -1 means not set this->requestModified(SP_OBJECT_MODIFIED_FLAG); @@ -939,6 +951,39 @@ static void sp_namedview_lock_guides(SPNamedView *nv) } } +static void sp_namedview_set_document_rotation(SPDocument *doc, SPNamedView *nv) +{ + SPDesktop * desktop = SP_ACTIVE_DESKTOP; + Geom::Rect area; + Geom::Point p = Geom::Point(); + if (desktop) { + area = desktop->get_display_area(); + p = area.midpoint(); + p *= desktop->doc2dt(); + p *= doc->getRoot()->rotation.inverse(); + } + doc->getRoot()->set_rotation(nv->document_rotation); + if (nv->document_rotation) { + nv->showborder = FALSE; + } else { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + nv->showborder = prefs->getBool("/template/base/showborder", 1.0); + } + if (desktop) { + p *= doc->getRoot()->rotation; + //desktop->scroll_world_in_svg_coords (p[Geom::X], p[Geom::Y], true); + // *= doc->getRoot()->c2p * doc->getRoot()->rotation(); + //desktop->zoom_absolute (p[Geom::X], p[Geom::Y], desktop->current_zoom()); + std::cout << p << "pppppp\n"; +// Geom::Point min_pt = Geom::Point(p[Geom::X] - (area.width() / 2.0), p[Geom::Y] - (area.height() / 2.0)); +// Geom::Point max_pt = Geom::Point(p[Geom::X] + (area.width() / 2.0), p[Geom::Y] + (area.height() / 2.0)); +// Geom::Rect const new_area(min_pt, max_pt); +// desktop->set_display_area (new_area, 0, false); + Inkscape::Selection * sel = desktop->getSelection(); + sel->clear(); + } +} + static void sp_namedview_show_single_guide(SPGuide* guide, bool show) { if (show) { diff --git a/src/sp-namedview.h b/src/sp-namedview.h index d8ac1a77e..9e523632d 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -54,6 +54,7 @@ public: double zoom; double cx; double cy; + double document_rotation; int window_width; int window_height; int window_x; diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 64a5d9866..f0d54d784 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -975,7 +975,12 @@ void Export::onExport () SPNamedView *nv = desktop->getNamedView(); SPDocument *doc = desktop->getDocument(); - + Geom::Affine rot = doc->getRoot()->c2p; + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; + //double rotate_angle = doc->getRoot()->get_rotation(); + //Inkscape::XML::Node *nv_repr = sp_item_group_get_child_by_name(doc->getRoot(), NULL, "sodipodi:namedview")->getRepr(); + //sp_repr_set_svg_double(nv_repr, "inkscape:document-rotation", 0.); + doc->ensureUpToDate(); bool exportSuccessful = false; bool hide = hide_export.get_active (); @@ -999,6 +1004,7 @@ void Export::onExport () if (num < 1) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No items selected.")); + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; } @@ -1090,6 +1096,7 @@ void Export::onExport () if (filename.empty()) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You have to enter a filename.")); sp_ui_error_dialog(_("You have to enter a filename")); + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; } @@ -1106,6 +1113,7 @@ void Export::onExport () if (!((x1 > x0) && (y1 > y0) && (width > 0) && (height > 0))) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The chosen area to be exported is invalid.")); sp_ui_error_dialog(_("The chosen area to be exported is invalid")); + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; } @@ -1128,6 +1136,7 @@ void Export::onExport () g_free(safeDir); g_free(error); + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; } @@ -1277,6 +1286,7 @@ void Export::onExport () } } } + doc->getRoot()->c2p *= doc->getRoot()->rotation; } // end of sp_export_export_clicked() /// Called when Browse button is clicked diff --git a/src/viewbox.cpp b/src/viewbox.cpp index 1b50fe71c..e40e477ef 100644 --- a/src/viewbox.cpp +++ b/src/viewbox.cpp @@ -17,6 +17,12 @@ #include "viewbox.h" #include "enums.h" #include "sp-item.h" +#include "display/sp-canvas-group.h" +#include "display/canvas-bpath.h" +#include "display/curve.h" +#include "inkscape.h" +#include "desktop.h" + SPViewBox::SPViewBox() : viewBox_set(false) @@ -25,6 +31,8 @@ SPViewBox::SPViewBox() , aspect_align(SP_ASPECT_XMID_YMID) // Default per spec , aspect_clip(SP_ASPECT_MEET) , c2p(Geom::identity()) + , rotation(Geom::identity()) + , angle(0) { } @@ -159,6 +167,14 @@ void SPViewBox::set_preserveAspectRatio(const gchar* value) { } } +double SPViewBox::get_rotation() { + return this->angle; +} + +void SPViewBox::set_rotation(double angle_val) { + this->angle = angle_val; +} + // Apply scaling from viewbox void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { @@ -224,18 +240,60 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { } /* Viewbox transform from scale and position */ - Geom::Affine q; - q[0] = scale_x; - q[1] = 0.0; - q[2] = 0.0; - q[3] = scale_y; - q[4] = x - scale_x * this->viewBox.left(); - q[5] = y - scale_y * this->viewBox.top(); - - // std::cout << " q\n" << q << std::endl; - - /* Append viewbox transformation */ - this->c2p = q * this->c2p; + Geom::Affine vbt = Geom::identity(); + vbt[0] = scale_x; + vbt[1] = 0.0; + vbt[2] = 0.0; + vbt[3] = scale_y; + vbt[4] = x - scale_x * this->viewBox.left(); + vbt[5] = y - scale_y * this->viewBox.top(); + // std::cout << " q\n" << q << std::endl + /* Append viewbox and turn transformation */ + if (this->angle > 0.0 || this->angle < 0.0 ) { //!0 + Geom::Point r0 = this->viewBox.min(); + Geom::Point r1 = this->viewBox.max(); + Geom::Point p = (r0 + r1) / 2; + SPDesktop * desktop = SP_ACTIVE_DESKTOP; + SPCanvasItem *vw_rot = NULL; + if (desktop) { + if (this->page_border_rotated) { + desktop->remove_temporary_canvasitem(this->page_border_rotated); + this->page_border_rotated = NULL; + } + SPCurve *c = new SPCurve(); + c->moveto(this->viewBox.min()); + c->lineto(Geom::Point(this->viewBox.max()[Geom::X],this->viewBox.min()[Geom::Y])); + c->lineto(Geom::Point(this->viewBox.max()[Geom::X],this->viewBox.max()[Geom::Y])); + c->lineto(Geom::Point(this->viewBox.min()[Geom::X],this->viewBox.max()[Geom::Y])); + c->closepath(); + vw_rot = sp_canvas_bpath_new(desktop->getTempGroup(), c, true); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(vw_rot), 0xFF00009A, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(vw_rot), 0, SP_WIND_RULE_NONZERO); + this->page_border_rotated = desktop->add_temporary_canvasitem(vw_rot, 0); + Geom::PathVector const box = c->get_pathvector(); + Geom::OptRect bbox = box.boundsFast(); + if (bbox){ + r0 = (*bbox).min(); + r1 = (*bbox).max(); + p = (r0 + r1) / 2; + } + Geom::Affine rot = Geom::identity(); + rot *= Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(-angle)) * Geom::Translate(p); + sp_canvas_item_affine_absolute(vw_rot, rot * vbt); + this->page_border_rotated = desktop->add_temporary_canvasitem(vw_rot, 0); + } + rotation = Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(angle)) * Geom::Translate(p); + this->c2p = rotation * vbt * this->c2p; + } else { + SPDesktop * desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + if (this->page_border_rotated) { + desktop->remove_temporary_canvasitem(this->page_border_rotated); + this->page_border_rotated = NULL; + } + } + this->c2p = vbt * this->c2p; + } } SPItemCtx SPViewBox::get_rctx(const SPItemCtx* ictx, double scale_none) { diff --git a/src/viewbox.h b/src/viewbox.h index c71abb610..df47c025b 100644 --- a/src/viewbox.h +++ b/src/viewbox.h @@ -17,6 +17,13 @@ #include <2geom/rect.h> #include +#include "display/sp-canvas.h" + +namespace Inkscape { + namespace Display { + class TemporaryItem; + } +} class SPItemCtx; @@ -36,6 +43,11 @@ public: /* Child to parent additional transform */ Geom::Affine c2p; + Geom::Affine rotation; + double angle; + double get_rotation(); + void set_rotation(double angle_val); + Inkscape::Display::TemporaryItem *page_border_rotated; void set_viewBox(const gchar* value); void set_preserveAspectRatio(const gchar* value); -- cgit v1.2.3 From f5e77f7f48954ec3bed892fa6763b0ed099a044e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 8 Oct 2016 16:48:24 +0200 Subject: add rotate from current desktop center (bzr r15142.1.3) --- src/sp-namedview.cpp | 40 +++++++++++++++++++++------------------- src/viewbox.cpp | 24 ++++++++++++++++++++---- src/viewbox.h | 2 ++ 3 files changed, 43 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 69fc78b33..b4199e4c4 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -39,6 +39,9 @@ #include "conn-avoid-ref.h" // for defaultConnSpacing. #include +#include "display/sodipodi-ctrl.h" +#include "ui/dialog/knot-properties.h" + using Inkscape::DocumentUndo; using Inkscape::Util::unit_table; @@ -416,7 +419,7 @@ void SPNamedView::set(unsigned int key, const gchar* value) { break; case SP_ATTR_INKSCAPE_DOCUMENT_ROTATION: this->document_rotation = value ? g_ascii_strtod(value, NULL) : 0; // zero means not set - if (value && document) { + if (document) { sp_namedview_set_document_rotation(document, this); } this->requestModified(SP_OBJECT_MODIFIED_FLAG); @@ -950,18 +953,26 @@ static void sp_namedview_lock_guides(SPNamedView *nv) sp_namedview_lock_single_guide(*it, nv->lockguides); } } - +void hp2(Geom::Point a) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + a = desktop->dt2doc(a); + guint32 color = 0xff0000ff; + SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(), + SP_TYPE_CTRL, + "anchor", SP_ANCHOR_CENTER, + "size", 8.0, + "stroked", TRUE, + "stroke_color", color, + "mode", SP_KNOT_MODE_XOR, + "shape", SP_KNOT_SHAPE_CROSS, + NULL ); + + SP_CTRL(canvasitem)->moveto(a); + sp_canvas_item_show(canvasitem); +} static void sp_namedview_set_document_rotation(SPDocument *doc, SPNamedView *nv) { SPDesktop * desktop = SP_ACTIVE_DESKTOP; - Geom::Rect area; - Geom::Point p = Geom::Point(); - if (desktop) { - area = desktop->get_display_area(); - p = area.midpoint(); - p *= desktop->doc2dt(); - p *= doc->getRoot()->rotation.inverse(); - } doc->getRoot()->set_rotation(nv->document_rotation); if (nv->document_rotation) { nv->showborder = FALSE; @@ -970,15 +981,6 @@ static void sp_namedview_set_document_rotation(SPDocument *doc, SPNamedView *nv) nv->showborder = prefs->getBool("/template/base/showborder", 1.0); } if (desktop) { - p *= doc->getRoot()->rotation; - //desktop->scroll_world_in_svg_coords (p[Geom::X], p[Geom::Y], true); - // *= doc->getRoot()->c2p * doc->getRoot()->rotation(); - //desktop->zoom_absolute (p[Geom::X], p[Geom::Y], desktop->current_zoom()); - std::cout << p << "pppppp\n"; -// Geom::Point min_pt = Geom::Point(p[Geom::X] - (area.width() / 2.0), p[Geom::Y] - (area.height() / 2.0)); -// Geom::Point max_pt = Geom::Point(p[Geom::X] + (area.width() / 2.0), p[Geom::Y] + (area.height() / 2.0)); -// Geom::Rect const new_area(min_pt, max_pt); -// desktop->set_display_area (new_area, 0, false); Inkscape::Selection * sel = desktop->getSelection(); sel->clear(); } diff --git a/src/viewbox.cpp b/src/viewbox.cpp index e40e477ef..ba316e2c2 100644 --- a/src/viewbox.cpp +++ b/src/viewbox.cpp @@ -23,6 +23,8 @@ #include "inkscape.h" #include "desktop.h" +#include "display/sodipodi-ctrl.h" +#include "ui/dialog/knot-properties.h" SPViewBox::SPViewBox() : viewBox_set(false) @@ -33,6 +35,8 @@ SPViewBox::SPViewBox() , c2p(Geom::identity()) , rotation(Geom::identity()) , angle(0) + , previous_angle(0) + , rotated(false) { } @@ -172,6 +176,8 @@ double SPViewBox::get_rotation() { } void SPViewBox::set_rotation(double angle_val) { + this->previous_angle = this->angle; + this->rotated = true; this->angle = angle_val; } @@ -255,6 +261,7 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { Geom::Point p = (r0 + r1) / 2; SPDesktop * desktop = SP_ACTIVE_DESKTOP; SPCanvasItem *vw_rot = NULL; + Geom::Point rot_center = Geom::Point(); if (desktop) { if (this->page_border_rotated) { desktop->remove_temporary_canvasitem(this->page_border_rotated); @@ -273,17 +280,25 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { Geom::PathVector const box = c->get_pathvector(); Geom::OptRect bbox = box.boundsFast(); if (bbox){ - r0 = (*bbox).min(); - r1 = (*bbox).max(); - p = (r0 + r1) / 2; + p = (*bbox).midpoint(); } + Geom::Rect view = desktop->get_display_area(); + rot_center = desktop->doc2dt(view.midpoint()); Geom::Affine rot = Geom::identity(); - rot *= Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(-angle)) * Geom::Translate(p); + rot *= Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(-angle)) * Geom::Translate(p); sp_canvas_item_affine_absolute(vw_rot, rot * vbt); this->page_border_rotated = desktop->add_temporary_canvasitem(vw_rot, 0); + Geom::Affine rotcenter = Geom::identity(); + rotcenter *= Geom::Translate(p * vbt).inverse() * Geom::Rotate(Geom::rad_from_deg(this->angle - this->previous_angle)) * Geom::Translate(p * vbt); + rot_center = rot_center * rotcenter; } rotation = Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(angle)) * Geom::Translate(p); this->c2p = rotation * vbt * this->c2p; + rot_center = desktop->dt2doc(rot_center); + if (desktop && this->rotated) { + desktop->zoom_relative(rot_center[Geom::X], rot_center[Geom::Y], 1.0); + this->rotated = false; + } } else { SPDesktop * desktop = SP_ACTIVE_DESKTOP; if (desktop) { @@ -296,6 +311,7 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { } } + SPItemCtx SPViewBox::get_rctx(const SPItemCtx* ictx, double scale_none) { /* Create copy of item context */ diff --git a/src/viewbox.h b/src/viewbox.h index df47c025b..70afa38a1 100644 --- a/src/viewbox.h +++ b/src/viewbox.h @@ -45,6 +45,8 @@ public: Geom::Affine c2p; Geom::Affine rotation; double angle; + double previous_angle; + bool rotated; double get_rotation(); void set_rotation(double angle_val); Inkscape::Display::TemporaryItem *page_border_rotated; -- cgit v1.2.3 From 45b6180786db318dd135ea918732ce8051470e75 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 8 Oct 2016 20:29:16 +0200 Subject: Keep selection (bzr r15142.1.5) --- src/sp-namedview.cpp | 43 +++++++++++++++---------------------------- src/viewbox.cpp | 8 ++------ src/viewbox.h | 4 ++-- 3 files changed, 19 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index b4199e4c4..e44c548bd 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -35,13 +35,11 @@ #include "preferences.h" #include "desktop.h" #include "selection.h" +#include "object-set.h" #include "inkscape.h" #include "conn-avoid-ref.h" // for defaultConnSpacing. #include -#include "display/sodipodi-ctrl.h" -#include "ui/dialog/knot-properties.h" - using Inkscape::DocumentUndo; using Inkscape::Util::unit_table; @@ -419,9 +417,7 @@ void SPNamedView::set(unsigned int key, const gchar* value) { break; case SP_ATTR_INKSCAPE_DOCUMENT_ROTATION: this->document_rotation = value ? g_ascii_strtod(value, NULL) : 0; // zero means not set - if (document) { - sp_namedview_set_document_rotation(document, this); - } + sp_namedview_set_document_rotation(document, this); this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_INKSCAPE_WINDOW_WIDTH: @@ -953,26 +949,10 @@ static void sp_namedview_lock_guides(SPNamedView *nv) sp_namedview_lock_single_guide(*it, nv->lockguides); } } -void hp2(Geom::Point a) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - a = desktop->dt2doc(a); - guint32 color = 0xff0000ff; - SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(), - SP_TYPE_CTRL, - "anchor", SP_ANCHOR_CENTER, - "size", 8.0, - "stroked", TRUE, - "stroke_color", color, - "mode", SP_KNOT_MODE_XOR, - "shape", SP_KNOT_SHAPE_CROSS, - NULL ); - - SP_CTRL(canvasitem)->moveto(a); - sp_canvas_item_show(canvasitem); -} + static void sp_namedview_set_document_rotation(SPDocument *doc, SPNamedView *nv) { - SPDesktop * desktop = SP_ACTIVE_DESKTOP; + doc->getRoot()->set_rotation(nv->document_rotation); if (nv->document_rotation) { nv->showborder = FALSE; @@ -980,10 +960,17 @@ static void sp_namedview_set_document_rotation(SPDocument *doc, SPNamedView *nv) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); nv->showborder = prefs->getBool("/template/base/showborder", 1.0); } - if (desktop) { - Inkscape::Selection * sel = desktop->getSelection(); - sel->clear(); - } +// //TODO: fix ti for work: To update knots of selected items +// SPDesktop * desktop = SP_ACTIVE_DESKTOP; +// if (desktop) { +// Inkscape::Selection * sel = desktop->getSelection(); +// std::vector il(sel->items().begin(), sel->items().end()); +// for (std::vector::const_iterator l = il.begin(); l != il.end(); l++){ +// SPItem *item = *l; +// sel->remove(item->getRepr()); +// sel->add(item->getRepr()); +// } +// } } static void sp_namedview_show_single_guide(SPGuide* guide, bool show) diff --git a/src/viewbox.cpp b/src/viewbox.cpp index ba316e2c2..dbbd462c8 100644 --- a/src/viewbox.cpp +++ b/src/viewbox.cpp @@ -17,15 +17,13 @@ #include "viewbox.h" #include "enums.h" #include "sp-item.h" +#include "sp-root.h" #include "display/sp-canvas-group.h" #include "display/canvas-bpath.h" #include "display/curve.h" #include "inkscape.h" #include "desktop.h" -#include "display/sodipodi-ctrl.h" -#include "ui/dialog/knot-properties.h" - SPViewBox::SPViewBox() : viewBox_set(false) , viewBox() @@ -177,8 +175,8 @@ double SPViewBox::get_rotation() { void SPViewBox::set_rotation(double angle_val) { this->previous_angle = this->angle; - this->rotated = true; this->angle = angle_val; + this->rotated = true; } // Apply scaling from viewbox @@ -244,7 +242,6 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { break; } } - /* Viewbox transform from scale and position */ Geom::Affine vbt = Geom::identity(); vbt[0] = scale_x; @@ -253,7 +250,6 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { vbt[3] = scale_y; vbt[4] = x - scale_x * this->viewBox.left(); vbt[5] = y - scale_y * this->viewBox.top(); - // std::cout << " q\n" << q << std::endl /* Append viewbox and turn transformation */ if (this->angle > 0.0 || this->angle < 0.0 ) { //!0 Geom::Point r0 = this->viewBox.min(); diff --git a/src/viewbox.h b/src/viewbox.h index 70afa38a1..661a9b24a 100644 --- a/src/viewbox.h +++ b/src/viewbox.h @@ -47,10 +47,10 @@ public: double angle; double previous_angle; bool rotated; - double get_rotation(); - void set_rotation(double angle_val); Inkscape::Display::TemporaryItem *page_border_rotated; + double get_rotation(); + void set_rotation(double angle_val); void set_viewBox(const gchar* value); void set_preserveAspectRatio(const gchar* value); -- cgit v1.2.3 From 7f008cb2f657420416aef950a1576e1162c89fa4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 9 Oct 2016 03:19:42 +0200 Subject: Added widget to to rotate (bzr r15142.1.7) --- src/sp-namedview.cpp | 9 ++++----- src/sp-namedview.h | 2 +- src/viewbox.cpp | 25 +++++++++++------------ src/widgets/desktop-widget.cpp | 46 +++++++++++++++++++++++++++++++++++++++--- src/widgets/desktop-widget.h | 2 +- 5 files changed, 61 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index e44c548bd..e51d62522 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -416,8 +416,8 @@ void SPNamedView::set(unsigned int key, const gchar* value) { this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_INKSCAPE_DOCUMENT_ROTATION: - this->document_rotation = value ? g_ascii_strtod(value, NULL) : 0; // zero means not set - sp_namedview_set_document_rotation(document, this); + this->document_rotation = value ? g_ascii_strtod(value, NULL) : 0; + sp_namedview_set_document_rotation(this); this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_INKSCAPE_WINDOW_WIDTH: @@ -950,10 +950,9 @@ static void sp_namedview_lock_guides(SPNamedView *nv) } } -static void sp_namedview_set_document_rotation(SPDocument *doc, SPNamedView *nv) +void sp_namedview_set_document_rotation(SPNamedView *nv) { - - doc->getRoot()->set_rotation(nv->document_rotation); + nv->document->getRoot()->set_rotation(nv->document_rotation); if (nv->document_rotation) { nv->showborder = FALSE; } else { diff --git a/src/sp-namedview.h b/src/sp-namedview.h index 9e523632d..e51908005 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -122,7 +122,7 @@ SPNamedView const *sp_document_namedview(SPDocument const *document, char const void sp_namedview_window_from_document(SPDesktop *desktop); void sp_namedview_document_from_window(SPDesktop *desktop); void sp_namedview_update_layers_from_document (SPDesktop *desktop); - +void sp_namedview_set_document_rotation(SPNamedView *nv); void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr); void sp_namedview_guides_toggle_lock(SPDocument *doc, Inkscape::XML::Node *repr); void sp_namedview_show_grids(SPNamedView *namedview, bool show, bool dirty_document); diff --git a/src/viewbox.cpp b/src/viewbox.cpp index dbbd462c8..d4e64a4da 100644 --- a/src/viewbox.cpp +++ b/src/viewbox.cpp @@ -251,13 +251,12 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { vbt[4] = x - scale_x * this->viewBox.left(); vbt[5] = y - scale_y * this->viewBox.top(); /* Append viewbox and turn transformation */ + Geom::Point rot_center = Geom::Point(); + Geom::Point p = this->viewBox.midpoint(); + Geom::Affine rotcenter = Geom::identity(); + SPDesktop * desktop = SP_ACTIVE_DESKTOP; if (this->angle > 0.0 || this->angle < 0.0 ) { //!0 - Geom::Point r0 = this->viewBox.min(); - Geom::Point r1 = this->viewBox.max(); - Geom::Point p = (r0 + r1) / 2; - SPDesktop * desktop = SP_ACTIVE_DESKTOP; SPCanvasItem *vw_rot = NULL; - Geom::Point rot_center = Geom::Point(); if (desktop) { if (this->page_border_rotated) { desktop->remove_temporary_canvasitem(this->page_border_rotated); @@ -284,20 +283,15 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { rot *= Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(-angle)) * Geom::Translate(p); sp_canvas_item_affine_absolute(vw_rot, rot * vbt); this->page_border_rotated = desktop->add_temporary_canvasitem(vw_rot, 0); - Geom::Affine rotcenter = Geom::identity(); rotcenter *= Geom::Translate(p * vbt).inverse() * Geom::Rotate(Geom::rad_from_deg(this->angle - this->previous_angle)) * Geom::Translate(p * vbt); - rot_center = rot_center * rotcenter; } rotation = Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(angle)) * Geom::Translate(p); this->c2p = rotation * vbt * this->c2p; - rot_center = desktop->dt2doc(rot_center); - if (desktop && this->rotated) { - desktop->zoom_relative(rot_center[Geom::X], rot_center[Geom::Y], 1.0); - this->rotated = false; - } } else { - SPDesktop * desktop = SP_ACTIVE_DESKTOP; if (desktop) { + Geom::Rect view = desktop->get_display_area(); + rot_center = desktop->doc2dt(view.midpoint()); + rotcenter *= Geom::Translate(p * vbt).inverse() * Geom::Rotate(Geom::rad_from_deg(this->angle - this->previous_angle)) * Geom::Translate(p * vbt); if (this->page_border_rotated) { desktop->remove_temporary_canvasitem(this->page_border_rotated); this->page_border_rotated = NULL; @@ -305,6 +299,11 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { } this->c2p = vbt * this->c2p; } + if (desktop && this->rotated) { + rot_center = desktop->dt2doc(rot_center * rotcenter); + desktop->zoom_relative(rot_center[Geom::X], rot_center[Geom::Y], 1.0); + this->rotated = false; + } } diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 55dc82dc0..df943b241 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -54,7 +54,7 @@ #include "ui/uxmanager.h" #include "util/ege-appear-time-tracker.h" #include "sp-root.h" - +#include "attributes.h" // We're in the "widgets" directory, so no need to explicitly prefix these: #include "button.h" #include "gimp/ruler.h" @@ -105,6 +105,7 @@ static void sp_update_guides_lock( GtkWidget *button, gpointer data ); static void cms_adjust_toggled( GtkWidget *button, gpointer data ); #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) static void cms_adjust_set_sensitive( SPDesktopWidget *dtw, bool enabled ); +static void sp_desktop_widget_rotate_document(GtkWidget *widget, GdkEvent *eventdtw, SPDesktopWidget *dtw); static void sp_desktop_widget_adjustment_value_changed (GtkAdjustment *adj, SPDesktopWidget *dtw); static gdouble sp_dtw_zoom_value_to_display (gdouble value); @@ -1430,6 +1431,12 @@ void SPDesktopWidget::layoutWidgets() } else { gtk_widget_show_all (dtw->menubar); } + + if (!prefs->getBool(pref_root + "menu/state", true)) { + gtk_widget_hide (dtw->rotatebar); + } else { + gtk_widget_show_all (dtw->rotatebar); + } if (!prefs->getBool(pref_root + "commands/state", true)) { gtk_widget_hide (dtw->commands_toolbox); @@ -1636,8 +1643,25 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) dtw->menubar = sp_ui_main_menubar (dtw->desktop); gtk_widget_set_name(dtw->menubar, "MenuBar"); gtk_widget_show_all (dtw->menubar); - gtk_box_pack_start (GTK_BOX (dtw->vbox), dtw->menubar, FALSE, FALSE, 0); - + SPNamedView *nv = dtw->desktop->namedview; + dtw->rotatebar = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,0.0,360.0,45.0); + gtk_range_set_value(GTK_RANGE (dtw->rotatebar), nv->document_rotation); + gtk_widget_set_name(dtw->rotatebar, "RotateBar"); + gtk_widget_show_all (dtw->rotatebar); + GtkWidget * containermenu = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_show_all (containermenu); + GtkWidget * separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL); + gtk_widget_show_all(separator); + GtkWidget * label = gtk_label_new (_("Rotation")); + gtk_widget_show_all(label); + gtk_box_pack_start (GTK_BOX (containermenu), dtw->menubar, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (containermenu), separator, FALSE, FALSE, 10); + gtk_box_pack_start (GTK_BOX (containermenu), dtw->rotatebar, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (containermenu), label, FALSE, FALSE, 10); + gtk_box_pack_start (GTK_BOX (dtw->vbox), containermenu, TRUE, TRUE, 0); + g_signal_connect (G_OBJECT (dtw->rotatebar), "button-release-event", G_CALLBACK (sp_desktop_widget_rotate_document), dtw); + g_signal_connect (G_OBJECT (dtw->rotatebar), "key-release-event", G_CALLBACK (sp_desktop_widget_rotate_document), dtw); + dtw->layoutWidgets(); std::vector toolboxes; @@ -1729,6 +1753,22 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) } } +static void +sp_desktop_widget_rotate_document(GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw) +{ + SPNamedView *nv = dtw->desktop->namedview; + double value = gtk_range_get_value(GTK_RANGE(widget)); + if (value != nv->document_rotation) { + sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value); + SPObject *updated = nv->document->getObjectByRepr(nv->getRepr()); + if (updated) { + updated->updateRepr(); + } + reinterpret_cast(dtw->desktop->currentLayer())->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } +} + + static void sp_desktop_widget_adjustment_value_changed (GtkAdjustment */*adj*/, SPDesktopWidget *dtw) { diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index 08966ad5f..26eaf1ff3 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -78,7 +78,7 @@ struct SPDesktopWidget { GtkWidget *hbox; - GtkWidget *menubar, *statusbar; + GtkWidget *menubar, *statusbar, *rotatebar; Inkscape::UI::Dialogs::SwatchesPanel *panels; -- cgit v1.2.3 From c7f5c676fa15f59f5f78c934263539981a26bbd2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 10 Oct 2016 14:08:35 +0200 Subject: Fix some canvas problems and refactorization (bzr r15142.1.8) --- src/display/canvas-temporary-item-list.h | 1 + src/document-undo.cpp | 4 ++ src/file.cpp | 4 +- src/sp-namedview.cpp | 37 ++++++++++++++++++- src/sp-namedview.h | 6 ++- src/viewbox.cpp | 63 ++++++++------------------------ src/viewbox.h | 9 +---- src/widgets/desktop-widget.cpp | 41 +++++++++++++++------ 8 files changed, 93 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/display/canvas-temporary-item-list.h b/src/display/canvas-temporary-item-list.h index 471bb99b9..6b0e5796b 100644 --- a/src/display/canvas-temporary-item-list.h +++ b/src/display/canvas-temporary-item-list.h @@ -14,6 +14,7 @@ struct SPCanvasItem; class SPDesktop; +class SPViewBox; namespace Inkscape { namespace Display { diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 113d09d66..023843fcc 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -281,6 +281,10 @@ gboolean Inkscape::DocumentUndo::undo(SPDocument *doc) if (ret) INKSCAPE.external_change(); + SPObject *updated = doc->getRoot(); + if (updated) { + updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } return ret; } diff --git a/src/file.cpp b/src/file.cpp index 7c17a6158..5a51bbf52 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -259,8 +259,9 @@ bool sp_file_open(const Glib::ustring &uri, SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { desktop->setWaitingCursor(); + desktop->remove_temporary_canvasitem(sp_document_namedview(desktop->getDocument(), NULL)->page_border_rotated); } - + SPDocument *doc = NULL; bool cancelled = false; try { @@ -287,7 +288,6 @@ bool sp_file_open(const Glib::ustring &uri, doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); DocumentUndo::setUndoSensitive(doc, true); } - SPDocument *existing = desktop ? desktop->getDocument() : NULL; if (existing && existing->virgin && replace_empty) { diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index e51d62522..ff0ac8336 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -19,7 +19,12 @@ #include "event-log.h" #include <2geom/transforms.h> +#include "display/sp-canvas-group.h" +#include "display/canvas-bpath.h" +#include "display/canvas-temporary-item.h" +#include "display/canvas-temporary-item-list.h" #include "display/canvas-grid.h" +#include "display/curve.h" #include "util/units.h" #include "svg/svg-color.h" #include "xml/repr.h" @@ -52,7 +57,6 @@ using Inkscape::Util::unit_table; #define DEFAULTPAGECOLOR 0xffffff00 static void sp_namedview_setup_guides(SPNamedView * nv); -static void sp_namedview_set_document_rotation(SPDocument * doc, SPNamedView * nv); static void sp_namedview_lock_guides(SPNamedView * nv); static void sp_namedview_show_single_guide(SPGuide* guide, bool show); static void sp_namedview_lock_single_guide(SPGuide* guide, bool show); @@ -97,9 +101,13 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) { this->default_layer_id = 0; this->connector_spacing = defaultConnSpacing; + this->page_border_rotated = NULL; } SPNamedView::~SPNamedView() { + if(!this->getViewList().empty()) { // >0 Desktops + this->getViewList()[0]->remove_temporary_canvasitem(this->page_border_rotated); + } } static void sp_namedview_generate_old_grid(SPNamedView * /*nv*/, SPDocument *document, Inkscape::XML::Node *repr) { @@ -952,7 +960,32 @@ static void sp_namedview_lock_guides(SPNamedView *nv) void sp_namedview_set_document_rotation(SPNamedView *nv) { - nv->document->getRoot()->set_rotation(nv->document_rotation); + if(!nv->getViewList().empty()) { // >0 Desktops + SPDesktop *desktop = nv->getViewList()[0]; + desktop->remove_temporary_canvasitem(nv->page_border_rotated); + SPRoot * root = nv->document->getRoot(); + SPCurve *c = new SPCurve(); + c->moveto(root->viewBox.min()); + c->lineto(Geom::Point(root->viewBox.max()[Geom::X],root->viewBox.min()[Geom::Y])); + c->lineto(Geom::Point(root->viewBox.max()[Geom::X],root->viewBox.max()[Geom::Y])); + c->lineto(Geom::Point(root->viewBox.min()[Geom::X],root->viewBox.max()[Geom::Y])); + c->closepath(); + Geom::Point page_center = root->viewBox.midpoint(); + Geom::PathVector const box = c->get_pathvector(); + Geom::Affine rot = Geom::identity(); + rot *= Geom::Translate(page_center).inverse(); + rot *= Geom::Rotate(Geom::rad_from_deg(nv->document_rotation * -1)); + rot *= Geom::Translate(page_center); + if (nv->document_rotation) { + SPCanvasItem *canvas_border = sp_canvas_bpath_new(desktop->getTempGroup(), c, true); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(canvas_border), 0xFF00009A, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(canvas_border), 0, SP_WIND_RULE_NONZERO); + sp_canvas_item_affine_absolute(canvas_border, rot * root->vbt); + nv->page_border_rotated = desktop->add_temporary_canvasitem(canvas_border, 0); + } + nv->document->getRoot()->set_rotation(nv->document_rotation); + c->unref(); + } if (nv->document_rotation) { nv->showborder = FALSE; } else { diff --git a/src/sp-namedview.h b/src/sp-namedview.h index e51908005..34f03e67e 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -21,6 +21,7 @@ #include "snap.h" #include "document.h" #include "util/units.h" +#include "display/sp-canvas.h" #include namespace Inkscape { @@ -28,6 +29,9 @@ namespace Inkscape { namespace Util { class Unit; } + namespace Display { + class TemporaryItem; + } } typedef unsigned int guint32; @@ -67,7 +71,7 @@ public: Inkscape::Util::Unit const *display_units; // Units used for the UI (*not* the same as units of SVG coordinates) Inkscape::Util::Unit const *page_size_units; // Only used in "Custom size" part of Document Properties dialog - + Inkscape::Display::TemporaryItem *page_border_rotated; GQuark default_layer_id; double connector_spacing; diff --git a/src/viewbox.cpp b/src/viewbox.cpp index d4e64a4da..15b5b19c4 100644 --- a/src/viewbox.cpp +++ b/src/viewbox.cpp @@ -17,10 +17,6 @@ #include "viewbox.h" #include "enums.h" #include "sp-item.h" -#include "sp-root.h" -#include "display/sp-canvas-group.h" -#include "display/canvas-bpath.h" -#include "display/curve.h" #include "inkscape.h" #include "desktop.h" @@ -31,6 +27,7 @@ SPViewBox::SPViewBox() , aspect_align(SP_ASPECT_XMID_YMID) // Default per spec , aspect_clip(SP_ASPECT_MEET) , c2p(Geom::identity()) + , vbt(Geom::identity()) , rotation(Geom::identity()) , angle(0) , previous_angle(0) @@ -243,7 +240,7 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { } } /* Viewbox transform from scale and position */ - Geom::Affine vbt = Geom::identity(); + vbt = Geom::identity(); vbt[0] = scale_x; vbt[1] = 0.0; vbt[2] = 0.0; @@ -251,57 +248,27 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { vbt[4] = x - scale_x * this->viewBox.left(); vbt[5] = y - scale_y * this->viewBox.top(); /* Append viewbox and turn transformation */ - Geom::Point rot_center = Geom::Point(); - Geom::Point p = this->viewBox.midpoint(); - Geom::Affine rotcenter = Geom::identity(); + Geom::Point page_center = this->viewBox.midpoint(); + Geom::Affine center_rotation = Geom::identity(); SPDesktop * desktop = SP_ACTIVE_DESKTOP; if (this->angle > 0.0 || this->angle < 0.0 ) { //!0 - SPCanvasItem *vw_rot = NULL; if (desktop) { - if (this->page_border_rotated) { - desktop->remove_temporary_canvasitem(this->page_border_rotated); - this->page_border_rotated = NULL; - } - SPCurve *c = new SPCurve(); - c->moveto(this->viewBox.min()); - c->lineto(Geom::Point(this->viewBox.max()[Geom::X],this->viewBox.min()[Geom::Y])); - c->lineto(Geom::Point(this->viewBox.max()[Geom::X],this->viewBox.max()[Geom::Y])); - c->lineto(Geom::Point(this->viewBox.min()[Geom::X],this->viewBox.max()[Geom::Y])); - c->closepath(); - vw_rot = sp_canvas_bpath_new(desktop->getTempGroup(), c, true); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(vw_rot), 0xFF00009A, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(vw_rot), 0, SP_WIND_RULE_NONZERO); - this->page_border_rotated = desktop->add_temporary_canvasitem(vw_rot, 0); - Geom::PathVector const box = c->get_pathvector(); - Geom::OptRect bbox = box.boundsFast(); - if (bbox){ - p = (*bbox).midpoint(); - } - Geom::Rect view = desktop->get_display_area(); - rot_center = desktop->doc2dt(view.midpoint()); - Geom::Affine rot = Geom::identity(); - rot *= Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(-angle)) * Geom::Translate(p); - sp_canvas_item_affine_absolute(vw_rot, rot * vbt); - this->page_border_rotated = desktop->add_temporary_canvasitem(vw_rot, 0); - rotcenter *= Geom::Translate(p * vbt).inverse() * Geom::Rotate(Geom::rad_from_deg(this->angle - this->previous_angle)) * Geom::Translate(p * vbt); + rotation = Geom::Translate(page_center).inverse() * Geom::Rotate(Geom::rad_from_deg(angle)) * Geom::Translate(page_center); + this->c2p = rotation * vbt * this->c2p; + } else { + this->c2p = vbt * this->c2p; } - rotation = Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(angle)) * Geom::Translate(p); - this->c2p = rotation * vbt * this->c2p; } else { - if (desktop) { - Geom::Rect view = desktop->get_display_area(); - rot_center = desktop->doc2dt(view.midpoint()); - rotcenter *= Geom::Translate(p * vbt).inverse() * Geom::Rotate(Geom::rad_from_deg(this->angle - this->previous_angle)) * Geom::Translate(p * vbt); - if (this->page_border_rotated) { - desktop->remove_temporary_canvasitem(this->page_border_rotated); - this->page_border_rotated = NULL; - } - } this->c2p = vbt * this->c2p; } if (desktop && this->rotated) { - rot_center = desktop->dt2doc(rot_center * rotcenter); - desktop->zoom_relative(rot_center[Geom::X], rot_center[Geom::Y], 1.0); + Geom::Rect view = desktop->get_display_area(); + Geom::Point view_center = desktop->doc2dt(view.midpoint()); + center_rotation *= Geom::Translate(page_center * vbt).inverse(); + center_rotation *= Geom::Rotate(Geom::rad_from_deg(this->angle - this->previous_angle)); + center_rotation *= Geom::Translate(page_center * vbt); + view_center = desktop->dt2doc(view_center * center_rotation); + desktop->zoom_relative(view_center[Geom::X], view_center[Geom::Y], 1.0); this->rotated = false; } } diff --git a/src/viewbox.h b/src/viewbox.h index 661a9b24a..2f107132c 100644 --- a/src/viewbox.h +++ b/src/viewbox.h @@ -17,13 +17,6 @@ #include <2geom/rect.h> #include -#include "display/sp-canvas.h" - -namespace Inkscape { - namespace Display { - class TemporaryItem; - } -} class SPItemCtx; @@ -43,11 +36,11 @@ public: /* Child to parent additional transform */ Geom::Affine c2p; + Geom::Affine vbt; Geom::Affine rotation; double angle; double previous_angle; bool rotated; - Inkscape::Display::TemporaryItem *page_border_rotated; double get_rotation(); void set_rotation(double angle_val); diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index df943b241..f648d8430 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1645,7 +1645,6 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) gtk_widget_show_all (dtw->menubar); SPNamedView *nv = dtw->desktop->namedview; dtw->rotatebar = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,0.0,360.0,45.0); - gtk_range_set_value(GTK_RANGE (dtw->rotatebar), nv->document_rotation); gtk_widget_set_name(dtw->rotatebar, "RotateBar"); gtk_widget_show_all (dtw->rotatebar); GtkWidget * containermenu = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); @@ -1661,7 +1660,11 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) gtk_box_pack_start (GTK_BOX (dtw->vbox), containermenu, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (dtw->rotatebar), "button-release-event", G_CALLBACK (sp_desktop_widget_rotate_document), dtw); g_signal_connect (G_OBJECT (dtw->rotatebar), "key-release-event", G_CALLBACK (sp_desktop_widget_rotate_document), dtw); - + gtk_range_set_value(GTK_RANGE (dtw->rotatebar), nv->document_rotation); + //TODO: Find a better way to refresh the widget + gtk_widget_set_visible (dtw->rotatebar,false); + gtk_widget_set_visible (dtw->rotatebar,true); + sp_namedview_set_document_rotation(nv); dtw->layoutWidgets(); std::vector toolboxes; @@ -1703,7 +1706,11 @@ sp_desktop_widget_update_rulers (SPDesktopWidget *dtw) void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) { SPNamedView *nv=SP_NAMEDVIEW(obj); - + gtk_range_set_value(GTK_RANGE(this->rotatebar), desktop->namedview->document_rotation); + sp_namedview_set_document_rotation(nv); + //TODO: Find a better way to refresh the widget + gtk_widget_set_visible (this->rotatebar,false); + gtk_widget_set_visible (this->rotatebar,true); if (flags & SP_OBJECT_MODIFIED_FLAG) { this->dt2r = 1. / nv->display_units->factor; this->ruler_origin = Geom::Point(0,0); //nv->gridorigin; Why was the grid origin used here? @@ -1756,15 +1763,27 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) static void sp_desktop_widget_rotate_document(GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw) { - SPNamedView *nv = dtw->desktop->namedview; - double value = gtk_range_get_value(GTK_RANGE(widget)); - if (value != nv->document_rotation) { - sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value); - SPObject *updated = nv->document->getObjectByRepr(nv->getRepr()); - if (updated) { - updated->updateRepr(); + if (event->type == GDK_BUTTON_RELEASE || + event->key.keyval == GDK_KEY_Page_Down || + event->key.keyval == GDK_KEY_Page_Up || + event->key.keyval == GDK_KEY_End || + event->key.keyval == GDK_KEY_Begin || + event->key.keyval == GDK_KEY_Up || + event->key.keyval == GDK_KEY_Down || + event->key.keyval == GDK_KEY_Left || + event->key.keyval == GDK_KEY_Right) + { + SPNamedView *nv = dtw->desktop->namedview; + double value = gtk_range_get_value(GTK_RANGE(widget)); + if (value != nv->document_rotation) { + nv->document_rotation = value; + sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value); + SPObject *updated = SP_OBJECT(nv); + if (updated) { + updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + gtk_widget_grab_focus(dtw->rotatebar); } - reinterpret_cast(dtw->desktop->currentLayer())->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } -- cgit v1.2.3 From b949d0bdb9f751a94fd71f8bab7610d9a6a11a90 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 10 Oct 2016 16:06:22 +0200 Subject: Fix some canvas item problems and refresh items on rotate (bzr r15142.1.10) --- src/document-undo.cpp | 51 +++++++++++++++++++++++++-------------------------- src/file.cpp | 4 +++- src/sp-namedview.cpp | 14 ++++++++++---- 3 files changed, 38 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 023843fcc..ae90c916e 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -240,53 +240,52 @@ static void perform_document_update(SPDocument &doc) { gboolean Inkscape::DocumentUndo::undo(SPDocument *doc) { - using Inkscape::Debug::EventTracker; - using Inkscape::Debug::SimpleEvent; + using Inkscape::Debug::EventTracker; + using Inkscape::Debug::SimpleEvent; - gboolean ret; + gboolean ret; - EventTracker > tracker("undo"); + EventTracker > tracker("undo"); - g_assert (doc != NULL); - g_assert (doc->priv != NULL); - g_assert (doc->priv->sensitive); + g_assert (doc != NULL); + g_assert (doc->priv != NULL); + g_assert (doc->priv->sensitive); - doc->priv->sensitive = FALSE; + doc->priv->sensitive = FALSE; doc->priv->seeking = true; - doc->actionkey.clear(); + doc->actionkey.clear(); - finish_incomplete_transaction(*doc); + finish_incomplete_transaction(*doc); - if (! doc->priv->undo.empty()) { - Inkscape::Event *log = doc->priv->undo.back(); - doc->priv->undo.pop_back(); - sp_repr_undo_log (log->event); - perform_document_update(*doc); + if (! doc->priv->undo.empty()) { + Inkscape::Event *log = doc->priv->undo.back(); + doc->priv->undo.pop_back(); + sp_repr_undo_log (log->event); + perform_document_update(*doc); - doc->priv->redo.push_back(log); + doc->priv->redo.push_back(log); doc->setModifiedSinceSave(); doc->priv->undoStackObservers.notifyUndoEvent(log); - ret = TRUE; - } else { - ret = FALSE; - } + ret = TRUE; + } else { + ret = FALSE; + } - sp_repr_begin_transaction (doc->rdoc); + sp_repr_begin_transaction (doc->rdoc); - doc->priv->sensitive = TRUE; + doc->priv->sensitive = TRUE; doc->priv->seeking = false; - if (ret) - INKSCAPE.external_change(); + if (ret) INKSCAPE.external_change(); + SPObject *updated = doc->getRoot(); if (updated) { updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - - return ret; + return ret; } gboolean Inkscape::DocumentUndo::redo(SPDocument *doc) diff --git a/src/file.cpp b/src/file.cpp index 5a51bbf52..324998774 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -257,9 +257,10 @@ bool sp_file_open(const Glib::ustring &uri, bool replace_empty) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Display::TemporaryItem *page_border_rotated = NULL; if (desktop) { desktop->setWaitingCursor(); - desktop->remove_temporary_canvasitem(sp_document_namedview(desktop->getDocument(), NULL)->page_border_rotated); + page_border_rotated = sp_document_namedview(desktop->getDocument(), NULL)->page_border_rotated; } SPDocument *doc = NULL; @@ -295,6 +296,7 @@ bool sp_file_open(const Glib::ustring &uri, doc->ensureUpToDate(); // TODO this will trigger broken link warnings, etc. desktop->change_document(doc); doc->emitResizedSignal(doc->getWidth().value("px"), doc->getHeight().value("px")); + desktop->remove_temporary_canvasitem(page_border_rotated); } else { // create a whole new desktop and window SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); // TODO this will trigger broken link warnings, etc. diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index ff0ac8336..df0778265 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -960,6 +960,7 @@ static void sp_namedview_lock_guides(SPNamedView *nv) void sp_namedview_set_document_rotation(SPNamedView *nv) { + if ( nv->document->getRoot()->get_rotation() == nv->document_rotation) return; if(!nv->getViewList().empty()) { // >0 Desktops SPDesktop *desktop = nv->getViewList()[0]; desktop->remove_temporary_canvasitem(nv->page_border_rotated); @@ -992,9 +993,10 @@ void sp_namedview_set_document_rotation(SPNamedView *nv) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); nv->showborder = prefs->getBool("/template/base/showborder", 1.0); } -// //TODO: fix ti for work: To update knots of selected items -// SPDesktop * desktop = SP_ACTIVE_DESKTOP; -// if (desktop) { + + SPDesktop * desktop = SP_ACTIVE_DESKTOP; + if (desktop) { +//TODO: Remove knots of shapes on selected items // Inkscape::Selection * sel = desktop->getSelection(); // std::vector il(sel->items().begin(), sel->items().end()); // for (std::vector::const_iterator l = il.begin(); l != il.end(); l++){ @@ -1002,7 +1004,11 @@ void sp_namedview_set_document_rotation(SPNamedView *nv) // sel->remove(item->getRepr()); // sel->add(item->getRepr()); // } -// } + SPObject *updated = desktop->getDocument()->getRoot(); + if (updated) { + updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + } } static void sp_namedview_show_single_guide(SPGuide* guide, bool show) -- cgit v1.2.3 From 4b43aeadc203a33bc854bcc40d986b0d1ff5f4f8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Oct 2016 22:24:30 +0200 Subject: Working with rotate widget (bzr r15142.1.11) --- src/widgets/desktop-widget.cpp | 93 +++++++++++++++++++++++++++++++++++++++++- src/widgets/desktop-widget.h | 2 + src/widgets/widget-sizes.h | 1 + 3 files changed, 94 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index f648d8430..6d07cbfd3 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -113,6 +113,17 @@ static gdouble sp_dtw_zoom_display_to_value (gdouble value); static gint sp_dtw_zoom_input (GtkSpinButton *spin, gdouble *new_val, gpointer data); static bool sp_dtw_zoom_output (GtkSpinButton *spin, gpointer data); static void sp_dtw_zoom_value_changed (GtkSpinButton *spin, gpointer data); +static void sp_dtw_rotate_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data); +//static void sp_dtw_rotate_menu_handler (SPDesktop *dt, gdouble factor); +//static void sp_dtw_rotate_minus_135 (GtkMenuItem *item, gpointer data); +//static void sp_dtw_rotate_minus_90 (GtkMenuItem *item, gpointer data); +//static void sp_dtw_rotate_minus_45 (GtkMenuItem *item, gpointer data); +//static void sp_dtw_rotate_0 (GtkMenuItem *item, gpointer data); +//static void sp_dtw_rotate_45 (GtkMenuItem *item, gpointer data); +//static void sp_dtw_rotate_90 (GtkMenuItem *item, gpointer data); +//static void sp_dtw_rotate_135 (GtkMenuItem *item, gpointer data); +//static void sp_dtw_rotate_180 (GtkMenuItem *item, gpointer data); + static void sp_dtw_zoom_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data); static void sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor); static void sp_dtw_zoom_50 (GtkMenuItem *item, gpointer data); @@ -601,6 +612,20 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) g_signal_connect (G_OBJECT (dtw->zoom_status), "key-press-event", G_CALLBACK (spinbutton_keypress), dtw->zoom_status); dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->zoom_status), "value_changed", G_CALLBACK (sp_dtw_zoom_value_changed), dtw); dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->zoom_status), "populate_popup", G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); + + // Rotate status spinbutton + dtw->rotation_status = gtk_spin_button_new_with_range (-180,180, 1.0); + gtk_widget_set_name(dtw->rotation_status, "RotationStatus"); + gtk_widget_set_tooltip_text (dtw->rotation_status, _("Rotation")); + gtk_widget_set_size_request (dtw->rotation_status, STATUS_ROTATION_WIDTH, -1); + gtk_entry_set_width_chars (GTK_ENTRY (dtw->rotation_status), 6); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dtw->rotation_status), FALSE); + gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (dtw->rotation_status), GTK_UPDATE_ALWAYS); + g_object_set_data (G_OBJECT (dtw->rotation_status), "dtw", dtw->canvas); + g_signal_connect (G_OBJECT (dtw->rotation_status), "focus-in-event", G_CALLBACK (spinbutton_focus_in), dtw->rotation_status); + g_signal_connect (G_OBJECT (dtw->rotation_status), "key-press-event", G_CALLBACK (spinbutton_keypress), dtw->rotation_status); + dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "value_changed", G_CALLBACK (sp_desktop_widget_rotate_document), dtw); + dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "populate_popup", G_CALLBACK (sp_dtw_rotate_populate_popup), dtw); // Cursor coordinates dtw->coord_status = gtk_grid_new(); @@ -627,12 +652,16 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) auto label_z = gtk_label_new(_("Z:")); gtk_widget_set_name(label_z, "ZLabel"); + auto label_r = gtk_label_new(_("R:")); + gtk_widget_set_name(label_r, "RLabel"); gtk_widget_set_halign(dtw->coord_status_x, GTK_ALIGN_END); gtk_widget_set_halign(dtw->coord_status_y, GTK_ALIGN_END); gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->coord_status_x, 2, 0, 1, 1); gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->coord_status_y, 2, 1, 1, 1); - gtk_grid_attach(GTK_GRID(dtw->coord_status), label_z, 3, 0, 1, 2); - gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->zoom_status, 4, 0, 1, 2); + gtk_grid_attach(GTK_GRID(dtw->coord_status), label_z, 3, 0, 1, 1); + gtk_grid_attach(GTK_GRID(dtw->coord_status), label_r, 3, 1, 1, 1); + gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->zoom_status, 4, 0, 1, 1); + gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->rotation_status, 4, 1, 1, 1); sp_set_font_size_smaller (dtw->coord_status); @@ -700,6 +729,9 @@ static void sp_desktop_widget_dispose(GObject *object) g_signal_handlers_disconnect_matched (G_OBJECT (dtw->zoom_status), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dtw->zoom_status); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_value_changed), dtw); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); + g_signal_handlers_disconnect_matched (G_OBJECT (dtw->rotation_status), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dtw->rotation_status); + g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_desktop_widget_rotate_document), dtw); + g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->canvas), (gpointer) G_CALLBACK (sp_desktop_widget_event), dtw); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->canvas_tbl), (gpointer) G_CALLBACK (canvas_tbl_size_allocate), dtw); @@ -2006,6 +2038,63 @@ sp_dtw_zoom_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data) gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); } + +static void +sp_dtw_rotate_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data) +{ + GList *children, *iter; + GtkWidget *item; + SPDesktop *dt = SP_DESKTOP_WIDGET (data)->desktop; + + children = gtk_container_get_children (GTK_CONTAINER (menu)); + for ( iter = children ; iter ; iter = g_list_next (iter)) { + gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (iter->data)); + } + g_list_free (children); + + item = gtk_menu_item_new_with_label ("-180º"); +// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_180), dt); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("-135º"); +// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_135), dt); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("-90º"); +// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_90), dt); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("-45º"); +// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_45), dt); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("0º"); +// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_0), dt); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("45º"); +// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_45), dt); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + + item = gtk_menu_item_new_with_label ("90º"); +// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_90), dt); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + + item = gtk_menu_item_new_with_label ("135º"); +// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_135), dt); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); +} + static void sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor) { diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index 26eaf1ff3..61c3b8b37 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -97,7 +97,9 @@ struct SPDesktopWidget { GtkWidget *select_status; GtkWidget *select_status_eventbox; GtkWidget *zoom_status; + GtkWidget *rotation_status; gulong zoom_update; + gulong rotation_update; Inkscape::UI::Widget::Dock *dock; diff --git a/src/widgets/widget-sizes.h b/src/widgets/widget-sizes.h index 87c7ca2e0..186cf4730 100644 --- a/src/widgets/widget-sizes.h +++ b/src/widgets/widget-sizes.h @@ -28,6 +28,7 @@ #define STATUS_BAR_FONT_SIZE 10000 #define STATUS_ZOOM_WIDTH 57 +#define STATUS_ROTATION_WIDTH 57 #define SELECTED_STYLE_SB_WIDTH 48 #define SELECTED_STYLE_WIDTH 190 -- cgit v1.2.3 From c57802d04d26ecf8618ffe8f1f9a90c79d36ed92 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 15 Oct 2016 01:48:35 +0200 Subject: Change from slider to spin (bzr r15142.1.13) --- src/viewbox.cpp | 2 +- src/widgets/desktop-widget.cpp | 166 +++++++++++++++++++++-------------------- 2 files changed, 88 insertions(+), 80 deletions(-) (limited to 'src') diff --git a/src/viewbox.cpp b/src/viewbox.cpp index 15b5b19c4..ebfc04d8a 100644 --- a/src/viewbox.cpp +++ b/src/viewbox.cpp @@ -249,7 +249,6 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { vbt[5] = y - scale_y * this->viewBox.top(); /* Append viewbox and turn transformation */ Geom::Point page_center = this->viewBox.midpoint(); - Geom::Affine center_rotation = Geom::identity(); SPDesktop * desktop = SP_ACTIVE_DESKTOP; if (this->angle > 0.0 || this->angle < 0.0 ) { //!0 if (desktop) { @@ -264,6 +263,7 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { if (desktop && this->rotated) { Geom::Rect view = desktop->get_display_area(); Geom::Point view_center = desktop->doc2dt(view.midpoint()); + Geom::Affine center_rotation = Geom::identity(); center_rotation *= Geom::Translate(page_center * vbt).inverse(); center_rotation *= Geom::Rotate(Geom::rad_from_deg(this->angle - this->previous_angle)); center_rotation *= Geom::Translate(page_center * vbt); diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 6d07cbfd3..f8ba25191 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -105,7 +105,7 @@ static void sp_update_guides_lock( GtkWidget *button, gpointer data ); static void cms_adjust_toggled( GtkWidget *button, gpointer data ); #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) static void cms_adjust_set_sensitive( SPDesktopWidget *dtw, bool enabled ); -static void sp_desktop_widget_rotate_document(GtkWidget *widget, GdkEvent *eventdtw, SPDesktopWidget *dtw); +static void sp_desktop_widget_rotate_document(GtkSpinButton *spin, SPDesktopWidget *dtw); static void sp_desktop_widget_adjustment_value_changed (GtkAdjustment *adj, SPDesktopWidget *dtw); static gdouble sp_dtw_zoom_value_to_display (gdouble value); @@ -113,16 +113,15 @@ static gdouble sp_dtw_zoom_display_to_value (gdouble value); static gint sp_dtw_zoom_input (GtkSpinButton *spin, gdouble *new_val, gpointer data); static bool sp_dtw_zoom_output (GtkSpinButton *spin, gpointer data); static void sp_dtw_zoom_value_changed (GtkSpinButton *spin, gpointer data); -static void sp_dtw_rotate_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data); -//static void sp_dtw_rotate_menu_handler (SPDesktop *dt, gdouble factor); -//static void sp_dtw_rotate_minus_135 (GtkMenuItem *item, gpointer data); -//static void sp_dtw_rotate_minus_90 (GtkMenuItem *item, gpointer data); -//static void sp_dtw_rotate_minus_45 (GtkMenuItem *item, gpointer data); -//static void sp_dtw_rotate_0 (GtkMenuItem *item, gpointer data); -//static void sp_dtw_rotate_45 (GtkMenuItem *item, gpointer data); -//static void sp_dtw_rotate_90 (GtkMenuItem *item, gpointer data); -//static void sp_dtw_rotate_135 (GtkMenuItem *item, gpointer data); -//static void sp_dtw_rotate_180 (GtkMenuItem *item, gpointer data); +static void sp_dtw_rotation_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data); +static void sp_dtw_rotate_minus_180 (GtkMenuItem *item, SPDesktopWidget * data); +static void sp_dtw_rotate_minus_135 (GtkMenuItem *item, SPDesktopWidget * data); +static void sp_dtw_rotate_minus_90 (GtkMenuItem *item, SPDesktopWidget * data); +static void sp_dtw_rotate_minus_45 (GtkMenuItem *item, SPDesktopWidget * data); +static void sp_dtw_rotate_0 (GtkMenuItem *item, SPDesktopWidget * data); +static void sp_dtw_rotate_45 (GtkMenuItem *item, SPDesktopWidget * data); +static void sp_dtw_rotate_90 (GtkMenuItem *item, SPDesktopWidget * data); +static void sp_dtw_rotate_135 (GtkMenuItem *item, SPDesktopWidget * data); static void sp_dtw_zoom_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data); static void sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor); @@ -624,8 +623,8 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) g_object_set_data (G_OBJECT (dtw->rotation_status), "dtw", dtw->canvas); g_signal_connect (G_OBJECT (dtw->rotation_status), "focus-in-event", G_CALLBACK (spinbutton_focus_in), dtw->rotation_status); g_signal_connect (G_OBJECT (dtw->rotation_status), "key-press-event", G_CALLBACK (spinbutton_keypress), dtw->rotation_status); - dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "value_changed", G_CALLBACK (sp_desktop_widget_rotate_document), dtw); - dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "populate_popup", G_CALLBACK (sp_dtw_rotate_populate_popup), dtw); + dtw->rotation_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "value_changed", G_CALLBACK (sp_desktop_widget_rotate_document), dtw); + dtw->rotation_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "populate_popup", G_CALLBACK (sp_dtw_rotation_populate_popup), dtw); // Cursor coordinates dtw->coord_status = gtk_grid_new(); @@ -731,7 +730,7 @@ static void sp_desktop_widget_dispose(GObject *object) g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); g_signal_handlers_disconnect_matched (G_OBJECT (dtw->rotation_status), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dtw->rotation_status); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_desktop_widget_rotate_document), dtw); - g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); + g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_dtw_rotation_populate_popup), dtw); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->canvas), (gpointer) G_CALLBACK (sp_desktop_widget_event), dtw); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->canvas_tbl), (gpointer) G_CALLBACK (canvas_tbl_size_allocate), dtw); @@ -1464,12 +1463,6 @@ void SPDesktopWidget::layoutWidgets() gtk_widget_show_all (dtw->menubar); } - if (!prefs->getBool(pref_root + "menu/state", true)) { - gtk_widget_hide (dtw->rotatebar); - } else { - gtk_widget_show_all (dtw->rotatebar); - } - if (!prefs->getBool(pref_root + "commands/state", true)) { gtk_widget_hide (dtw->commands_toolbox); } else { @@ -1676,29 +1669,10 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) gtk_widget_set_name(dtw->menubar, "MenuBar"); gtk_widget_show_all (dtw->menubar); SPNamedView *nv = dtw->desktop->namedview; - dtw->rotatebar = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,0.0,360.0,45.0); - gtk_widget_set_name(dtw->rotatebar, "RotateBar"); - gtk_widget_show_all (dtw->rotatebar); - GtkWidget * containermenu = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_widget_show_all (containermenu); - GtkWidget * separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL); - gtk_widget_show_all(separator); - GtkWidget * label = gtk_label_new (_("Rotation")); - gtk_widget_show_all(label); - gtk_box_pack_start (GTK_BOX (containermenu), dtw->menubar, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (containermenu), separator, FALSE, FALSE, 10); - gtk_box_pack_start (GTK_BOX (containermenu), dtw->rotatebar, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (containermenu), label, FALSE, FALSE, 10); - gtk_box_pack_start (GTK_BOX (dtw->vbox), containermenu, TRUE, TRUE, 0); - g_signal_connect (G_OBJECT (dtw->rotatebar), "button-release-event", G_CALLBACK (sp_desktop_widget_rotate_document), dtw); - g_signal_connect (G_OBJECT (dtw->rotatebar), "key-release-event", G_CALLBACK (sp_desktop_widget_rotate_document), dtw); - gtk_range_set_value(GTK_RANGE (dtw->rotatebar), nv->document_rotation); - //TODO: Find a better way to refresh the widget - gtk_widget_set_visible (dtw->rotatebar,false); - gtk_widget_set_visible (dtw->rotatebar,true); - sp_namedview_set_document_rotation(nv); + gtk_box_pack_start (GTK_BOX (dtw->vbox), dtw->menubar, TRUE, TRUE, 0); dtw->layoutWidgets(); - + gtk_spin_button_set_value(GTK_SPIN_BUTTON (dtw->rotation_status), namedview->document_rotation); + sp_namedview_set_document_rotation(namedview); std::vector toolboxes; toolboxes.push_back(dtw->tool_toolbox); toolboxes.push_back(dtw->aux_toolbox); @@ -1738,11 +1712,9 @@ sp_desktop_widget_update_rulers (SPDesktopWidget *dtw) void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) { SPNamedView *nv=SP_NAMEDVIEW(obj); - gtk_range_set_value(GTK_RANGE(this->rotatebar), desktop->namedview->document_rotation); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(this->rotation_status), desktop->namedview->document_rotation); sp_namedview_set_document_rotation(nv); - //TODO: Find a better way to refresh the widget - gtk_widget_set_visible (this->rotatebar,false); - gtk_widget_set_visible (this->rotatebar,true); + if (flags & SP_OBJECT_MODIFIED_FLAG) { this->dt2r = 1. / nv->display_units->factor; this->ruler_origin = Geom::Point(0,0); //nv->gridorigin; Why was the grid origin used here? @@ -1793,30 +1765,19 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) } static void -sp_desktop_widget_rotate_document(GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw) -{ - if (event->type == GDK_BUTTON_RELEASE || - event->key.keyval == GDK_KEY_Page_Down || - event->key.keyval == GDK_KEY_Page_Up || - event->key.keyval == GDK_KEY_End || - event->key.keyval == GDK_KEY_Begin || - event->key.keyval == GDK_KEY_Up || - event->key.keyval == GDK_KEY_Down || - event->key.keyval == GDK_KEY_Left || - event->key.keyval == GDK_KEY_Right) - { - SPNamedView *nv = dtw->desktop->namedview; - double value = gtk_range_get_value(GTK_RANGE(widget)); - if (value != nv->document_rotation) { - nv->document_rotation = value; - sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value); - SPObject *updated = SP_OBJECT(nv); - if (updated) { - updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } - gtk_widget_grab_focus(dtw->rotatebar); +sp_desktop_widget_rotate_document(GtkSpinButton *spin, SPDesktopWidget *dtw) +{ + SPNamedView *nv = dtw->desktop->namedview; + double value = gtk_spin_button_get_value (spin); + if (!dtw->desktop->getDocument()->getRoot()->rotated && value != nv->document_rotation) { + nv->document_rotation = value; + sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value); + SPObject *updated = SP_OBJECT(nv); + if (updated) { + updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } + spinbutton_defocus (GTK_WIDGET(spin)); } @@ -2040,12 +2001,11 @@ sp_dtw_zoom_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data) static void -sp_dtw_rotate_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data) +sp_dtw_rotation_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data) { GList *children, *iter; GtkWidget *item; - SPDesktop *dt = SP_DESKTOP_WIDGET (data)->desktop; - + SPDesktopWidget *dtw = static_cast(data); children = gtk_container_get_children (GTK_CONTAINER (menu)); for ( iter = children ; iter ; iter = g_list_next (iter)) { gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (iter->data)); @@ -2053,48 +2013,96 @@ sp_dtw_rotate_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data) g_list_free (children); item = gtk_menu_item_new_with_label ("-180º"); -// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_180), dt); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_180), dtw); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = gtk_menu_item_new_with_label ("-135º"); -// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_135), dt); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_135), dtw); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = gtk_menu_item_new_with_label ("-90º"); -// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_90), dt); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_90), dtw); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = gtk_menu_item_new_with_label ("-45º"); -// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_45), dt); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_45), dtw); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = gtk_menu_item_new_with_label ("0º"); -// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_0), dt); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_0), dtw); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = gtk_menu_item_new_with_label ("45º"); -// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_45), dt); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_45), dtw); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = gtk_menu_item_new_with_label ("90º"); -// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_90), dt); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_90), dtw); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = gtk_menu_item_new_with_label ("135º"); -// g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_135), dt); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_135), dtw); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); } +static void +sp_dtw_rotate_minus_180 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status),-180); +} + +static void +sp_dtw_rotate_minus_135 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), -135); +} + +static void +sp_dtw_rotate_minus_90 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), -90); +} + +static void +sp_dtw_rotate_minus_45 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), -45); +} + +static void +sp_dtw_rotate_0 (GtkMenuItem */*item*/,SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), 0); +} + +static void +sp_dtw_rotate_45 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), 45); +} + +static void +sp_dtw_rotate_90 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), 90); +} + +static void +sp_dtw_rotate_135 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), 135); +} + static void sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor) { -- cgit v1.2.3 From 3aa73f0b577fd25f64e0414a5cbfa74c076f57be Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 15 Oct 2016 14:27:30 +0200 Subject: Reposition widget and add degree symbol (bzr r15142.1.14) --- src/widgets/desktop-widget.cpp | 60 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index f8ba25191..16d71b4d2 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -108,11 +108,8 @@ static void cms_adjust_set_sensitive( SPDesktopWidget *dtw, bool enabled ); static void sp_desktop_widget_rotate_document(GtkSpinButton *spin, SPDesktopWidget *dtw); static void sp_desktop_widget_adjustment_value_changed (GtkAdjustment *adj, SPDesktopWidget *dtw); -static gdouble sp_dtw_zoom_value_to_display (gdouble value); -static gdouble sp_dtw_zoom_display_to_value (gdouble value); -static gint sp_dtw_zoom_input (GtkSpinButton *spin, gdouble *new_val, gpointer data); -static bool sp_dtw_zoom_output (GtkSpinButton *spin, gpointer data); -static void sp_dtw_zoom_value_changed (GtkSpinButton *spin, gpointer data); +static gint sp_dtw_rotation_input (GtkSpinButton *spin, gdouble *new_val, gpointer data); +static bool sp_dtw_rotation_output (GtkSpinButton *spin, gpointer data); static void sp_dtw_rotation_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data); static void sp_dtw_rotate_minus_180 (GtkMenuItem *item, SPDesktopWidget * data); static void sp_dtw_rotate_minus_135 (GtkMenuItem *item, SPDesktopWidget * data); @@ -122,7 +119,11 @@ static void sp_dtw_rotate_0 (GtkMenuItem *item, SPDesktopWidget * data); static void sp_dtw_rotate_45 (GtkMenuItem *item, SPDesktopWidget * data); static void sp_dtw_rotate_90 (GtkMenuItem *item, SPDesktopWidget * data); static void sp_dtw_rotate_135 (GtkMenuItem *item, SPDesktopWidget * data); - +static gdouble sp_dtw_zoom_value_to_display (gdouble value); +static gdouble sp_dtw_zoom_display_to_value (gdouble value); +static gint sp_dtw_zoom_input (GtkSpinButton *spin, gdouble *new_val, gpointer data); +static bool sp_dtw_zoom_output (GtkSpinButton *spin, gpointer data); +static void sp_dtw_zoom_value_changed (GtkSpinButton *spin, gpointer data); static void sp_dtw_zoom_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data); static void sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor); static void sp_dtw_zoom_50 (GtkMenuItem *item, gpointer data); @@ -611,21 +612,34 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) g_signal_connect (G_OBJECT (dtw->zoom_status), "key-press-event", G_CALLBACK (spinbutton_keypress), dtw->zoom_status); dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->zoom_status), "value_changed", G_CALLBACK (sp_dtw_zoom_value_changed), dtw); dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->zoom_status), "populate_popup", G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); + auto css_provider_spinbutton = Gtk::CssProvider::create(); + css_provider_spinbutton->load_from_data("* { padding-left: 2; padding-right: 2; padding-top: 0; padding-bottom: 0;}"); + auto zoomstat = Glib::wrap(dtw->zoom_status); + zoomstat->set_name("ZoomStatus"); + auto context_zoom = zoomstat->get_style_context(); + context_zoom->add_provider(css_provider_spinbutton, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); // Rotate status spinbutton dtw->rotation_status = gtk_spin_button_new_with_range (-180,180, 1.0); - gtk_widget_set_name(dtw->rotation_status, "RotationStatus"); gtk_widget_set_tooltip_text (dtw->rotation_status, _("Rotation")); gtk_widget_set_size_request (dtw->rotation_status, STATUS_ROTATION_WIDTH, -1); gtk_entry_set_width_chars (GTK_ENTRY (dtw->rotation_status), 6); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dtw->rotation_status), FALSE); gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (dtw->rotation_status), GTK_UPDATE_ALWAYS); + g_signal_connect (G_OBJECT (dtw->rotation_status), "input", G_CALLBACK (sp_dtw_rotation_input), dtw); + g_signal_connect (G_OBJECT (dtw->rotation_status), "output", G_CALLBACK (sp_dtw_rotation_output), dtw); g_object_set_data (G_OBJECT (dtw->rotation_status), "dtw", dtw->canvas); g_signal_connect (G_OBJECT (dtw->rotation_status), "focus-in-event", G_CALLBACK (spinbutton_focus_in), dtw->rotation_status); g_signal_connect (G_OBJECT (dtw->rotation_status), "key-press-event", G_CALLBACK (spinbutton_keypress), dtw->rotation_status); dtw->rotation_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "value_changed", G_CALLBACK (sp_desktop_widget_rotate_document), dtw); dtw->rotation_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "populate_popup", G_CALLBACK (sp_dtw_rotation_populate_popup), dtw); + auto rotstat = Glib::wrap(dtw->rotation_status); + rotstat->set_name("RotationStatus"); + auto context_rotation = rotstat->get_style_context(); + context_rotation->add_provider(css_provider_spinbutton, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + + // Cursor coordinates dtw->coord_status = gtk_grid_new(); gtk_widget_set_name(dtw->coord_status, "CoordinateAndZStatus"); @@ -657,10 +671,10 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_widget_set_halign(dtw->coord_status_y, GTK_ALIGN_END); gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->coord_status_x, 2, 0, 1, 1); gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->coord_status_y, 2, 1, 1, 1); - gtk_grid_attach(GTK_GRID(dtw->coord_status), label_z, 3, 0, 1, 1); - gtk_grid_attach(GTK_GRID(dtw->coord_status), label_r, 3, 1, 1, 1); - gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->zoom_status, 4, 0, 1, 1); - gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->rotation_status, 4, 1, 1, 1); + gtk_grid_attach(GTK_GRID(dtw->coord_status), label_z, 3, 0, 1, 2); + gtk_grid_attach(GTK_GRID(dtw->coord_status), label_r, 5, 0, 1, 2); + gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->zoom_status, 4, 0, 1, 2); + gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->rotation_status, 6, 0, 1, 2); sp_set_font_size_smaller (dtw->coord_status); @@ -728,6 +742,8 @@ static void sp_desktop_widget_dispose(GObject *object) g_signal_handlers_disconnect_matched (G_OBJECT (dtw->zoom_status), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dtw->zoom_status); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_value_changed), dtw); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); + g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK(sp_dtw_rotation_input), dtw); + g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK(sp_dtw_rotation_output), dtw); g_signal_handlers_disconnect_matched (G_OBJECT (dtw->rotation_status), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dtw->rotation_status); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_desktop_widget_rotate_document), dtw); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_dtw_rotation_populate_popup), dtw); @@ -1861,6 +1877,28 @@ sp_dtw_zoom_output (GtkSpinButton *spin, gpointer /*data*/) return TRUE; } +static gint +sp_dtw_rotation_input (GtkSpinButton *spin, gdouble *new_val, gpointer /*data*/) +{ + gdouble new_scrolled = gtk_spin_button_get_value (spin); + const gchar *b = gtk_entry_get_text (GTK_ENTRY (spin)); + gdouble new_typed = atof (b); + + *new_val = new_typed; + + return TRUE; +} + +static bool +sp_dtw_rotation_output (GtkSpinButton *spin, gpointer /*data*/) +{ + gchar b[64]; + double val = gtk_spin_button_get_value (spin); + g_snprintf (b, 64, "%3.0fº", val); + gtk_entry_set_text (GTK_ENTRY (spin), b); + return TRUE; +} + static void sp_dtw_zoom_value_changed (GtkSpinButton *spin, gpointer data) { -- cgit v1.2.3 From f2d2c7740567dcf2452c41d8332380708f557157 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 19 Oct 2016 12:50:29 +0200 Subject: Working with rotate preview (bzr r15142.1.15) --- src/display/sp-canvas.cpp | 169 ++++++++++++++++++++++++++++++++++++++++- src/display/sp-canvas.h | 4 +- src/ui/tools/tool-base.cpp | 2 - src/widgets/desktop-widget.cpp | 24 +++--- 4 files changed, 183 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 9201168ef..36d0b7e7c 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -27,15 +27,19 @@ #include "helper/sp-marshal.h" #include <2geom/rect.h> #include <2geom/affine.h> -#include "display/cairo-utils.h" #include "display/sp-canvas.h" #include "display/sp-canvas-group.h" +#include "display/rendermode.h" +#include "display/cairo-utils.h" +#include "display/cairo-templates.h" +#include "display/drawing-context.h" +#include "display/drawing-item.h" +#include "display/nr-filter-colormatrix.h" +#include "display/canvas-arena.h" #include "preferences.h" #include "inkscape.h" #include "sodipodi-ctrlrect.h" #include "cms-system.h" -#include "display/rendermode.h" -#include "display/cairo-utils.h" #include "debug/gdk-event-latency-tracker.h" #include "desktop.h" #include "color.h" @@ -1945,6 +1949,165 @@ void SPCanvas::scrollTo(double cx, double cy, unsigned int clear, bool is_scroll } addIdle(); } +gdouble grayscale_value_matrix[20] = { + 0.21, 0.72, 0.072, 0, 0, + 0.21, 0.72, 0.072, 0, 0, + 0.21, 0.72, 0.072, 0, 0, + 0 , 0 , 0 , 1, 0 + }; +cairo_surface_t *surface_rotated; +cairo_surface_t *surface_origin; +cairo_surface_t *surface_measure; +double start_angle = 0; +bool started = false; +void SPCanvas::startRotateTo(double angle) +{ + if (!_backing_store || started) { + return; + } + start_angle = angle; + started = true; + GtkAllocation allocation; + gtk_widget_get_allocation(&_widget, &allocation); + int half_w = allocation.width/2; + int half_h = allocation.height/2; + int half_min = std::min(half_w,half_h); + cairo_surface_t *new_backing_store = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height); + cairo_t *cr = cairo_create(new_backing_store); + cairo_arc(cr, half_w, half_h, half_min-15, 0, 2*M_PI); + cairo_fill(cr); + cairo_set_operator(cr, CAIRO_OPERATOR_IN); + cairo_set_source_surface(cr, _backing_store, 0, 0); + cairo_paint(cr); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + cairo_arc(cr, half_w, half_h, half_min-16, 0, 2*M_PI); + cairo_set_source_rgba (cr, 1, 1, 1, 0.5); + cairo_stroke(cr); + cairo_destroy(cr); + surface_rotated = new_backing_store; + + cairo_surface_t *new_backing_store_measure = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height); + cr = cairo_create(new_backing_store_measure); + cairo_arc(cr, half_w, half_h, half_min-15, 0, 2*M_PI); + cairo_set_source_rgba (cr, 1, 1, 1, 0.2); + cairo_fill(cr); + cairo_translate(cr, half_w, half_h); + for (gint x = 0; x < 360 ; x++){ + gint ang = 360 - x ;//+ 90; + if (ang > 180) { + ang -= 360; + } + double rot = (-180.0 + x - start_angle)*(M_PI/180.); + double dist = half_min-9; + gint inverse = 1; + if((x- start_angle) < 91 || (x- start_angle) > 270) { + inverse = -1; + } + if(x%10 == 0) { + cairo_rotate(cr, -rot); + cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size(cr, 10.0); + cairo_text_extents_t extents; + std::string s = std::to_string(ang) + "º"; + cairo_text_extents(cr, s.c_str(), &extents); + //std::cout << extents.width/2 << "extents.x_bearing\n"; + cairo_translate(cr, (extents.width/2) * inverse * -1, (dist + ((extents.height/2)* inverse))); + if((x- start_angle) < 91 || (x- start_angle) > 270) { + cairo_rotate(cr, 180*(M_PI/180.0)); + } + cairo_text_path(cr, s.c_str()); + if((x- start_angle) < 91 || (x- start_angle) > 270) { + cairo_rotate(cr, -180*(M_PI/180.0)); + } + cairo_translate(cr, (extents.width/2) * inverse , (dist + ((extents.height/2)* inverse)) * -1); + cairo_set_source_rgba (cr, 1, 1, 1, 1); + cairo_fill(cr); + cairo_rotate(cr, rot); + } + cairo_rotate(cr, x*(M_PI/180.)); + if(x%5 == 0) { + cairo_move_to(cr, 0, half_min-30); + cairo_line_to(cr, 0, half_min-17); + } else { + cairo_move_to(cr, 0, half_min-20); + cairo_line_to(cr, 0, half_min-15); + } + cairo_line_to(cr, 0, half_min-15); + cairo_set_source_rgba (cr, 0, 0, 0, 0.4); + cairo_set_line_width (cr,1); + cairo_stroke(cr); + cairo_rotate(cr, -x*(M_PI/180.)); + } + cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); + cairo_translate(cr, -half_w, -half_h); + cairo_arc(cr, half_w, half_h, half_min-30, 0, 2*M_PI); + cairo_set_source_rgba (cr, 1, 1, 1, 1); + cairo_fill(cr); + cairo_destroy(cr); + surface_measure = new_backing_store_measure; + + cairo_surface_t *new_backing_store_grey = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height); + cr = cairo_create(new_backing_store_grey); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + cairo_set_source_surface(cr, _backing_store, 0, 0); + cairo_paint(cr); + Inkscape::Filters::FilterColorMatrix::ColorMatrixMatrix _grayscale_colormatrix = std::vector (grayscale_value_matrix, grayscale_value_matrix + 20); + cairo_surface_t *out = ink_cairo_surface_create_identical(new_backing_store_grey); + ink_cairo_surface_filter(new_backing_store_grey, out, _grayscale_colormatrix); + cairo_set_source_surface(cr, out, 0, 0); + cairo_surface_destroy(out); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_paint(cr); + cairo_destroy(cr); + surface_origin = new_backing_store_grey; + +} + +void SPCanvas::endRotateTo() +{ + if (!_backing_store) { + return; + } + started = false; + surface_rotated = NULL; + surface_origin = NULL; + gtk_widget_queue_draw(GTK_WIDGET(this)); + dirtyAll(); + addIdle(); +} + +void SPCanvas::rotateTo(SPCanvasItem * item, double angle) +{ + if (!_backing_store) { + return; + } + GtkAllocation allocation; + gtk_widget_get_allocation(&_widget, &allocation); + cairo_surface_t *new_backing_store = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height); + cairo_t *cr = cairo_create(new_backing_store); + cairo_set_source_surface(cr, surface_origin, 0, 0); + cairo_paint(cr); + cairo_set_source_rgba (cr, 0, 0, 0, 0.5); + cairo_paint(cr); + cairo_pattern_t *source_pattern; + cairo_matrix_t matrix; + source_pattern = cairo_pattern_create_for_surface (surface_rotated); + cairo_matrix_init_identity (&matrix); + cairo_matrix_translate (&matrix, allocation.width/2.0, allocation.height/2.0); + cairo_matrix_rotate (&matrix, Geom::rad_from_deg(angle - start_angle) * -1); + cairo_matrix_translate (&matrix, -allocation.width/2.0, -allocation.height/2.0); + cairo_pattern_set_matrix (source_pattern, &matrix); + cairo_set_source(cr, source_pattern); + cairo_paint(cr); + cairo_set_source_surface(cr, surface_measure, 0, 0); + cairo_paint(cr); + cairo_destroy(cr); + cairo_surface_destroy(_backing_store); + _backing_store = new_backing_store; + cairo_pattern_destroy (source_pattern); + gtk_widget_queue_draw(GTK_WIDGET(this)); + addIdle(); +} void SPCanvas::updateNow() { diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index 78d96d728..b78cdcdd5 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -72,7 +72,9 @@ GType sp_canvas_get_type() G_GNUC_CONST; struct SPCanvas { /// Scrolls canvas to specific position (cx and cy are measured in screen pixels). void scrollTo(double cx, double cy, unsigned int clear, bool is_scrolling = false); - + void startRotateTo(double angle); + void rotateTo(SPCanvasItem * item, double angle); + void endRotateTo(); /// Synchronously updates the canvas if necessary. void updateNow(); diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 8a35882b9..128a09878 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -345,7 +345,6 @@ bool ToolBase::root_handler(GdkEvent* event) { /* sp_desktop_dialog(); */ } break; - case GDK_BUTTON_PRESS: // save drag origin xp = (gint) event->button.x; @@ -446,7 +445,6 @@ bool ToolBase::root_handler(GdkEvent* event) { // do not drag if we're within tolerance from origin break; } - // Once the user has moved farther than tolerance from // the original location (indicating they intend to move // the object, not click), then always process the motion diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 16d71b4d2..e868dd2d6 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -62,7 +62,6 @@ #include "spw-utilities.h" #include "toolbox.h" #include "widget-sizes.h" - #include "verbs.h" #include #include @@ -1785,15 +1784,20 @@ sp_desktop_widget_rotate_document(GtkSpinButton *spin, SPDesktopWidget *dtw) { SPNamedView *nv = dtw->desktop->namedview; double value = gtk_spin_button_get_value (spin); - if (!dtw->desktop->getDocument()->getRoot()->rotated && value != nv->document_rotation) { - nv->document_rotation = value; - sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value); - SPObject *updated = SP_OBJECT(nv); - if (updated) { - updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } - } - spinbutton_defocus (GTK_WIDGET(spin)); +// if (!dtw->desktop->getDocument()->getRoot()->rotated && value != nv->document_rotation) { +// nv->document_rotation = value; +// sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value); +// SPObject *updated = SP_OBJECT(nv); +// if (updated) { +// updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +// } +// //dtw->desktop->canvas->endRotateTo(); +// } else if( value != nv->document_rotation ) { + dtw->desktop->canvas->startRotateTo(0); + dtw->desktop->canvas->rotateTo(dtw->desktop->getDrawing(),value); + if (value == 180) { dtw->desktop->canvas->endRotateTo();} +// } + spinbutton_defocus (GTK_WIDGET(spin)); } -- cgit v1.2.3 From ab9795b860412f259eecc095225893b9b130bc42 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 19 Oct 2016 22:02:50 +0200 Subject: Styling rotate (bzr r15142.1.17) --- src/display/sp-canvas.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 36d0b7e7c..ae20cd92d 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1997,10 +1997,10 @@ void SPCanvas::startRotateTo(double angle) if (ang > 180) { ang -= 360; } - double rot = (-180.0 + x - start_angle)*(M_PI/180.); + double rot = (-180.0 + x)*(M_PI/180.); double dist = half_min-9; gint inverse = 1; - if((x- start_angle) < 91 || (x- start_angle) > 270) { + if((x) < 91 || (x) > 270) { inverse = -1; } if(x%10 == 0) { @@ -2012,11 +2012,11 @@ void SPCanvas::startRotateTo(double angle) cairo_text_extents(cr, s.c_str(), &extents); //std::cout << extents.width/2 << "extents.x_bearing\n"; cairo_translate(cr, (extents.width/2) * inverse * -1, (dist + ((extents.height/2)* inverse))); - if((x- start_angle) < 91 || (x- start_angle) > 270) { + if((x) < 91 || (x) > 270) { cairo_rotate(cr, 180*(M_PI/180.0)); } cairo_text_path(cr, s.c_str()); - if((x- start_angle) < 91 || (x- start_angle) > 270) { + if((x) < 91 || (x) > 270) { cairo_rotate(cr, -180*(M_PI/180.0)); } cairo_translate(cr, (extents.width/2) * inverse , (dist + ((extents.height/2)* inverse)) * -1); @@ -2043,6 +2043,21 @@ void SPCanvas::startRotateTo(double angle) cairo_arc(cr, half_w, half_h, half_min-30, 0, 2*M_PI); cairo_set_source_rgba (cr, 1, 1, 1, 1); cairo_fill(cr); + cairo_translate(cr, half_w, half_h); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + cairo_rotate(cr, start_angle*(M_PI/180.)); + cairo_move_to(cr, 0, 0); + cairo_line_to(cr, 0, (half_min-17) * -1); + cairo_set_source_rgba (cr, 1, 1, 1, 0.25); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_width (cr,5); + cairo_stroke(cr); + cairo_move_to(cr, 0, 0); + cairo_line_to(cr, 0, (half_min-17) * -1); + cairo_set_source_rgba (cr, 1, 0, 0, 0.9); + cairo_set_line_width (cr,1); + cairo_stroke(cr); + cairo_rotate(cr, -start_angle*(M_PI/180.)); cairo_destroy(cr); surface_measure = new_backing_store_measure; @@ -2083,6 +2098,9 @@ void SPCanvas::rotateTo(SPCanvasItem * item, double angle) } GtkAllocation allocation; gtk_widget_get_allocation(&_widget, &allocation); + int half_w = allocation.width/2; + int half_h = allocation.height/2; + int half_min = std::min(half_w,half_h); cairo_surface_t *new_backing_store = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height); cairo_t *cr = cairo_create(new_backing_store); cairo_set_source_surface(cr, surface_origin, 0, 0); @@ -2101,6 +2119,33 @@ void SPCanvas::rotateTo(SPCanvasItem * item, double angle) cairo_paint(cr); cairo_set_source_surface(cr, surface_measure, 0, 0); cairo_paint(cr); + cairo_translate(cr, half_w, half_h); + cairo_rotate(cr, angle*(M_PI/180.)); + cairo_move_to(cr, 0, 0); + cairo_line_to(cr, 0, (half_min-17) * -1); + cairo_set_source_rgba (cr, 1, 1, 1, 0.25); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_width (cr,5); + cairo_stroke(cr); + cairo_move_to(cr, 0, 0); + cairo_line_to(cr, 0, (half_min-17) * -1); + cairo_set_source_rgba (cr, 1, 1, 1, 0.9); + cairo_set_line_width (cr,1); + cairo_stroke(cr); + cairo_move_to(cr, 0, 0); + cairo_line_to(cr, 0, (half_min-17) * -1); + cairo_set_source_rgba (cr, 1, 0, 0, 0.9); + const double dashed[] = {6.0, 3.0}; + int len = sizeof(dashed) / sizeof(dashed[0]); + cairo_set_dash(cr, dashed, len, 1); + cairo_stroke(cr); + cairo_translate(cr, -half_w, -half_h); + cairo_set_source_rgba (cr, 1, 1, 1, 0.25); + cairo_arc(cr, half_w, half_h, 7, 0, 2*M_PI); + cairo_fill(cr); + cairo_set_source_rgba (cr, 1, 0, 0, 0.7); + cairo_arc(cr, half_w, half_h, 5, 0, 2*M_PI); + cairo_fill(cr); cairo_destroy(cr); cairo_surface_destroy(_backing_store); _backing_store = new_backing_store; -- cgit v1.2.3 From 50c101849a9f591972b5478a7a83407558e7bff7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 23 Oct 2016 11:03:35 +0200 Subject: Add right click attempt (bzr r15142.1.20) --- src/display/sp-canvas.cpp | 68 ++++++++++++- src/display/sp-canvas.h | 2 +- src/ui/tools/tool-base.cpp | 216 ++++++++++++++++++++++++----------------- src/widgets/desktop-widget.cpp | 34 +++---- 4 files changed, 207 insertions(+), 113 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index ae20cd92d..745896dd7 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -43,6 +43,8 @@ #include "debug/gdk-event-latency-tracker.h" #include "desktop.h" #include "color.h" +#include +#include using Inkscape::Debug::GdkEventLatencyTracker; @@ -1992,6 +1994,8 @@ void SPCanvas::startRotateTo(double angle) cairo_set_source_rgba (cr, 1, 1, 1, 0.2); cairo_fill(cr); cairo_translate(cr, half_w, half_h); + cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size(cr, 10.0); for (gint x = 0; x < 360 ; x++){ gint ang = 360 - x ;//+ 90; if (ang > 180) { @@ -2005,8 +2009,6 @@ void SPCanvas::startRotateTo(double angle) } if(x%10 == 0) { cairo_rotate(cr, -rot); - cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - cairo_set_font_size(cr, 10.0); cairo_text_extents_t extents; std::string s = std::to_string(ang) + "º"; cairo_text_extents(cr, s.c_str(), &extents); @@ -2075,7 +2077,9 @@ void SPCanvas::startRotateTo(double angle) cairo_paint(cr); cairo_destroy(cr); surface_origin = new_backing_store_grey; - + gtk_widget_queue_draw(GTK_WIDGET(this)); + dirtyAll(); + addIdle(); } void SPCanvas::endRotateTo() @@ -2091,9 +2095,9 @@ void SPCanvas::endRotateTo() addIdle(); } -void SPCanvas::rotateTo(SPCanvasItem * item, double angle) +void SPCanvas::rotateTo(SPCanvasItem * item, double angle, bool widget) { - if (!_backing_store) { + if (!_backing_store || !started) { return; } GtkAllocation allocation; @@ -2146,6 +2150,60 @@ void SPCanvas::rotateTo(SPCanvasItem * item, double angle) cairo_set_source_rgba (cr, 1, 0, 0, 0.7); cairo_arc(cr, half_w, half_h, 5, 0, 2*M_PI); cairo_fill(cr); + cairo_translate(cr, half_w, half_h); + cairo_rotate(cr, -angle*(M_PI/180.)); + if (!widget) { + cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size(cr, 15.0); + cairo_text_extents_t extents; + std::ostringstream s; + s << _("Original angle ") << std::fixed << std::setprecision(2) << start_angle << "º"; + cairo_text_extents(cr, s.str().c_str(), &extents); + cairo_translate(cr, half_w - extents.width -15 ,-half_h + 25); + cairo_set_source_rgba (cr, 1, 1, 1, 1); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 25) *-1); + s.str(""); + s << _("New angle ") << std::fixed << std::setprecision(2) << angle << "º"; + cairo_text_extents(cr, s.str().c_str(), &extents); + cairo_translate(cr, half_w - extents.width -15 ,-half_h + 45); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 45) *-1); + s.str(""); + s << _("Gap ") << std::fixed << std::setprecision(2) << std::abs(start_angle-angle) << "º"; + cairo_text_extents(cr, s.str().c_str(), &extents); + cairo_translate(cr, half_w - extents.width -15 ,-half_h + 65); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 65) *-1); + cairo_translate(cr, -half_w + 10 ,-half_h + 25); + s.str(""); + cairo_set_font_size(cr, 12.0); + s << _("Normal mode, 1º round step"); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (-half_w +10) * -1 ,(-half_h + 25) * -1); + cairo_translate(cr, -half_w + 10 ,-half_h + 40); + s.str(""); + s << _("+CTRL, Fractional degrees"); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 40) * -1); + cairo_translate(cr, -half_w + 10 ,-half_h + 55); + s.str(""); + s << _("+SHIFT, 5º round step"); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 55) * -1); + cairo_translate(cr, -half_w + 10 ,-half_h + 70); + s.str(""); + s << _("+ALT, Reset"); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + //cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 60) * -1); + } cairo_destroy(cr); cairo_surface_destroy(_backing_store); _backing_store = new_backing_store; diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index b78cdcdd5..5c4cd5047 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -73,7 +73,7 @@ struct SPCanvas { /// Scrolls canvas to specific position (cx and cy are measured in screen pixels). void scrollTo(double cx, double cy, unsigned int clear, bool is_scrolling = false); void startRotateTo(double angle); - void rotateTo(SPCanvasItem * item, double angle); + void rotateTo(SPCanvasItem * item, double angle, bool widget = false); void endRotateTo(); /// Synchronously updates the canvas if necessary. void updateNow(); diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 128a09878..d8800284b 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -327,6 +327,7 @@ bool ToolBase::root_handler(GdkEvent* event) { static unsigned int panning = 0; static unsigned int panning_cursor = 0; static unsigned int zoom_rb = 0; + static double angle = 0; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -345,6 +346,7 @@ bool ToolBase::root_handler(GdkEvent* event) { /* sp_desktop_dialog(); */ } break; + case GDK_BUTTON_PRESS: // save drag origin xp = (gint) event->button.x; @@ -393,21 +395,25 @@ bool ToolBase::root_handler(GdkEvent* event) { break; case 3: - if ((event->button.state & GDK_SHIFT_MASK) || (event->button.state & GDK_CONTROL_MASK)) { - // When starting panning, make sure there are no snap events pending because these might disable the panning again - if (_uses_snap) { - sp_event_context_discard_delayed_snap_event(this); - } - panning = 3; - - sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), - GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK - | GDK_POINTER_MOTION_HINT_MASK, NULL, - event->button.time); - - ret = TRUE; - } else { +// if ((event->button.state & GDK_SHIFT_MASK) || (event->button.state & GDK_CONTROL_MASK)) { +// // When starting panning, make sure there are no snap events pending because these might disable the panning again +// if (_uses_snap) { +// sp_event_context_discard_delayed_snap_event(this); +// } +// panning = 3; + +// sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), +// GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK +// | GDK_POINTER_MOTION_HINT_MASK, NULL, +// event->button.time); + +// ret = TRUE; +// } else + if( !this->space_panning ) { sp_event_root_menu_popup(desktop, NULL, event); + } else { + panning = 5; + desktop->canvas->startRotateTo(desktop->namedview->document_rotation); } break; @@ -418,7 +424,27 @@ bool ToolBase::root_handler(GdkEvent* event) { case GDK_MOTION_NOTIFY: if (panning) { - if (panning == 4 && !xp && !yp ) { + if (panning == 5) { + button_w = Geom::Point(event->motion.x, event->motion.y); + Geom::Point const motion_dt(desktop->w2d(button_w)); + Geom::Rect view = desktop->get_display_area(); + Geom::Point view_center = desktop->doc2dt(view.midpoint()); + Geom::Ray center_ray(motion_dt,view_center); + if (event->motion.state & GDK_BUTTON3_MASK) { + desktop->canvas->startRotateTo(desktop->namedview->document_rotation); + if (event->motion.state & GDK_SHIFT_MASK) { + angle = floor(center_ray.angle()/5) * 5; + } else if (event->motion.state & GDK_CONTROL_MASK) { + angle = center_ray.angle(); + } else if (event->motion.state & GDK_KEY_Alt_L || + event->motion.state & GDK_KEY_Alt_R){ + angle = desktop->namedview->document_rotation; + } else { + angle = floor(center_ray.angle()); + } + desktop->canvas->rotateTo(desktop->getDrawing(), angle); + } + } else if (panning == 4 && !xp && !yp ) { // + mouse panning started, save location and grab canvas xp = event->motion.x; yp = event->motion.y; @@ -430,41 +456,43 @@ bool ToolBase::root_handler(GdkEvent* event) { | GDK_POINTER_MOTION_HINT_MASK, NULL, event->motion.time - 1); } + if (panning != 5) { + if ((panning == 2 && !(event->motion.state & GDK_BUTTON2_MASK)) + || (panning == 1 && !(event->motion.state & GDK_BUTTON1_MASK)) + || (panning == 3 && !(event->motion.state & GDK_BUTTON3_MASK))) { + /* Gdk seems to lose button release for us sometimes :-( */ + panning = 0; + sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); + ret = TRUE; + } else { + if (within_tolerance && (abs((gint) event->motion.x - xp) + < tolerance) && (abs((gint) event->motion.y - yp) + < tolerance)) { + // do not drag if we're within tolerance from origin + break; + } - if ((panning == 2 && !(event->motion.state & GDK_BUTTON2_MASK)) - || (panning == 1 && !(event->motion.state & GDK_BUTTON1_MASK)) - || (panning == 3 && !(event->motion.state & GDK_BUTTON3_MASK))) { - /* Gdk seems to lose button release for us sometimes :-( */ - panning = 0; - sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); - ret = TRUE; - } else { - if (within_tolerance && (abs((gint) event->motion.x - xp) - < tolerance) && (abs((gint) event->motion.y - yp) - < tolerance)) { - // do not drag if we're within tolerance from origin - break; - } - // Once the user has moved farther than tolerance from - // the original location (indicating they intend to move - // the object, not click), then always process the motion - // notify coordinates as given (no snapping back to origin) - within_tolerance = false; - - // gobble subsequent motion events to prevent "sticking" - // when scrolling is slow - gobble_motion_events(panning == 2 ? GDK_BUTTON2_MASK : (panning - == 1 ? GDK_BUTTON1_MASK : GDK_BUTTON3_MASK)); - - if (panning_cursor == 0) { - panning_cursor = 1; - this->sp_event_context_set_cursor(GDK_FLEUR); - } + // Once the user has moved farther than tolerance from + // the original location (indicating they intend to move + // the object, not click), then always process the motion + // notify coordinates as given (no snapping back to origin) + within_tolerance = false; - Geom::Point const motion_w(event->motion.x, event->motion.y); - Geom::Point const moved_w(motion_w - button_w); - this->desktop->scroll_world(moved_w, true); // we're still scrolling, do not redraw - ret = TRUE; + // gobble subsequent motion events to prevent "sticking" + // when scrolling is slow + gobble_motion_events(panning == 2 ? GDK_BUTTON2_MASK : (panning + == 1 ? GDK_BUTTON1_MASK : GDK_BUTTON3_MASK)); + + if (panning_cursor == 0) { + panning_cursor = 1; + this->sp_event_context_set_cursor(GDK_FLEUR); + } + + Geom::Point const motion_w(event->motion.x, event->motion.y); + Geom::Point const moved_w(motion_w - button_w); + this->desktop->scroll_world(moved_w, true); // we're still scrolling, do not redraw + ret = TRUE; + } } } else if (zoom_rb) { Geom::Point const motion_w(event->motion.x, event->motion.y); @@ -494,60 +522,68 @@ bool ToolBase::root_handler(GdkEvent* event) { break; case GDK_BUTTON_RELEASE: - xp = yp = 0; + if (panning == 5) { + desktop->canvas->endRotateTo(); + sp_repr_set_svg_double(desktop->namedview->getRepr(), "inkscape:document-rotation", angle); + SPObject *updated = SP_OBJECT(desktop->namedview); + if (updated) { + updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + } else { + xp = yp = 0; + if (panning_cursor == 1) { + panning_cursor = 0; + GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); + gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor); + } - if (panning_cursor == 1) { - panning_cursor = 0; - GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); - gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor); - } + if (within_tolerance && (panning || zoom_rb)) { + zoom_rb = 0; - if (within_tolerance && (panning || zoom_rb)) { - zoom_rb = 0; + if (panning) { + panning = 0; + sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), + event->button.time); + } - if (panning) { - panning = 0; - sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), - event->button.time); - } + Geom::Point const event_w(event->button.x, event->button.y); + Geom::Point const event_dt(desktop->w2d(event_w)); - Geom::Point const event_w(event->button.x, event->button.y); - Geom::Point const event_dt(desktop->w2d(event_w)); + double const zoom_inc = prefs->getDoubleLimited( + "/options/zoomincrement/value", M_SQRT2, 1.01, 10); - double const zoom_inc = prefs->getDoubleLimited( - "/options/zoomincrement/value", M_SQRT2, 1.01, 10); + desktop->zoom_relative_keep_point(event_dt, (event->button.state + & GDK_SHIFT_MASK) ? 1 / zoom_inc : zoom_inc); - desktop->zoom_relative_keep_point(event_dt, (event->button.state - & GDK_SHIFT_MASK) ? 1 / zoom_inc : zoom_inc); + desktop->updateNow(); + ret = TRUE; + } else if (panning == event->button.button) { + panning = 0; + sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), + event->button.time); - desktop->updateNow(); - ret = TRUE; - } else if (panning == event->button.button) { - panning = 0; - sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), - event->button.time); + // in slow complex drawings, some of the motion events are lost; + // to make up for this, we scroll it once again to the button-up event coordinates + // (i.e. canvas will always get scrolled all the way to the mouse release point, + // even if few intermediate steps were visible) + Geom::Point const motion_w(event->button.x, event->button.y); + Geom::Point const moved_w(motion_w - button_w); - // in slow complex drawings, some of the motion events are lost; - // to make up for this, we scroll it once again to the button-up event coordinates - // (i.e. canvas will always get scrolled all the way to the mouse release point, - // even if few intermediate steps were visible) - Geom::Point const motion_w(event->button.x, event->button.y); - Geom::Point const moved_w(motion_w - button_w); + this->desktop->scroll_world(moved_w); + desktop->updateNow(); + ret = TRUE; + } else if (zoom_rb == event->button.button) { + zoom_rb = 0; - this->desktop->scroll_world(moved_w); - desktop->updateNow(); - ret = TRUE; - } else if (zoom_rb == event->button.button) { - zoom_rb = 0; + Geom::OptRect const b = Inkscape::Rubberband::get(desktop)->getRectangle(); + Inkscape::Rubberband::get(desktop)->stop(); - Geom::OptRect const b = Inkscape::Rubberband::get(desktop)->getRectangle(); - Inkscape::Rubberband::get(desktop)->stop(); + if (b && !within_tolerance) { + desktop->set_display_area(*b, 10); + } - if (b && !within_tolerance) { - desktop->set_display_area(*b, 10); + ret = TRUE; } - - ret = TRUE; } break; diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index e868dd2d6..bc08c4f58 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -619,11 +619,12 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) context_zoom->add_provider(css_provider_spinbutton, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); // Rotate status spinbutton - dtw->rotation_status = gtk_spin_button_new_with_range (-180,180, 1.0); + dtw->rotation_status = gtk_spin_button_new_with_range (-360.0,360.0, 1.0); gtk_widget_set_tooltip_text (dtw->rotation_status, _("Rotation")); gtk_widget_set_size_request (dtw->rotation_status, STATUS_ROTATION_WIDTH, -1); - gtk_entry_set_width_chars (GTK_ENTRY (dtw->rotation_status), 6); + gtk_entry_set_width_chars (GTK_ENTRY (dtw->rotation_status), 7); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dtw->rotation_status), FALSE); + gtk_spin_button_set_digits (GTK_SPIN_BUTTON (dtw->rotation_status), 2); gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (dtw->rotation_status), GTK_UPDATE_ALWAYS); g_signal_connect (G_OBJECT (dtw->rotation_status), "input", G_CALLBACK (sp_dtw_rotation_input), dtw); g_signal_connect (G_OBJECT (dtw->rotation_status), "output", G_CALLBACK (sp_dtw_rotation_output), dtw); @@ -1784,20 +1785,19 @@ sp_desktop_widget_rotate_document(GtkSpinButton *spin, SPDesktopWidget *dtw) { SPNamedView *nv = dtw->desktop->namedview; double value = gtk_spin_button_get_value (spin); -// if (!dtw->desktop->getDocument()->getRoot()->rotated && value != nv->document_rotation) { -// nv->document_rotation = value; -// sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value); -// SPObject *updated = SP_OBJECT(nv); -// if (updated) { -// updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -// } -// //dtw->desktop->canvas->endRotateTo(); -// } else if( value != nv->document_rotation ) { - dtw->desktop->canvas->startRotateTo(0); - dtw->desktop->canvas->rotateTo(dtw->desktop->getDrawing(),value); - if (value == 180) { dtw->desktop->canvas->endRotateTo();} -// } - spinbutton_defocus (GTK_WIDGET(spin)); + if (!dtw->desktop->getDocument()->getRoot()->rotated && value != nv->document_rotation) { + nv->document_rotation = value; + sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value); + SPObject *updated = SP_OBJECT(nv); + if (updated) { + updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + //dtw->desktop->canvas->endRotateTo(); + }// else if( value != nv->document_rotation ) { + //dtw->desktop->canvas->startRotateTo(value); + // dtw->desktop->canvas->rotateTo(dtw->desktop->getDrawing(),value); + // } + spinbutton_defocus (GTK_WIDGET(spin)); } @@ -1898,7 +1898,7 @@ sp_dtw_rotation_output (GtkSpinButton *spin, gpointer /*data*/) { gchar b[64]; double val = gtk_spin_button_get_value (spin); - g_snprintf (b, 64, "%3.0fº", val); + g_snprintf (b, 64, "%3.2fº", val); gtk_entry_set_text (GTK_ENTRY (spin), b); return TRUE; } -- cgit v1.2.3 From 74edf9fcbc3106cccddb2a293275748fefa08f0b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 23 Oct 2016 20:04:23 +0200 Subject: Add right click rotation panning (bzr r15142.1.22) --- src/display/sp-canvas.cpp | 19 +++++++++++-------- src/display/sp-canvas.h | 2 +- src/ui/tools/tool-base.cpp | 11 +++++------ 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 2f6caadd3..115b8c613 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -2077,31 +2077,33 @@ void SPCanvas::startRotateTo(double angle) cairo_paint(cr); cairo_destroy(cr); surface_origin = new_backing_store_grey; - clearRotateTo(true); + gtk_widget_queue_draw(GTK_WIDGET(this)); + dirtyAll(); + addIdle(); } bool SPCanvas::endRotateTo() { - if (!started) { + if (!_backing_store || !started) { return false; } started = false; surface_rotated = NULL; surface_origin = NULL; - clearRotateTo(true); + gtk_widget_queue_draw(GTK_WIDGET(this)); + dirtyAll(); + addIdle(); return true; } -void SPCanvas::clearRotateTo(bool clear) +void SPCanvas::clearRotateTo() { if (!started) { return; } gtk_widget_queue_draw(GTK_WIDGET(this)); dirtyAll(); - if (clear) { - addIdle(); - } + addIdle(); } void SPCanvas::rotateTo(SPCanvasItem * item, double angle, bool widget) @@ -2217,7 +2219,8 @@ void SPCanvas::rotateTo(SPCanvasItem * item, double angle, bool widget) cairo_surface_destroy(_backing_store); _backing_store = new_backing_store; cairo_pattern_destroy (source_pattern); - clearRotateTo(false); + gtk_widget_queue_draw(GTK_WIDGET(this)); + addIdle(); } void SPCanvas::updateNow() diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index 122cc2d8c..628bc74ca 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -75,7 +75,7 @@ struct SPCanvas { void startRotateTo(double angle); void rotateTo(SPCanvasItem * item, double angle, bool widget = false); bool endRotateTo(); - void clearRotateTo(bool clear); + void clearRotateTo(); /// Synchronously updates the canvas if necessary. void updateNow(); diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 87f808039..33c0492d7 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -334,7 +334,6 @@ bool ToolBase::root_handler(GdkEvent* event) { /// @todo REmove redundant /value in preference keys tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); bool allow_panning = prefs->getBool("/options/spacebarpans/value"); - bool clear = true; gint ret = FALSE; switch (event->type) { @@ -346,7 +345,6 @@ bool ToolBase::root_handler(GdkEvent* event) { } else { /* sp_desktop_dialog(); */ } - desktop->canvas->clearRotateTo(); break; case GDK_BUTTON_PRESS: @@ -434,14 +432,13 @@ bool ToolBase::root_handler(GdkEvent* event) { | GDK_POINTER_MOTION_HINT_MASK, NULL, event->motion.time - 1); } else if (this->space_panning && event->motion.state & GDK_BUTTON3_MASK) { - clear = false; sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); desktop->canvas->startRotateTo(desktop->namedview->document_rotation); button_w = Geom::Point(event->motion.x, event->motion.y); - Geom::Point const motion_dt(desktop->w2d(button_w)); + Geom::Point const motion_dt(desktop->doc2dt(desktop->w2d(button_w))); Geom::Rect view = desktop->get_display_area(); Geom::Point view_center = desktop->doc2dt(view.midpoint()); - Geom::Ray center_ray(view_center, motion_dt); + Geom::Ray center_ray(motion_dt, view_center); desktop->canvas->startRotateTo(desktop->namedview->document_rotation); angle = Geom::deg_from_rad(center_ray.angle()) - 90; if (event->motion.state & GDK_SHIFT_MASK && event->motion.state & GDK_CONTROL_MASK) { @@ -583,6 +580,7 @@ bool ToolBase::root_handler(GdkEvent* event) { ret = TRUE; } } + desktop->canvas->clearRotateTo(); break; case GDK_KEY_PRESS: { @@ -752,6 +750,7 @@ bool ToolBase::root_handler(GdkEvent* event) { switch (get_group0_keyval(&event->key)) { case GDK_KEY_space: + desktop->canvas->clearRotateTo(); if (within_tolerance) { // Space was pressed, but not panned sp_toggle_selector(desktop); @@ -773,6 +772,7 @@ bool ToolBase::root_handler(GdkEvent* event) { default: break; } + desktop->canvas->clearRotateTo(); break; case GDK_SCROLL: { @@ -856,7 +856,6 @@ bool ToolBase::root_handler(GdkEvent* event) { default: break; } - desktop->canvas->clearRotateTo(clear); return ret; } -- cgit v1.2.3 From b65d3fdc9c15af81c5e433d8f1b714ef4ab61487 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 23 Oct 2016 21:18:11 +0200 Subject: Add right click rotation panning, some fixes (bzr r15142.1.23) --- src/display/sp-canvas.cpp | 113 ++++++++++++++++++++++------------------- src/display/sp-canvas.h | 2 +- src/ui/tools/tool-base.cpp | 15 +++++- src/widgets/desktop-widget.cpp | 12 +++-- 4 files changed, 82 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 115b8c613..242a30248 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -2101,12 +2101,21 @@ void SPCanvas::clearRotateTo() if (!started) { return; } + GtkAllocation allocation; + gtk_widget_get_allocation(&_widget, &allocation); + cairo_surface_t *new_backing_store = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height); + cairo_t *cr = cairo_create(new_backing_store); + cairo_set_source(cr, _background); + cairo_paint(cr); + cairo_destroy(cr); + cairo_surface_destroy(_backing_store); + _backing_store = new_backing_store; gtk_widget_queue_draw(GTK_WIDGET(this)); dirtyAll(); addIdle(); } -void SPCanvas::rotateTo(SPCanvasItem * item, double angle, bool widget) +void SPCanvas::rotateTo(SPCanvasItem * item, double angle) { if (!_backing_store || !started) { return; @@ -2163,58 +2172,56 @@ void SPCanvas::rotateTo(SPCanvasItem * item, double angle, bool widget) cairo_fill(cr); cairo_translate(cr, half_w, half_h); cairo_rotate(cr, -angle*(M_PI/180.)); - if (!widget) { - cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - cairo_set_font_size(cr, 15.0); - cairo_text_extents_t extents; - std::ostringstream s; - s << _("Original angle ") << std::fixed << std::setprecision(2) << start_angle << "º"; - cairo_text_extents(cr, s.str().c_str(), &extents); - cairo_translate(cr, half_w - extents.width -15 ,-half_h + 25); - cairo_set_source_rgba (cr, 1, 1, 1, 1); - cairo_text_path(cr, s.str().c_str()); - cairo_fill(cr); - cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 25) *-1); - s.str(""); - s << _("New angle ") << std::fixed << std::setprecision(2) << angle << "º"; - cairo_text_extents(cr, s.str().c_str(), &extents); - cairo_translate(cr, half_w - extents.width -15 ,-half_h + 45); - cairo_text_path(cr, s.str().c_str()); - cairo_fill(cr); - cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 45) *-1); - s.str(""); - s << _("Gap ") << std::fixed << std::setprecision(2) << std::abs(start_angle-angle) << "º"; - cairo_text_extents(cr, s.str().c_str(), &extents); - cairo_translate(cr, half_w - extents.width -15 ,-half_h + 65); - cairo_text_path(cr, s.str().c_str()); - cairo_fill(cr); - cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 65) *-1); - cairo_translate(cr, -half_w + 10 ,-half_h + 25); - s.str(""); - cairo_set_font_size(cr, 12.0); - s << _("Normal mode, 1º round step"); - cairo_text_path(cr, s.str().c_str()); - cairo_fill(cr); - cairo_translate(cr, (-half_w +10) * -1 ,(-half_h + 25) * -1); - cairo_translate(cr, -half_w + 10 ,-half_h + 40); - s.str(""); - s << _("+CTRL, Fractional degrees"); - cairo_text_path(cr, s.str().c_str()); - cairo_fill(cr); - cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 40) * -1); - cairo_translate(cr, -half_w + 10 ,-half_h + 55); - s.str(""); - s << _("+SHIFT, 5º round step"); - cairo_text_path(cr, s.str().c_str()); - cairo_fill(cr); - cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 55) * -1); - cairo_translate(cr, -half_w + 10 ,-half_h + 70); - s.str(""); - s << _("+CTRL+SHIFT, Reset"); - cairo_text_path(cr, s.str().c_str()); - cairo_fill(cr); - //cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 60) * -1); - } + cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size(cr, 15.0); + cairo_text_extents_t extents; + std::ostringstream s; + s << _("Original angle ") << std::fixed << std::setprecision(2) << start_angle << "º"; + cairo_text_extents(cr, s.str().c_str(), &extents); + cairo_translate(cr, half_w - extents.width -15 ,-half_h + 25); + cairo_set_source_rgba (cr, 1, 1, 1, 1); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 25) *-1); + s.str(""); + s << _("New angle ") << std::fixed << std::setprecision(2) << angle << "º"; + cairo_text_extents(cr, s.str().c_str(), &extents); + cairo_translate(cr, half_w - extents.width -15 ,-half_h + 45); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 45) *-1); + s.str(""); + s << _("Gap ") << std::fixed << std::setprecision(2) << std::abs(start_angle-angle) << "º"; + cairo_text_extents(cr, s.str().c_str(), &extents); + cairo_translate(cr, half_w - extents.width -15 ,-half_h + 65); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 65) *-1); + cairo_translate(cr, -half_w + 10 ,-half_h + 25); + s.str(""); + cairo_set_font_size(cr, 12.0); + s << _("Normal mode, 1º round step"); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (-half_w +10) * -1 ,(-half_h + 25) * -1); + cairo_translate(cr, -half_w + 10 ,-half_h + 40); + s.str(""); + s << _("+CTRL, Fractional degrees"); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 40) * -1); + cairo_translate(cr, -half_w + 10 ,-half_h + 55); + s.str(""); + s << _("+SHIFT, 5º round step"); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 55) * -1); + cairo_translate(cr, -half_w + 10 ,-half_h + 70); + s.str(""); + s << _("+CTRL+SHIFT, Reset"); + cairo_text_path(cr, s.str().c_str()); + cairo_fill(cr); + //cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 60) * -1); cairo_destroy(cr); cairo_surface_destroy(_backing_store); _backing_store = new_backing_store; diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index 628bc74ca..53b852140 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -73,7 +73,7 @@ struct SPCanvas { /// Scrolls canvas to specific position (cx and cy are measured in screen pixels). void scrollTo(double cx, double cy, unsigned int clear, bool is_scrolling = false); void startRotateTo(double angle); - void rotateTo(SPCanvasItem * item, double angle, bool widget = false); + void rotateTo(SPCanvasItem * item, double angle); bool endRotateTo(); void clearRotateTo(); /// Synchronously updates the canvas if necessary. diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 33c0492d7..f7315c648 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -516,7 +516,21 @@ bool ToolBase::root_handler(GdkEvent* event) { break; case GDK_BUTTON_RELEASE: + desktop->canvas->clearRotateTo(); if (this->space_panning && event->button.button == 3) { + xp = yp = 0; + if (panning_cursor == 1) { + panning_cursor = 0; + GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); + gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor); + } + zoom_rb = 0; + if (panning) { + panning = 0; + sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), + event->button.time); + } + ret = TRUE; if (desktop->canvas->endRotateTo()) { sp_repr_set_svg_double(desktop->namedview->getRepr(), "inkscape:document-rotation", angle); SPObject *updated = SP_OBJECT(desktop->namedview); @@ -580,7 +594,6 @@ bool ToolBase::root_handler(GdkEvent* event) { ret = TRUE; } } - desktop->canvas->clearRotateTo(); break; case GDK_KEY_PRESS: { diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index bc08c4f58..477414342 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1792,11 +1792,13 @@ sp_desktop_widget_rotate_document(GtkSpinButton *spin, SPDesktopWidget *dtw) if (updated) { updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - //dtw->desktop->canvas->endRotateTo(); - }// else if( value != nv->document_rotation ) { - //dtw->desktop->canvas->startRotateTo(value); - // dtw->desktop->canvas->rotateTo(dtw->desktop->getDrawing(),value); - // } + dtw->desktop->canvas->endRotateTo(); + } +// } else if( value != nv->document_rotation ) { +// dtw->desktop->canvas->clearRotateTo(); +// dtw->desktop->canvas->startRotateTo(value); +// dtw->desktop->canvas->rotateTo(dtw->desktop->getDrawing(),value); +// } spinbutton_defocus (GTK_WIDGET(spin)); } -- cgit v1.2.3 From fdb897947621a286ae05cd990e8663bb6c3dd907 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 23 Oct 2016 22:24:00 +0200 Subject: Fix for widget value of rotate (bzr r15142.1.24) --- src/widgets/desktop-widget.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 477414342..94abd23a9 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #if defined (SOLARIS) && (SOLARIS == 8) #include "round.h" @@ -1890,7 +1891,11 @@ sp_dtw_rotation_input (GtkSpinButton *spin, gdouble *new_val, gpointer /*data*/) const gchar *b = gtk_entry_get_text (GTK_ENTRY (spin)); gdouble new_typed = atof (b); - *new_val = new_typed; + if (new_scrolled == new_typed) { // the new value is set by scrolling + *new_val = new_scrolled; + } else { // the new value is typed in + *new_val = new_typed; + } return TRUE; } @@ -1900,8 +1905,10 @@ sp_dtw_rotation_output (GtkSpinButton *spin, gpointer /*data*/) { gchar b[64]; double val = gtk_spin_button_get_value (spin); - g_snprintf (b, 64, "%3.2fº", val); - gtk_entry_set_text (GTK_ENTRY (spin), b); + std::ostringstream s; + s.imbue(std::locale(""));; + s << std::fixed << std::setprecision(2) << val << "º"; + gtk_entry_set_text (GTK_ENTRY (spin), s.str().c_str()); return TRUE; } -- cgit v1.2.3 From 043578ee79ae7dccc1967a9e380d276c9f73ed46 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 25 Oct 2016 23:30:06 +0200 Subject: Some bug fixes and improvements (bzr r15142.1.25) --- src/display/sp-canvas.cpp | 12 ------------ src/ui/tools/tool-base.cpp | 4 ---- src/widgets/desktop-widget.cpp | 11 ----------- 3 files changed, 27 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 242a30248..c4d454cb9 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -2077,9 +2077,6 @@ void SPCanvas::startRotateTo(double angle) cairo_paint(cr); cairo_destroy(cr); surface_origin = new_backing_store_grey; - gtk_widget_queue_draw(GTK_WIDGET(this)); - dirtyAll(); - addIdle(); } bool SPCanvas::endRotateTo() @@ -2101,15 +2098,6 @@ void SPCanvas::clearRotateTo() if (!started) { return; } - GtkAllocation allocation; - gtk_widget_get_allocation(&_widget, &allocation); - cairo_surface_t *new_backing_store = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height); - cairo_t *cr = cairo_create(new_backing_store); - cairo_set_source(cr, _background); - cairo_paint(cr); - cairo_destroy(cr); - cairo_surface_destroy(_backing_store); - _backing_store = new_backing_store; gtk_widget_queue_draw(GTK_WIDGET(this)); dirtyAll(); addIdle(); diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index f7315c648..8d1034161 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -533,10 +533,6 @@ bool ToolBase::root_handler(GdkEvent* event) { ret = TRUE; if (desktop->canvas->endRotateTo()) { sp_repr_set_svg_double(desktop->namedview->getRepr(), "inkscape:document-rotation", angle); - SPObject *updated = SP_OBJECT(desktop->namedview); - if (updated) { - updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } } } else { xp = yp = 0; diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 94abd23a9..4f5724ac2 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1787,19 +1787,8 @@ sp_desktop_widget_rotate_document(GtkSpinButton *spin, SPDesktopWidget *dtw) SPNamedView *nv = dtw->desktop->namedview; double value = gtk_spin_button_get_value (spin); if (!dtw->desktop->getDocument()->getRoot()->rotated && value != nv->document_rotation) { - nv->document_rotation = value; sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value); - SPObject *updated = SP_OBJECT(nv); - if (updated) { - updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } - dtw->desktop->canvas->endRotateTo(); } -// } else if( value != nv->document_rotation ) { -// dtw->desktop->canvas->clearRotateTo(); -// dtw->desktop->canvas->startRotateTo(value); -// dtw->desktop->canvas->rotateTo(dtw->desktop->getDrawing(),value); -// } spinbutton_defocus (GTK_WIDGET(spin)); } -- cgit v1.2.3 From b539e66398261e60f2b9218ff72058e962fe832d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 26 Oct 2016 12:31:09 +0200 Subject: Add fadding from temporary rotate draw to real ones (bzr r15142.1.27) --- src/display/sp-canvas.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index c4d454cb9..f168cffe6 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1891,6 +1891,19 @@ SPCanvasGroup *SPCanvas::getRoot() return SP_CANVAS_GROUP(_root); } +gdouble grayscale_value_matrix[20] = { + 0.21, 0.72, 0.072, 0, 0, + 0.21, 0.72, 0.072, 0, 0, + 0.21, 0.72, 0.072, 0, 0, + 0 , 0 , 0 , 1, 0 + }; +cairo_surface_t *surface_rotated; +cairo_surface_t *surface_origin; +cairo_surface_t *surface_measure; +double start_angle = 0; +bool started = false; +bool rotated = false; + void SPCanvas::scrollTo(double cx, double cy, unsigned int clear, bool is_scrolling) { GtkAllocation allocation; @@ -1913,9 +1926,14 @@ void SPCanvas::scrollTo(double cx, double cy, unsigned int clear, bool is_scroll cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); // Paint the background cairo_translate(cr, -ix, -iy); + if (rotated) { + cairo_translate(cr, dx, dy); + rotated = false; + } cairo_set_source(cr, _background); cairo_paint(cr); // Copy the old backing store contents + cairo_set_source_surface(cr, _backing_store, _x0, _y0); cairo_rectangle(cr, _x0, _y0, allocation.width, allocation.height); cairo_clip(cr); @@ -1951,17 +1969,7 @@ void SPCanvas::scrollTo(double cx, double cy, unsigned int clear, bool is_scroll } addIdle(); } -gdouble grayscale_value_matrix[20] = { - 0.21, 0.72, 0.072, 0, 0, - 0.21, 0.72, 0.072, 0, 0, - 0.21, 0.72, 0.072, 0, 0, - 0 , 0 , 0 , 1, 0 - }; -cairo_surface_t *surface_rotated; -cairo_surface_t *surface_origin; -cairo_surface_t *surface_measure; -double start_angle = 0; -bool started = false; + void SPCanvas::startRotateTo(double angle) { if (!_backing_store || started) { @@ -2090,6 +2098,7 @@ bool SPCanvas::endRotateTo() gtk_widget_queue_draw(GTK_WIDGET(this)); dirtyAll(); addIdle(); + rotated = true; return true; } -- cgit v1.2.3 From 126cabd5f87ca04262879584dd4ec1ac923edacd Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 1 Nov 2016 18:01:07 +0100 Subject: Fix angle constrain, thanks to vlada, Mc and LiamW (bzr r15142.1.29) --- src/display/sp-canvas.cpp | 2 +- src/ui/tools/tool-base.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index e84303816..427cec20a 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -2211,7 +2211,7 @@ void SPCanvas::rotateTo(double angle) cairo_translate(cr, -half_w + 10 ,-half_h + 55); s.str(""); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - s << _("+CTRL, ") << prefs->getInt("/options/rotationsnapsperpi/value", 15) << _("º round step"); + s << _("+CTRL, ") << 180.0/prefs->getInt("/options/rotationsnapsperpi/value", 12) << _("º round step"); cairo_text_path(cr, s.str().c_str()); cairo_fill(cr); cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 55) * -1); diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index e1b2f97af..999e2d0b2 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -335,7 +335,7 @@ bool ToolBase::root_handler(GdkEvent* event) { /// @todo REmove redundant /value in preference keys tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); bool allow_panning = prefs->getBool("/options/spacebarpans/value"); - int rotation_snap = prefs->getInt("/options/rotationsnapsperpi/value", 15); + int rotation_snap = 180.0/prefs->getInt("/options/rotationsnapsperpi/value", 12); gint ret = FALSE; switch (event->type) { -- cgit v1.2.3 From bf313d184ec2c93b4605b7c88ed9fcf341510d35 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 5 Nov 2016 18:52:21 +0100 Subject: Change modifier to enter rotate mode from SHIFT to CONTROL (bzr r15142.1.31) --- src/ui/tools/tool-base.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 999e2d0b2..6acbe9f9f 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -376,7 +376,7 @@ bool ToolBase::root_handler(GdkEvent* event) { break; case 2: - if (event->button.state & GDK_MOD1_MASK) { + if (event->button.state & GDK_CONTROL_MASK) { sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); desktop->canvas->startRotateTo(desktop->namedview->document_rotation); this->rotating_mode = true; @@ -406,7 +406,7 @@ bool ToolBase::root_handler(GdkEvent* event) { break; case 3: - if (event->button.state & GDK_MOD1_MASK) { + if (event->button.state & GDK_CONTROL_MASK) { sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); desktop->canvas->startRotateTo(desktop->namedview->document_rotation); this->rotating_mode = true; @@ -742,7 +742,7 @@ bool ToolBase::root_handler(GdkEvent* event) { break; case GDK_KEY_space: - if (event->key.state & GDK_MOD1_MASK) { + if (event->key.state & GDK_CONTROL_MASK) { sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); desktop->canvas->startRotateTo(desktop->namedview->document_rotation); this->rotating_mode = true; -- cgit v1.2.3 From 647b3ccad1fd3b178e92341fdc92fd276a234dff Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 5 Nov 2016 22:29:03 +0100 Subject: Add exporters (bzr r15142.1.32) --- src/extension/internal/cairo-png-out.cpp | 4 ++-- src/extension/internal/cairo-ps-out.cpp | 7 +++++-- src/extension/internal/cairo-renderer-pdf-out.cpp | 4 +++- src/extension/internal/emf-inout.cpp | 5 +++-- src/extension/internal/javafx-out.cpp | 9 +++++++-- src/extension/internal/latex-pstricks-out.cpp | 2 ++ src/extension/internal/odf.cpp | 9 ++++++++- src/extension/internal/pov-out.cpp | 13 ++++++++++--- src/extension/internal/wmf-inout.cpp | 7 +++++-- src/print.cpp | 2 ++ src/ui/dialog/export.cpp | 3 --- 11 files changed, 47 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cairo-png-out.cpp b/src/extension/internal/cairo-png-out.cpp index 956fcce9a..5859a82da 100644 --- a/src/extension/internal/cairo-png-out.cpp +++ b/src/extension/internal/cairo-png-out.cpp @@ -53,11 +53,10 @@ png_render_document_to_file(SPDocument *doc, gchar const *filename) { CairoRenderer *renderer; CairoRenderContext *ctx; - + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; doc->ensureUpToDate(); /* Start */ - SPItem *base = doc->getRoot(); Inkscape::Drawing drawing; unsigned dkey = SPItem::display_key_new(1); @@ -77,6 +76,7 @@ png_render_document_to_file(SPDocument *doc, gchar const *filename) renderer->destroyContext(ctx); base->invoke_hide(dkey); + doc->getRoot()->c2p *= doc->getRoot()->rotation; /* end */ delete renderer; diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index e8f47e79e..809125266 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -68,6 +68,7 @@ static bool ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool omittext, bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas, float bleedmargin_px, bool eps = false) { + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; doc->ensureUpToDate(); SPItem *base = NULL; @@ -84,9 +85,10 @@ ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int l pageBoundingBox = !exportDrawing; } - if (!base) + if (!base) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; return false; - + } Inkscape::Drawing drawing; unsigned dkey = SPItem::display_key_new(1); base->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY); @@ -115,6 +117,7 @@ ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int l renderer->destroyContext(ctx); delete renderer; + doc->getRoot()->c2p *= doc->getRoot()->rotation; return ret; } diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index 5576676b2..5558fe1ad 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -61,6 +61,7 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int bool texttopath, bool omittext, bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas, float bleedmargin_px) { + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; doc->ensureUpToDate(); /* Start */ @@ -80,6 +81,7 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int } if (!base) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; return false; } @@ -112,7 +114,7 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int renderer->destroyContext(ctx); delete renderer; - + doc->getRoot()->c2p *= doc->getRoot()->rotation; return ret; } diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index 12751c5ec..198c18ff2 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -94,7 +94,7 @@ Emf::print_document_to_file(SPDocument *doc, const gchar *filename) const gchar *oldconst; gchar *oldoutput; unsigned int ret; - + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; doc->ensureUpToDate(); mod = Inkscape::Extension::get_print(PRINT_EMF); @@ -114,6 +114,7 @@ Emf::print_document_to_file(SPDocument *doc, const gchar *filename) /* Print document */ ret = mod->begin(doc); if (ret) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; g_free(oldoutput); throw Inkscape::Extension::Output::save_failed(); } @@ -127,7 +128,7 @@ Emf::print_document_to_file(SPDocument *doc, const gchar *filename) mod->set_param_string("destination", oldoutput); g_free(oldoutput); - + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; } diff --git a/src/extension/internal/javafx-out.cpp b/src/extension/internal/javafx-out.cpp index d7ad7e6f7..c95434939 100644 --- a/src/extension/internal/javafx-out.cpp +++ b/src/extension/internal/javafx-out.cpp @@ -843,7 +843,8 @@ void JavaFXOutput::reset() bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) { reset(); - + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; + doc->ensureUpToDate(); name = Glib::path_get_basename(filename_utf8); int pos = name.find('.'); @@ -856,12 +857,14 @@ bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) //# Lets do the curves first, to get the stats if (!doTree(doc)) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; return false; } String curveBuf = outbuf; outbuf.clear(); if (!doHeader()) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; return false; } @@ -875,6 +878,7 @@ bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) doBody(doc, doc->getRoot()); if (!doTail()) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; return false; } @@ -884,6 +888,7 @@ bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) FILE *f = Inkscape::IO::fopen_utf8name(filename_utf8, "w"); if (!f) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; err("Could open JavaFX file '%s' for writing", filename_utf8); return false; } @@ -894,7 +899,7 @@ bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) } fclose(f); - + doc->getRoot()->c2p *= doc->getRoot()->rotation; return true; } diff --git a/src/extension/internal/latex-pstricks-out.cpp b/src/extension/internal/latex-pstricks-out.cpp index 3ce2c5531..aa6ea6963 100644 --- a/src/extension/internal/latex-pstricks-out.cpp +++ b/src/extension/internal/latex-pstricks-out.cpp @@ -49,6 +49,7 @@ bool LatexOutput::check(Inkscape::Extension::Extension * /*module*/) void LatexOutput::save(Inkscape::Extension::Output * /*mod2*/, SPDocument *doc, gchar const *filename) { SPPrintContext context; + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; doc->ensureUpToDate(); Inkscape::Extension::Print *mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_LATEX); @@ -76,6 +77,7 @@ void LatexOutput::save(Inkscape::Extension::Output * /*mod2*/, SPDocument *doc, mod->set_param_string("destination", oldoutput); g_free(oldoutput); + doc->getRoot()->c2p *= doc->getRoot()->rotation; } #include "clear-n_.h" diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index f885ef5e5..66d370357 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -72,6 +72,7 @@ #include "sp-path.h" #include "sp-text.h" #include "sp-flowtext.h" +#include "sp-root.h" #include "svg/svg.h" #include "text-editing.h" #include "util/units.h" @@ -2095,7 +2096,8 @@ void OdfOutput::reset() void OdfOutput::save(Inkscape::Extension::Output */*mod*/, SPDocument *doc, gchar const *filename) { reset(); - + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; + doc->ensureUpToDate(); documentUri = Inkscape::URI(filename); ZipFile zf; @@ -2104,25 +2106,30 @@ void OdfOutput::save(Inkscape::Extension::Output */*mod*/, SPDocument *doc, gcha if (!writeManifest(zf)) { g_warning("Failed to write manifest"); + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; } if (!writeContent(zf, doc->rroot)) { g_warning("Failed to write content"); + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; } if (!writeMeta(zf)) { g_warning("Failed to write metafile"); + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; } if (!zf.writeFile(filename)) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; } + doc->getRoot()->c2p *= doc->getRoot()->rotation; } diff --git a/src/extension/internal/pov-out.cpp b/src/extension/internal/pov-out.cpp index 8df883069..03a2ecd62 100644 --- a/src/extension/internal/pov-out.cpp +++ b/src/extension/internal/pov-out.cpp @@ -616,11 +616,13 @@ void PovOutput::reset() void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) { reset(); - + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; + doc->ensureUpToDate(); //###### SAVE IN POV FORMAT TO BUFFER //# Lets do the curves first, to get the stats if (!doTree(doc)) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; err("Could not output curves for %s", filename_utf8); return; } @@ -630,6 +632,7 @@ void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) if (!doHeader()) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; err("Could not write header for %s", filename_utf8); return; } @@ -638,6 +641,7 @@ void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) if (!doTail()) { + doc->getRoot()->c2p *= doc->getRoot()->rotation; err("Could not write footer for %s", filename_utf8); return; } @@ -648,9 +652,11 @@ void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) //###### WRITE TO FILE Inkscape::IO::dump_fopen_call(filename_utf8, "L"); FILE *f = Inkscape::IO::fopen_utf8name(filename_utf8, "w"); - if (!f) + if (!f){ + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; - + } + for (String::iterator iter = outbuf.begin() ; iter!=outbuf.end(); ++iter) { int ch = *iter; @@ -658,6 +664,7 @@ void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) } fclose(f); + doc->getRoot()->c2p *= doc->getRoot()->rotation; } diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index c7226a58a..a79af5ec1 100644 --- a/src/extension/internal/wmf-inout.cpp +++ b/src/extension/internal/wmf-inout.cpp @@ -95,7 +95,7 @@ Wmf::print_document_to_file(SPDocument *doc, const gchar *filename) SPPrintContext context; const gchar *oldconst; gchar *oldoutput; - + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; doc->ensureUpToDate(); mod = Inkscape::Extension::get_print(PRINT_WMF); @@ -115,6 +115,7 @@ Wmf::print_document_to_file(SPDocument *doc, const gchar *filename) /* Print document */ if (mod->begin(doc)) { g_free(oldoutput); + doc->getRoot()->c2p *= doc->getRoot()->rotation; throw Inkscape::Extension::Output::save_failed(); } mod->base->invoke_print(&context); @@ -127,7 +128,7 @@ Wmf::print_document_to_file(SPDocument *doc, const gchar *filename) mod->set_param_string("destination", oldoutput); g_free(oldoutput); - + doc->getRoot()->c2p *= doc->getRoot()->rotation; return; } @@ -135,6 +136,8 @@ Wmf::print_document_to_file(SPDocument *doc, const gchar *filename) void Wmf::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename) { + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; + doc->ensureUpToDate(); Inkscape::Extension::Extension * ext; ext = Inkscape::Extension::db.get(PRINT_WMF); diff --git a/src/print.cpp b/src/print.cpp index 7cd05ac93..479401995 100644 --- a/src/print.cpp +++ b/src/print.cpp @@ -79,6 +79,7 @@ unsigned int sp_print_text(SPPrintContext *ctx, char const *text, Geom::Point p, void sp_print_document(Gtk::Window& parentWindow, SPDocument *doc) { + doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; doc->ensureUpToDate(); // Build arena @@ -88,6 +89,7 @@ sp_print_document(Gtk::Window& parentWindow, SPDocument *doc) Inkscape::UI::Dialog::Print printop(doc,base); Gtk::PrintOperationResult res = printop.run(Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG, parentWindow); (void)res; // TODO handle this + doc->getRoot()->c2p *= doc->getRoot()->rotation; } void sp_print_document_to_file(SPDocument *doc, gchar const *filename) diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 95c97390d..c38e798ec 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -977,9 +977,6 @@ void Export::onExport () SPDocument *doc = desktop->getDocument(); Geom::Affine rot = doc->getRoot()->c2p; doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p; - //double rotate_angle = doc->getRoot()->get_rotation(); - //Inkscape::XML::Node *nv_repr = sp_item_group_get_child_by_name(doc->getRoot(), NULL, "sodipodi:namedview")->getRepr(); - //sp_repr_set_svg_double(nv_repr, "inkscape:document-rotation", 0.); doc->ensureUpToDate(); bool exportSuccessful = false; -- cgit v1.2.3 From f18cdd20ca7d36fb3b67b4c4b1ae9b315791e02e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 6 Nov 2016 21:10:58 +0100 Subject: Fix a bug that allow to enter rotate mode with right click (bzr r15142.1.33) --- src/ui/tools/tool-base.cpp | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 6acbe9f9f..fba9ae94f 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -406,34 +406,25 @@ bool ToolBase::root_handler(GdkEvent* event) { break; case 3: - if (event->button.state & GDK_CONTROL_MASK) { - sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); - desktop->canvas->startRotateTo(desktop->namedview->document_rotation); - this->rotating_mode = true; - this->message_context->set(Inkscape::INFORMATION_MESSAGE, - _("Space+ALT+mouse move to rotate canvas")); - } else { - if ((event->button.state & GDK_SHIFT_MASK) || (event->button.state & GDK_CONTROL_MASK)) { - // When starting panning, make sure there are no snap events pending because these might disable the panning again - if (_uses_snap) { - sp_event_context_discard_delayed_snap_event(this); - } - panning = 3; + if ((event->button.state & GDK_SHIFT_MASK) || (event->button.state & GDK_CONTROL_MASK)) { + // When starting panning, make sure there are no snap events pending because these might disable the panning again + if (_uses_snap) { + sp_event_context_discard_delayed_snap_event(this); + } + panning = 3; - sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), - GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK - | GDK_POINTER_MOTION_HINT_MASK, NULL, - event->button.time); + sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK + | GDK_POINTER_MOTION_HINT_MASK, NULL, + event->button.time); - ret = TRUE; - } else if( !this->space_panning) { - sp_event_root_menu_popup(desktop, NULL, event); - } - desktop->canvas->clearRotateTo(); - this->rotating_mode = false; ret = TRUE; - desktop->canvas->endRotateTo(); + } else if( !this->space_panning) { + sp_event_root_menu_popup(desktop, NULL, event); } + desktop->canvas->clearRotateTo(); + this->rotating_mode = false; + ret = TRUE; break; default: -- cgit v1.2.3 From 46d3c703414abe90dfbe79befbd0b4c80a86ea36 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Nov 2016 19:33:24 +0100 Subject: Fix some bugs pointed by vlada (bzr r15142.1.35) --- src/ui/tools/tool-base.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index fba9ae94f..c789b44bb 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -381,7 +381,7 @@ bool ToolBase::root_handler(GdkEvent* event) { desktop->canvas->startRotateTo(desktop->namedview->document_rotation); this->rotating_mode = true; this->message_context->set(Inkscape::INFORMATION_MESSAGE, - _("Space+ALT+mouse move to rotate canvas")); + _("MMB + mouse move to rotate canvas, use modifiers on screen to change snaps")); } else { if (event->button.state & GDK_SHIFT_MASK) { zoom_rb = 2; @@ -397,10 +397,7 @@ bool ToolBase::root_handler(GdkEvent* event) { | GDK_POINTER_MOTION_HINT_MASK, NULL, event->button.time - 1); } - desktop->canvas->clearRotateTo(); - this->rotating_mode = false; ret = TRUE; - desktop->canvas->endRotateTo(); } ret = TRUE; break; @@ -422,8 +419,6 @@ bool ToolBase::root_handler(GdkEvent* event) { } else if( !this->space_panning) { sp_event_root_menu_popup(desktop, NULL, event); } - desktop->canvas->clearRotateTo(); - this->rotating_mode = false; ret = TRUE; break; @@ -464,7 +459,7 @@ bool ToolBase::root_handler(GdkEvent* event) { | GDK_POINTER_MOTION_HINT_MASK, NULL, event->motion.time - 1); } - if (panning) { + if (panning && !this->rotating_mode) { if ((panning == 2 && !(event->motion.state & GDK_BUTTON2_MASK)) || (panning == 1 && !(event->motion.state & GDK_BUTTON1_MASK)) || (panning == 3 && !(event->motion.state & GDK_BUTTON3_MASK))) { @@ -738,7 +733,7 @@ bool ToolBase::root_handler(GdkEvent* event) { desktop->canvas->startRotateTo(desktop->namedview->document_rotation); this->rotating_mode = true; this->message_context->set(Inkscape::INFORMATION_MESSAGE, - _("Space+ALT+mouse move to rotate canvas")); + _("Space+mouse move to rotate canvas, use modifiers on screen to change snaps")); } else { within_tolerance = true; xp = yp = 0; -- cgit v1.2.3 From 7f2d487d23d4b0e95ceb8d1cc4ad6ffb18a32f90 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Nov 2016 19:53:29 +0100 Subject: Fix some bugs (bzr r15142.1.37) --- src/ui/tools/tool-base.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index c789b44bb..ca700f652 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -373,6 +373,8 @@ bool ToolBase::root_handler(GdkEvent* event) { ret = TRUE; } + desktop->canvas->clearRotateTo(); + this->rotating_mode = false; break; case 2: @@ -420,6 +422,8 @@ bool ToolBase::root_handler(GdkEvent* event) { sp_event_root_menu_popup(desktop, NULL, event); } ret = TRUE; + desktop->canvas->clearRotateTo(); + this->rotating_mode = false; break; default: @@ -836,9 +840,7 @@ bool ToolBase::root_handler(GdkEvent* event) { if (this->rotating_mode) { desktop->canvas->clearRotateTo(); this->rotating_mode = false; - ret = TRUE; desktop->canvas->endRotateTo(); - break; } bool ctrl = (event->scroll.state & GDK_CONTROL_MASK); bool wheelzooms = prefs->getBool("/options/wheelzooms/value"); -- cgit v1.2.3 From 4d33b96eb8c47f5aef22f795dd199ba04b734784 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sat, 3 Dec 2016 23:49:17 +0100 Subject: Start coding (bzr r15295.1.1) --- src/live_effects/lpe-mirror_symmetry.cpp | 201 ++++++++++++++++++++++++++++--- src/live_effects/lpe-mirror_symmetry.h | 14 +++ 2 files changed, 200 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 4deb29d8f..e62dbbca9 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -14,12 +14,18 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ #include "live_effects/lpe-mirror_symmetry.h" -#include -#include +#include "display/curve.h" +#include "svg/path-string.h" +#include "svg/svg.h" +#include "sp-defs.h" #include "helper/geom.h" -#include <2geom/path-intersection.h> +#include "2geom/path-intersection.h" +#include "2geom/affine.h" +#include "uri.h" +#include "uri-references.h" #include "knotholder.h" // TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { @@ -34,6 +40,9 @@ static const Util::EnumData ModeTypeData[MT_END] = { static const Util::EnumDataConverter MTConverter(ModeTypeData, MT_END); +std::vector ms_elements; +SPObject * ms_container; + namespace MS { class KnotHolderEntityCenterMirrorSymmetry : public LPEKnotHolderEntity { @@ -65,6 +74,9 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : discard_orig_path(_("Discard original path?"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), + split(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split", &wr, this, false), + split_sensitive(_("Make split selectable"), _("Allow select splited elements"), "split", &wr, this, false), + split_style(_("Make splits with style"), _("Allow Change colors to split"), "split", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, "Adjust the start of mirroring"), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring") { @@ -73,6 +85,9 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : registerParameter( &discard_orig_path); registerParameter( &fuse_paths); registerParameter( &oposite_fuse); + registerParameter( &split); + registerParameter( &split_sensitive); + registerParameter( &split_style); registerParameter( &start_point); registerParameter( &end_point); apply_to_clippath_and_mask = true; @@ -142,8 +157,155 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } } previous_center = center_point; + if (split) { + SPLPEItem * splpeitem = const_cast(lpeitem); + ms_container = dynamic_cast(splpeitem->parent); + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node *root = splpeitem->document->getReprRoot(); + Inkscape::XML::Node *root_origin = doc->getReprRoot(); + if (root_origin != root) { + return; + } + Geom::Point point_a(line_separation.initialPoint()); + Geom::Point point_b(line_separation.finalPoint()); + + Geom::Translate m1(point_a[0], point_a[1]); + double hyp = Geom::distance(point_a, point_b); + double cos = 0; + double sin = 0; + if (hyp > 0) { + cos = (point_b[0] - point_a[0]) / hyp; + sin = (point_b[1] - point_a[1]) / hyp; + } + Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); + Geom::Scale sca(1.0, -1.0); + + Geom::Affine m = m1.inverse() * m2; + m = m * sca; + m = m * m2.inverse(); + m = m * m1; + createPhantom(splpeitem , (Glib::ustring) "origin-clon-", split_style); + createClone(splpeitem , m, (Glib::ustring) "clon-"); + } +} + +void +LPEMirrorSymmetry::createPhantom(SPLPEItem *origin, Glib::ustring id, bool styling) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + id = id + (Glib::ustring)this->getRepr()->attribute("id"); + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + Inkscape::XML::Node *phantom = origin->getRepr()->duplicate(xml_doc); + if (elemref = SVGElemRef->getObject()) { + elemref->deleteObject(); + } + if (styling) { + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property (css, "fill", NULL); + sp_repr_css_set_property (css, "stroke",NULL); + Glib::ustring css_str; + sp_repr_css_write_string(css,css_str); + sp_repr_css_change_recursive (phantom, css, css_str.c_str()); + } + phantom->setAttribute("id", id); + phantom->setAttribute("inkscape:path-effect", NULL); + SP_OBJECT(desktop->getDocument()->getDefs()->appendChildRepr(phantom)); + Inkscape::GC::release(phantom); + ms_elements.push_back(id); + } +} + +void +LPEMirrorSymmetry::createClone(SPLPEItem *origin, Geom::Affine transform, Glib::ustring id) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + id = id + (Glib::ustring)this->getRepr()->attribute("id"); + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + Inkscape::XML::Node *use = NULL; + use = xml_doc->createElement("svg:use"); + use->setAttribute("transform" , sp_svg_transform_write(transform)); + use->setAttribute("xlink:href", ((Glib::ustring)"#origin-" + id).c_str()); + use->setAttribute("width", "100%"); + use->setAttribute("height", "100%"); + use->setAttribute("id", id); + use->setAttribute("x", "0"); + use->setAttribute("y", "0"); + if (split_sensitive) { + use->setAttribute("sodipodi:insensitive" , "false"); + } else { + use->setAttribute("sodipodi:insensitive" , "true"); + } + if (elemref) { + elemref->deleteObject(); + } + elemref = ms_container->appendChildRepr(use); + Inkscape::GC::release(use); + ms_elements.push_back(id); + } +} + + +void +LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) +{ + processObjects(LPE_VISIBILITY); +} + +void +LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) +{ + if (!erase_extra_objects) { + processObjects(LPE_TO_OBJECTS); + ms_elements.clear(); + return; + } + processObjects(LPE_ERASE); } +void +LPEMirrorSymmetry::processObjects(LpeAction lpe_action) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + for (std::vector::iterator el_it = ms_elements.begin(); + el_it != ms_elements.end();++el_it) { + Glib::ustring id = *el_it; + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + if (elemref = SVGElemRef->getObject()) { + switch (lpe_action){ + case LPE_TO_OBJECTS: + elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); + break; + case LPE_ERASE: + elemref->deleteObject(); + break; + default: //LPE_VISIBILITY + if (!this->isVisible()) { + elemref->getRepr()->setAttribute("style", "display:none"); + } else { + elemref->getRepr()->setAttribute("style", NULL); + } + break; + } + } + } + if (lpe_action == LPE_ERASE) { + ms_elements.clear(); + } + } +} + + void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { @@ -178,6 +340,9 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) Geom::PathVector LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) { + if (split && !fuse_paths) { + return path_in; + } Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); Geom::PathVector path_out; @@ -204,7 +369,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) m = m * m2.inverse(); m = m * m1; - if (fuse_paths && !discard_orig_path) { + if (fuse_paths && (!discard_orig_path || split )) { for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -255,11 +420,15 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) } if (position == 1) { Geom::Path mirror = portion.reversed() * m; - mirror.setInitial(portion.finalPoint()); - portion.append(mirror); - if(i!=0) { - portion.setFinal(portion.initialPoint()); + if (split) { portion.close(); + } else { + mirror.setInitial(portion.finalPoint()); + portion.append(mirror); + if(i!=0) { + portion.setFinal(portion.initialPoint()); + portion.close(); + } } tmp_path.push_back(portion); } @@ -277,10 +446,14 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) Geom::Path portion = original.portion(time_start, original.size()); if (!portion.empty()) { portion = portion.reversed(); - Geom::Path mirror = portion.reversed() * m; - mirror.setInitial(portion.finalPoint()); - portion.append(mirror); - portion = portion.reversed(); + if (split) { + + } else { + Geom::Path mirror = portion.reversed() * m; + mirror.setInitial(portion.finalPoint()); + portion.append(mirror); + portion = portion.reversed(); + } if (!original.closed()) { tmp_path.push_back(portion); } else { @@ -304,9 +477,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } - } - - if (!fuse_paths || discard_orig_path) { + } else if (!fuse_paths || discard_orig_path) { for (size_t i = 0; i < original_pathv.size(); ++i) { path_out.push_back(original_pathv[i] * m); } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 7ec4029e0..70c82e330 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -31,6 +31,12 @@ namespace MS { class KnotHolderEntityCenterMirrorSymmetry; } +enum LpeAction { + LPE_ERASE = 0, + LPE_TO_OBJECTS, + LPE_VISIBILITY +}; + enum ModeType { MT_V, MT_H, @@ -48,8 +54,13 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); + virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); + virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); + void processObjects(LpeAction lpe_action); /* the knotholder entity classes must be declared friends */ friend class MS::KnotHolderEntityCenterMirrorSymmetry; + void createPhantom(SPLPEItem *origin, Glib::ustring id, bool styling); + void createClone(SPLPEItem *origin, Geom::Affine transform, Glib::ustring id); void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: @@ -60,6 +71,9 @@ private: BoolParam discard_orig_path; BoolParam fuse_paths; BoolParam oposite_fuse; + BoolParam split; + BoolParam split_sensitive; + BoolParam split_style; PointParam start_point; PointParam end_point; Geom::Line line_separation; -- cgit v1.2.3 From 4839ba469180e32f7bff635c3f0a4b436511bf3b Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 5 Dec 2016 15:04:19 +0100 Subject: Added rough mirror improvements, things to fix (bzr r15295.1.3) --- src/live_effects/effect.h | 8 +- src/live_effects/lpe-measure-line.h | 6 - src/live_effects/lpe-mirror_symmetry.cpp | 230 +++++++++++++++++++------------ src/live_effects/lpe-mirror_symmetry.h | 18 ++- 4 files changed, 158 insertions(+), 104 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 06aa075eb..28a1a4e8e 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -44,6 +44,12 @@ enum LPEPathFlashType { DEFAULT }; +enum LpeAction { + LPE_ERASE = 0, + LPE_TO_OBJECTS, + LPE_VISIBILITY +}; + class Effect { public: static Effect* New(EffectType lpenr, LivePathEffectObject *lpeobj); @@ -125,6 +131,7 @@ public: bool apply_to_clippath_and_mask; bool erase_extra_objects; // set this to false allow retain extra generated objects, see measure line LPE bool upd_params; + BoolParam is_visible; protected: Effect(LivePathEffectObject *lpeobject); @@ -150,7 +157,6 @@ protected: bool _provides_knotholder_entities; int oncanvasedit_it; - BoolParam is_visible; bool show_orig_path; // set this to true in derived effects to automatically have the original // path displayed as helperpath diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h index a05189039..d668fbd30 100644 --- a/src/live_effects/lpe-measure-line.h +++ b/src/live_effects/lpe-measure-line.h @@ -32,12 +32,6 @@ enum OrientationMethod { OM_END }; -enum LpeAction { - LPE_ERASE = 0, - LPE_TO_OBJECTS, - LPE_VISIBILITY -}; - class LPEMeasureLine : public Effect { public: LPEMeasureLine(LivePathEffectObject *lpeobject); diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index e62dbbca9..f420c7e69 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -40,7 +40,7 @@ static const Util::EnumData ModeTypeData[MT_END] = { static const Util::EnumDataConverter MTConverter(ModeTypeData, MT_END); -std::vector ms_elements; +std::vector ms_elements; SPObject * ms_container; namespace MS { @@ -52,45 +52,38 @@ public: virtual Geom::Point knot_get() const; }; -class KnotHolderEntityStartMirrorSymmetry : public LPEKnotHolderEntity { -public: - KnotHolderEntityStartMirrorSymmetry(LPEMirrorSymmetry *effect) : LPEKnotHolderEntity(effect){}; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; -}; - -class KnotHolderEntityEndMirrorSymmetry : public LPEKnotHolderEntity { -public: - KnotHolderEntityEndMirrorSymmetry(LPEMirrorSymmetry *effect) : LPEKnotHolderEntity(effect){}; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; -}; - } // namespace MS LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), + split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, 0), discard_orig_path(_("Discard original path?"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), - split(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split", &wr, this, false), - split_sensitive(_("Make split selectable"), _("Allow select splited elements"), "split", &wr, this, false), - split_style(_("Make splits with style"), _("Allow Change colors to split"), "split", &wr, this, false), + split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split_elements", &wr, this, false), + split_sensitive(_("Make split selectable"), _("Allow select splited elements"), "split_sensitive", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, "Adjust the start of mirroring"), - end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring") + end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring"), + id_origin("id_origin", "id_origin", "id_origin", &wr, this,"") { show_orig_path = true; registerParameter(&mode); + registerParameter( &split_gap); registerParameter( &discard_orig_path); registerParameter( &fuse_paths); registerParameter( &oposite_fuse); - registerParameter( &split); - registerParameter( &split_sensitive); - registerParameter( &split_style); + registerParameter( &split_elements); + //registerParameter( &split_sensitive); registerParameter( &start_point); registerParameter( &end_point); + registerParameter( &id_origin); + id_origin.param_hide_canvas_text(); + split_gap.param_set_range(-999999.0, 999999.0); + split_gap.param_set_increments(0.1, 0.1); + split_gap.param_set_digits(2); apply_to_clippath_and_mask = true; + actual = true; } LPEMirrorSymmetry::~LPEMirrorSymmetry() @@ -98,14 +91,30 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry() } void - LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { + SPLPEItem * splpeitem = const_cast(lpeitem); + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::Selection *sel = desktop->getSelection(); + if ( sel && !sel->isEmpty() ) { + SPItem *item = sel->singleItem(); + if (item) { + if(std::strcmp(splpeitem->getId(),item->getId()) != 0) { + actual = false; + return; + } + } else { + + } + } + } + using namespace Geom; original_bbox(lpeitem); + Geom::Affine m = Geom::identity();//lpeitem->transform; Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); - Point point_c(boundingbox_X.max(), boundingbox_Y.middle()); + gchar * id = g_strdup(((Glib::ustring)"mirror-" + (Glib::ustring)id_origin.param_getSVGValue() + (Glib::ustring)"-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); if (mode == MT_Y) { point_a = Geom::Point(boundingbox_X.min(),center_point[Y]); point_b = Geom::Point(boundingbox_X.max(),center_point[Y]); @@ -157,8 +166,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } } previous_center = center_point; - if (split) { - SPLPEItem * splpeitem = const_cast(lpeitem); + if (split_elements) { ms_container = dynamic_cast(splpeitem->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node *root = splpeitem->document->getReprRoot(); @@ -166,9 +174,16 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) if (root_origin != root) { return; } +// if (std::strcmp(splpeitem->getId(), id) == 0) { +// Geom::Affine affine = Geom::identity(); +// affine *= Geom::Translate(center_point).inverse(); +// affine *= Geom::Rotate(Geom::rad_from_deg(180)); +// affine *= Geom::Translate(center_point); +// line_separation *= affine; +// } Geom::Point point_a(line_separation.initialPoint()); Geom::Point point_b(line_separation.finalPoint()); - + Geom::Point gap = Geom::Point(split_gap,0); Geom::Translate m1(point_a[0], point_a[1]); double hyp = Geom::distance(point_a, point_b); double cos = 0; @@ -178,76 +193,80 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) sin = (point_b[1] - point_a[1]) / hyp; } Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); + gap *= m2; Geom::Scale sca(1.0, -1.0); - - Geom::Affine m = m1.inverse() * m2; + if (std::strcmp(splpeitem->getId(), id) == 0) { + id = id_origin.param_getSVGValue(); + } + m = m1.inverse() * m2; m = m * sca; m = m * m2.inverse(); m = m * m1; - createPhantom(splpeitem , (Glib::ustring) "origin-clon-", split_style); - createClone(splpeitem , m, (Glib::ustring) "clon-"); + m = m * gap; + m = m * lpeitem->transform; + ms_elements.clear(); + createMirror(splpeitem, m, id); + } else { + processObjects(LPE_ERASE); } } void -LPEMirrorSymmetry::createPhantom(SPLPEItem *origin, Glib::ustring id, bool styling) +LPEMirrorSymmetry::cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...) { - if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); - id = id + (Glib::ustring)this->getRepr()->attribute("id"); - Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); - Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); - SVGElemRef->attach(SVGElem_uri); - SPObject *elemref = NULL; - Inkscape::XML::Node *phantom = origin->getRepr()->duplicate(xml_doc); - if (elemref = SVGElemRef->getObject()) { - elemref->deleteObject(); - } - if (styling) { - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property (css, "fill", NULL); - sp_repr_css_set_property (css, "stroke",NULL); - Glib::ustring css_str; - sp_repr_css_write_string(css,css_str); - sp_repr_css_change_recursive (phantom, css, css_str.c_str()); + va_list args; + va_start(args, first_attribute); + + if ( origin->name() == "svg:g" && origin->childCount() == dest->childCount() ) { + Inkscape::XML::Node * node_it = origin->firstChild(); + size_t index = 0; + while (node_it != origin->lastChild()) { + cloneAttrbutes(node_it, dest->nthChild(index), first_attribute, args); + node_it = node_it->next(); + index++; } - phantom->setAttribute("id", id); - phantom->setAttribute("inkscape:path-effect", NULL); - SP_OBJECT(desktop->getDocument()->getDefs()->appendChildRepr(phantom)); - Inkscape::GC::release(phantom); - ms_elements.push_back(id); } + while(char const * att = va_arg(args, char const *)) { + dest->setAttribute(att,origin->attribute(att)); + } + va_end(args); } void -LPEMirrorSymmetry::createClone(SPLPEItem *origin, Geom::Affine transform, Glib::ustring id) +LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, gchar * id) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); - id = id + (Glib::ustring)this->getRepr()->attribute("id"); Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); - SPObject *elemref = NULL; - Inkscape::XML::Node *use = NULL; - use = xml_doc->createElement("svg:use"); - use->setAttribute("transform" , sp_svg_transform_write(transform)); - use->setAttribute("xlink:href", ((Glib::ustring)"#origin-" + id).c_str()); - use->setAttribute("width", "100%"); - use->setAttribute("height", "100%"); - use->setAttribute("id", id); - use->setAttribute("x", "0"); - use->setAttribute("y", "0"); - if (split_sensitive) { - use->setAttribute("sodipodi:insensitive" , "false"); + SPObject *elemref= NULL; + Inkscape::XML::Node *phantom = NULL; + if (elemref = SVGElemRef->getObject()) { + phantom = elemref->getRepr(); } else { - use->setAttribute("sodipodi:insensitive" , "true"); + phantom = origin->getRepr()->duplicate(xml_doc); } - if (elemref) { + cloneAttrbutes(origin->getRepr(), phantom, "inkscape:original-d"); + phantom->setAttribute("id", id); + // if (std::strcmp(id, id_origin.param_getSVGValue()) != 0) { + phantom->setAttribute("transform" , sp_svg_transform_write(transform)); + +// if (split_sensitive) { +// phantom->setAttribute("sodipodi:insensitive" , NULL); +// } else { +// phantom->setAttribute("sodipodi:insensitive" , "true"); +// } + if (!elemref) { + elemref = ms_container->appendChildRepr(phantom); + Inkscape::GC::release(phantom); + } else if (elemref->parent != ms_container) { + Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); + ms_container->appendChildRepr(copy); + Inkscape::GC::release(copy); elemref->deleteObject(); + copy->setAttribute("id", id); } - elemref = ms_container->appendChildRepr(use); - Inkscape::GC::release(use); ms_elements.push_back(id); } } @@ -274,9 +293,9 @@ void LPEMirrorSymmetry::processObjects(LpeAction lpe_action) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - for (std::vector::iterator el_it = ms_elements.begin(); + for (std::vector::iterator el_it = ms_elements.begin(); el_it != ms_elements.end();++el_it) { - Glib::ustring id = *el_it; + gchar * id = *el_it; Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); @@ -285,6 +304,7 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) switch (lpe_action){ case LPE_TO_OBJECTS: elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); + SP_LPE_ITEM(elemref)->removeAllPathEffects(true); break; case LPE_ERASE: elemref->deleteObject(); @@ -309,12 +329,14 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { - center_point *= postmul; - previous_center = center_point; - // cycle through all parameters. Most parameters will not need transformation, but path and point params do. - for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { - Parameter * param = *it; - param->param_transform_multiply(postmul, set); + if( !split_elements) { + center_point *= postmul; + previous_center = center_point; + // cycle through all parameters. Most parameters will not need transformation, but path and point params do. + for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { + Parameter * param = *it; + param->param_transform_multiply(postmul, set); + } } } @@ -334,13 +356,14 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) end_point.param_update_default(point_b); center_point = point_c; previous_center = center_point; + id_origin.param_setValue((Glib::ustring)lpeitem->getId()); } Geom::PathVector LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) { - if (split && !fuse_paths) { + if (split_elements && !fuse_paths) { return path_in; } Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); @@ -369,7 +392,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) m = m * m2.inverse(); m = m * m1; - if (fuse_paths && (!discard_orig_path || split )) { + if (fuse_paths && (!discard_orig_path || split_elements )) { for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -420,7 +443,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) } if (position == 1) { Geom::Path mirror = portion.reversed() * m; - if (split) { + if (split_elements) { portion.close(); } else { mirror.setInitial(portion.finalPoint()); @@ -446,9 +469,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) Geom::Path portion = original.portion(time_start, original.size()); if (!portion.empty()) { portion = portion.reversed(); - if (split) { - - } else { + if (!split_elements) { Geom::Path mirror = portion.reversed() * m; mirror.setInitial(portion.finalPoint()); portion.append(mirror); @@ -486,6 +507,41 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) return path_out; } + +Gtk::Widget *LPEMirrorSymmetry::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + if (param->param_key != "id_origin") { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + } + + ++it; + } + return dynamic_cast(vbox); +} + void LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) { diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 70c82e330..00bc45488 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -17,6 +17,7 @@ */ #include #include "live_effects/effect.h" +#include "live_effects/parameter/text.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/point.h" #include "live_effects/parameter/path.h" @@ -31,12 +32,6 @@ namespace MS { class KnotHolderEntityCenterMirrorSymmetry; } -enum LpeAction { - LPE_ERASE = 0, - LPE_TO_OBJECTS, - LPE_VISIBILITY -}; - enum ModeType { MT_V, MT_H, @@ -56,11 +51,12 @@ public: virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); + virtual Gtk::Widget *newWidget(); void processObjects(LpeAction lpe_action); /* the knotholder entity classes must be declared friends */ friend class MS::KnotHolderEntityCenterMirrorSymmetry; - void createPhantom(SPLPEItem *origin, Glib::ustring id, bool styling); - void createClone(SPLPEItem *origin, Geom::Affine transform, Glib::ustring id); + void createMirror(SPLPEItem *origin, Geom::Affine transform, gchar * id); + void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...); void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: @@ -68,17 +64,19 @@ protected: private: EnumParam mode; + ScalarParam split_gap; BoolParam discard_orig_path; BoolParam fuse_paths; BoolParam oposite_fuse; - BoolParam split; + BoolParam split_elements; BoolParam split_sensitive; - BoolParam split_style; PointParam start_point; PointParam end_point; + TextParam id_origin; Geom::Line line_separation; Geom::Point previous_center; Geom::Point center_point; + bool actual; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); -- cgit v1.2.3 From 64e8f0b5a189cffa91b182c24043b73eaa5e0b4c Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 5 Dec 2016 15:07:45 +0100 Subject: Rollback a unwanted modified file (bzr r15295.1.5) --- src/live_effects/lpe-measure-line.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h index d668fbd30..a05189039 100644 --- a/src/live_effects/lpe-measure-line.h +++ b/src/live_effects/lpe-measure-line.h @@ -32,6 +32,12 @@ enum OrientationMethod { OM_END }; +enum LpeAction { + LPE_ERASE = 0, + LPE_TO_OBJECTS, + LPE_VISIBILITY +}; + class LPEMeasureLine : public Effect { public: LPEMeasureLine(LivePathEffectObject *lpeobject); -- cgit v1.2.3 From 1361cbe77c067e59ccbd25ed5eb1c50e177f8b34 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 5 Dec 2016 21:55:14 +0100 Subject: Working on mirror LPE (bzr r15295.1.6) --- src/live_effects/lpe-measure-line.h | 6 -- src/live_effects/lpe-mirror_symmetry.cpp | 107 +++++++++++++++++++++---------- src/live_effects/lpe-mirror_symmetry.h | 7 +- src/sp-object.cpp | 14 ++++ src/sp-object.h | 3 + 5 files changed, 93 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h index a05189039..d668fbd30 100644 --- a/src/live_effects/lpe-measure-line.h +++ b/src/live_effects/lpe-measure-line.h @@ -32,12 +32,6 @@ enum OrientationMethod { OM_END }; -enum LpeAction { - LPE_ERASE = 0, - LPE_TO_OBJECTS, - LPE_VISIBILITY -}; - class LPEMeasureLine : public Effect { public: LPEMeasureLine(LivePathEffectObject *lpeobject); diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index f420c7e69..d6989fa41 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -40,9 +40,6 @@ static const Util::EnumData ModeTypeData[MT_END] = { static const Util::EnumDataConverter MTConverter(ModeTypeData, MT_END); -std::vector ms_elements; -SPObject * ms_container; - namespace MS { class KnotHolderEntityCenterMirrorSymmetry : public LPEKnotHolderEntity { @@ -62,7 +59,6 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split_elements", &wr, this, false), - split_sensitive(_("Make split selectable"), _("Allow select splited elements"), "split_sensitive", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, "Adjust the start of mirroring"), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring"), id_origin("id_origin", "id_origin", "id_origin", &wr, this,"") @@ -74,7 +70,6 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : registerParameter( &fuse_paths); registerParameter( &oposite_fuse); registerParameter( &split_elements); - //registerParameter( &split_sensitive); registerParameter( &start_point); registerParameter( &end_point); registerParameter( &id_origin); @@ -167,6 +162,9 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } previous_center = center_point; if (split_elements) { + ms_elements.clear(); + ms_elements.push_back(id); + ms_elements.push_back(id_origin.param_getSVGValue()); ms_container = dynamic_cast(splpeitem->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node *root = splpeitem->document->getReprRoot(); @@ -174,13 +172,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) if (root_origin != root) { return; } -// if (std::strcmp(splpeitem->getId(), id) == 0) { -// Geom::Affine affine = Geom::identity(); -// affine *= Geom::Translate(center_point).inverse(); -// affine *= Geom::Rotate(Geom::rad_from_deg(180)); -// affine *= Geom::Translate(center_point); -// line_separation *= affine; -// } Geom::Point point_a(line_separation.initialPoint()); Geom::Point point_b(line_separation.finalPoint()); Geom::Point gap = Geom::Point(split_gap,0); @@ -204,30 +195,75 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) m = m * m1; m = m * gap; m = m * lpeitem->transform; - ms_elements.clear(); createMirror(splpeitem, m, id); } else { + ms_elements.clear(); processObjects(LPE_ERASE); } } +//void +//LPEMirrorSymmetry::cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...) +//{ +// va_list args; +// va_start(args, first_attribute); + +// if ( origin->name() == "svg:g" && origin->childCount() == dest->childCount() ) { +// Inkscape::XML::Node * node_it = origin->firstChild(); +// size_t index = 0; +// while (node_it != origin->lastChild()) { +// cloneAttrbutes(node_it, dest->nthChild(index), first_attribute, live, args); +// node_it = node_it->next(); +// index++; +// } +// } +// while(char const * att = va_arg(args, char const *)) { +// dest->setAttribute(att,origin->attribute(att)); +// } +// va_end(args); +//} + void -LPEMirrorSymmetry::cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...) +LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, char const * first_attribute, ...) { va_list args; va_start(args, first_attribute); - - if ( origin->name() == "svg:g" && origin->childCount() == dest->childCount() ) { - Inkscape::XML::Node * node_it = origin->firstChild(); + + if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { + std::vector< SPObject * > childs = origin->childList(true); size_t index = 0; - while (node_it != origin->lastChild()) { - cloneAttrbutes(node_it, dest->nthChild(index), first_attribute, args); - node_it = node_it->next(); + for (std::vector::iterator obj_it = childs.begin(); + obj_it != childs.end(); ++obj_it) { + SPObject *dest_child = dest->nthChild(index); + cloneAttrbutes(*obj_it, dest_child, live, first_attribute, args); index++; } } + unsigned counter = 0; while(char const * att = va_arg(args, char const *)) { - dest->setAttribute(att,origin->attribute(att)); + if (counter % 2 != 0){ + SPShape * shape = SP_SHAPE(origin); + if (shape) { + if ( live && (att == "d" || att == "inkscape:original-d")) { + SPCurve *c = NULL; + if (att == "d") { + c = shape->getCurve(); + } else { + c = shape->getCurveBeforeLPE(); + } + if (c) { + dest->getRepr()->setAttribute(att,sp_svg_write_path(c->get_pathvector())); + c->reset(); + g_free(c); + } else { + dest->getRepr()->setAttribute(att,NULL); + } + } else { + dest->getRepr()->setAttribute(att,origin->getRepr()->attribute(att)); + } + } + } + counter++; } va_end(args); } @@ -247,27 +283,21 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, gchar } else { phantom = origin->getRepr()->duplicate(xml_doc); } - cloneAttrbutes(origin->getRepr(), phantom, "inkscape:original-d"); + phantom->setAttribute("id", id); - // if (std::strcmp(id, id_origin.param_getSVGValue()) != 0) { - phantom->setAttribute("transform" , sp_svg_transform_write(transform)); - -// if (split_sensitive) { -// phantom->setAttribute("sodipodi:insensitive" , NULL); -// } else { -// phantom->setAttribute("sodipodi:insensitive" , "true"); -// } if (!elemref) { elemref = ms_container->appendChildRepr(phantom); Inkscape::GC::release(phantom); - } else if (elemref->parent != ms_container) { + } + cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d"); + elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); + if (elemref->parent != ms_container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); + copy->setAttribute("id", id); ms_container->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); - copy->setAttribute("id", id); } - ms_elements.push_back(id); } } @@ -283,6 +313,7 @@ LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) { if (!erase_extra_objects) { processObjects(LPE_TO_OBJECTS); + std::cout << ms_elements.size() << "ms_elements.size() ms_elements.size() ms_elements.size() ms_elements.size() ms_elements.size() \n"; ms_elements.clear(); return; } @@ -294,17 +325,22 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { for (std::vector::iterator el_it = ms_elements.begin(); - el_it != ms_elements.end();++el_it) { + el_it != ms_elements.end(); ++el_it) { gchar * id = *el_it; + std::cout << id << "idididididididididi\n"; Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); SPObject *elemref = NULL; if (elemref = SVGElemRef->getObject()) { + SPLPEItem *lpe_element = dynamic_cast(elemref); + std::cout << elemref->getId() << "elemref->getId()elemref->getId()elemref->getId()elemref->getId()\n"; switch (lpe_action){ case LPE_TO_OBJECTS: elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); - SP_LPE_ITEM(elemref)->removeAllPathEffects(true); + if (lpe_element && lpe_element->hasPathEffect()) { + lpe_element->removeAllPathEffects(true); + } break; case LPE_ERASE: elemref->deleteObject(); @@ -357,6 +393,7 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) center_point = point_c; previous_center = center_point; id_origin.param_setValue((Glib::ustring)lpeitem->getId()); + id_origin.write_to_SVG(); } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 00bc45488..cdbfe67e2 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -56,7 +56,8 @@ public: /* the knotholder entity classes must be declared friends */ friend class MS::KnotHolderEntityCenterMirrorSymmetry; void createMirror(SPLPEItem *origin, Geom::Affine transform, gchar * id); - void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...); +// void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...); + void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, char const * first_attribute, ...); void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: @@ -69,7 +70,6 @@ private: BoolParam fuse_paths; BoolParam oposite_fuse; BoolParam split_elements; - BoolParam split_sensitive; PointParam start_point; PointParam end_point; TextParam id_origin; @@ -77,7 +77,8 @@ private: Geom::Point previous_center; Geom::Point center_point; bool actual; - + std::vector ms_elements; + SPObject * ms_container; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); }; diff --git a/src/sp-object.cpp b/src/sp-object.cpp index e9c60fc7d..c2122e109 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -773,6 +773,20 @@ void SPObject::appendChild(Inkscape::XML::Node *child) { repr->appendChild(child); } +SPObject* SPObject::nthChild(unsigned index) { + g_assert(this->repr); + if (hasChildren()) { + std::vector l; + unsigned counter = 0; + for (auto& child: children) { + if (counter == index) { + return &child; + } + } + } + return NULL; +} + void SPObject::addChild(Inkscape::XML::Node *child, Inkscape::XML::Node * prev) { g_assert(this->repr); diff --git a/src/sp-object.h b/src/sp-object.h index 9abbd324b..d145e966b 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -318,6 +318,9 @@ public: SPObject *lastChild() { return children.empty() ? nullptr : &children.back(); } SPObject const *lastChild() const { return children.empty() ? nullptr : &children.back(); } + SPObject *nthChild(unsigned index); + SPObject const *nthChild(unsigned index) const; + enum Action { ActionGeneral, ActionBBox, ActionUpdate, ActionShow }; /** -- cgit v1.2.3 From 03098d9de7fbca944663da45b1a662be8a69c485 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 6 Dec 2016 22:16:46 +0100 Subject: Fix to const char (bzr r15295.1.9) --- src/live_effects/lpe-mirror_symmetry.cpp | 32 ++++++++++++++++---------------- src/live_effects/lpe-mirror_symmetry.h | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index d6989fa41..e44d57a0e 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -109,7 +109,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Affine m = Geom::identity();//lpeitem->transform; Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); - gchar * id = g_strdup(((Glib::ustring)"mirror-" + (Glib::ustring)id_origin.param_getSVGValue() + (Glib::ustring)"-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); if (mode == MT_Y) { point_a = Geom::Point(boundingbox_X.min(),center_point[Y]); point_b = Geom::Point(boundingbox_X.max(),center_point[Y]); @@ -162,9 +161,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } previous_center = center_point; if (split_elements) { - ms_elements.clear(); - ms_elements.push_back(id); - ms_elements.push_back(id_origin.param_getSVGValue()); ms_container = dynamic_cast(splpeitem->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node *root = splpeitem->document->getReprRoot(); @@ -186,16 +182,22 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); gap *= m2; Geom::Scale sca(1.0, -1.0); - if (std::strcmp(splpeitem->getId(), id) == 0) { - id = id_origin.param_getSVGValue(); - } + const char * id_original = id_origin.param_getSVGValue(); + const char * id = g_strdup(Glib::ustring("mirror-").append(id_original).append("-").append(this->getRepr()->attribute("id")).c_str()); m = m1.inverse() * m2; m = m * sca; m = m * m2.inverse(); m = m * m1; m = m * gap; m = m * lpeitem->transform; - createMirror(splpeitem, m, id); + if (std::strcmp(splpeitem->getId(), id) == 0) { + createMirror(splpeitem, m, id_original); + } else { + createMirror(splpeitem, m, id); + } + ms_elements.clear(); + ms_elements.push_back(id); + ms_elements.push_back(id_original); } else { ms_elements.clear(); processObjects(LPE_ERASE); @@ -269,11 +271,11 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c } void -LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, gchar * id) +LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); - Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); + Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); SPObject *elemref= NULL; @@ -324,17 +326,15 @@ void LPEMirrorSymmetry::processObjects(LpeAction lpe_action) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - for (std::vector::iterator el_it = ms_elements.begin(); + for (std::vector::iterator el_it = ms_elements.begin(); el_it != ms_elements.end(); ++el_it) { - gchar * id = *el_it; - std::cout << id << "idididididididididi\n"; - Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); + const char * id = *el_it; + Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); SPObject *elemref = NULL; if (elemref = SVGElemRef->getObject()) { SPLPEItem *lpe_element = dynamic_cast(elemref); - std::cout << elemref->getId() << "elemref->getId()elemref->getId()elemref->getId()elemref->getId()\n"; switch (lpe_action){ case LPE_TO_OBJECTS: elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); @@ -392,7 +392,7 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) end_point.param_update_default(point_b); center_point = point_c; previous_center = center_point; - id_origin.param_setValue((Glib::ustring)lpeitem->getId()); + id_origin.param_setValue(Glib::ustring(lpeitem->getId())); id_origin.write_to_SVG(); } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index cdbfe67e2..9ca86872f 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -55,7 +55,7 @@ public: void processObjects(LpeAction lpe_action); /* the knotholder entity classes must be declared friends */ friend class MS::KnotHolderEntityCenterMirrorSymmetry; - void createMirror(SPLPEItem *origin, Geom::Affine transform, gchar * id); + void createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, char const * first_attribute, ...); void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); @@ -77,7 +77,7 @@ private: Geom::Point previous_center; Geom::Point center_point; bool actual; - std::vector ms_elements; + std::vector ms_elements; SPObject * ms_container; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); -- cgit v1.2.3 From 34215a3e1d3b00357b4741ec397cf7d257770556 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Wed, 7 Dec 2016 02:24:26 +0100 Subject: Fixing and commiting (bzr r15295.1.10) --- src/live_effects/lpe-measure-line.cpp | 44 +++++++++---- src/live_effects/lpe-measure-line.h | 1 + src/live_effects/lpe-mirror_symmetry.cpp | 110 ++++++++++++++++--------------- src/live_effects/lpe-mirror_symmetry.h | 6 +- 4 files changed, 93 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index a1de035fb..8b73781b5 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -14,6 +14,7 @@ #include #include "inkscape.h" #include "xml/node.h" +#include "xml/sp-css-attr.h" #include "uri.h" #include "uri-references.h" #include "preferences.h" @@ -61,6 +62,7 @@ LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) : helpline_overlap(_("Helpline overlap*"), _("Helpline overlap"), "helpline_overlap", &wr, this, 2.0), scale(_("Scale*"), _("Scaling factor"), "scale", &wr, this, 1.0), format(_("Format*"), _("Format the number ex:{measure} {unit}, return to save"), "format", &wr, this,"{measure}{unit}"), + id_origin("id_origin", "id_origin", "id_origin", &wr, this,""), arrows_outside(_("Arrows outside"), _("Arrows outside"), "arrows_outside", &wr, this, false), flip_side(_("Flip side*"), _("Flip side"), "flip_side", &wr, this, false), scale_sensitive(_("Scale sensitive*"), _("Costrained scale sensitive to transformed containers"), "scale_sensitive", &wr, this, true), @@ -97,6 +99,8 @@ LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) : registerParameter(&helperlines_format); registerParameter(&anotation_format); registerParameter(&arrows_format); + registerParameter(&id_origin); + id_origin.param_hide_canvas_text(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring fontbutton_value = prefs->getString("/live_effects/measure-line/fontbutton"); if(fontbutton_value.empty()){ @@ -505,6 +509,8 @@ LPEMeasureLine::doOnApply(SPLPEItem const* lpeitem) SPLPEItem * item = const_cast(lpeitem); item->removeCurrentPathEffect(false); } + id_origin.param_setValue(Glib::ustring(lpeitem->getId())); + id_origin.write_to_SVG(); } void @@ -701,31 +707,43 @@ LPEMeasureLine::doOnRemove (SPLPEItem const* /*lpeitem*/) void LPEMeasureLine::processObjects(LpeAction lpe_action) { - if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - for (std::vector::const_iterator el_it = elements.begin(); - el_it != elements.end();++el_it) { - const char * id = (const char *)(*el_it); - std::cout << id << "asdfffgasdfasdsdgf\n"; + for (std::vector::iterator el_it = elements.begin(); + el_it != elements.end(); ++el_it) { + const char * id = *el_it; Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); SPObject *elemref = NULL; if (elemref = SVGElemRef->getObject()) { + SPCSSAttr *css; + Glib::ustring css_str; switch (lpe_action){ case LPE_TO_OBJECTS: + elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); - break; + break; + case LPE_ERASE: - elemref->deleteObject(); - break; - default: //LPE_VISIBILITY - if (!this->isVisible()) { - elemref->getRepr()->setAttribute("style", "display:none"); + if (std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { + elemref->deleteObject(); + } + break; + + case LPE_VISIBILITY: + css = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); + if (!this->isVisible() && std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { + css->setAttribute("display", "none"); } else { - elemref->getRepr()->setAttribute("style", NULL); + css->setAttribute("display", NULL); } - break; + sp_repr_css_write_string(css,css_str); + elemref->getRepr()->setAttribute("style", css_str.c_str()); + break; + + default: + break; } } } diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h index d680282a5..dea5ca47a 100644 --- a/src/live_effects/lpe-measure-line.h +++ b/src/live_effects/lpe-measure-line.h @@ -62,6 +62,7 @@ private: ScalarParam helpline_overlap; ScalarParam scale; TextParam format; + TextParam id_origin; BoolParam arrows_outside; BoolParam flip_side; BoolParam scale_sensitive; diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index e44d57a0e..bb38acbf1 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -24,6 +24,8 @@ #include "uri.h" #include "uri-references.h" #include "knotholder.h" +#include "style.h" +#include "xml/sp-css-attr.h" // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -98,12 +100,9 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) actual = false; return; } - } else { - } } } - using namespace Geom; original_bbox(lpeitem); Geom::Affine m = Geom::identity();//lpeitem->transform; @@ -170,7 +169,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } Geom::Point point_a(line_separation.initialPoint()); Geom::Point point_b(line_separation.finalPoint()); - Geom::Point gap = Geom::Point(split_gap,0); + Geom::Point gap(split_gap,0); Geom::Translate m1(point_a[0], point_a[1]); double hyp = Geom::distance(point_a, point_b); double cos = 0; @@ -180,7 +179,9 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) sin = (point_b[1] - point_a[1]) / hyp; } Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); - gap *= m2; + Geom::Point dir = unit_vector(point_b - point_a); + Geom::Point offset = (point_a + point_b)/2 + dir.ccw() * split_gap; + line_separation *= Geom::Translate(offset); Geom::Scale sca(1.0, -1.0); const char * id_original = id_origin.param_getSVGValue(); const char * id = g_strdup(Glib::ustring("mirror-").append(id_original).append("-").append(this->getRepr()->attribute("id")).c_str()); @@ -188,24 +189,23 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) m = m * sca; m = m * m2.inverse(); m = m * m1; - m = m * gap; m = m * lpeitem->transform; if (std::strcmp(splpeitem->getId(), id) == 0) { createMirror(splpeitem, m, id_original); } else { createMirror(splpeitem, m, id); } - ms_elements.clear(); - ms_elements.push_back(id); - ms_elements.push_back(id_original); + elements.clear(); + elements.push_back(id); + elements.push_back(id_original); } else { - ms_elements.clear(); + elements.clear(); processObjects(LPE_ERASE); } } //void -//LPEMirrorSymmetry::cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...) +//LPEMirrorSymmetry::cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...) //{ // va_list args; // va_start(args, first_attribute); @@ -219,14 +219,14 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) // index++; // } // } -// while(char const * att = va_arg(args, char const *)) { +// while(const char * att = va_arg(args, const char *)) { // dest->setAttribute(att,origin->attribute(att)); // } // va_end(args); //} void -LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, char const * first_attribute, ...) +LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...) { va_list args; va_start(args, first_attribute); @@ -241,31 +241,27 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c index++; } } - unsigned counter = 0; - while(char const * att = va_arg(args, char const *)) { - if (counter % 2 != 0){ - SPShape * shape = SP_SHAPE(origin); - if (shape) { - if ( live && (att == "d" || att == "inkscape:original-d")) { - SPCurve *c = NULL; - if (att == "d") { - c = shape->getCurve(); - } else { - c = shape->getCurveBeforeLPE(); - } - if (c) { - dest->getRepr()->setAttribute(att,sp_svg_write_path(c->get_pathvector())); - c->reset(); - g_free(c); - } else { - dest->getRepr()->setAttribute(att,NULL); - } + for (const char* att = first_attribute; att != NULL; att = va_arg(args, const char*)) { + SPShape * shape = SP_SHAPE(origin); + if (shape) { + if ( live && (att == "d" || att == "inkscape:original-d")) { + SPCurve *c = NULL; + if (att == "d") { + c = shape->getCurve(); + } else { + c = shape->getCurveBeforeLPE(); + } + if (c) { + dest->getRepr()->setAttribute(att,sp_svg_write_path(c->get_pathvector())); + c->reset(); + g_free(c); } else { - dest->getRepr()->setAttribute(att,origin->getRepr()->attribute(att)); + dest->getRepr()->setAttribute(att,NULL); } + } else { + dest->getRepr()->setAttribute(att,origin->getRepr()->attribute(att)); } } - counter++; } va_end(args); } @@ -291,7 +287,7 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const elemref = ms_container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d"); + cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); if (elemref->parent != ms_container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); @@ -315,8 +311,8 @@ LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) { if (!erase_extra_objects) { processObjects(LPE_TO_OBJECTS); - std::cout << ms_elements.size() << "ms_elements.size() ms_elements.size() ms_elements.size() ms_elements.size() ms_elements.size() \n"; - ms_elements.clear(); + std::cout << elements.size() << "elements.size() elements.size() elements.size() elements.size() elements.size() \n"; + elements.clear(); return; } processObjects(LPE_ERASE); @@ -326,37 +322,47 @@ void LPEMirrorSymmetry::processObjects(LpeAction lpe_action) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - for (std::vector::iterator el_it = ms_elements.begin(); - el_it != ms_elements.end(); ++el_it) { + for (std::vector::iterator el_it = elements.begin(); + el_it != elements.end(); ++el_it) { const char * id = *el_it; Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); SPObject *elemref = NULL; if (elemref = SVGElemRef->getObject()) { - SPLPEItem *lpe_element = dynamic_cast(elemref); + SPCSSAttr *css; + Glib::ustring css_str; switch (lpe_action){ case LPE_TO_OBJECTS: + elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); - if (lpe_element && lpe_element->hasPathEffect()) { - lpe_element->removeAllPathEffects(true); - } - break; + break; + case LPE_ERASE: - elemref->deleteObject(); - break; - default: //LPE_VISIBILITY - if (!this->isVisible()) { - elemref->getRepr()->setAttribute("style", "display:none"); + if (std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { + elemref->deleteObject(); + } + break; + + case LPE_VISIBILITY: + css = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); + if (!this->isVisible() && std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { + css->setAttribute("display", "none"); } else { - elemref->getRepr()->setAttribute("style", NULL); + css->setAttribute("display", NULL); } - break; + sp_repr_css_write_string(css,css_str); + elemref->getRepr()->setAttribute("style", css_str.c_str()); + break; + + default: + break; } } } if (lpe_action == LPE_ERASE) { - ms_elements.clear(); + elements.clear(); } } } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 9ca86872f..7b090ed82 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -56,8 +56,8 @@ public: /* the knotholder entity classes must be declared friends */ friend class MS::KnotHolderEntityCenterMirrorSymmetry; void createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id); -// void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...); - void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, char const * first_attribute, ...); +// void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); + void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...); void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: @@ -77,7 +77,7 @@ private: Geom::Point previous_center; Geom::Point center_point; bool actual; - std::vector ms_elements; + std::vector elements; SPObject * ms_container; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); -- cgit v1.2.3 From 832e5be17eb44f74710b680b493e8ad7ed957128 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 7 Dec 2016 18:47:41 +0100 Subject: Fixing retaining LPE on extra elements (bzr r15295.1.13) --- src/live_effects/lpe-mirror_symmetry.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index bb38acbf1..abf578078 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -287,7 +287,7 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const elemref = ms_container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required + cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", NULL); //NULL required elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); if (elemref->parent != ms_container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); @@ -334,7 +334,9 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) Glib::ustring css_str; switch (lpe_action){ case LPE_TO_OBJECTS: - elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); + if (sp_lpe_item->getId() != id) { + elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); + } elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); break; -- cgit v1.2.3 From 9b078f84a03865319b411bf537c256744d46e8e3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 7 Dec 2016 20:07:41 +0100 Subject: fixing extra LPE on copies on release (bzr r15295.1.15) --- src/live_effects/lpe-measure-line.cpp | 9 ++++++++- src/live_effects/lpe-mirror_symmetry.cpp | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index 8b73781b5..3d0583f55 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -696,7 +696,9 @@ LPEMeasureLine::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPEMeasureLine::doOnRemove (SPLPEItem const* /*lpeitem*/) { + std::cout << "111111111111111111111111\n"; if (!erase_extra_objects) { + std::cout << "2222222222222222222222222\n"; processObjects(LPE_TO_OBJECTS); elements.clear(); return; @@ -720,7 +722,12 @@ LPEMeasureLine::processObjects(LpeAction lpe_action) Glib::ustring css_str; switch (lpe_action){ case LPE_TO_OBJECTS: - elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); + std::cout << sp_lpe_item->getId() << "sp_lpe_item->getId()\n"; + std::cout << id << "Id()\n"; + if (std::strcmp(sp_lpe_item->getId(), id) != 0) { + std::cout << id << "loborro\n"; + elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); + } elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); break; diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index abf578078..fd7c7824d 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -334,7 +334,7 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) Glib::ustring css_str; switch (lpe_action){ case LPE_TO_OBJECTS: - if (sp_lpe_item->getId() != id) { + if (std::strcmp(sp_lpe_item->getId(), id) != 0) { elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); } elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); -- cgit v1.2.3 From 043cb3136f9118e411aff77e8105b3ac0b05b6b8 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Wed, 7 Dec 2016 23:19:44 +0100 Subject: Fix the duplicated LPE on erase bug (bzr r15295.1.16) --- src/live_effects/lpe-measure-line.cpp | 15 ++++++--------- src/live_effects/lpe-mirror_symmetry.cpp | 11 ++++++----- src/sp-lpe-item.cpp | 6 +++++- 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index 3d0583f55..ef63888d9 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -686,7 +686,7 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) } } - +//TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMeasureLine::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) { @@ -696,9 +696,8 @@ LPEMeasureLine::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPEMeasureLine::doOnRemove (SPLPEItem const* /*lpeitem*/) { - std::cout << "111111111111111111111111\n"; + //unset "erase_extra_objects" hook on sp-lpe-item.cpp if (!erase_extra_objects) { - std::cout << "2222222222222222222222222\n"; processObjects(LPE_TO_OBJECTS); elements.clear(); return; @@ -713,6 +712,9 @@ LPEMeasureLine::processObjects(LpeAction lpe_action) for (std::vector::iterator el_it = elements.begin(); el_it != elements.end(); ++el_it) { const char * id = *el_it; + if (!id || strlen(id) == 0) { + return; + } Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); @@ -722,12 +724,7 @@ LPEMeasureLine::processObjects(LpeAction lpe_action) Glib::ustring css_str; switch (lpe_action){ case LPE_TO_OBJECTS: - std::cout << sp_lpe_item->getId() << "sp_lpe_item->getId()\n"; - std::cout << id << "Id()\n"; - if (std::strcmp(sp_lpe_item->getId(), id) != 0) { - std::cout << id << "loborro\n"; - elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); - } + elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); break; diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index fd7c7824d..a338f60f4 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -299,7 +299,7 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const } } - +//TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) { @@ -309,9 +309,9 @@ LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) { + //unset "erase_extra_objects" hook on sp-lpe-item.cpp if (!erase_extra_objects) { processObjects(LPE_TO_OBJECTS); - std::cout << elements.size() << "elements.size() elements.size() elements.size() elements.size() elements.size() \n"; elements.clear(); return; } @@ -325,6 +325,9 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) for (std::vector::iterator el_it = elements.begin(); el_it != elements.end(); ++el_it) { const char * id = *el_it; + if (!id || strlen(id) == 0) { + return; + } Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); @@ -334,9 +337,7 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) Glib::ustring css_str; switch (lpe_action){ case LPE_TO_OBJECTS: - if (std::strcmp(sp_lpe_item->getId(), id) != 0) { - elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); - } + elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); break; diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 872a88289..9cf9dadc1 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -24,6 +24,7 @@ #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" #include "live_effects/lpe-measure-line.h" +#include "live_effects/lpe-mirror_symmetry.h" #include "sp-path.h" #include "sp-item-group.h" @@ -125,7 +126,10 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { { if (!value) { LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (Inkscape::LivePathEffect::LPEMeasureLine * lpe = dynamic_cast(lpeobj->get_lpe())) { + Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); + if (dynamic_cast(lpe) || + dynamic_cast(lpe) ) + { lpe->doOnRemove(this); } } -- cgit v1.2.3 From 29ce4ffa9e5e7ba3baf08a43e5848c0bc8038149 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Thu, 8 Dec 2016 03:08:15 +0100 Subject: Noumerous bugfixes (bzr r15295.1.18) --- src/live_effects/lpe-measure-line.cpp | 16 ++++++++++++---- src/live_effects/lpe-mirror_symmetry.cpp | 20 +++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index ef63888d9..8847b78aa 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -24,6 +24,7 @@ #include "svg/svg.h" #include "display/curve.h" #include "2geom/affine.h" +#include "path-chemistry.h" #include "style.h" #include "sp-root.h" #include "sp-defs.h" @@ -720,12 +721,19 @@ LPEMeasureLine::processObjects(LpeAction lpe_action) SVGElemRef->attach(SVGElem_uri); SPObject *elemref = NULL; if (elemref = SVGElemRef->getObject()) { + Inkscape::XML::Node * elemnode = elemref->getRepr(); + std::vector item_list; + item_list.push_back(SP_ITEM(elemref)); + std::vector item_to_select; + std::vector item_selected; SPCSSAttr *css; Glib::ustring css_str; switch (lpe_action){ case LPE_TO_OBJECTS: - elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); - elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); + if (elemnode->attribute("inkscape:path-effect")) { + sp_item_list_to_curves(item_list, item_selected, item_to_select); + } + elemnode->setAttribute("sodipodi:insensitive", NULL); break; case LPE_ERASE: @@ -743,7 +751,7 @@ LPEMeasureLine::processObjects(LpeAction lpe_action) css->setAttribute("display", NULL); } sp_repr_css_write_string(css,css_str); - elemref->getRepr()->setAttribute("style", css_str.c_str()); + elemnode->setAttribute("style", css_str.c_str()); break; default: @@ -751,7 +759,7 @@ LPEMeasureLine::processObjects(LpeAction lpe_action) } } } - if (lpe_action == LPE_ERASE) { + if (lpe_action == LPE_ERASE || lpe_action == LPE_TO_OBJECTS) { elements.clear(); } } diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index a338f60f4..11620b23f 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -23,6 +23,7 @@ #include "2geom/affine.h" #include "uri.h" #include "uri-references.h" +#include "path-chemistry.h" #include "knotholder.h" #include "style.h" #include "xml/sp-css-attr.h" @@ -93,7 +94,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) SPLPEItem * splpeitem = const_cast(lpeitem); if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { Inkscape::Selection *sel = desktop->getSelection(); - if ( sel && !sel->isEmpty() ) { + if ( sel && !sel->isEmpty() && actual) { SPItem *item = sel->singleItem(); if (item) { if(std::strcmp(splpeitem->getId(),item->getId()) != 0) { @@ -312,7 +313,6 @@ LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) //unset "erase_extra_objects" hook on sp-lpe-item.cpp if (!erase_extra_objects) { processObjects(LPE_TO_OBJECTS); - elements.clear(); return; } processObjects(LPE_ERASE); @@ -333,12 +333,19 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) SVGElemRef->attach(SVGElem_uri); SPObject *elemref = NULL; if (elemref = SVGElemRef->getObject()) { + Inkscape::XML::Node * elemnode = elemref->getRepr(); + std::vector item_list; + item_list.push_back(SP_ITEM(elemref)); + std::vector item_to_select; + std::vector item_selected; SPCSSAttr *css; Glib::ustring css_str; switch (lpe_action){ case LPE_TO_OBJECTS: - elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); - elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); + if (elemnode->attribute("inkscape:path-effect")) { + sp_item_list_to_curves(item_list, item_selected, item_to_select); + } + elemnode->setAttribute("sodipodi:insensitive", NULL); break; case LPE_ERASE: @@ -356,7 +363,7 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) css->setAttribute("display", NULL); } sp_repr_css_write_string(css,css_str); - elemref->getRepr()->setAttribute("style", css_str.c_str()); + elemnode->setAttribute("style", css_str.c_str()); break; default: @@ -364,7 +371,7 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) } } } - if (lpe_action == LPE_ERASE) { + if (lpe_action == LPE_ERASE || lpe_action == LPE_TO_OBJECTS) { elements.clear(); } } @@ -627,7 +634,6 @@ KnotHolderEntityCenterMirrorSymmetry::knot_set(Geom::Point const &p, Geom::Point LPEMirrorSymmetry* lpe = dynamic_cast(_effect); Geom::Point const s = snap_knot_position(p, state); lpe->center_point = s; - // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); } -- cgit v1.2.3 From 76dc7d78c1f595659cb32d34bf046e13fe08721e Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Thu, 8 Dec 2016 23:22:16 +0100 Subject: Working on nested LPE (bzr r15295.1.19) --- src/live_effects/lpe-mirror_symmetry.cpp | 146 +++++++------------------------ src/live_effects/lpe-mirror_symmetry.h | 13 +-- src/sp-lpe-item.cpp | 6 +- src/sp-lpe-item.h | 2 +- 4 files changed, 40 insertions(+), 127 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 11620b23f..8225c152f 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -43,17 +43,6 @@ static const Util::EnumData ModeTypeData[MT_END] = { static const Util::EnumDataConverter MTConverter(ModeTypeData, MT_END); -namespace MS { - -class KnotHolderEntityCenterMirrorSymmetry : public LPEKnotHolderEntity { -public: - KnotHolderEntityCenterMirrorSymmetry(LPEMirrorSymmetry *effect) : LPEKnotHolderEntity(effect){}; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; -}; - -} // namespace MS - LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), @@ -62,9 +51,9 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split_elements", &wr, this, false), - start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, "Adjust the start of mirroring"), - end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring"), - id_origin("id_origin", "id_origin", "id_origin", &wr, this,"") + start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust the start of mirroring")), + end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), + center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) { show_orig_path = true; registerParameter(&mode); @@ -75,13 +64,12 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : registerParameter( &split_elements); registerParameter( &start_point); registerParameter( &end_point); - registerParameter( &id_origin); - id_origin.param_hide_canvas_text(); + registerParameter( ¢er_point); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); split_gap.param_set_digits(2); apply_to_clippath_and_mask = true; - actual = true; + previous_center = Geom::Point(0,0); } LPEMirrorSymmetry::~LPEMirrorSymmetry() @@ -94,11 +82,10 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) SPLPEItem * splpeitem = const_cast(lpeitem); if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { Inkscape::Selection *sel = desktop->getSelection(); - if ( sel && !sel->isEmpty() && actual) { + if ( sel && !sel->isEmpty()) { SPItem *item = sel->singleItem(); if (item) { if(std::strcmp(splpeitem->getId(),item->getId()) != 0) { - actual = false; return; } } @@ -117,11 +104,14 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) point_a = Geom::Point(center_point[X],boundingbox_Y.min()); point_b = Geom::Point(center_point[X],boundingbox_Y.max()); } + if (Geom::are_near((Geom::Point)start_point, (Geom::Point)end_point, 0.01)) { + start_point.param_setValue(point_a); + end_point.param_setValue(point_b); + } line_separation.setPoints(point_a, point_b); if ( mode == MT_X || mode == MT_Y ) { start_point.param_setValue(point_a); end_point.param_setValue(point_b); - center_point = Geom::middle_point(point_a, point_b); } else if ( mode == MT_FREE) { if(!are_near(previous_center,center_point, 0.01)) { Geom::Point trans = center_point - previous_center; @@ -129,7 +119,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) end_point.param_setValue(end_point * trans); line_separation.setPoints(start_point, end_point); } else { - center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); line_separation.setPoints(start_point, end_point); } } else if ( mode == MT_V){ @@ -142,7 +131,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point ep = Geom::Point(view_box_rect.width()/2.0, view_box_rect.height()); ep *= i2anc_affine(SP_OBJECT(lpeitem), SP_OBJECT(SP_ACTIVE_DESKTOP->currentLayer()->parent)) .inverse(); end_point.param_setValue(ep); - center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); line_separation.setPoints(start_point, end_point); } } else { //horizontal page @@ -155,11 +143,14 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point ep = Geom::Point(view_box_rect.width(), view_box_rect.height()/2.0); ep *= i2anc_affine(SP_OBJECT(lpeitem), SP_OBJECT(SP_ACTIVE_DESKTOP->currentLayer()->parent)) .inverse(); end_point.param_setValue(ep); - center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); line_separation.setPoints(start_point, end_point); } } - previous_center = center_point; + + previous_center = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); + if (!are_near(previous_center, center_point,0.01)) { + center_point.param_setValue(previous_center); + } if (split_elements) { ms_container = dynamic_cast(splpeitem->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; @@ -168,6 +159,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) if (root_origin != root) { return; } + Geom::Point point_a(line_separation.initialPoint()); Geom::Point point_b(line_separation.finalPoint()); Geom::Point gap(split_gap,0); @@ -184,21 +176,22 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point offset = (point_a + point_b)/2 + dir.ccw() * split_gap; line_separation *= Geom::Translate(offset); Geom::Scale sca(1.0, -1.0); - const char * id_original = id_origin.param_getSVGValue(); - const char * id = g_strdup(Glib::ustring("mirror-").append(id_original).append("-").append(this->getRepr()->attribute("id")).c_str()); + const char * mirror_a = g_strdup(Glib::ustring("mirror-a-").append(this->getRepr()->attribute("id")).c_str()); + const char * mirror_b = g_strdup(Glib::ustring("mirror-b-").append(this->getRepr()->attribute("id")).c_str()); m = m1.inverse() * m2; m = m * sca; m = m * m2.inverse(); m = m * m1; m = m * lpeitem->transform; - if (std::strcmp(splpeitem->getId(), id) == 0) { - createMirror(splpeitem, m, id_original); - } else { - createMirror(splpeitem, m, id); + if (std::strcmp(splpeitem->getId(), mirror_a) != 0) { + createMirror(splpeitem, m, mirror_a); + } + if (std::strcmp(splpeitem->getId(), mirror_b) != 0) { + createMirror(splpeitem, m, mirror_b); } elements.clear(); - elements.push_back(id); - elements.push_back(id_original); + elements.push_back(mirror_a); + elements.push_back(mirror_b); } else { elements.clear(); processObjects(LPE_ERASE); @@ -288,7 +281,7 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const elemref = ms_container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", NULL); //NULL required + cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); if (elemref->parent != ms_container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); @@ -349,7 +342,7 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) break; case LPE_ERASE: - if (std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { + if (std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0) { elemref->deleteObject(); } break; @@ -357,7 +350,7 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) case LPE_VISIBILITY: css = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); - if (!this->isVisible() && std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { + if (!this->isVisible() && std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0) { css->setAttribute("display", "none"); } else { css->setAttribute("display", NULL); @@ -382,8 +375,6 @@ void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { if( !split_elements) { - center_point *= postmul; - previous_center = center_point; // cycle through all parameters. Most parameters will not need transformation, but path and point params do. for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { Parameter * param = *it; @@ -406,10 +397,13 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) start_point.param_update_default(point_a); end_point.param_setValue(point_b); end_point.param_update_default(point_b); - center_point = point_c; + center_point.param_setValue(point_c); previous_center = center_point; - id_origin.param_setValue(Glib::ustring(lpeitem->getId())); - id_origin.write_to_SVG(); + SPLPEItem * splpeitem = const_cast(lpeitem); + Glib::ustring mirror_a = Glib::ustring("mirror-a-").append(this->getRepr()->attribute("id")); + if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet + splpeitem->getRepr()->setAttribute("id", mirror_a.c_str()); + } } @@ -560,41 +554,6 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) return path_out; } - -Gtk::Widget *LPEMirrorSymmetry::newWidget() -{ - // use manage here, because after deletion of Effect object, others might - // still be pointing to this widget. - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - - vbox->set_border_width(5); - vbox->set_homogeneous(false); - vbox->set_spacing(2); - - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter *param = *it; - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - if (param->param_key != "id_origin") { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - } - - ++it; - } - return dynamic_cast(vbox); -} - void LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) { @@ -610,43 +569,6 @@ LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector hp_vec.push_back(helper); } -void -LPEMirrorSymmetry::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) -{ - SPKnotShapeType knot_shape = SP_KNOT_SHAPE_CIRCLE; - SPKnotModeType knot_mode = SP_KNOT_MODE_XOR; - guint32 knot_color = 0x0000ff00; - { - KnotHolderEntity *c = new MS::KnotHolderEntityCenterMirrorSymmetry(this); - c->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the center"), knot_shape, knot_mode, knot_color ); - knotholder->add(c); - } -}; - -namespace MS { - -using namespace Geom; - -void -KnotHolderEntityCenterMirrorSymmetry::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) -{ - LPEMirrorSymmetry* lpe = dynamic_cast(_effect); - Geom::Point const s = snap_knot_position(p, state); - lpe->center_point = s; - // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. - sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); -} - -Geom::Point -KnotHolderEntityCenterMirrorSymmetry::knot_get() const -{ - LPEMirrorSymmetry const *lpe = dynamic_cast(_effect); - return lpe->center_point; -} - -} // namespace CR - } //namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 7b090ed82..fba16c750 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -27,11 +27,6 @@ namespace Inkscape { namespace LivePathEffect { -namespace MS { -// we need a separate namespace to avoid clashes with LPEPerpBisector -class KnotHolderEntityCenterMirrorSymmetry; -} - enum ModeType { MT_V, MT_H, @@ -51,14 +46,10 @@ public: virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); - virtual Gtk::Widget *newWidget(); void processObjects(LpeAction lpe_action); - /* the knotholder entity classes must be declared friends */ - friend class MS::KnotHolderEntityCenterMirrorSymmetry; void createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...); - void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -72,11 +63,9 @@ private: BoolParam split_elements; PointParam start_point; PointParam end_point; - TextParam id_origin; + PointParam center_point; Geom::Line line_separation; Geom::Point previous_center; - Geom::Point center_point; - bool actual; std::vector elements; SPObject * ms_container; LPEMirrorSymmetry(const LPEMirrorSymmetry&); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 9cf9dadc1..98428512f 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -607,7 +607,7 @@ bool SPLPEItem::hasPathEffect() const return true; } -bool SPLPEItem::hasPathEffectOfType(int const type) const +bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const { if (path_effect_list->empty()) { return false; @@ -619,7 +619,9 @@ bool SPLPEItem::hasPathEffectOfType(int const type) const if (lpeobj) { Inkscape::LivePathEffect::Effect const* lpe = lpeobj->get_lpe(); if (lpe && (lpe->effectType() == type)) { - return true; + if (is_ready || lpe->isReady()) { + return true; + } } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 9e5cb3329..db4a0c7a3 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -73,7 +73,7 @@ public: bool pathEffectsEnabled() const; bool hasPathEffect() const; - bool hasPathEffectOfType(int const type) const; + bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; -- cgit v1.2.3 From 2569672abb50eb7a6eacd5e094ed8119e83de8e7 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Fri, 16 Dec 2016 12:59:18 +0100 Subject: Fixing nested mirrors (bzr r15295.1.22) --- src/live_effects/lpe-mirror_symmetry.cpp | 125 ++++++++++++++++++------------- src/live_effects/lpe-mirror_symmetry.h | 4 +- 2 files changed, 75 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index fa054a283..e4ae0bbdb 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -56,18 +56,21 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split_elements", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust the start of mirroring")), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), - center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) + center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), + original("hidden", "hidden", "original", &wr, this,"") { show_orig_path = true; registerParameter(&mode); - registerParameter( &split_gap); - registerParameter( &discard_orig_path); - registerParameter( &fuse_paths); - registerParameter( &oposite_fuse); - registerParameter( &split_elements); - registerParameter( &start_point); - registerParameter( &end_point); - registerParameter( ¢er_point); + registerParameter(&split_gap); + registerParameter(&discard_orig_path); + registerParameter(&fuse_paths); + registerParameter(&oposite_fuse); + registerParameter(&split_elements); + registerParameter(&start_point); + registerParameter(&end_point); + registerParameter(¢er_point); + registerParameter(&original); + original.param_hide_canvas_text(); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); split_gap.param_set_digits(2); @@ -155,45 +158,43 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) center_point.param_setValue(previous_center); } if (split_elements) { - ms_container = dynamic_cast(splpeitem->parent); + container = dynamic_cast(splpeitem->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node *root = splpeitem->document->getReprRoot(); Inkscape::XML::Node *root_origin = doc->getReprRoot(); if (root_origin != root) { return; } - - Geom::Point point_a(line_separation.initialPoint()); - Geom::Point point_b(line_separation.finalPoint()); - Geom::Point gap(split_gap,0); - Geom::Translate m1(point_a[0], point_a[1]); - double hyp = Geom::distance(point_a, point_b); - double cos = 0; - double sin = 0; - if (hyp > 0) { - cos = (point_b[0] - point_a[0]) / hyp; - sin = (point_b[1] - point_a[1]) / hyp; - } - Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); - Geom::Point dir = unit_vector(point_b - point_a); - Geom::Point offset = (point_a + point_b)/2 + dir.ccw() * split_gap; - line_separation *= Geom::Translate(offset); - Geom::Scale sca(1.0, -1.0); - const char * mirror_a = g_strdup(Glib::ustring("mirror-a-").append(this->getRepr()->attribute("id")).c_str()); - const char * mirror_b = g_strdup(Glib::ustring("mirror-b-").append(this->getRepr()->attribute("id")).c_str()); - m = m1.inverse() * m2; - m = m * sca; - m = m * m2.inverse(); - m = m * m1; - m = m * lpeitem->transform; - if (std::strcmp(splpeitem->getId(), mirror_a) != 0) { - createMirror(splpeitem, m, mirror_a); - } - if (std::strcmp(splpeitem->getId(), mirror_b) != 0) { + const char * mirror_a = g_strdup(Glib::ustring(original.param_getSVGValue()).c_str()); + const char * mirror_b = g_strdup(Glib::ustring("mirror-").append(this->getRepr()->attribute("id")).c_str()); + if (std::strcmp(splpeitem->getId(), mirror_b) == 0) { + syncMirror(splpeitem, mirror_a); + } else { + Geom::Point point_a(line_separation.initialPoint()); + Geom::Point point_b(line_separation.finalPoint()); + Geom::Point gap(split_gap,0); + Geom::Translate m1(point_a[0], point_a[1]); + double hyp = Geom::distance(point_a, point_b); + double cos = 0; + double sin = 0; + if (hyp > 0) { + cos = (point_b[0] - point_a[0]) / hyp; + sin = (point_b[1] - point_a[1]) / hyp; + } + Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); + Geom::Point dir = unit_vector(point_b - point_a); + Geom::Point offset = (point_a + point_b)/2 + dir.ccw() * split_gap; + line_separation *= Geom::Translate(offset); + Geom::Scale sca(1.0, -1.0); + m = m1.inverse() * m2; + m = m * sca; + m = m * m2.inverse(); + m = m * m1; + m = m * splpeitem->transform; + //if (std::strcmp(splpeitem->getId(), mirror_b) != 0) { createMirror(splpeitem, m, mirror_b); } elements.clear(); - elements.push_back(mirror_a); elements.push_back(mirror_b); } else { elements.clear(); @@ -251,7 +252,7 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c if (c) { dest->getRepr()->setAttribute(att,sp_svg_write_path(c->get_pathvector())); c->reset(); - g_free(c); + g_free(c); } else { dest->getRepr()->setAttribute(att,NULL); } @@ -278,24 +279,40 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const } else { phantom = origin->getRepr()->duplicate(xml_doc); } - phantom->setAttribute("id", id); if (!elemref) { - elemref = ms_container->appendChildRepr(phantom); + elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required + cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", NULL); //NULL required elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); - if (elemref->parent != ms_container) { + if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); copy->setAttribute("id", id); - ms_container->appendChildRepr(copy); + container->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); } } } +void +LPEMirrorSymmetry::syncMirror(SPLPEItem *origin, const char * id) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref= NULL; + Inkscape::XML::Node *phantom = NULL; + if (elemref = SVGElemRef->getObject()) { + cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required + } + } +} + + //TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) @@ -345,15 +362,15 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) break; case LPE_ERASE: - if (std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0) { + //if (std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0) { elemref->deleteObject(); - } + //} break; case LPE_VISIBILITY: css = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); - if (!this->isVisible() && std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0) { + if (!this->isVisible()/* && std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0*/) { css->setAttribute("display", "none"); } else { css->setAttribute("display", NULL); @@ -402,11 +419,13 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) end_point.param_update_default(point_b); center_point.param_setValue(point_c); previous_center = center_point; - SPLPEItem * splpeitem = const_cast(lpeitem); - Glib::ustring mirror_a = Glib::ustring("mirror-a-").append(this->getRepr()->attribute("id")); - if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet - splpeitem->getRepr()->setAttribute("id", mirror_a.c_str()); - } + original.param_setValue(lpeitem->getId()); + original.write_to_SVG(); +// SPLPEItem * splpeitem = const_cast(lpeitem); +// Glib::ustring mirror_a = Glib::ustring("mirror-a-").append(this->getRepr()->attribute("id")); +// if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet +// splpeitem->getRepr()->setAttribute("id", mirror_a.c_str()); +// } } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 03396fdf3..3a78db169 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -49,6 +49,7 @@ public: void processObjects(LpeAction lpe_action); void createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); + void syncMirror(SPLPEItem *origin, const char * id); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...); protected: @@ -64,10 +65,11 @@ private: PointParam start_point; PointParam end_point; PointParam center_point; + TextParam original; Geom::Line line_separation; Geom::Point previous_center; std::vector elements; - SPObject * ms_container; + SPObject * container; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); }; -- cgit v1.2.3 From 8ce90cc9aeecfd5133926156f23ac3cbe318c49d Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Fri, 16 Dec 2016 23:44:26 +0100 Subject: working with mirrors (bzr r15295.1.24) --- src/live_effects/lpe-mirror_symmetry.cpp | 134 +++++++++++++++++++++++-------- src/live_effects/lpe-mirror_symmetry.h | 9 ++- 2 files changed, 104 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index e4ae0bbdb..f34421df2 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -15,6 +15,8 @@ */ #include +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" #include "live_effects/lpe-mirror_symmetry.h" #include "display/curve.h" #include "svg/path-string.h" @@ -53,11 +55,10 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : discard_orig_path(_("Discard original path?"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), - split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split_elements", &wr, this, false), + split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints. Group result to apply nested"), "split_elements", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust the start of mirroring")), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), - center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), - original("hidden", "hidden", "original", &wr, this,"") + center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) { show_orig_path = true; registerParameter(&mode); @@ -69,8 +70,6 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : registerParameter(&start_point); registerParameter(&end_point); registerParameter(¢er_point); - registerParameter(&original); - original.param_hide_canvas_text(); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); split_gap.param_set_digits(2); @@ -157,7 +156,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) if (!are_near(previous_center, center_point,0.01)) { center_point.param_setValue(previous_center); } - if (split_elements) { + if (split_elements && allow_split()) { container = dynamic_cast(splpeitem->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node *root = splpeitem->document->getReprRoot(); @@ -165,11 +164,10 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) if (root_origin != root) { return; } - const char * mirror_a = g_strdup(Glib::ustring(original.param_getSVGValue()).c_str()); - const char * mirror_b = g_strdup(Glib::ustring("mirror-").append(this->getRepr()->attribute("id")).c_str()); - if (std::strcmp(splpeitem->getId(), mirror_b) == 0) { - syncMirror(splpeitem, mirror_a); - } else { + const char * mirror = g_strdup(Glib::ustring("mirror-b-").append(this->getRepr()->attribute("id")).c_str()); +// if (std::strcmp(splpeitem->getId(), mirror_b) == 0) { +// syncMirror(splpeitem, mirror_a); +// } else { Geom::Point point_a(line_separation.initialPoint()); Geom::Point point_b(line_separation.finalPoint()); Geom::Point gap(split_gap,0); @@ -191,14 +189,15 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) m = m * m2.inverse(); m = m * m1; m = m * splpeitem->transform; - //if (std::strcmp(splpeitem->getId(), mirror_b) != 0) { - createMirror(splpeitem, m, mirror_b); - } - elements.clear(); - elements.push_back(mirror_b); + createMirror(splpeitem, m); + //} } else { - elements.clear(); + if (!allow_split()) { + std::cout << "Only one operation of split allowed. Group results to nested effects.\n"; + split_elements.param_setValue(false); + } processObjects(LPE_ERASE); + elements.clear(); } } @@ -265,9 +264,19 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c } void -LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id) +LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + const char * id; + Glib::ustring idbase = Glib::ustring(sp_lpe_item->getId()); + size_t pos = idbase.find("-mirror"); + if (pos <= idbase.size()) { + id = g_strdup(idbase.substr(pos).c_str()); + } else { + id = g_strdup(idbase.append("-mirror").c_str()); + elements.clear(); + elements.push_back(id); + } Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); @@ -284,7 +293,7 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", NULL); //NULL required + cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); @@ -296,22 +305,77 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const } } -void -LPEMirrorSymmetry::syncMirror(SPLPEItem *origin, const char * id) -{ - if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); - Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); - Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); - SVGElemRef->attach(SVGElem_uri); - SPObject *elemref= NULL; - Inkscape::XML::Node *phantom = NULL; - if (elemref = SVGElemRef->getObject()) { - cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required +//void +//LPEMirrorSymmetry::syncMirror(SPLPEItem *origin, const char * id) +//{ +// if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { +// Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); +// Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); +// Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); +// SVGElemRef->attach(SVGElem_uri); +// SPObject *elemref= NULL; +// Inkscape::XML::Node *phantom = NULL; +// if (elemref = SVGElemRef->getObject()) { +// cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required +// } +// } +//} + +bool +LPEMirrorSymmetry::allow_split(){ + if (sp_lpe_item->path_effect_list->empty()) { + return false; + } + size_t count = 0; + for (PathEffectList::const_iterator it = sp_lpe_item->path_effect_list->begin(); it != sp_lpe_item->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::LPEMirrorSymmetry * ms = dynamic_cast(lpeobj->get_lpe()); + if (ms && ms->split_elements) { + count++; + } } } + return count <= 1; } +//Gtk::Widget * +//LPEMirrorSymmetry::newWidget() +//{ +// // use manage here, because after deletion of Effect object, others might +// // still be pointing to this widget. +// Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + +// vbox->set_border_width(5); +// std::vector::iterator it = param_vector.begin(); +// while (it != param_vector.end()) { +// if ((*it)->widget_is_visible) { +// Parameter *param = *it; +// Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); +// if (widg) { +// if (param->param_key == "split_elements") { +// Gtk::CheckButton *widg_registered = Gtk::manage(dynamic_cast(widg)); +// if (!allow_split()) { +// widg_registered->set_sensitive("false"); +// } +// widg = dynamic_cast(widg_registered); +// } +// Glib::ustring *tip = param->param_getTooltip(); +// vbox->pack_start(*widg, true, true, 2); +// if (tip) { +// widg->set_tooltip_text(*tip); +// } else { +// widg->set_tooltip_text(""); +// widg->set_has_tooltip(false); +// } +// } +// } + +// ++it; +// } +// return dynamic_cast(vbox); +//} //TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void @@ -419,12 +483,12 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) end_point.param_update_default(point_b); center_point.param_setValue(point_c); previous_center = center_point; - original.param_setValue(lpeitem->getId()); - original.write_to_SVG(); // SPLPEItem * splpeitem = const_cast(lpeitem); -// Glib::ustring mirror_a = Glib::ustring("mirror-a-").append(this->getRepr()->attribute("id")); // if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet -// splpeitem->getRepr()->setAttribute("id", mirror_a.c_str()); +// const char * mirror_a = g_strdup(Glib::ustring("mirror-a-").append(this->getRepr()->attribute("id")).c_str()); +// splpeitem->setAttribute("id", mirror_a); +// first_lpe.param_setValue(this->getRepr()->attribute("id")); +// first_lpe.write_to_SVG(); // } } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 3a78db169..12ceebaf8 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -17,8 +17,8 @@ */ #include "live_effects/effect.h" -#include "live_effects/parameter/text.h" #include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" #include "live_effects/parameter/path.h" #include "live_effects/parameter/enum.h" @@ -46,11 +46,13 @@ public: virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); +// virtual Gtk::Widget * newWidget(); void processObjects(LpeAction lpe_action); - void createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id); + void createMirror(SPLPEItem *origin, Geom::Affine transform); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); - void syncMirror(SPLPEItem *origin, const char * id); +// void syncMirror(SPLPEItem *origin, const char * id); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...); + bool allow_split(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -65,7 +67,6 @@ private: PointParam start_point; PointParam end_point; PointParam center_point; - TextParam original; Geom::Line line_separation; Geom::Point previous_center; std::vector elements; -- cgit v1.2.3 From 5927b3bf5d9d8dcc9f519b4b9060669bd2599a28 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Fri, 16 Dec 2016 23:49:53 +0100 Subject: Rollback 15315 (bzr r15295.1.25) --- src/desktop-style.cpp | 11 +- src/file.cpp | 270 +++------------------- src/live_effects/lpe-angle_bisector.cpp | 8 +- src/live_effects/lpe-attach-path.cpp | 5 +- src/live_effects/lpe-bendpath.cpp | 3 +- src/live_effects/lpe-bounding-box.cpp | 6 +- src/live_effects/lpe-bspline.h | 2 +- src/live_effects/lpe-circle_3pts.cpp | 2 - src/live_effects/lpe-circle_with_radius.cpp | 2 - src/live_effects/lpe-clone-original.cpp | 5 +- src/live_effects/lpe-constructgrid.cpp | 4 +- src/live_effects/lpe-copy_rotate.cpp | 156 ++++++++----- src/live_effects/lpe-copy_rotate.h | 14 +- src/live_effects/lpe-curvestitch.cpp | 5 +- src/live_effects/lpe-dynastroke.cpp | 2 - src/live_effects/lpe-ellipse_5pts.cpp | 5 +- src/live_effects/lpe-envelope.cpp | 2 - src/live_effects/lpe-extrude.cpp | 4 +- src/live_effects/lpe-fill-between-many.cpp | 2 +- src/live_effects/lpe-fill-between-strokes.cpp | 5 +- src/live_effects/lpe-fillet-chamfer.cpp | 2 +- src/live_effects/lpe-gears.cpp | 5 +- src/live_effects/lpe-interpolate.cpp | 6 +- src/live_effects/lpe-interpolate_points.cpp | 3 +- src/live_effects/lpe-jointype.cpp | 2 - src/live_effects/lpe-knot.cpp | 3 - src/live_effects/lpe-lattice.cpp | 3 +- src/live_effects/lpe-lattice2.cpp | 3 - src/live_effects/lpe-lattice2.h | 2 +- src/live_effects/lpe-line_segment.cpp | 2 - src/live_effects/lpe-mirror_symmetry.cpp | 314 +++++++++++++------------- src/live_effects/lpe-mirror_symmetry.h | 24 +- src/live_effects/lpe-offset.cpp | 5 +- src/live_effects/lpe-parallel.cpp | 5 +- src/live_effects/lpe-path_length.cpp | 4 +- src/live_effects/lpe-patternalongpath.cpp | 2 - src/live_effects/lpe-perp_bisector.cpp | 6 +- src/live_effects/lpe-perspective-envelope.cpp | 3 - src/live_effects/lpe-perspective_path.cpp | 5 +- src/live_effects/lpe-powerstroke.cpp | 3 - src/live_effects/lpe-recursiveskeleton.cpp | 5 +- src/live_effects/lpe-rough-hatches.cpp | 3 +- src/live_effects/lpe-roughen.cpp | 3 - src/live_effects/lpe-roughen.h | 1 + src/live_effects/lpe-ruler.cpp | 3 +- src/live_effects/lpe-show_handles.cpp | 2 - src/live_effects/lpe-show_handles.h | 1 + src/live_effects/lpe-simplify.cpp | 2 - src/live_effects/lpe-simplify.h | 1 + src/live_effects/lpe-skeleton.cpp | 3 +- src/live_effects/lpe-sketch.cpp | 5 +- src/live_effects/lpe-tangent_to_curve.cpp | 4 +- src/live_effects/lpe-taperstroke.cpp | 2 - src/live_effects/lpe-test-doEffect-stack.cpp | 5 +- src/live_effects/lpe-text_label.cpp | 5 +- src/live_effects/lpe-transform_2pts.cpp | 1 - src/live_effects/lpe-vonkoch.cpp | 2 +- src/live_effects/parameter/fontbutton.cpp | 2 +- src/live_effects/parameter/fontbutton.h | 1 + src/preferences-skeleton.h | 5 +- src/sp-item-group.cpp | 5 +- src/sp-lpe-item.cpp | 6 +- src/sp-lpe-item.h | 2 +- src/sp-mesh-array.cpp | 10 +- src/ui/tools/tweak-tool.cpp | 3 +- src/widgets/mesh-toolbar.cpp | 165 ++++++++------ src/widgets/text-toolbar.cpp | 166 ++------------ src/widgets/toolbox.cpp | 11 +- 68 files changed, 523 insertions(+), 816 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 4c07c76ea..65e511245 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -209,7 +209,7 @@ sp_desktop_set_style(Inkscape::ObjectSet *set, SPDesktop *desktop, SPCSSAttr *cs if (!change) return; -// 2. Emit signal... See desktop->connectSetStyle in text-tool, tweak-tool, and gradient-drag. +// 2. Emit signal bool intercepted = desktop->_set_style_signal.emit(css); /** \todo @@ -1045,7 +1045,6 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r bool lineheight_normal = false; bool lineheight_unit_proportional = false; bool lineheight_unit_absolute = false; - bool lineheight_set = false; // Set true if any object has lineheight set. double size_prev = 0; double letterspacing_prev = 0; @@ -1131,9 +1130,6 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r lineheight_normal = false; lineheight += lineheight_current * doc_scale; } - if (style->line_height.set) { - lineheight_set = true; - } if ((size_prev != 0 && style->font_size.computed != size_prev) || (letterspacing_prev != 0 && style->letter_spacing.computed != letterspacing_prev) || @@ -1209,9 +1205,6 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r } } - // Used by text toolbar unset 'line-height' - style_res->line_height.set = lineheight_set; - if (texts > 1) { if (different || different_lineheight) { return QUERY_STYLE_MULTIPLE_AVERAGED; @@ -1914,7 +1907,7 @@ sp_desktop_query_style_from_list (const std::vector &list, SPStyle *sty int sp_desktop_query_style(SPDesktop *desktop, SPStyle *style, int property) { - // Used by text tool and in gradient dragging. See connectQueryStyle. + // Used by text tool and in gradient dragging int ret = desktop->_query_style_signal.emit(style, property); if (ret != QUERY_STYLE_NOTHING) diff --git a/src/file.cpp b/src/file.cpp index 8f283e1f8..55089209a 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -66,10 +66,6 @@ // For updating old Inkscape SVG files #include "display/canvas-grid.h" #include "sp-guide.h" -#include "selection-chemistry.h" -#include "persp3d.h" -#include "proj_pt.h" -#include "ui/shape-editor.h" #include @@ -357,13 +353,11 @@ bool sp_file_open(const Glib::ustring &uri, bool need_fix_units = false; bool need_fix_guides = false; bool need_fix_grid_mm = false; - bool need_fix_box3d = false; - bool did_scaling = false; + bool is_extension = false; // Check if potentially need viewbox or unit fix switch (root->width.unit) { case SP_CSS_UNIT_PC: - case SP_CSS_UNIT_PT: case SP_CSS_UNIT_MM: case SP_CSS_UNIT_CM: case SP_CSS_UNIT_IN: @@ -372,19 +366,13 @@ bool sp_file_open(const Glib::ustring &uri, case SP_CSS_UNIT_NONE: case SP_CSS_UNIT_PX: need_fix_units = true; + default: break; - case SP_CSS_UNIT_EM: - case SP_CSS_UNIT_EX: - case SP_CSS_UNIT_PERCENT: // OK - break; - default: - std::cerr << "sp_file_open: Unhandled width unit!" << std::endl; } switch (root->height.unit) { case SP_CSS_UNIT_PC: - case SP_CSS_UNIT_PT: case SP_CSS_UNIT_MM: case SP_CSS_UNIT_CM: case SP_CSS_UNIT_IN: @@ -393,21 +381,14 @@ bool sp_file_open(const Glib::ustring &uri, case SP_CSS_UNIT_NONE: case SP_CSS_UNIT_PX: need_fix_units = true; + default: break; - case SP_CSS_UNIT_EM: - case SP_CSS_UNIT_EX: - case SP_CSS_UNIT_PERCENT: // OK - break; - default: - std::cerr << "sp_file_open: Unhandled height unit!" << std::endl; } // std::cout << "Absolute SVG units in root? " << (need_fix_viewbox?"true":"false") << std::endl; // std::cout << "User units in root? " << (need_fix_units ?"true":"false") << std::endl; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (!root->viewBox_set && need_fix_viewbox) { Glib::ustring msg = _( @@ -420,37 +401,31 @@ bool sp_file_open(const Glib::ustring &uri, Gtk::Label info; info.set_markup(msg.c_str()); info.show(); - scaleDialog.get_content_area()->pack_start(info, false, false, 20); + scaleDialog.get_content_area()->pack_start(info, false, false, 20); Gtk::CheckButton backupButton( _("Create backup file (in same directory).") ); - bool backup = prefs->getBool("/options/dpifixbackup", true); - backupButton.set_active( backup ); + backupButton.set_active(); backupButton.show(); - scaleDialog.get_content_area()->pack_start(backupButton, false, false, 20); - scaleDialog.add_button(_("Set 'viewBox'"), 1); - scaleDialog.add_button(_("Scale elements"), 2); - scaleDialog.add_button(_("Ignore"), 3); - scaleDialog.add_button("Scale test - group", 4); - scaleDialog.add_button("Scale test - children", 5); + scaleDialog.get_content_area()->pack_start(backupButton, false, false, 20); + scaleDialog.add_button("Set 'viewBox'", 1); + scaleDialog.add_button("Scale elements", 2); + scaleDialog.add_button("Ignore", 3); gint response = scaleDialog.run(); - backup = backupButton.get_active(); - prefs->setBool("/options/dpifixbackup", backup); - - if ( backup && response != 3) { - sp_file_save_backup( uri ); - } - + bool backup = backupButton.get_active(); if (response == 1) { - + if (backup) { + sp_file_save_backup( uri ); + } doc->setViewBox(Geom::Rect::from_xywh( 0, 0, doc->getWidth().value("px") * ratio, doc->getHeight().value("px") * ratio)); - } else if (response == 2 ) { - + if (backup) { + sp_file_save_backup( uri ); + } std::list effects; Inkscape::Extension::db.get_effect_list(effects); std::list::iterator it = effects.begin(); @@ -467,65 +442,12 @@ bool sp_file_open(const Glib::ustring &uri, if (!did) { std::cerr << "sp_file_open: Failed to find dpi90to96 extension." << std::endl; } - did_scaling = true; - - } else if (response == 4) { - - // Save preferences - bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true); - bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); - - prefs->setBool("/options/kbselection/onlysensitive", false); - prefs->setBool("/options/kbselection/onlyvisible", false); - - Inkscape::Selection *selection = desktop->getSelection(); - Inkscape::SelectionHelper::selectAllInAll( desktop ); - selection->group(); - SPItem * group = selection->singleItem(); - if (group) { - group->setAttribute("transform","scale(1.06666667,1.06666667)"); - } else { - std::cerr << "sp_file_open: Failed to get group!" << std::endl; - } - selection->clear(); - selection->add( group ); - selection->ungroup(); - selection->clear(); - - prefs->setBool("/options/kbselection/onlysensitive", onlysensitive); - prefs->setBool("/options/kbselection/onlyvisible", onlyvisible ); - - did_scaling = true; - - } else if (response == 5) { - - // Save preferences - bool transform_stroke = prefs->getBool("/options/transform/stroke", true); - bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true); - bool transform_pattern = prefs->getBool("/options/transform/pattern", true); - bool transform_gradient = prefs->getBool("/options/transform/gradient", true); - - prefs->setBool("/options/transform/stroke", true); - prefs->setBool("/options/transform/rectcorners", true); - prefs->setBool("/options/transform/pattern", true); - prefs->setBool("/options/transform/gradient", true); - - Inkscape::UI::ShapeEditor::blockSetItem(true); - doc->getRoot()->scaleChildItemsRec(Geom::Scale(1/ratio),Geom::Point(0, 0), false); - Inkscape::UI::ShapeEditor::blockSetItem(false); - - // Restore preferences - prefs->setBool("/options/transform/stroke", transform_stroke); - prefs->setBool("/options/transform/rectcorners", transform_rectcorners); - prefs->setBool("/options/transform/pattern", transform_pattern); - prefs->setBool("/options/transform/gradient", transform_gradient); + is_extension = true; } - - need_fix_box3d = true; need_fix_guides = true; // Always fix guides } - else if (need_fix_units) { + if (need_fix_units) { Glib::ustring msg = ( "Old Inkscape files use 1in == 90px. CSS requires 1in == 96px.\n" "Drawings meant to match a physical size (e.g. Letter or A4)\n" @@ -540,27 +462,19 @@ bool sp_file_open(const Glib::ustring &uri, scaleDialog.get_content_area()->pack_start(info, false, false, 20); Gtk::CheckButton backupButton( _("Create backup file (in same directory).") ); - bool backup = prefs->getBool("/options/dpifixbackup", true); - backupButton.set_active( backup ); - backupButton.show(); scaleDialog.get_content_area()->pack_start(backupButton, false, false, 20); + backupButton.show(); - scaleDialog.add_button(_("Set 'viewBox'"), 1); - scaleDialog.add_button(_("Scale elements"), 2); - scaleDialog.add_button(_("Ignore"), 3); - scaleDialog.add_button("Scale test - group", 4); - scaleDialog.add_button("Scale test - children", 5); + scaleDialog.add_button("Set 'viewBox'", 1); + scaleDialog.add_button("Scale elements", 2); + scaleDialog.add_button("Ignore", 3); gint response = scaleDialog.run(); - backup = backupButton.get_active(); - prefs->setBool("/options/dpifixbackup", backup); - - if ( backup && response != 3) { - sp_file_save_backup( uri ); - } - + bool backup = backupButton.get_active(); if (response == 1) { - + if (backup) { + sp_file_save_backup( uri ); + } if (!root->viewBox_set) { doc->setViewBox(Geom::Rect::from_xywh( 0, 0, @@ -574,10 +488,10 @@ bool sp_file_open(const Glib::ustring &uri, doc->setWidthAndHeight( width, height, false ); need_fix_guides = true; // Only fix guides if drawing scaled - need_fix_box3d = true; - } else if (response == 2) { - + if (backup) { + sp_file_save_backup( uri ); + } std::list effects; Inkscape::Extension::db.get_effect_list(effects); std::list::iterator it = effects.begin(); @@ -595,94 +509,14 @@ bool sp_file_open(const Glib::ustring &uri, std::cerr << "sp_file_open: Failed to find dpi90to96 extension." << std::endl; } need_fix_guides = true; // Only fix guides if drawing scaled - did_scaling = true; - - } else if (response == 4) { - - Inkscape::Util::Quantity width = - Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" ); - Inkscape::Util::Quantity height = - Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" ); - doc->setWidthAndHeight( width, height, false ); - - if (!root->viewBox_set) { - - // Save preferences - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true); - bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); - - prefs->setBool("/options/kbselection/onlysensitive", false); - prefs->setBool("/options/kbselection/onlyvisible", false); - - Inkscape::Selection *selection = desktop->getSelection(); - Inkscape::SelectionHelper::selectAllInAll( desktop ); - selection->group(); - SPItem * group = selection->singleItem(); - if (group) { - group->setAttribute("transform","scale(1.06666667,1.06666667)"); - } else { - std::cerr << "sp_file_open: Failed to get group!" << std::endl; - } - selection->clear(); - selection->add( group ); - selection->ungroup(); - selection->clear(); - - prefs->setBool("/options/kbselection/onlysensitive", onlysensitive); - prefs->setBool("/options/kbselection/onlyvisible", onlyvisible ); - - did_scaling = true; - } - - need_fix_box3d = true; - need_fix_guides = true; // Only fix guides if drawing scaled - - } else if (response == 5) { - - Inkscape::Util::Quantity width = - Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" ); - Inkscape::Util::Quantity height = - Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" ); - doc->setWidthAndHeight( width, height, false ); - - if (!root->viewBox_set) { - - // Save preferences - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool transform_stroke = prefs->getBool("/options/transform/stroke", true); - bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true); - bool transform_pattern = prefs->getBool("/options/transform/pattern", true); - bool transform_gradient = prefs->getBool("/options/transform/gradient", true); - - prefs->setBool("/options/transform/stroke", true); - prefs->setBool("/options/transform/rectcorners", true); - prefs->setBool("/options/transform/pattern", true); - prefs->setBool("/options/transform/gradient", true); - - Inkscape::UI::ShapeEditor::blockSetItem(true); - doc->getRoot()->scaleChildItemsRec(Geom::Scale(1/ratio),Geom::Point(0, 0), false); - Inkscape::UI::ShapeEditor::blockSetItem(false); - - // Restore preferences - prefs->setBool("/options/transform/stroke", transform_stroke); - prefs->setBool("/options/transform/rectcorners", transform_rectcorners); - prefs->setBool("/options/transform/pattern", transform_pattern); - prefs->setBool("/options/transform/gradient", transform_gradient); - - did_scaling = true; - } - - need_fix_box3d = true; - need_fix_guides = true; // Only fix guides if drawing scaled - + is_extension = true; } else { // Ignore need_fix_grid_mm = true; } } - // Fix guides and grids and perspective + // Fix guides and grids for (SPObject *child = root->firstChild() ; child; child = child->getNext() ) { SPNamedView *nv = dynamic_cast(child); if (nv) { @@ -721,53 +555,21 @@ bool sp_file_open(const Glib::ustring &uri, } } else { if (need_fix_guides) { - if(did_scaling){ + // HACK: Scaling the document does not seem to cause + // grids defined in document units to be updated. + // This forces an update. + if(is_extension){ xy->Scale( Geom::Scale(ratio,ratio).inverse() ); } else { - // HACK: Scaling the document does not seem to cause - // grids defined in document units to be updated. - // This forces an update. xy->Scale( Geom::Scale(1,1) ); } } } } } - } // If SPNamedView - - SPDefs *defs = dynamic_cast(child); - if (defs && need_fix_box3d) { - for (SPObject *child = defs->firstChild() ; child; child = child->getNext() ) { - Persp3D* persp3d = dynamic_cast(child); - if (persp3d) { - std::vector tokens; - - const gchar* vp_x = persp3d->getAttribute("inkscape:vp_x"); - const gchar* vp_y = persp3d->getAttribute("inkscape:vp_y"); - const gchar* vp_z = persp3d->getAttribute("inkscape:vp_z"); - const gchar* vp_o = persp3d->getAttribute("inkscape:persp3d-origin"); - // std::cout << "Found Persp3d: " - // << " vp_x: " << vp_x - // << " vp_y: " << vp_y - // << " vp_z: " << vp_z << std::endl; - Proj::Pt2 pt_x (vp_x); - Proj::Pt2 pt_y (vp_y); - Proj::Pt2 pt_z (vp_z); - Proj::Pt2 pt_o (vp_o); - pt_x = pt_x * (1.0/ratio); - pt_y = pt_y * (1.0/ratio); - pt_z = pt_z * (1.0/ratio); - pt_o = pt_o * (1.0/ratio); - persp3d->setAttribute("inkscape:vp_x",pt_x.coord_string()); - persp3d->setAttribute("inkscape:vp_y",pt_y.coord_string()); - persp3d->setAttribute("inkscape:vp_z",pt_z.coord_string()); - persp3d->setAttribute("inkscape:persp3d-origin",pt_o.coord_string()); - } - } } - } // Look for SPNamedView and SPDefs loop + } // Look for SPNamedView loop - // desktop->getDocument()->ensureUpToDate(); // Does not update box3d! DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Update Document")); } // If old Inkscape version diff --git a/src/live_effects/lpe-angle_bisector.cpp b/src/live_effects/lpe-angle_bisector.cpp index 56d33eb4b..9bfbf4ca8 100644 --- a/src/live_effects/lpe-angle_bisector.cpp +++ b/src/live_effects/lpe-angle_bisector.cpp @@ -8,13 +8,15 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include + #include "live_effects/lpe-angle_bisector.h" -#include "2geom/sbasis-to-bezier.h" + +#include <2geom/sbasis-to-bezier.h> + #include "sp-lpe-item.h" #include "knot-holder-entity.h" #include "knotholder.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-attach-path.cpp b/src/live_effects/lpe-attach-path.cpp index 302165719..d2b44dd4e 100644 --- a/src/live_effects/lpe-attach-path.cpp +++ b/src/live_effects/lpe-attach-path.cpp @@ -4,14 +4,15 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include + #include "live_effects/lpe-attach-path.h" + #include "display/curve.h" #include "sp-shape.h" #include "sp-text.h" #include "2geom/path-sink.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index b1e133292..c24d38d7b 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -7,10 +7,9 @@ #include "live_effects/lpe-bendpath.h" #include "sp-item-group.h" + #include "knot-holder-entity.h" #include "knotholder.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include using std::vector; diff --git a/src/live_effects/lpe-bounding-box.cpp b/src/live_effects/lpe-bounding-box.cpp index 11fb34e04..2de768c3a 100644 --- a/src/live_effects/lpe-bounding-box.cpp +++ b/src/live_effects/lpe-bounding-box.cpp @@ -3,14 +3,14 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ + +#include + #include "live_effects/lpe-bounding-box.h" #include "display/curve.h" #include "sp-shape.h" #include "sp-text.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 90cf82c19..7823f00f0 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -6,8 +6,8 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - #include "live_effects/effect.h" + #include namespace Inkscape { diff --git a/src/live_effects/lpe-circle_3pts.cpp b/src/live_effects/lpe-circle_3pts.cpp index 3410b13f2..18252f6a0 100644 --- a/src/live_effects/lpe-circle_3pts.cpp +++ b/src/live_effects/lpe-circle_3pts.cpp @@ -17,8 +17,6 @@ // You might need to include other 2geom files. You can add them here: #include <2geom/circle.h> #include <2geom/path-sink.h> -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-circle_with_radius.cpp b/src/live_effects/lpe-circle_with_radius.cpp index fcefc4ec6..6e03cb1ce 100644 --- a/src/live_effects/lpe-circle_with_radius.cpp +++ b/src/live_effects/lpe-circle_with_radius.cpp @@ -17,8 +17,6 @@ // You might need to include other 2geom files. You can add them here: #include <2geom/circle.h> #include <2geom/path-sink.h> -// TODO due to internal breakage in glibmm headers, this must be last: -#include using namespace Geom; diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 10418a02d..7541c0be2 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -4,10 +4,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include + #include "live_effects/lpe-clone-original.h" + #include "display/curve.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-constructgrid.cpp b/src/live_effects/lpe-constructgrid.cpp index 8d24f9f47..4af8891e8 100644 --- a/src/live_effects/lpe-constructgrid.cpp +++ b/src/live_effects/lpe-constructgrid.cpp @@ -10,10 +10,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "live_effects/lpe-constructgrid.h" -// TODO due to internal breakage in glibmm headers, this must be last: #include +#include "live_effects/lpe-constructgrid.h" + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 5b94e9083..1133e083a 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -11,17 +11,36 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include #include <2geom/path-intersection.h> #include <2geom/sbasis-to-bezier.h> #include "live_effects/lpe-copy_rotate.h" + +#include "knotholder.h" // TODO due to internal breakage in glibmm headers, this must be last: #include namespace Inkscape { namespace LivePathEffect { +namespace CR { + +class KnotHolderEntityStartingAngle : public LPEKnotHolderEntity { +public: + KnotHolderEntityStartingAngle(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; +}; + +class KnotHolderEntityRotationAngle : public LPEKnotHolderEntity { +public: + KnotHolderEntityRotationAngle(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; +}; + +} // namespace CR + bool pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const &p2, Geom::Point const &p3) { @@ -40,7 +59,6 @@ pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const & LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this), - starting_point("hidden", "hidden", "starting_point", &wr, this), starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 60.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 6), @@ -56,7 +74,6 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : registerParameter(&copies_to_360); registerParameter(&fuse_paths); registerParameter(&starting_angle); - registerParameter(&starting_point); registerParameter(&rotation_angle); registerParameter(&num_copies); registerParameter(&origin); @@ -70,41 +87,6 @@ LPECopyRotate::~LPECopyRotate() } -Gtk::Widget * LPECopyRotate::newWidget() -{ - // use manage here, because after deletion of Effect object, others might - // still be pointing to this widget. - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - - vbox->set_border_width(5); - vbox->set_homogeneous(false); - vbox->set_spacing(2); - - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter *param = *it; - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - if (param->param_key != "starting_point") { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - } - - ++it; - } - return dynamic_cast(vbox); -} - - void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { @@ -122,6 +104,11 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { + if(fuse_paths) { + Geom::Coord angle = Geom::deg_from_rad(atan(-postmul[1]/postmul[0])); + angle += starting_angle; + starting_angle.param_set_value(angle); + } // cycle through all parameters. Most parameters will not need transformation, but path and point params do. for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { @@ -159,25 +146,11 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) dir = unit_vector(B - A); // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) - bool near = Geom::are_near(previous_start_point, (Geom::Point)starting_point, 0.01); - if (!near) { - starting_angle.param_set_value(deg_from_rad(-angle_between(dir, starting_point - origin))); - if (GDK_SHIFT_MASK) { - dist_angle_handle = L2(B - A); - } else { - dist_angle_handle = L2(starting_point - origin); - } - } start_pos = origin + dir * Rotate(-rad_from_deg(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle; - if (near) { - starting_point.param_setValue(start_pos); - } - previous_start_point = (Geom::Point)starting_point; if ( fuse_paths || copies_to_360 ) { rot_pos = origin; } - SPLPEItem * item = const_cast(lpeitem); item->apply_to_clippath(item); item->apply_to_mask(item); @@ -445,6 +418,85 @@ LPECopyRotate::resetDefaults(SPItem const* item) original_bbox(SP_LPE_ITEM(item)); } +void +LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ + { + KnotHolderEntity *e = new CR::KnotHolderEntityStartingAngle(this); + e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, + _("Adjust the starting angle")); + knotholder->add(e); + } + { + KnotHolderEntity *e = new CR::KnotHolderEntityRotationAngle(this); + e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, + _("Adjust the rotation angle")); + knotholder->add(e); + } +}; + +namespace CR { + +using namespace Geom; + +void +KnotHolderEntityStartingAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +{ + LPECopyRotate* lpe = dynamic_cast(_effect); + + Geom::Point const s = snap_knot_position(p, state); + + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + lpe->starting_angle.param_set_value(deg_from_rad(-angle_between(lpe->dir, s - lpe->origin))); + if (state & GDK_SHIFT_MASK) { + lpe->dist_angle_handle = L2(lpe->B - lpe->A); + } else { + lpe->dist_angle_handle = L2(p - lpe->origin); + } + + // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} + +void +KnotHolderEntityRotationAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +{ + LPECopyRotate* lpe = dynamic_cast(_effect); + + Geom::Point const s = snap_knot_position(p, state); + + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + lpe->rotation_angle.param_set_value(deg_from_rad(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); + if (state & GDK_SHIFT_MASK) { + lpe->dist_angle_handle = L2(lpe->B - lpe->A); + } else { + lpe->dist_angle_handle = L2(p - lpe->origin); + } + + // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} + +Geom::Point +KnotHolderEntityStartingAngle::knot_get() const +{ + LPECopyRotate const *lpe = dynamic_cast(_effect); + return lpe->start_pos; +} + +Geom::Point +KnotHolderEntityRotationAngle::knot_get() const +{ + LPECopyRotate const *lpe = dynamic_cast(_effect); + return lpe->rot_pos; +} + +} // namespace CR + +/* ######################## */ + } //namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 8f9fc12ac..87af867df 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -21,6 +21,12 @@ namespace Inkscape { namespace LivePathEffect { +namespace CR { +// we need a separate namespace to avoid clashes with LPEPerpBisector +class KnotHolderEntityStartingAngle; +class KnotHolderEntityRotationAngle; +} + class LPECopyRotate : public Effect, GroupBBoxEffect { public: LPECopyRotate(LivePathEffectObject *lpeobject); @@ -32,13 +38,16 @@ public: virtual void split(Geom::PathVector &path_in, Geom::Path const ÷r); virtual void resetDefaults(SPItem const* item); virtual void transform_multiply(Geom::Affine const& postmul, bool set); - virtual Gtk::Widget * newWidget(); + /* the knotholder entity classes must be declared friends */ + friend class CR::KnotHolderEntityStartingAngle; + friend class CR::KnotHolderEntityRotationAngle; + void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); + protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: PointParam origin; - PointParam starting_point; ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; @@ -49,7 +58,6 @@ private: Geom::Point dir; Geom::Point start_pos; Geom::Point rot_pos; - Geom::Point previous_start_point; double dist_angle_handle; LPECopyRotate(const LPECopyRotate&); LPECopyRotate& operator=(const LPECopyRotate&); diff --git a/src/live_effects/lpe-curvestitch.cpp b/src/live_effects/lpe-curvestitch.cpp index 38cbeaac0..3beedaf57 100644 --- a/src/live_effects/lpe-curvestitch.cpp +++ b/src/live_effects/lpe-curvestitch.cpp @@ -13,6 +13,8 @@ */ #include "ui/widget/scalar.h" +#include + #include "live_effects/lpe-curvestitch.h" #include "sp-path.h" @@ -20,9 +22,6 @@ #include "xml/repr.h" #include <2geom/bezier-to-sbasis.h> -// TODO due to internal breakage in glibmm headers, this must be last: -#include - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-dynastroke.cpp b/src/live_effects/lpe-dynastroke.cpp index 50bbe6451..7e22f6e51 100644 --- a/src/live_effects/lpe-dynastroke.cpp +++ b/src/live_effects/lpe-dynastroke.cpp @@ -16,8 +16,6 @@ #include <2geom/bezier-to-sbasis.h> #include <2geom/sbasis-math.h> -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-ellipse_5pts.cpp b/src/live_effects/lpe-ellipse_5pts.cpp index 28e7058d7..0371fc313 100644 --- a/src/live_effects/lpe-ellipse_5pts.cpp +++ b/src/live_effects/lpe-ellipse_5pts.cpp @@ -12,14 +12,15 @@ */ #include "live_effects/lpe-ellipse_5pts.h" + +// You might need to include other 2geom files. You can add them here: +#include #include <2geom/circle.h> #include <2geom/ellipse.h> #include <2geom/path-sink.h> #include "inkscape.h" #include "desktop.h" #include "message-stack.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-envelope.cpp b/src/live_effects/lpe-envelope.cpp index 61a696435..c3b0a7c10 100644 --- a/src/live_effects/lpe-envelope.cpp +++ b/src/live_effects/lpe-envelope.cpp @@ -6,8 +6,6 @@ #include "live_effects/lpe-envelope.h" #include "display/curve.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include using std::vector; diff --git a/src/live_effects/lpe-extrude.cpp b/src/live_effects/lpe-extrude.cpp index daa30d45a..d22007f76 100644 --- a/src/live_effects/lpe-extrude.cpp +++ b/src/live_effects/lpe-extrude.cpp @@ -12,10 +12,10 @@ */ #include "live_effects/lpe-extrude.h" -#include "sp-item.h" -// TODO due to internal breakage in glibmm headers, this must be last: + #include +#include "sp-item.h" namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-fill-between-many.cpp b/src/live_effects/lpe-fill-between-many.cpp index 1e2eadfdb..2087925fa 100644 --- a/src/live_effects/lpe-fill-between-many.cpp +++ b/src/live_effects/lpe-fill-between-many.cpp @@ -11,7 +11,7 @@ #include "display/curve.h" #include "sp-shape.h" #include "sp-text.h" -// TODO due to internal breakage in glibmm headers, this must be last: + #include namespace Inkscape { diff --git a/src/live_effects/lpe-fill-between-strokes.cpp b/src/live_effects/lpe-fill-between-strokes.cpp index 0dbebdf26..b1e328d18 100644 --- a/src/live_effects/lpe-fill-between-strokes.cpp +++ b/src/live_effects/lpe-fill-between-strokes.cpp @@ -3,13 +3,14 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ + +#include + #include "live_effects/lpe-fill-between-strokes.h" #include "display/curve.h" #include "sp-shape.h" #include "sp-text.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 1e2df7dc8..24ee2ccc3 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -25,8 +25,8 @@ // for programmatically updating knots #include "ui/tools-switch.h" + // TODO due to internal breakage in glibmm headers, this must be last: -#include using namespace Geom; namespace Inkscape { diff --git a/src/live_effects/lpe-gears.cpp b/src/live_effects/lpe-gears.cpp index 17579c64e..1d5398aa5 100644 --- a/src/live_effects/lpe-gears.cpp +++ b/src/live_effects/lpe-gears.cpp @@ -7,10 +7,11 @@ */ #include "live_effects/lpe-gears.h" -#include <2geom/bezier-to-sbasis.h> -// TODO due to internal breakage in glibmm headers, this must be last: + #include +#include <2geom/bezier-to-sbasis.h> + using std::vector; using namespace Geom; diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp index e95dc5f38..43da4d105 100644 --- a/src/live_effects/lpe-interpolate.cpp +++ b/src/live_effects/lpe-interpolate.cpp @@ -9,15 +9,15 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ + +#include + #include "live_effects/lpe-interpolate.h" #include <2geom/sbasis-to-bezier.h> #include "sp-path.h" #include "display/curve.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-interpolate_points.cpp b/src/live_effects/lpe-interpolate_points.cpp index 0a0bcea14..ab0576174 100644 --- a/src/live_effects/lpe-interpolate_points.cpp +++ b/src/live_effects/lpe-interpolate_points.cpp @@ -12,9 +12,8 @@ */ #include "live_effects/lpe-interpolate_points.h" + #include "live_effects/lpe-powerstroke-interpolators.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp index dacb87dd9..3bfbd6288 100644 --- a/src/live_effects/lpe-jointype.cpp +++ b/src/live_effects/lpe-jointype.cpp @@ -19,8 +19,6 @@ #include <2geom/elliptical-arc.h> #include "lpe-jointype.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index c35da0601..474523aa3 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -33,9 +33,6 @@ #include "document.h" #include "document-undo.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-lattice.cpp b/src/live_effects/lpe-lattice.cpp index acffed000..091b6ddca 100644 --- a/src/live_effects/lpe-lattice.cpp +++ b/src/live_effects/lpe-lattice.cpp @@ -20,8 +20,7 @@ #include <2geom/sbasis-2d.h> #include <2geom/bezier-to-sbasis.h> -// TODO due to internal breakage in glibmm headers, this must be last: -#include + using namespace Geom; namespace Inkscape { diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index e827491c0..9e9fc153a 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -16,15 +16,12 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include "live_effects/lpe-lattice2.h" #include "display/curve.h" #include "helper/geom.h" #include <2geom/sbasis-2d.h> #include <2geom/bezier-to-sbasis.h> - // TODO due to internal breakage in glibmm headers, this must be last: -#include using namespace Geom; diff --git a/src/live_effects/lpe-lattice2.h b/src/live_effects/lpe-lattice2.h index 59a0350d3..4a025d182 100644 --- a/src/live_effects/lpe-lattice2.h +++ b/src/live_effects/lpe-lattice2.h @@ -18,7 +18,7 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - +#include #include "live_effects/effect.h" #include "live_effects/parameter/enum.h" #include "live_effects/parameter/point.h" diff --git a/src/live_effects/lpe-line_segment.cpp b/src/live_effects/lpe-line_segment.cpp index cc024fb92..4c9edabd4 100644 --- a/src/live_effects/lpe-line_segment.cpp +++ b/src/live_effects/lpe-line_segment.cpp @@ -13,8 +13,6 @@ #include "live_effects/lpe-line_segment.h" #include "ui/tools/lpe-tool.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index f34421df2..11620b23f 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -13,10 +13,6 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - -#include -#include "live_effects/lpeobject.h" -#include "live_effects/lpeobject-reference.h" #include "live_effects/lpe-mirror_symmetry.h" #include "display/curve.h" #include "svg/path-string.h" @@ -31,7 +27,6 @@ #include "knotholder.h" #include "style.h" #include "xml/sp-css-attr.h" - // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -48,6 +43,17 @@ static const Util::EnumData ModeTypeData[MT_END] = { static const Util::EnumDataConverter MTConverter(ModeTypeData, MT_END); +namespace MS { + +class KnotHolderEntityCenterMirrorSymmetry : public LPEKnotHolderEntity { +public: + KnotHolderEntityCenterMirrorSymmetry(LPEMirrorSymmetry *effect) : LPEKnotHolderEntity(effect){}; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; +}; + +} // namespace MS + LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), @@ -55,26 +61,27 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : discard_orig_path(_("Discard original path?"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), - split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints. Group result to apply nested"), "split_elements", &wr, this, false), - start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust the start of mirroring")), - end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), - center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) + split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split_elements", &wr, this, false), + start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, "Adjust the start of mirroring"), + end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring"), + id_origin("id_origin", "id_origin", "id_origin", &wr, this,"") { show_orig_path = true; registerParameter(&mode); - registerParameter(&split_gap); - registerParameter(&discard_orig_path); - registerParameter(&fuse_paths); - registerParameter(&oposite_fuse); - registerParameter(&split_elements); - registerParameter(&start_point); - registerParameter(&end_point); - registerParameter(¢er_point); + registerParameter( &split_gap); + registerParameter( &discard_orig_path); + registerParameter( &fuse_paths); + registerParameter( &oposite_fuse); + registerParameter( &split_elements); + registerParameter( &start_point); + registerParameter( &end_point); + registerParameter( &id_origin); + id_origin.param_hide_canvas_text(); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); split_gap.param_set_digits(2); apply_to_clippath_and_mask = true; - previous_center = Geom::Point(0,0); + actual = true; } LPEMirrorSymmetry::~LPEMirrorSymmetry() @@ -87,10 +94,11 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) SPLPEItem * splpeitem = const_cast(lpeitem); if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { Inkscape::Selection *sel = desktop->getSelection(); - if ( sel && !sel->isEmpty()) { + if ( sel && !sel->isEmpty() && actual) { SPItem *item = sel->singleItem(); if (item) { if(std::strcmp(splpeitem->getId(),item->getId()) != 0) { + actual = false; return; } } @@ -109,14 +117,11 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) point_a = Geom::Point(center_point[X],boundingbox_Y.min()); point_b = Geom::Point(center_point[X],boundingbox_Y.max()); } - if (Geom::are_near((Geom::Point)start_point, (Geom::Point)end_point, 0.01)) { - start_point.param_setValue(point_a); - end_point.param_setValue(point_b); - } line_separation.setPoints(point_a, point_b); if ( mode == MT_X || mode == MT_Y ) { start_point.param_setValue(point_a); end_point.param_setValue(point_b); + center_point = Geom::middle_point(point_a, point_b); } else if ( mode == MT_FREE) { if(!are_near(previous_center,center_point, 0.01)) { Geom::Point trans = center_point - previous_center; @@ -124,6 +129,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) end_point.param_setValue(end_point * trans); line_separation.setPoints(start_point, end_point); } else { + center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); line_separation.setPoints(start_point, end_point); } } else if ( mode == MT_V){ @@ -136,6 +142,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point ep = Geom::Point(view_box_rect.width()/2.0, view_box_rect.height()); ep *= i2anc_affine(SP_OBJECT(lpeitem), SP_OBJECT(SP_ACTIVE_DESKTOP->currentLayer()->parent)) .inverse(); end_point.param_setValue(ep); + center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); line_separation.setPoints(start_point, end_point); } } else { //horizontal page @@ -148,56 +155,53 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point ep = Geom::Point(view_box_rect.width(), view_box_rect.height()/2.0); ep *= i2anc_affine(SP_OBJECT(lpeitem), SP_OBJECT(SP_ACTIVE_DESKTOP->currentLayer()->parent)) .inverse(); end_point.param_setValue(ep); + center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); line_separation.setPoints(start_point, end_point); } } - - previous_center = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); - if (!are_near(previous_center, center_point,0.01)) { - center_point.param_setValue(previous_center); - } - if (split_elements && allow_split()) { - container = dynamic_cast(splpeitem->parent); + previous_center = center_point; + if (split_elements) { + ms_container = dynamic_cast(splpeitem->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node *root = splpeitem->document->getReprRoot(); Inkscape::XML::Node *root_origin = doc->getReprRoot(); if (root_origin != root) { return; } - const char * mirror = g_strdup(Glib::ustring("mirror-b-").append(this->getRepr()->attribute("id")).c_str()); -// if (std::strcmp(splpeitem->getId(), mirror_b) == 0) { -// syncMirror(splpeitem, mirror_a); -// } else { - Geom::Point point_a(line_separation.initialPoint()); - Geom::Point point_b(line_separation.finalPoint()); - Geom::Point gap(split_gap,0); - Geom::Translate m1(point_a[0], point_a[1]); - double hyp = Geom::distance(point_a, point_b); - double cos = 0; - double sin = 0; - if (hyp > 0) { - cos = (point_b[0] - point_a[0]) / hyp; - sin = (point_b[1] - point_a[1]) / hyp; - } - Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); - Geom::Point dir = unit_vector(point_b - point_a); - Geom::Point offset = (point_a + point_b)/2 + dir.ccw() * split_gap; - line_separation *= Geom::Translate(offset); - Geom::Scale sca(1.0, -1.0); - m = m1.inverse() * m2; - m = m * sca; - m = m * m2.inverse(); - m = m * m1; - m = m * splpeitem->transform; - createMirror(splpeitem, m); - //} - } else { - if (!allow_split()) { - std::cout << "Only one operation of split allowed. Group results to nested effects.\n"; - split_elements.param_setValue(false); + Geom::Point point_a(line_separation.initialPoint()); + Geom::Point point_b(line_separation.finalPoint()); + Geom::Point gap(split_gap,0); + Geom::Translate m1(point_a[0], point_a[1]); + double hyp = Geom::distance(point_a, point_b); + double cos = 0; + double sin = 0; + if (hyp > 0) { + cos = (point_b[0] - point_a[0]) / hyp; + sin = (point_b[1] - point_a[1]) / hyp; } - processObjects(LPE_ERASE); + Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); + Geom::Point dir = unit_vector(point_b - point_a); + Geom::Point offset = (point_a + point_b)/2 + dir.ccw() * split_gap; + line_separation *= Geom::Translate(offset); + Geom::Scale sca(1.0, -1.0); + const char * id_original = id_origin.param_getSVGValue(); + const char * id = g_strdup(Glib::ustring("mirror-").append(id_original).append("-").append(this->getRepr()->attribute("id")).c_str()); + m = m1.inverse() * m2; + m = m * sca; + m = m * m2.inverse(); + m = m * m1; + m = m * lpeitem->transform; + if (std::strcmp(splpeitem->getId(), id) == 0) { + createMirror(splpeitem, m, id_original); + } else { + createMirror(splpeitem, m, id); + } + elements.clear(); + elements.push_back(id); + elements.push_back(id_original); + } else { elements.clear(); + processObjects(LPE_ERASE); } } @@ -251,7 +255,7 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c if (c) { dest->getRepr()->setAttribute(att,sp_svg_write_path(c->get_pathvector())); c->reset(); - g_free(c); + g_free(c); } else { dest->getRepr()->setAttribute(att,NULL); } @@ -264,19 +268,9 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c } void -LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform) +LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - const char * id; - Glib::ustring idbase = Glib::ustring(sp_lpe_item->getId()); - size_t pos = idbase.find("-mirror"); - if (pos <= idbase.size()) { - id = g_strdup(idbase.substr(pos).c_str()); - } else { - id = g_strdup(idbase.append("-mirror").c_str()); - elements.clear(); - elements.push_back(id); - } Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); @@ -288,95 +282,24 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform) } else { phantom = origin->getRepr()->duplicate(xml_doc); } + phantom->setAttribute("id", id); if (!elemref) { - elemref = container->appendChildRepr(phantom); + elemref = ms_container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required + cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", NULL); //NULL required elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); - if (elemref->parent != container) { + if (elemref->parent != ms_container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); copy->setAttribute("id", id); - container->appendChildRepr(copy); + ms_container->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); } } } -//void -//LPEMirrorSymmetry::syncMirror(SPLPEItem *origin, const char * id) -//{ -// if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { -// Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); -// Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); -// Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); -// SVGElemRef->attach(SVGElem_uri); -// SPObject *elemref= NULL; -// Inkscape::XML::Node *phantom = NULL; -// if (elemref = SVGElemRef->getObject()) { -// cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required -// } -// } -//} - -bool -LPEMirrorSymmetry::allow_split(){ - if (sp_lpe_item->path_effect_list->empty()) { - return false; - } - size_t count = 0; - for (PathEffectList::const_iterator it = sp_lpe_item->path_effect_list->begin(); it != sp_lpe_item->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::LPEMirrorSymmetry * ms = dynamic_cast(lpeobj->get_lpe()); - if (ms && ms->split_elements) { - count++; - } - } - } - return count <= 1; -} - -//Gtk::Widget * -//LPEMirrorSymmetry::newWidget() -//{ -// // use manage here, because after deletion of Effect object, others might -// // still be pointing to this widget. -// Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - -// vbox->set_border_width(5); -// std::vector::iterator it = param_vector.begin(); -// while (it != param_vector.end()) { -// if ((*it)->widget_is_visible) { -// Parameter *param = *it; -// Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); -// if (widg) { -// if (param->param_key == "split_elements") { -// Gtk::CheckButton *widg_registered = Gtk::manage(dynamic_cast(widg)); -// if (!allow_split()) { -// widg_registered->set_sensitive("false"); -// } -// widg = dynamic_cast(widg_registered); -// } -// Glib::ustring *tip = param->param_getTooltip(); -// vbox->pack_start(*widg, true, true, 2); -// if (tip) { -// widg->set_tooltip_text(*tip); -// } else { -// widg->set_tooltip_text(""); -// widg->set_has_tooltip(false); -// } -// } -// } - -// ++it; -// } -// return dynamic_cast(vbox); -//} - //TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) @@ -426,15 +349,15 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) break; case LPE_ERASE: - //if (std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0) { + if (std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { elemref->deleteObject(); - //} + } break; case LPE_VISIBILITY: css = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); - if (!this->isVisible()/* && std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0*/) { + if (!this->isVisible() && std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { css->setAttribute("display", "none"); } else { css->setAttribute("display", NULL); @@ -459,6 +382,8 @@ void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { if( !split_elements) { + center_point *= postmul; + previous_center = center_point; // cycle through all parameters. Most parameters will not need transformation, but path and point params do. for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { Parameter * param = *it; @@ -481,15 +406,10 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) start_point.param_update_default(point_a); end_point.param_setValue(point_b); end_point.param_update_default(point_b); - center_point.param_setValue(point_c); + center_point = point_c; previous_center = center_point; -// SPLPEItem * splpeitem = const_cast(lpeitem); -// if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet -// const char * mirror_a = g_strdup(Glib::ustring("mirror-a-").append(this->getRepr()->attribute("id")).c_str()); -// splpeitem->setAttribute("id", mirror_a); -// first_lpe.param_setValue(this->getRepr()->attribute("id")); -// first_lpe.write_to_SVG(); -// } + id_origin.param_setValue(Glib::ustring(lpeitem->getId())); + id_origin.write_to_SVG(); } @@ -640,6 +560,41 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) return path_out; } + +Gtk::Widget *LPEMirrorSymmetry::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + if (param->param_key != "id_origin") { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + } + + ++it; + } + return dynamic_cast(vbox); +} + void LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) { @@ -655,6 +610,43 @@ LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector hp_vec.push_back(helper); } +void +LPEMirrorSymmetry::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ + SPKnotShapeType knot_shape = SP_KNOT_SHAPE_CIRCLE; + SPKnotModeType knot_mode = SP_KNOT_MODE_XOR; + guint32 knot_color = 0x0000ff00; + { + KnotHolderEntity *c = new MS::KnotHolderEntityCenterMirrorSymmetry(this); + c->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, + _("Adjust the center"), knot_shape, knot_mode, knot_color ); + knotholder->add(c); + } +}; + +namespace MS { + +using namespace Geom; + +void +KnotHolderEntityCenterMirrorSymmetry::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) +{ + LPEMirrorSymmetry* lpe = dynamic_cast(_effect); + Geom::Point const s = snap_knot_position(p, state); + lpe->center_point = s; + // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} + +Geom::Point +KnotHolderEntityCenterMirrorSymmetry::knot_get() const +{ + LPEMirrorSymmetry const *lpe = dynamic_cast(_effect); + return lpe->center_point; +} + +} // namespace CR + } //namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 12ceebaf8..7b090ed82 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -15,10 +15,10 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - +#include #include "live_effects/effect.h" -#include "live_effects/parameter/parameter.h" #include "live_effects/parameter/text.h" +#include "live_effects/parameter/parameter.h" #include "live_effects/parameter/point.h" #include "live_effects/parameter/path.h" #include "live_effects/parameter/enum.h" @@ -27,6 +27,11 @@ namespace Inkscape { namespace LivePathEffect { +namespace MS { +// we need a separate namespace to avoid clashes with LPEPerpBisector +class KnotHolderEntityCenterMirrorSymmetry; +} + enum ModeType { MT_V, MT_H, @@ -46,13 +51,14 @@ public: virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); -// virtual Gtk::Widget * newWidget(); + virtual Gtk::Widget *newWidget(); void processObjects(LpeAction lpe_action); - void createMirror(SPLPEItem *origin, Geom::Affine transform); + /* the knotholder entity classes must be declared friends */ + friend class MS::KnotHolderEntityCenterMirrorSymmetry; + void createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); -// void syncMirror(SPLPEItem *origin, const char * id); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...); - bool allow_split(); + void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -66,11 +72,13 @@ private: BoolParam split_elements; PointParam start_point; PointParam end_point; - PointParam center_point; + TextParam id_origin; Geom::Line line_separation; Geom::Point previous_center; + Geom::Point center_point; + bool actual; std::vector elements; - SPObject * container; + SPObject * ms_container; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); }; diff --git a/src/live_effects/lpe-offset.cpp b/src/live_effects/lpe-offset.cpp index 057f404e0..a0fa46c3f 100644 --- a/src/live_effects/lpe-offset.cpp +++ b/src/live_effects/lpe-offset.cpp @@ -11,12 +11,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include + #include "live_effects/lpe-offset.h" #include "sp-shape.h" #include "display/curve.h" + #include <2geom/elliptical-arc.h> -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-parallel.cpp b/src/live_effects/lpe-parallel.cpp index 276749c43..9cd8ecf46 100644 --- a/src/live_effects/lpe-parallel.cpp +++ b/src/live_effects/lpe-parallel.cpp @@ -11,15 +11,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include + #include "live_effects/lpe-parallel.h" #include "sp-shape.h" #include "display/curve.h" #include "knotholder.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-path_length.cpp b/src/live_effects/lpe-path_length.cpp index a06dbde98..6ec1e0ede 100644 --- a/src/live_effects/lpe-path_length.cpp +++ b/src/live_effects/lpe-path_length.cpp @@ -11,10 +11,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include + #include "live_effects/lpe-path_length.h" #include "util/units.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 9cfeffee7..15c2817c4 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -12,8 +12,6 @@ #include "knotholder.h" #include -// TODO due to internal breakage in glibmm headers, this must be last: -#include using std::vector; diff --git a/src/live_effects/lpe-perp_bisector.cpp b/src/live_effects/lpe-perp_bisector.cpp index bce22250a..f69dae6a1 100644 --- a/src/live_effects/lpe-perp_bisector.cpp +++ b/src/live_effects/lpe-perp_bisector.cpp @@ -11,6 +11,9 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ + +#include + #include "live_effects/lpe-perp_bisector.h" #include "display/curve.h" #include "sp-path.h" @@ -18,9 +21,6 @@ #include "knotholder.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include - namespace Inkscape { namespace LivePathEffect { namespace PB { diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index e834c0e86..6a6b59519 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -20,9 +20,6 @@ #include "display/curve.h" #include -// TODO due to internal breakage in glibmm headers, this must be last: -#include - using namespace Geom; namespace Inkscape { diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 2c6d66cee..cb4e43d87 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -11,6 +11,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ #include +#include + #include "persp3d.h" //#include "transf_mat_3x4.h" #include "document-private.h" @@ -21,9 +23,6 @@ #include "desktop.h" #include -// TODO due to internal breakage in glibmm headers, this must be last: -#include - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index e9f3975c7..329a00756 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -25,9 +25,6 @@ #include <2geom/circle.h> #include "helper/geom.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include - namespace Geom { // should all be moved to 2geom at some point diff --git a/src/live_effects/lpe-recursiveskeleton.cpp b/src/live_effects/lpe-recursiveskeleton.cpp index aa0db920b..ed0c915ce 100644 --- a/src/live_effects/lpe-recursiveskeleton.cpp +++ b/src/live_effects/lpe-recursiveskeleton.cpp @@ -10,13 +10,12 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include + #include "live_effects/lpe-recursiveskeleton.h" #include <2geom/bezier-to-sbasis.h> -// TODO due to internal breakage in glibmm headers, this must be last: -#include - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-rough-hatches.cpp b/src/live_effects/lpe-rough-hatches.cpp index 3cc8658ea..2fb65b349 100644 --- a/src/live_effects/lpe-rough-hatches.cpp +++ b/src/live_effects/lpe-rough-hatches.cpp @@ -13,6 +13,7 @@ */ #include "ui/widget/scalar.h" +#include #include "live_effects/lpe-rough-hatches.h" #include "sp-item.h" @@ -22,8 +23,6 @@ #include <2geom/sbasis-math.h> #include <2geom/bezier-to-sbasis.h> -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index c6edffd9b..3a486ff10 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -13,14 +13,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include "live_effects/lpe-roughen.h" #include "display/curve.h" #include #include "helper/geom.h" - // TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index bab06022f..dbdb91e62 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -12,6 +12,7 @@ #ifndef INKSCAPE_LPE_ROUGHEN_H #define INKSCAPE_LPE_ROUGHEN_H +#include #include "live_effects/effect.h" #include "live_effects/parameter/enum.h" #include "live_effects/parameter/parameter.h" diff --git a/src/live_effects/lpe-ruler.cpp b/src/live_effects/lpe-ruler.cpp index 60c2a3e1c..3a2d78b2c 100644 --- a/src/live_effects/lpe-ruler.cpp +++ b/src/live_effects/lpe-ruler.cpp @@ -12,8 +12,7 @@ */ #include "live_effects/lpe-ruler.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp index 7c298d0e7..170b6dccb 100644 --- a/src/live_effects/lpe-show_handles.cpp +++ b/src/live_effects/lpe-show_handles.cpp @@ -6,7 +6,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include "live_effects/lpe-show_handles.h" #include <2geom/sbasis-to-bezier.h> #include <2geom/svg-path-parser.h> @@ -14,7 +13,6 @@ #include "desktop-style.h" #include "style.h" #include "svg/svg.h" - // TODO due to internal breakage in glibmm headers, this must be last: #include diff --git a/src/live_effects/lpe-show_handles.h b/src/live_effects/lpe-show_handles.h index c46abd2c2..3eda04649 100644 --- a/src/live_effects/lpe-show_handles.h +++ b/src/live_effects/lpe-show_handles.h @@ -8,6 +8,7 @@ * Copyright (C) Jabier Arraiza Cenoz 2014 * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include "helper/geom-nodetype.h" #include "live_effects/effect.h" #include "live_effects/lpegroupbbox.h" diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 8bdb19b4f..ec21e10d2 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -2,7 +2,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include "live_effects/lpe-simplify.h" #include "display/curve.h" #include "helper/geom.h" @@ -10,7 +9,6 @@ #include "svg/svg.h" #include "ui/tools/node-tool.h" #include "ui/icon-names.h" - // TODO due to internal breakage in glibmm headers, this must be last: #include diff --git a/src/live_effects/lpe-simplify.h b/src/live_effects/lpe-simplify.h index 6c407f572..8135561af 100644 --- a/src/live_effects/lpe-simplify.h +++ b/src/live_effects/lpe-simplify.h @@ -6,6 +6,7 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include "live_effects/effect.h" #include "live_effects/parameter/togglebutton.h" #include "live_effects/lpegroupbbox.h" diff --git a/src/live_effects/lpe-skeleton.cpp b/src/live_effects/lpe-skeleton.cpp index adc4a3493..7d34db699 100644 --- a/src/live_effects/lpe-skeleton.cpp +++ b/src/live_effects/lpe-skeleton.cpp @@ -20,7 +20,8 @@ #include "live_effects/lpe-skeleton.h" -// TODO due to internal breakage in glibmm headers, this must be last: +// You might need to include other 2geom files. You can add them here: + #include namespace Inkscape { diff --git a/src/live_effects/lpe-sketch.cpp b/src/live_effects/lpe-sketch.cpp index e01516f2e..95e2f6f0d 100644 --- a/src/live_effects/lpe-sketch.cpp +++ b/src/live_effects/lpe-sketch.cpp @@ -13,14 +13,13 @@ #include "live_effects/lpe-sketch.h" +#include + // You might need to include other 2geom files. You can add them here: #include <2geom/sbasis-math.h> #include <2geom/bezier-to-sbasis.h> #include <2geom/path-intersection.h> -// TODO due to internal breakage in glibmm headers, this must be last: -#include - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-tangent_to_curve.cpp b/src/live_effects/lpe-tangent_to_curve.cpp index 76d4ea71b..b308ef8d7 100644 --- a/src/live_effects/lpe-tangent_to_curve.cpp +++ b/src/live_effects/lpe-tangent_to_curve.cpp @@ -13,13 +13,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include + #include "live_effects/lpe-tangent_to_curve.h" #include "sp-path.h" #include "display/curve.h" #include "knotholder.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 4ffc41691..f6f6b33dc 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -26,8 +26,6 @@ #include "svg/svg.h" #include "knotholder.h" -// TODO due to internal breakage in glibmm headers, this must be last: -#include template inline bool withinRange(T value, T low, T high) { diff --git a/src/live_effects/lpe-test-doEffect-stack.cpp b/src/live_effects/lpe-test-doEffect-stack.cpp index 324893706..c7ecf6481 100644 --- a/src/live_effects/lpe-test-doEffect-stack.cpp +++ b/src/live_effects/lpe-test-doEffect-stack.cpp @@ -4,11 +4,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "live_effects/lpe-test-doEffect-stack.h" - -// TODO due to internal breakage in glibmm headers, this must be last: #include +#include "live_effects/lpe-test-doEffect-stack.h" + using std::memcpy; namespace Inkscape { diff --git a/src/live_effects/lpe-text_label.cpp b/src/live_effects/lpe-text_label.cpp index 709d05e18..602a6897c 100644 --- a/src/live_effects/lpe-text_label.cpp +++ b/src/live_effects/lpe-text_label.cpp @@ -11,11 +11,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "live_effects/lpe-text_label.h" - -// TODO due to internal breakage in glibmm headers, this must be last: #include +#include "live_effects/lpe-text_label.h" + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index e1f36eee7..78db622f2 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -20,7 +20,6 @@ // TODO due to internal breakage in glibmm headers, this must be last: #include - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index 47e2a1cec..2486f3366 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -5,7 +5,7 @@ */ #include "live_effects/lpe-vonkoch.h" -// TODO due to internal breakage in glibmm headers, this must be last: + #include //using std::vector; diff --git a/src/live_effects/parameter/fontbutton.cpp b/src/live_effects/parameter/fontbutton.cpp index 64c203093..ff8ab76a0 100644 --- a/src/live_effects/parameter/fontbutton.cpp +++ b/src/live_effects/parameter/fontbutton.cpp @@ -4,7 +4,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include + #include "ui/widget/registered-widget.h" #include "live_effects/parameter/fontbutton.h" #include "live_effects/effect.h" diff --git a/src/live_effects/parameter/fontbutton.h b/src/live_effects/parameter/fontbutton.h index df47251a2..387ad130b 100644 --- a/src/live_effects/parameter/fontbutton.h +++ b/src/live_effects/parameter/fontbutton.h @@ -8,6 +8,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ #include +#include #include "live_effects/parameter/parameter.h" namespace Inkscape { diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index ed00092b2..ff43c2ca3 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -74,7 +74,8 @@ static char const preferences_skeleton[] = " \n" "\n" " \n" +" bounding_box=\"0\"\n" +" style=\"fill:none;stroke:black;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;\">\n" " \n" " \n" " \n" @@ -87,7 +88,7 @@ static char const preferences_skeleton[] = " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 7b2507b5e..96dcdbe30 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -584,13 +584,12 @@ sp_item_group_ungroup (SPGroup *group, std::vector &children, bool do_d SPText * text = dynamic_cast(citem); if (text) { //this causes a change in text-on-path appearance when there is a non-conformal transform, see bug #1594565 + double scale = (ctrans.expansionX() + ctrans.expansionY()) / 2.0; SPTextPath * text_path = dynamic_cast(text->firstChild()); if (!text_path) { nrepr->setAttribute("transform", affinestr); } else { - // The following breaks roundtripping group -> ungroup - // double scale = (ctrans.expansionX() + ctrans.expansionY()) / 2.0; - // sp_recursive_scale_text_size(nrepr, scale); + sp_recursive_scale_text_size(nrepr, scale); Geom::Affine ttrans = ctrans.inverse() * SP_ITEM(text)->transform * ctrans; gchar *affinestr = sp_svg_transform_write(ttrans); nrepr->setAttribute("transform", affinestr); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 98428512f..9cf9dadc1 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -607,7 +607,7 @@ bool SPLPEItem::hasPathEffect() const return true; } -bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const +bool SPLPEItem::hasPathEffectOfType(int const type) const { if (path_effect_list->empty()) { return false; @@ -619,9 +619,7 @@ bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const if (lpeobj) { Inkscape::LivePathEffect::Effect const* lpe = lpeobj->get_lpe(); if (lpe && (lpe->effectType() == type)) { - if (is_ready || lpe->isReady()) { - return true; - } + return true; } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index db4a0c7a3..9e5cb3329 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -73,7 +73,7 @@ public: bool pathEffectsEnabled() const; bool hasPathEffect() const; - bool hasPathEffectOfType(int const type, bool is_ready = true) const; + bool hasPathEffectOfType(int const type) const; bool hasPathEffectRecursive() const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index f192d0e44..f2604976e 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -1198,7 +1198,7 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb ry = arc->ry.computed; start = arc->start; end = arc->end; - if( end <= start ) { + if( end == start ) { end += 2.0 * M_PI; } } @@ -2026,7 +2026,7 @@ guint SPMeshNodeArray::side_arc( std::vector corners ) { { case 'L': case 'l': - std::cerr << "SPMeshNodeArray::side_arc: Can't convert straight lines to arcs." << std::endl; + std::cout << "SPMeshNodeArray::arc_sides: Can't convert straight lines to arcs."; break; case 'C': @@ -2052,15 +2052,15 @@ guint SPMeshNodeArray::side_arc( std::vector corners ) { ++arced; } else { - std::cerr << "SPMeshNodeArray::side_arc: No crossing, can't turn into arc." << std::endl; + std::cout << "SPMeshNodeArray::arc_sides: No crossing, can't turn into arc." << std::endl; } } else { - std::cerr << "SPMeshNodeArray::side_arc: Handles parallel, can't turn into arc." << std::endl; + std::cout << "SPMeshNodeArray::arc_sides: Handles parallel, can't turn into arc." << std::endl; } break; } default: - std::cerr << "SPMeshNodeArray::side_arc: Invalid path type: " << n[1]->path_type << std::endl; + std::cout << "SPMeshNodeArray::arc_sides: Invalid path type: " << n[1]->path_type << std::endl; } } } diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index ff5d623c2..56939cc30 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -1084,8 +1084,7 @@ sp_tweak_dilate (TweakTool *tc, Geom::Point event_p, Geom::Point p, Geom::Point double move_force = get_move_force(tc); double color_force = MIN(sqrt(path_force)/20.0, 1); -// auto items= selection->items(); - std::vector items(selection->items().begin(), selection->items().end()); + auto items= selection->items(); for(auto i=items.begin();i!=items.end(); ++i){ SPItem *item = *i; diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index ea0faf1df..f7b7a6ec9 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -67,79 +67,76 @@ static bool blocked = false; //## Mesh ## //######################## - -// Get a list of selected meshes taking into account fill/stroke toggles -std::vector ms_get_dt_selected_gradients(Inkscape::Selection *selection) +/* + * Get the current selection and dragger status from the desktop + */ +void ms_read_selection( Inkscape::Selection *selection, + SPMeshGradient *&ms_selected, + bool &ms_selected_multi, + SPMeshType &ms_type, + bool &ms_type_multi ) { - std::vector ms_selected; - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool edit_fill = prefs->getBool("/tools/mesh/edit_fill", true); - bool edit_stroke = prefs->getBool("/tools/mesh/edit_stroke", true); + // Read desktop selection + bool first = true; + ms_type = SP_MESH_TYPE_COONS; + auto itemlist= selection->items(); for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i;// get the items gradient, not the getVector() version + SPItem *item = *i; SPStyle *style = item->style; - if (style) { + if (style && (style->fill.isPaintserver())) { + SPPaintServer *server = item->style->getFillPaintServer(); + if ( SP_IS_MESHGRADIENT(server) ) { - - if (edit_fill && style->fill.isPaintserver()) { - SPPaintServer *server = item->style->getFillPaintServer(); - SPMeshGradient *mesh = dynamic_cast(server); - if (mesh) { - ms_selected.push_back(mesh); - } - } + SPMeshGradient *gradient = SP_MESHGRADIENT(server); // ->getVector(); + SPMeshType type = gradient->type; - if (edit_stroke && style->stroke.isPaintserver()) { - SPPaintServer *server = item->style->getStrokePaintServer(); - SPMeshGradient *mesh = dynamic_cast(server); - if (mesh) { - ms_selected.push_back(mesh); + if (gradient != ms_selected) { + if (ms_selected) { + ms_selected_multi = true; + } else { + ms_selected = gradient; + } } + if( type != ms_type ) { + if (ms_type != SP_MESH_TYPE_COONS && !first) { + ms_type_multi = true; + } else { + ms_type = type; + } + } + first = false; } } - } - return ms_selected; -} + if (style && (style->stroke.isPaintserver())) { + SPPaintServer *server = item->style->getStrokePaintServer(); + if ( SP_IS_MESHGRADIENT(server) ) { + SPMeshGradient *gradient = SP_MESHGRADIENT(server); // ->getVector(); + SPMeshType type = gradient->type; -/* - * Get the current selection status from the desktop - */ -void ms_read_selection( Inkscape::Selection *selection, - SPMeshGradient *&ms_selected, - bool &ms_selected_multi, - SPMeshType &ms_type, - bool &ms_type_multi ) -{ - ms_selected = NULL; - ms_selected_multi = false; - ms_type = SP_MESH_TYPE_COONS; - ms_type_multi = false; - - bool first = true; - - // Read desktop selection, taking into account fill/stroke toggles - std::vector meshes = ms_get_dt_selected_gradients( selection ); - for (auto i = meshes.begin(); i != meshes.end(); ++i) { - if (first) { - ms_selected = (*i); - ms_type = (*i)->type; - first = false; - } else { - if (ms_selected != (*i)) { - ms_selected_multi = true; - } - if (ms_type != (*i)->type) { - ms_type_multi = true; + if (gradient != ms_selected) { + if (ms_selected) { + ms_selected_multi = true; + } else { + ms_selected = gradient; + } + } + if( type != ms_type ) { + if (ms_type != SP_MESH_TYPE_COONS && !first) { + ms_type_multi = true; + } else { + ms_type = type; + } + } + first = false; } } } -} + } /* * Core function, setup all the widgets whenever something changes on the desktop @@ -176,7 +173,7 @@ static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointe // std::cout << " type: " << ms_type << std::endl; EgeSelectOneAction* type = (EgeSelectOneAction *) g_object_get_data(G_OBJECT(widget), "mesh_select_type_action"); - gtk_action_set_sensitive( GTK_ACTION(type), (ms_selected && !ms_type_multi) ); + gtk_action_set_sensitive( GTK_ACTION(type), (ms_selected && !ms_selected_multi) ); if (ms_selected) { blocked = TRUE; ege_select_one_action_set_active( type, ms_type ); @@ -207,6 +204,34 @@ static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GObject *widg ms_tb_selection_changed(NULL, widget); } +void ms_get_dt_selected_gradient(Inkscape::Selection *selection, SPMeshGradient *&ms_selected) +{ + SPMeshGradient *gradient = 0; + + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i;// get the items gradient, not the getVector() version + SPStyle *style = item->style; + SPPaintServer *server = 0; + + if (style && (style->fill.isPaintserver())) { + server = item->style->getFillPaintServer(); + } + if (style && (style->stroke.isPaintserver())) { + server = item->style->getStrokePaintServer(); + } + + if ( SP_IS_MESHGRADIENT(server) ) { + gradient = SP_MESHGRADIENT(server); + } + } + + if (gradient) { + ms_selected = gradient; + } +} + + /* * Callback functions for user actions */ @@ -271,17 +296,18 @@ static void ms_type_changed(EgeSelectOneAction *act, GtkWidget *widget) SPDesktop *desktop = static_cast(g_object_get_data(G_OBJECT(widget), "desktop")); Inkscape::Selection *selection = desktop->getSelection(); - std::vector meshes = ms_get_dt_selected_gradients(selection); + SPMeshGradient *gradient = 0; + ms_get_dt_selected_gradient(selection, gradient); - SPMeshType type = (SPMeshType) ege_select_one_action_get_active(act); - for (auto i = meshes.begin(); i != meshes.end(); ++i) { + if (gradient) { + SPMeshType type = (SPMeshType) ege_select_one_action_get_active(act); // std::cout << " type: " << type << std::endl; - (*i)->type = type; - (*i)->type_set = true; - (*i)->updateRepr(); - } - if (!meshes.empty() ) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH,_("Set mesh type")); + gradient->type = type; + gradient->type_set = true; + gradient->updateRepr(); + + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, + _("Set mesh type")); } } @@ -340,7 +366,7 @@ static void ms_toggle_handles(void) } } -static void ms_toggle_fill_stroke(InkToggleAction * /*act*/, gpointer data) +static void ms_toggle_fill_stroke(void) { MeshTool *mt = get_mesh_tool(); if (mt) { @@ -348,7 +374,6 @@ static void ms_toggle_fill_stroke(InkToggleAction * /*act*/, gpointer data) drag->updateDraggers(); drag->updateLines(); drag->updateLevels(); - ms_tb_selection_changed(NULL, data); // Need to update Type widget } } @@ -482,7 +507,7 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/edit_fill"); g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), holder); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), 0); } /* Edit stroke mesh */ @@ -495,7 +520,7 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/edit_stroke"); g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), holder); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), 0); } /* Show/hide side and tensor handles */ diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 784c467f1..114d946bb 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -117,8 +117,6 @@ static void sp_print_fontstyle( SPStyle *query ) { } #endif -static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false); - // Font family static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) { @@ -227,35 +225,8 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje sp_repr_css_set_property (css, "font-size", osfs.str().c_str()); // Apply font size to selected objects. - // Calling sp_desktop_set_style will result in a call to TextTool::_styleSet() which - // will set the style on selected text inside the element. If we want to set - // the style on the outer objects we need to bypass this call. - bool outer = prefs->getInt("/tools/text/outer_style", false); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (outer) { - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (dynamic_cast(*i) || dynamic_cast(*i)) { - SPItem *item = *i; - - // Scale by inverse of accumulated parent transform - SPCSSAttr *css_set = sp_repr_css_attr_new(); - sp_repr_css_merge(css_set, css); - Geom::Affine const local(item->i2doc_affine()); - double const ex(local.descrim()); - if ( (ex != 0.0) && (ex != 1.0) ) { - sp_css_attr_scale(css_set, 1/ex); - } - - item->changeCSS(css_set,"style"); - - sp_repr_css_attr_unref(css_set); - } - } - } else { - sp_desktop_set_style (desktop, css, true, true); - } + sp_desktop_set_style (desktop, css, true, true); // If no selected objects, set default. SPStyle query(SP_ACTIVE_DOCUMENT); @@ -310,40 +281,6 @@ static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObj g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } -// Changes selection to only text outer elements. -static void sp_text_outer_style_changed( InkToggleAction*act, GObject *tbl ) -{ - bool outer = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(act) ); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/text/outer_style", outer); - - // Update widgets to reflect new state of Text Outer Style button. - sp_text_toolbox_selection_changed( NULL, tbl ); -} - -// Unset line height on selection's inner text objects (tspan, etc.). -static void sp_text_lineheight_unset_changed( InkToggleAction*act, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_unset_property(css, "line-height"); - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css); - - sp_repr_css_attr_unref(css); - - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, - _("Text: Unset line height.")); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - // Handles both Superscripts and Subscripts static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) { @@ -612,34 +549,9 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); - // Apply line-height to selected objects. See comment in font size function. - bool outer = prefs->getInt("/tools/text/outer_style", false); + // Apply line-height to selected objects. SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (outer) { - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (dynamic_cast(*i) || dynamic_cast(*i)) { - SPItem *item = *i; - - // Scale by inverse of accumulated parent transform - SPCSSAttr *css_set = sp_repr_css_attr_new(); - sp_repr_css_merge(css_set, css); - Geom::Affine const local(item->i2doc_affine()); - double const ex(local.descrim()); - if ( (ex != 0.0) && (ex != 1.0) ) { - sp_css_attr_scale(css_set, 1/ex); - } - - item->changeCSS(css_set,"style"); - - sp_repr_css_attr_unref(css_set); - } - } - } else { - sp_desktop_set_style (desktop, css, true, true); - } - + sp_desktop_set_style (desktop, css, true, false); // Only need to save for undo if a text item has been changed. @@ -740,7 +652,7 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) double font_size = 0; int count = 0; for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT(*i)) { + if (SP_IS_TEXT (*i)) { double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); font_size += (*i)->style->font_size.computed * doc_scale; ++count; @@ -769,7 +681,7 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) double font_size = 0; int count = 0; for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT (*i)) { + if (SP_IS_TEXT (*i)) { double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); font_size += (*i)->style->font_size.computed * doc_scale; ++count; @@ -1161,7 +1073,7 @@ static void sp_text_set_sizes(GtkListStore* model_size, int unit) * It is called whenever a text selection is changed, including stepping cursor * through text, or setting focus to text. */ -static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection) // don't bother to update font list if subsel changed +static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false) // don't bother to update font list if subsel changed { #ifdef DEBUG_TEXT static int count = 0; @@ -1170,11 +1082,12 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << "sp_text_toolbox_selection_changed: start " << count << std::endl; - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist0= selection->items(); - for(auto i=itemlist0.begin();i!=itemlist0.end(); ++i) { - const gchar* id = (*i)->getId(); + std::cout << " Selected items:" << std::endl; + for (GSList const *items = SP_ACTIVE_DESKTOP->getSelection()->itemList(); + items != NULL; + items = items->next) + { + const gchar* id = reinterpret_cast(items->data)->getId(); std::cout << " " << id << std::endl; } Glib::ustring selected_text = sp_text_get_selected_text((SP_ACTIVE_DESKTOP)->event_context); @@ -1216,7 +1129,8 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ gboolean isFlow = false; auto itemlist= SP_ACTIVE_DESKTOP->getSelection()->items(); for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - // std::cout << " " << ((*i)->getId()?(*i)->getId():"null") << std::endl; + // const gchar* id = reinterpret_cast(items->data)->getId(); + // std::cout << " " << id << std::endl; if( SP_IS_FLOWTEXT(*i)) { isFlow = true; // std::cout << " Found flowed text" << std::endl; @@ -1234,26 +1148,10 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ SPStyle query(SP_ACTIVE_DOCUMENT); int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); + int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); int result_wmode = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); - // Calling sp_desktop_query_style will result in a call to TextTool::_styleQueried(). - // This returns the style of the selected text inside the element... which - // is often the style of one or more s. If we want the style of the outer - // objects then we need to bypass the call to TextTool::_styleQueried(). - // The desktop selection never includes the elements inside the element. - int result_numbers = 0; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - bool outer = prefs->getInt("/tools/text/outer_style", false); - if (outer) { - Inkscape::Selection *selection = desktop->getSelection(); - std::vector vec(selection->items().begin(), selection->items().end()); - result_numbers = sp_desktop_query_style_from_list (vec, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - } else { - result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - } - /* * If no text in selection (querying returned nothing), read the style from * the /tools/text preferencess (default style for new texts). Return if @@ -1428,13 +1326,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } // Save unit so we can do convertions between new/old units. g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(line_height_unit)); - - // Enable and turn on only if selection includes an object with line height set. - InkToggleAction* lineHeightUnset = - INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextLineHeightUnsetAction")); - gtk_action_set_sensitive(GTK_ACTION(lineHeightUnset), query.line_height.set ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(lineHeightUnset), query.line_height.set ); - + // Word spacing double wordSpacing; if (query.word_spacing.normal) wordSpacing = 0.0; @@ -2129,32 +2021,6 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje g_object_set( G_OBJECT(eact), "iconId", "text_rotation", NULL ); } - /* Text line height unset */ - { - InkToggleAction* act = ink_toggle_action_new( "TextLineHeightUnsetAction", // Name - _("Unset line height"), // Label - _("If enabled, line height is set on part of selection. Click to unset."), - INKSCAPE_ICON("paint-unknown"), - secondarySize ); // Icon size - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_lineheight_unset_changed), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/line_height_unset", false) ); - g_object_set_data( holder, "TextLineHeightUnsetAction", act ); - } - - /* Text outer style */ - { - InkToggleAction* act = ink_toggle_action_new( "TextOuterStyleAction", // Name - _("Show outer style"), // Label - _("Show style of outermost text element. The 'font-size' and 'line-height' values of the outermost text element determine the minimum line spacing in the block."), - INKSCAPE_ICON("text_outer_style"), - secondarySize ); // Icon size - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_outer_style_changed), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/outer_style", false) ); - g_object_set_data( holder, "TextOuterStyleAction", act ); - } - // Is this necessary to call? Shouldn't hurt. sp_text_toolbox_selection_changed(desktop->getSelection(), holder); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index a3db3c33d..53de2d342 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -508,19 +508,18 @@ static gchar const * ui_descr = " " " " - " " - " " - " " " " - " " - " " - " " + " " +// " " +// " " " " " " " " " " " " " " + " " + " " " " " " " " -- cgit v1.2.3 From 57175b32ef6539d7249a0d28d302c174ba453275 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Fri, 16 Dec 2016 23:53:43 +0100 Subject: remove rollback to 15315 (bzr r15295.1.26) --- src/desktop-style.cpp | 11 +- src/file.cpp | 270 +++++++++++++++++++--- src/live_effects/lpe-angle_bisector.cpp | 8 +- src/live_effects/lpe-attach-path.cpp | 5 +- src/live_effects/lpe-bendpath.cpp | 3 +- src/live_effects/lpe-bounding-box.cpp | 6 +- src/live_effects/lpe-bspline.h | 2 +- src/live_effects/lpe-circle_3pts.cpp | 2 + src/live_effects/lpe-circle_with_radius.cpp | 2 + src/live_effects/lpe-clone-original.cpp | 5 +- src/live_effects/lpe-constructgrid.cpp | 4 +- src/live_effects/lpe-copy_rotate.cpp | 156 +++++-------- src/live_effects/lpe-copy_rotate.h | 14 +- src/live_effects/lpe-curvestitch.cpp | 5 +- src/live_effects/lpe-dynastroke.cpp | 2 + src/live_effects/lpe-ellipse_5pts.cpp | 5 +- src/live_effects/lpe-envelope.cpp | 2 + src/live_effects/lpe-extrude.cpp | 4 +- src/live_effects/lpe-fill-between-many.cpp | 2 +- src/live_effects/lpe-fill-between-strokes.cpp | 5 +- src/live_effects/lpe-fillet-chamfer.cpp | 2 +- src/live_effects/lpe-gears.cpp | 5 +- src/live_effects/lpe-interpolate.cpp | 6 +- src/live_effects/lpe-interpolate_points.cpp | 3 +- src/live_effects/lpe-jointype.cpp | 2 + src/live_effects/lpe-knot.cpp | 3 + src/live_effects/lpe-lattice.cpp | 3 +- src/live_effects/lpe-lattice2.cpp | 3 + src/live_effects/lpe-lattice2.h | 2 +- src/live_effects/lpe-line_segment.cpp | 2 + src/live_effects/lpe-mirror_symmetry.cpp | 314 +++++++++++++------------- src/live_effects/lpe-mirror_symmetry.h | 24 +- src/live_effects/lpe-offset.cpp | 5 +- src/live_effects/lpe-parallel.cpp | 5 +- src/live_effects/lpe-path_length.cpp | 4 +- src/live_effects/lpe-patternalongpath.cpp | 2 + src/live_effects/lpe-perp_bisector.cpp | 6 +- src/live_effects/lpe-perspective-envelope.cpp | 3 + src/live_effects/lpe-perspective_path.cpp | 5 +- src/live_effects/lpe-powerstroke.cpp | 3 + src/live_effects/lpe-recursiveskeleton.cpp | 5 +- src/live_effects/lpe-rough-hatches.cpp | 3 +- src/live_effects/lpe-roughen.cpp | 3 + src/live_effects/lpe-roughen.h | 1 - src/live_effects/lpe-ruler.cpp | 3 +- src/live_effects/lpe-show_handles.cpp | 2 + src/live_effects/lpe-show_handles.h | 1 - src/live_effects/lpe-simplify.cpp | 2 + src/live_effects/lpe-simplify.h | 1 - src/live_effects/lpe-skeleton.cpp | 3 +- src/live_effects/lpe-sketch.cpp | 5 +- src/live_effects/lpe-tangent_to_curve.cpp | 4 +- src/live_effects/lpe-taperstroke.cpp | 2 + src/live_effects/lpe-test-doEffect-stack.cpp | 5 +- src/live_effects/lpe-text_label.cpp | 5 +- src/live_effects/lpe-transform_2pts.cpp | 1 + src/live_effects/lpe-vonkoch.cpp | 2 +- src/live_effects/parameter/fontbutton.cpp | 2 +- src/live_effects/parameter/fontbutton.h | 1 - src/preferences-skeleton.h | 5 +- src/sp-item-group.cpp | 5 +- src/sp-lpe-item.cpp | 6 +- src/sp-lpe-item.h | 2 +- src/sp-mesh-array.cpp | 10 +- src/ui/tools/tweak-tool.cpp | 3 +- src/widgets/mesh-toolbar.cpp | 165 ++++++-------- src/widgets/text-toolbar.cpp | 166 ++++++++++++-- src/widgets/toolbox.cpp | 11 +- 68 files changed, 816 insertions(+), 523 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 65e511245..4c07c76ea 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -209,7 +209,7 @@ sp_desktop_set_style(Inkscape::ObjectSet *set, SPDesktop *desktop, SPCSSAttr *cs if (!change) return; -// 2. Emit signal +// 2. Emit signal... See desktop->connectSetStyle in text-tool, tweak-tool, and gradient-drag. bool intercepted = desktop->_set_style_signal.emit(css); /** \todo @@ -1045,6 +1045,7 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r bool lineheight_normal = false; bool lineheight_unit_proportional = false; bool lineheight_unit_absolute = false; + bool lineheight_set = false; // Set true if any object has lineheight set. double size_prev = 0; double letterspacing_prev = 0; @@ -1130,6 +1131,9 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r lineheight_normal = false; lineheight += lineheight_current * doc_scale; } + if (style->line_height.set) { + lineheight_set = true; + } if ((size_prev != 0 && style->font_size.computed != size_prev) || (letterspacing_prev != 0 && style->letter_spacing.computed != letterspacing_prev) || @@ -1205,6 +1209,9 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r } } + // Used by text toolbar unset 'line-height' + style_res->line_height.set = lineheight_set; + if (texts > 1) { if (different || different_lineheight) { return QUERY_STYLE_MULTIPLE_AVERAGED; @@ -1907,7 +1914,7 @@ sp_desktop_query_style_from_list (const std::vector &list, SPStyle *sty int sp_desktop_query_style(SPDesktop *desktop, SPStyle *style, int property) { - // Used by text tool and in gradient dragging + // Used by text tool and in gradient dragging. See connectQueryStyle. int ret = desktop->_query_style_signal.emit(style, property); if (ret != QUERY_STYLE_NOTHING) diff --git a/src/file.cpp b/src/file.cpp index 55089209a..8f283e1f8 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -66,6 +66,10 @@ // For updating old Inkscape SVG files #include "display/canvas-grid.h" #include "sp-guide.h" +#include "selection-chemistry.h" +#include "persp3d.h" +#include "proj_pt.h" +#include "ui/shape-editor.h" #include @@ -353,11 +357,13 @@ bool sp_file_open(const Glib::ustring &uri, bool need_fix_units = false; bool need_fix_guides = false; bool need_fix_grid_mm = false; - bool is_extension = false; + bool need_fix_box3d = false; + bool did_scaling = false; // Check if potentially need viewbox or unit fix switch (root->width.unit) { case SP_CSS_UNIT_PC: + case SP_CSS_UNIT_PT: case SP_CSS_UNIT_MM: case SP_CSS_UNIT_CM: case SP_CSS_UNIT_IN: @@ -366,13 +372,19 @@ bool sp_file_open(const Glib::ustring &uri, case SP_CSS_UNIT_NONE: case SP_CSS_UNIT_PX: need_fix_units = true; - default: break; + case SP_CSS_UNIT_EM: + case SP_CSS_UNIT_EX: + case SP_CSS_UNIT_PERCENT: // OK + break; + default: + std::cerr << "sp_file_open: Unhandled width unit!" << std::endl; } switch (root->height.unit) { case SP_CSS_UNIT_PC: + case SP_CSS_UNIT_PT: case SP_CSS_UNIT_MM: case SP_CSS_UNIT_CM: case SP_CSS_UNIT_IN: @@ -381,14 +393,21 @@ bool sp_file_open(const Glib::ustring &uri, case SP_CSS_UNIT_NONE: case SP_CSS_UNIT_PX: need_fix_units = true; - default: break; + case SP_CSS_UNIT_EM: + case SP_CSS_UNIT_EX: + case SP_CSS_UNIT_PERCENT: // OK + break; + default: + std::cerr << "sp_file_open: Unhandled height unit!" << std::endl; } // std::cout << "Absolute SVG units in root? " << (need_fix_viewbox?"true":"false") << std::endl; // std::cout << "User units in root? " << (need_fix_units ?"true":"false") << std::endl; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (!root->viewBox_set && need_fix_viewbox) { Glib::ustring msg = _( @@ -401,31 +420,37 @@ bool sp_file_open(const Glib::ustring &uri, Gtk::Label info; info.set_markup(msg.c_str()); info.show(); - scaleDialog.get_content_area()->pack_start(info, false, false, 20); + Gtk::CheckButton backupButton( _("Create backup file (in same directory).") ); - backupButton.set_active(); + bool backup = prefs->getBool("/options/dpifixbackup", true); + backupButton.set_active( backup ); backupButton.show(); - scaleDialog.get_content_area()->pack_start(backupButton, false, false, 20); - scaleDialog.add_button("Set 'viewBox'", 1); - scaleDialog.add_button("Scale elements", 2); - scaleDialog.add_button("Ignore", 3); + + scaleDialog.add_button(_("Set 'viewBox'"), 1); + scaleDialog.add_button(_("Scale elements"), 2); + scaleDialog.add_button(_("Ignore"), 3); + scaleDialog.add_button("Scale test - group", 4); + scaleDialog.add_button("Scale test - children", 5); gint response = scaleDialog.run(); - bool backup = backupButton.get_active(); + backup = backupButton.get_active(); + prefs->setBool("/options/dpifixbackup", backup); + + if ( backup && response != 3) { + sp_file_save_backup( uri ); + } + if (response == 1) { - if (backup) { - sp_file_save_backup( uri ); - } + doc->setViewBox(Geom::Rect::from_xywh( 0, 0, doc->getWidth().value("px") * ratio, doc->getHeight().value("px") * ratio)); + } else if (response == 2 ) { - if (backup) { - sp_file_save_backup( uri ); - } + std::list effects; Inkscape::Extension::db.get_effect_list(effects); std::list::iterator it = effects.begin(); @@ -442,12 +467,65 @@ bool sp_file_open(const Glib::ustring &uri, if (!did) { std::cerr << "sp_file_open: Failed to find dpi90to96 extension." << std::endl; } - is_extension = true; + did_scaling = true; + + } else if (response == 4) { + + // Save preferences + bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true); + bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); + + prefs->setBool("/options/kbselection/onlysensitive", false); + prefs->setBool("/options/kbselection/onlyvisible", false); + + Inkscape::Selection *selection = desktop->getSelection(); + Inkscape::SelectionHelper::selectAllInAll( desktop ); + selection->group(); + SPItem * group = selection->singleItem(); + if (group) { + group->setAttribute("transform","scale(1.06666667,1.06666667)"); + } else { + std::cerr << "sp_file_open: Failed to get group!" << std::endl; + } + selection->clear(); + selection->add( group ); + selection->ungroup(); + selection->clear(); + + prefs->setBool("/options/kbselection/onlysensitive", onlysensitive); + prefs->setBool("/options/kbselection/onlyvisible", onlyvisible ); + + did_scaling = true; + + } else if (response == 5) { + + // Save preferences + bool transform_stroke = prefs->getBool("/options/transform/stroke", true); + bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true); + bool transform_pattern = prefs->getBool("/options/transform/pattern", true); + bool transform_gradient = prefs->getBool("/options/transform/gradient", true); + + prefs->setBool("/options/transform/stroke", true); + prefs->setBool("/options/transform/rectcorners", true); + prefs->setBool("/options/transform/pattern", true); + prefs->setBool("/options/transform/gradient", true); + + Inkscape::UI::ShapeEditor::blockSetItem(true); + doc->getRoot()->scaleChildItemsRec(Geom::Scale(1/ratio),Geom::Point(0, 0), false); + Inkscape::UI::ShapeEditor::blockSetItem(false); + + // Restore preferences + prefs->setBool("/options/transform/stroke", transform_stroke); + prefs->setBool("/options/transform/rectcorners", transform_rectcorners); + prefs->setBool("/options/transform/pattern", transform_pattern); + prefs->setBool("/options/transform/gradient", transform_gradient); } + + need_fix_box3d = true; need_fix_guides = true; // Always fix guides } - if (need_fix_units) { + else if (need_fix_units) { Glib::ustring msg = ( "Old Inkscape files use 1in == 90px. CSS requires 1in == 96px.\n" "Drawings meant to match a physical size (e.g. Letter or A4)\n" @@ -462,19 +540,27 @@ bool sp_file_open(const Glib::ustring &uri, scaleDialog.get_content_area()->pack_start(info, false, false, 20); Gtk::CheckButton backupButton( _("Create backup file (in same directory).") ); - scaleDialog.get_content_area()->pack_start(backupButton, false, false, 20); + bool backup = prefs->getBool("/options/dpifixbackup", true); + backupButton.set_active( backup ); backupButton.show(); + scaleDialog.get_content_area()->pack_start(backupButton, false, false, 20); - scaleDialog.add_button("Set 'viewBox'", 1); - scaleDialog.add_button("Scale elements", 2); - scaleDialog.add_button("Ignore", 3); + scaleDialog.add_button(_("Set 'viewBox'"), 1); + scaleDialog.add_button(_("Scale elements"), 2); + scaleDialog.add_button(_("Ignore"), 3); + scaleDialog.add_button("Scale test - group", 4); + scaleDialog.add_button("Scale test - children", 5); gint response = scaleDialog.run(); - bool backup = backupButton.get_active(); + backup = backupButton.get_active(); + prefs->setBool("/options/dpifixbackup", backup); + + if ( backup && response != 3) { + sp_file_save_backup( uri ); + } + if (response == 1) { - if (backup) { - sp_file_save_backup( uri ); - } + if (!root->viewBox_set) { doc->setViewBox(Geom::Rect::from_xywh( 0, 0, @@ -488,10 +574,10 @@ bool sp_file_open(const Glib::ustring &uri, doc->setWidthAndHeight( width, height, false ); need_fix_guides = true; // Only fix guides if drawing scaled + need_fix_box3d = true; + } else if (response == 2) { - if (backup) { - sp_file_save_backup( uri ); - } + std::list effects; Inkscape::Extension::db.get_effect_list(effects); std::list::iterator it = effects.begin(); @@ -509,14 +595,94 @@ bool sp_file_open(const Glib::ustring &uri, std::cerr << "sp_file_open: Failed to find dpi90to96 extension." << std::endl; } need_fix_guides = true; // Only fix guides if drawing scaled - is_extension = true; + did_scaling = true; + + } else if (response == 4) { + + Inkscape::Util::Quantity width = + Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" ); + Inkscape::Util::Quantity height = + Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" ); + doc->setWidthAndHeight( width, height, false ); + + if (!root->viewBox_set) { + + // Save preferences + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true); + bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); + + prefs->setBool("/options/kbselection/onlysensitive", false); + prefs->setBool("/options/kbselection/onlyvisible", false); + + Inkscape::Selection *selection = desktop->getSelection(); + Inkscape::SelectionHelper::selectAllInAll( desktop ); + selection->group(); + SPItem * group = selection->singleItem(); + if (group) { + group->setAttribute("transform","scale(1.06666667,1.06666667)"); + } else { + std::cerr << "sp_file_open: Failed to get group!" << std::endl; + } + selection->clear(); + selection->add( group ); + selection->ungroup(); + selection->clear(); + + prefs->setBool("/options/kbselection/onlysensitive", onlysensitive); + prefs->setBool("/options/kbselection/onlyvisible", onlyvisible ); + + did_scaling = true; + } + + need_fix_box3d = true; + need_fix_guides = true; // Only fix guides if drawing scaled + + } else if (response == 5) { + + Inkscape::Util::Quantity width = + Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" ); + Inkscape::Util::Quantity height = + Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" ); + doc->setWidthAndHeight( width, height, false ); + + if (!root->viewBox_set) { + + // Save preferences + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool transform_stroke = prefs->getBool("/options/transform/stroke", true); + bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true); + bool transform_pattern = prefs->getBool("/options/transform/pattern", true); + bool transform_gradient = prefs->getBool("/options/transform/gradient", true); + + prefs->setBool("/options/transform/stroke", true); + prefs->setBool("/options/transform/rectcorners", true); + prefs->setBool("/options/transform/pattern", true); + prefs->setBool("/options/transform/gradient", true); + + Inkscape::UI::ShapeEditor::blockSetItem(true); + doc->getRoot()->scaleChildItemsRec(Geom::Scale(1/ratio),Geom::Point(0, 0), false); + Inkscape::UI::ShapeEditor::blockSetItem(false); + + // Restore preferences + prefs->setBool("/options/transform/stroke", transform_stroke); + prefs->setBool("/options/transform/rectcorners", transform_rectcorners); + prefs->setBool("/options/transform/pattern", transform_pattern); + prefs->setBool("/options/transform/gradient", transform_gradient); + + did_scaling = true; + } + + need_fix_box3d = true; + need_fix_guides = true; // Only fix guides if drawing scaled + } else { // Ignore need_fix_grid_mm = true; } } - // Fix guides and grids + // Fix guides and grids and perspective for (SPObject *child = root->firstChild() ; child; child = child->getNext() ) { SPNamedView *nv = dynamic_cast(child); if (nv) { @@ -555,21 +721,53 @@ bool sp_file_open(const Glib::ustring &uri, } } else { if (need_fix_guides) { - // HACK: Scaling the document does not seem to cause - // grids defined in document units to be updated. - // This forces an update. - if(is_extension){ + if(did_scaling){ xy->Scale( Geom::Scale(ratio,ratio).inverse() ); } else { + // HACK: Scaling the document does not seem to cause + // grids defined in document units to be updated. + // This forces an update. xy->Scale( Geom::Scale(1,1) ); } } } } } + } // If SPNamedView + + SPDefs *defs = dynamic_cast(child); + if (defs && need_fix_box3d) { + for (SPObject *child = defs->firstChild() ; child; child = child->getNext() ) { + Persp3D* persp3d = dynamic_cast(child); + if (persp3d) { + std::vector tokens; + + const gchar* vp_x = persp3d->getAttribute("inkscape:vp_x"); + const gchar* vp_y = persp3d->getAttribute("inkscape:vp_y"); + const gchar* vp_z = persp3d->getAttribute("inkscape:vp_z"); + const gchar* vp_o = persp3d->getAttribute("inkscape:persp3d-origin"); + // std::cout << "Found Persp3d: " + // << " vp_x: " << vp_x + // << " vp_y: " << vp_y + // << " vp_z: " << vp_z << std::endl; + Proj::Pt2 pt_x (vp_x); + Proj::Pt2 pt_y (vp_y); + Proj::Pt2 pt_z (vp_z); + Proj::Pt2 pt_o (vp_o); + pt_x = pt_x * (1.0/ratio); + pt_y = pt_y * (1.0/ratio); + pt_z = pt_z * (1.0/ratio); + pt_o = pt_o * (1.0/ratio); + persp3d->setAttribute("inkscape:vp_x",pt_x.coord_string()); + persp3d->setAttribute("inkscape:vp_y",pt_y.coord_string()); + persp3d->setAttribute("inkscape:vp_z",pt_z.coord_string()); + persp3d->setAttribute("inkscape:persp3d-origin",pt_o.coord_string()); + } + } } - } // Look for SPNamedView loop + } // Look for SPNamedView and SPDefs loop + // desktop->getDocument()->ensureUpToDate(); // Does not update box3d! DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Update Document")); } // If old Inkscape version diff --git a/src/live_effects/lpe-angle_bisector.cpp b/src/live_effects/lpe-angle_bisector.cpp index 9bfbf4ca8..56d33eb4b 100644 --- a/src/live_effects/lpe-angle_bisector.cpp +++ b/src/live_effects/lpe-angle_bisector.cpp @@ -8,15 +8,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-angle_bisector.h" - -#include <2geom/sbasis-to-bezier.h> - +#include "2geom/sbasis-to-bezier.h" #include "sp-lpe-item.h" #include "knot-holder-entity.h" #include "knotholder.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-attach-path.cpp b/src/live_effects/lpe-attach-path.cpp index d2b44dd4e..302165719 100644 --- a/src/live_effects/lpe-attach-path.cpp +++ b/src/live_effects/lpe-attach-path.cpp @@ -4,15 +4,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include - #include "live_effects/lpe-attach-path.h" - #include "display/curve.h" #include "sp-shape.h" #include "sp-text.h" #include "2geom/path-sink.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index c24d38d7b..b1e133292 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -7,9 +7,10 @@ #include "live_effects/lpe-bendpath.h" #include "sp-item-group.h" - #include "knot-holder-entity.h" #include "knotholder.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include using std::vector; diff --git a/src/live_effects/lpe-bounding-box.cpp b/src/live_effects/lpe-bounding-box.cpp index 2de768c3a..11fb34e04 100644 --- a/src/live_effects/lpe-bounding-box.cpp +++ b/src/live_effects/lpe-bounding-box.cpp @@ -3,14 +3,14 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - -#include - #include "live_effects/lpe-bounding-box.h" #include "display/curve.h" #include "sp-shape.h" #include "sp-text.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 7823f00f0..90cf82c19 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -6,8 +6,8 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "live_effects/effect.h" +#include "live_effects/effect.h" #include namespace Inkscape { diff --git a/src/live_effects/lpe-circle_3pts.cpp b/src/live_effects/lpe-circle_3pts.cpp index 18252f6a0..3410b13f2 100644 --- a/src/live_effects/lpe-circle_3pts.cpp +++ b/src/live_effects/lpe-circle_3pts.cpp @@ -17,6 +17,8 @@ // You might need to include other 2geom files. You can add them here: #include <2geom/circle.h> #include <2geom/path-sink.h> +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-circle_with_radius.cpp b/src/live_effects/lpe-circle_with_radius.cpp index 6e03cb1ce..fcefc4ec6 100644 --- a/src/live_effects/lpe-circle_with_radius.cpp +++ b/src/live_effects/lpe-circle_with_radius.cpp @@ -17,6 +17,8 @@ // You might need to include other 2geom files. You can add them here: #include <2geom/circle.h> #include <2geom/path-sink.h> +// TODO due to internal breakage in glibmm headers, this must be last: +#include using namespace Geom; diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 7541c0be2..10418a02d 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -4,11 +4,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-clone-original.h" - #include "display/curve.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-constructgrid.cpp b/src/live_effects/lpe-constructgrid.cpp index 4af8891e8..8d24f9f47 100644 --- a/src/live_effects/lpe-constructgrid.cpp +++ b/src/live_effects/lpe-constructgrid.cpp @@ -10,9 +10,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-constructgrid.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 1133e083a..5b94e9083 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -11,36 +11,17 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include #include <2geom/path-intersection.h> #include <2geom/sbasis-to-bezier.h> #include "live_effects/lpe-copy_rotate.h" - -#include "knotholder.h" // TODO due to internal breakage in glibmm headers, this must be last: #include namespace Inkscape { namespace LivePathEffect { -namespace CR { - -class KnotHolderEntityStartingAngle : public LPEKnotHolderEntity { -public: - KnotHolderEntityStartingAngle(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; -}; - -class KnotHolderEntityRotationAngle : public LPEKnotHolderEntity { -public: - KnotHolderEntityRotationAngle(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; -}; - -} // namespace CR - bool pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const &p2, Geom::Point const &p3) { @@ -59,6 +40,7 @@ pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const & LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this), + starting_point("hidden", "hidden", "starting_point", &wr, this), starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 60.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 6), @@ -74,6 +56,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : registerParameter(&copies_to_360); registerParameter(&fuse_paths); registerParameter(&starting_angle); + registerParameter(&starting_point); registerParameter(&rotation_angle); registerParameter(&num_copies); registerParameter(&origin); @@ -87,6 +70,41 @@ LPECopyRotate::~LPECopyRotate() } +Gtk::Widget * LPECopyRotate::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + if (param->param_key != "starting_point") { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + } + + ++it; + } + return dynamic_cast(vbox); +} + + void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { @@ -104,11 +122,6 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { - if(fuse_paths) { - Geom::Coord angle = Geom::deg_from_rad(atan(-postmul[1]/postmul[0])); - angle += starting_angle; - starting_angle.param_set_value(angle); - } // cycle through all parameters. Most parameters will not need transformation, but path and point params do. for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { @@ -146,11 +159,25 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) dir = unit_vector(B - A); // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) + bool near = Geom::are_near(previous_start_point, (Geom::Point)starting_point, 0.01); + if (!near) { + starting_angle.param_set_value(deg_from_rad(-angle_between(dir, starting_point - origin))); + if (GDK_SHIFT_MASK) { + dist_angle_handle = L2(B - A); + } else { + dist_angle_handle = L2(starting_point - origin); + } + } start_pos = origin + dir * Rotate(-rad_from_deg(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle; + if (near) { + starting_point.param_setValue(start_pos); + } + previous_start_point = (Geom::Point)starting_point; if ( fuse_paths || copies_to_360 ) { rot_pos = origin; } + SPLPEItem * item = const_cast(lpeitem); item->apply_to_clippath(item); item->apply_to_mask(item); @@ -418,85 +445,6 @@ LPECopyRotate::resetDefaults(SPItem const* item) original_bbox(SP_LPE_ITEM(item)); } -void -LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) -{ - { - KnotHolderEntity *e = new CR::KnotHolderEntityStartingAngle(this); - e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the starting angle")); - knotholder->add(e); - } - { - KnotHolderEntity *e = new CR::KnotHolderEntityRotationAngle(this); - e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the rotation angle")); - knotholder->add(e); - } -}; - -namespace CR { - -using namespace Geom; - -void -KnotHolderEntityStartingAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) -{ - LPECopyRotate* lpe = dynamic_cast(_effect); - - Geom::Point const s = snap_knot_position(p, state); - - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - lpe->starting_angle.param_set_value(deg_from_rad(-angle_between(lpe->dir, s - lpe->origin))); - if (state & GDK_SHIFT_MASK) { - lpe->dist_angle_handle = L2(lpe->B - lpe->A); - } else { - lpe->dist_angle_handle = L2(p - lpe->origin); - } - - // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. - sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); -} - -void -KnotHolderEntityRotationAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) -{ - LPECopyRotate* lpe = dynamic_cast(_effect); - - Geom::Point const s = snap_knot_position(p, state); - - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - lpe->rotation_angle.param_set_value(deg_from_rad(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); - if (state & GDK_SHIFT_MASK) { - lpe->dist_angle_handle = L2(lpe->B - lpe->A); - } else { - lpe->dist_angle_handle = L2(p - lpe->origin); - } - - // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. - sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); -} - -Geom::Point -KnotHolderEntityStartingAngle::knot_get() const -{ - LPECopyRotate const *lpe = dynamic_cast(_effect); - return lpe->start_pos; -} - -Geom::Point -KnotHolderEntityRotationAngle::knot_get() const -{ - LPECopyRotate const *lpe = dynamic_cast(_effect); - return lpe->rot_pos; -} - -} // namespace CR - -/* ######################## */ - } //namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 87af867df..8f9fc12ac 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -21,12 +21,6 @@ namespace Inkscape { namespace LivePathEffect { -namespace CR { -// we need a separate namespace to avoid clashes with LPEPerpBisector -class KnotHolderEntityStartingAngle; -class KnotHolderEntityRotationAngle; -} - class LPECopyRotate : public Effect, GroupBBoxEffect { public: LPECopyRotate(LivePathEffectObject *lpeobject); @@ -38,16 +32,13 @@ public: virtual void split(Geom::PathVector &path_in, Geom::Path const ÷r); virtual void resetDefaults(SPItem const* item); virtual void transform_multiply(Geom::Affine const& postmul, bool set); - /* the knotholder entity classes must be declared friends */ - friend class CR::KnotHolderEntityStartingAngle; - friend class CR::KnotHolderEntityRotationAngle; - void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); - + virtual Gtk::Widget * newWidget(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: PointParam origin; + PointParam starting_point; ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; @@ -58,6 +49,7 @@ private: Geom::Point dir; Geom::Point start_pos; Geom::Point rot_pos; + Geom::Point previous_start_point; double dist_angle_handle; LPECopyRotate(const LPECopyRotate&); LPECopyRotate& operator=(const LPECopyRotate&); diff --git a/src/live_effects/lpe-curvestitch.cpp b/src/live_effects/lpe-curvestitch.cpp index 3beedaf57..38cbeaac0 100644 --- a/src/live_effects/lpe-curvestitch.cpp +++ b/src/live_effects/lpe-curvestitch.cpp @@ -13,8 +13,6 @@ */ #include "ui/widget/scalar.h" -#include - #include "live_effects/lpe-curvestitch.h" #include "sp-path.h" @@ -22,6 +20,9 @@ #include "xml/repr.h" #include <2geom/bezier-to-sbasis.h> +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-dynastroke.cpp b/src/live_effects/lpe-dynastroke.cpp index 7e22f6e51..50bbe6451 100644 --- a/src/live_effects/lpe-dynastroke.cpp +++ b/src/live_effects/lpe-dynastroke.cpp @@ -16,6 +16,8 @@ #include <2geom/bezier-to-sbasis.h> #include <2geom/sbasis-math.h> +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-ellipse_5pts.cpp b/src/live_effects/lpe-ellipse_5pts.cpp index 0371fc313..28e7058d7 100644 --- a/src/live_effects/lpe-ellipse_5pts.cpp +++ b/src/live_effects/lpe-ellipse_5pts.cpp @@ -12,15 +12,14 @@ */ #include "live_effects/lpe-ellipse_5pts.h" - -// You might need to include other 2geom files. You can add them here: -#include #include <2geom/circle.h> #include <2geom/ellipse.h> #include <2geom/path-sink.h> #include "inkscape.h" #include "desktop.h" #include "message-stack.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-envelope.cpp b/src/live_effects/lpe-envelope.cpp index c3b0a7c10..61a696435 100644 --- a/src/live_effects/lpe-envelope.cpp +++ b/src/live_effects/lpe-envelope.cpp @@ -6,6 +6,8 @@ #include "live_effects/lpe-envelope.h" #include "display/curve.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include using std::vector; diff --git a/src/live_effects/lpe-extrude.cpp b/src/live_effects/lpe-extrude.cpp index d22007f76..daa30d45a 100644 --- a/src/live_effects/lpe-extrude.cpp +++ b/src/live_effects/lpe-extrude.cpp @@ -12,10 +12,10 @@ */ #include "live_effects/lpe-extrude.h" - +#include "sp-item.h" +// TODO due to internal breakage in glibmm headers, this must be last: #include -#include "sp-item.h" namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-fill-between-many.cpp b/src/live_effects/lpe-fill-between-many.cpp index 2087925fa..1e2eadfdb 100644 --- a/src/live_effects/lpe-fill-between-many.cpp +++ b/src/live_effects/lpe-fill-between-many.cpp @@ -11,7 +11,7 @@ #include "display/curve.h" #include "sp-shape.h" #include "sp-text.h" - +// TODO due to internal breakage in glibmm headers, this must be last: #include namespace Inkscape { diff --git a/src/live_effects/lpe-fill-between-strokes.cpp b/src/live_effects/lpe-fill-between-strokes.cpp index b1e328d18..0dbebdf26 100644 --- a/src/live_effects/lpe-fill-between-strokes.cpp +++ b/src/live_effects/lpe-fill-between-strokes.cpp @@ -3,14 +3,13 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - -#include - #include "live_effects/lpe-fill-between-strokes.h" #include "display/curve.h" #include "sp-shape.h" #include "sp-text.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 24ee2ccc3..1e2df7dc8 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -25,8 +25,8 @@ // for programmatically updating knots #include "ui/tools-switch.h" - // TODO due to internal breakage in glibmm headers, this must be last: +#include using namespace Geom; namespace Inkscape { diff --git a/src/live_effects/lpe-gears.cpp b/src/live_effects/lpe-gears.cpp index 1d5398aa5..17579c64e 100644 --- a/src/live_effects/lpe-gears.cpp +++ b/src/live_effects/lpe-gears.cpp @@ -7,10 +7,9 @@ */ #include "live_effects/lpe-gears.h" - -#include - #include <2geom/bezier-to-sbasis.h> +// TODO due to internal breakage in glibmm headers, this must be last: +#include using std::vector; using namespace Geom; diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp index 43da4d105..e95dc5f38 100644 --- a/src/live_effects/lpe-interpolate.cpp +++ b/src/live_effects/lpe-interpolate.cpp @@ -9,15 +9,15 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - -#include - #include "live_effects/lpe-interpolate.h" #include <2geom/sbasis-to-bezier.h> #include "sp-path.h" #include "display/curve.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-interpolate_points.cpp b/src/live_effects/lpe-interpolate_points.cpp index ab0576174..0a0bcea14 100644 --- a/src/live_effects/lpe-interpolate_points.cpp +++ b/src/live_effects/lpe-interpolate_points.cpp @@ -12,8 +12,9 @@ */ #include "live_effects/lpe-interpolate_points.h" - #include "live_effects/lpe-powerstroke-interpolators.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp index 3bfbd6288..dacb87dd9 100644 --- a/src/live_effects/lpe-jointype.cpp +++ b/src/live_effects/lpe-jointype.cpp @@ -19,6 +19,8 @@ #include <2geom/elliptical-arc.h> #include "lpe-jointype.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index 474523aa3..c35da0601 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -33,6 +33,9 @@ #include "document.h" #include "document-undo.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-lattice.cpp b/src/live_effects/lpe-lattice.cpp index 091b6ddca..acffed000 100644 --- a/src/live_effects/lpe-lattice.cpp +++ b/src/live_effects/lpe-lattice.cpp @@ -20,7 +20,8 @@ #include <2geom/sbasis-2d.h> #include <2geom/bezier-to-sbasis.h> - +// TODO due to internal breakage in glibmm headers, this must be last: +#include using namespace Geom; namespace Inkscape { diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index 9e9fc153a..e827491c0 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -16,12 +16,15 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include "live_effects/lpe-lattice2.h" #include "display/curve.h" #include "helper/geom.h" #include <2geom/sbasis-2d.h> #include <2geom/bezier-to-sbasis.h> + // TODO due to internal breakage in glibmm headers, this must be last: +#include using namespace Geom; diff --git a/src/live_effects/lpe-lattice2.h b/src/live_effects/lpe-lattice2.h index 4a025d182..59a0350d3 100644 --- a/src/live_effects/lpe-lattice2.h +++ b/src/live_effects/lpe-lattice2.h @@ -18,7 +18,7 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ -#include + #include "live_effects/effect.h" #include "live_effects/parameter/enum.h" #include "live_effects/parameter/point.h" diff --git a/src/live_effects/lpe-line_segment.cpp b/src/live_effects/lpe-line_segment.cpp index 4c9edabd4..cc024fb92 100644 --- a/src/live_effects/lpe-line_segment.cpp +++ b/src/live_effects/lpe-line_segment.cpp @@ -13,6 +13,8 @@ #include "live_effects/lpe-line_segment.h" #include "ui/tools/lpe-tool.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 11620b23f..f34421df2 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -13,6 +13,10 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ + +#include +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" #include "live_effects/lpe-mirror_symmetry.h" #include "display/curve.h" #include "svg/path-string.h" @@ -27,6 +31,7 @@ #include "knotholder.h" #include "style.h" #include "xml/sp-css-attr.h" + // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -43,17 +48,6 @@ static const Util::EnumData ModeTypeData[MT_END] = { static const Util::EnumDataConverter MTConverter(ModeTypeData, MT_END); -namespace MS { - -class KnotHolderEntityCenterMirrorSymmetry : public LPEKnotHolderEntity { -public: - KnotHolderEntityCenterMirrorSymmetry(LPEMirrorSymmetry *effect) : LPEKnotHolderEntity(effect){}; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; -}; - -} // namespace MS - LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), @@ -61,27 +55,26 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : discard_orig_path(_("Discard original path?"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), - split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split_elements", &wr, this, false), - start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, "Adjust the start of mirroring"), - end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring"), - id_origin("id_origin", "id_origin", "id_origin", &wr, this,"") + split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints. Group result to apply nested"), "split_elements", &wr, this, false), + start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust the start of mirroring")), + end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), + center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) { show_orig_path = true; registerParameter(&mode); - registerParameter( &split_gap); - registerParameter( &discard_orig_path); - registerParameter( &fuse_paths); - registerParameter( &oposite_fuse); - registerParameter( &split_elements); - registerParameter( &start_point); - registerParameter( &end_point); - registerParameter( &id_origin); - id_origin.param_hide_canvas_text(); + registerParameter(&split_gap); + registerParameter(&discard_orig_path); + registerParameter(&fuse_paths); + registerParameter(&oposite_fuse); + registerParameter(&split_elements); + registerParameter(&start_point); + registerParameter(&end_point); + registerParameter(¢er_point); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); split_gap.param_set_digits(2); apply_to_clippath_and_mask = true; - actual = true; + previous_center = Geom::Point(0,0); } LPEMirrorSymmetry::~LPEMirrorSymmetry() @@ -94,11 +87,10 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) SPLPEItem * splpeitem = const_cast(lpeitem); if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { Inkscape::Selection *sel = desktop->getSelection(); - if ( sel && !sel->isEmpty() && actual) { + if ( sel && !sel->isEmpty()) { SPItem *item = sel->singleItem(); if (item) { if(std::strcmp(splpeitem->getId(),item->getId()) != 0) { - actual = false; return; } } @@ -117,11 +109,14 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) point_a = Geom::Point(center_point[X],boundingbox_Y.min()); point_b = Geom::Point(center_point[X],boundingbox_Y.max()); } + if (Geom::are_near((Geom::Point)start_point, (Geom::Point)end_point, 0.01)) { + start_point.param_setValue(point_a); + end_point.param_setValue(point_b); + } line_separation.setPoints(point_a, point_b); if ( mode == MT_X || mode == MT_Y ) { start_point.param_setValue(point_a); end_point.param_setValue(point_b); - center_point = Geom::middle_point(point_a, point_b); } else if ( mode == MT_FREE) { if(!are_near(previous_center,center_point, 0.01)) { Geom::Point trans = center_point - previous_center; @@ -129,7 +124,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) end_point.param_setValue(end_point * trans); line_separation.setPoints(start_point, end_point); } else { - center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); line_separation.setPoints(start_point, end_point); } } else if ( mode == MT_V){ @@ -142,7 +136,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point ep = Geom::Point(view_box_rect.width()/2.0, view_box_rect.height()); ep *= i2anc_affine(SP_OBJECT(lpeitem), SP_OBJECT(SP_ACTIVE_DESKTOP->currentLayer()->parent)) .inverse(); end_point.param_setValue(ep); - center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); line_separation.setPoints(start_point, end_point); } } else { //horizontal page @@ -155,53 +148,56 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point ep = Geom::Point(view_box_rect.width(), view_box_rect.height()/2.0); ep *= i2anc_affine(SP_OBJECT(lpeitem), SP_OBJECT(SP_ACTIVE_DESKTOP->currentLayer()->parent)) .inverse(); end_point.param_setValue(ep); - center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); line_separation.setPoints(start_point, end_point); } } - previous_center = center_point; - if (split_elements) { - ms_container = dynamic_cast(splpeitem->parent); + + previous_center = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); + if (!are_near(previous_center, center_point,0.01)) { + center_point.param_setValue(previous_center); + } + if (split_elements && allow_split()) { + container = dynamic_cast(splpeitem->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node *root = splpeitem->document->getReprRoot(); Inkscape::XML::Node *root_origin = doc->getReprRoot(); if (root_origin != root) { return; } - Geom::Point point_a(line_separation.initialPoint()); - Geom::Point point_b(line_separation.finalPoint()); - Geom::Point gap(split_gap,0); - Geom::Translate m1(point_a[0], point_a[1]); - double hyp = Geom::distance(point_a, point_b); - double cos = 0; - double sin = 0; - if (hyp > 0) { - cos = (point_b[0] - point_a[0]) / hyp; - sin = (point_b[1] - point_a[1]) / hyp; - } - Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); - Geom::Point dir = unit_vector(point_b - point_a); - Geom::Point offset = (point_a + point_b)/2 + dir.ccw() * split_gap; - line_separation *= Geom::Translate(offset); - Geom::Scale sca(1.0, -1.0); - const char * id_original = id_origin.param_getSVGValue(); - const char * id = g_strdup(Glib::ustring("mirror-").append(id_original).append("-").append(this->getRepr()->attribute("id")).c_str()); - m = m1.inverse() * m2; - m = m * sca; - m = m * m2.inverse(); - m = m * m1; - m = m * lpeitem->transform; - if (std::strcmp(splpeitem->getId(), id) == 0) { - createMirror(splpeitem, m, id_original); - } else { - createMirror(splpeitem, m, id); - } - elements.clear(); - elements.push_back(id); - elements.push_back(id_original); + const char * mirror = g_strdup(Glib::ustring("mirror-b-").append(this->getRepr()->attribute("id")).c_str()); +// if (std::strcmp(splpeitem->getId(), mirror_b) == 0) { +// syncMirror(splpeitem, mirror_a); +// } else { + Geom::Point point_a(line_separation.initialPoint()); + Geom::Point point_b(line_separation.finalPoint()); + Geom::Point gap(split_gap,0); + Geom::Translate m1(point_a[0], point_a[1]); + double hyp = Geom::distance(point_a, point_b); + double cos = 0; + double sin = 0; + if (hyp > 0) { + cos = (point_b[0] - point_a[0]) / hyp; + sin = (point_b[1] - point_a[1]) / hyp; + } + Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); + Geom::Point dir = unit_vector(point_b - point_a); + Geom::Point offset = (point_a + point_b)/2 + dir.ccw() * split_gap; + line_separation *= Geom::Translate(offset); + Geom::Scale sca(1.0, -1.0); + m = m1.inverse() * m2; + m = m * sca; + m = m * m2.inverse(); + m = m * m1; + m = m * splpeitem->transform; + createMirror(splpeitem, m); + //} } else { - elements.clear(); + if (!allow_split()) { + std::cout << "Only one operation of split allowed. Group results to nested effects.\n"; + split_elements.param_setValue(false); + } processObjects(LPE_ERASE); + elements.clear(); } } @@ -255,7 +251,7 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c if (c) { dest->getRepr()->setAttribute(att,sp_svg_write_path(c->get_pathvector())); c->reset(); - g_free(c); + g_free(c); } else { dest->getRepr()->setAttribute(att,NULL); } @@ -268,9 +264,19 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c } void -LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id) +LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + const char * id; + Glib::ustring idbase = Glib::ustring(sp_lpe_item->getId()); + size_t pos = idbase.find("-mirror"); + if (pos <= idbase.size()) { + id = g_strdup(idbase.substr(pos).c_str()); + } else { + id = g_strdup(idbase.append("-mirror").c_str()); + elements.clear(); + elements.push_back(id); + } Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); @@ -282,24 +288,95 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, const } else { phantom = origin->getRepr()->duplicate(xml_doc); } - phantom->setAttribute("id", id); if (!elemref) { - elemref = ms_container->appendChildRepr(phantom); + elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", NULL); //NULL required + cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); - if (elemref->parent != ms_container) { + if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); copy->setAttribute("id", id); - ms_container->appendChildRepr(copy); + container->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); } } } +//void +//LPEMirrorSymmetry::syncMirror(SPLPEItem *origin, const char * id) +//{ +// if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { +// Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); +// Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); +// Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); +// SVGElemRef->attach(SVGElem_uri); +// SPObject *elemref= NULL; +// Inkscape::XML::Node *phantom = NULL; +// if (elemref = SVGElemRef->getObject()) { +// cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required +// } +// } +//} + +bool +LPEMirrorSymmetry::allow_split(){ + if (sp_lpe_item->path_effect_list->empty()) { + return false; + } + size_t count = 0; + for (PathEffectList::const_iterator it = sp_lpe_item->path_effect_list->begin(); it != sp_lpe_item->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::LPEMirrorSymmetry * ms = dynamic_cast(lpeobj->get_lpe()); + if (ms && ms->split_elements) { + count++; + } + } + } + return count <= 1; +} + +//Gtk::Widget * +//LPEMirrorSymmetry::newWidget() +//{ +// // use manage here, because after deletion of Effect object, others might +// // still be pointing to this widget. +// Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + +// vbox->set_border_width(5); +// std::vector::iterator it = param_vector.begin(); +// while (it != param_vector.end()) { +// if ((*it)->widget_is_visible) { +// Parameter *param = *it; +// Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); +// if (widg) { +// if (param->param_key == "split_elements") { +// Gtk::CheckButton *widg_registered = Gtk::manage(dynamic_cast(widg)); +// if (!allow_split()) { +// widg_registered->set_sensitive("false"); +// } +// widg = dynamic_cast(widg_registered); +// } +// Glib::ustring *tip = param->param_getTooltip(); +// vbox->pack_start(*widg, true, true, 2); +// if (tip) { +// widg->set_tooltip_text(*tip); +// } else { +// widg->set_tooltip_text(""); +// widg->set_has_tooltip(false); +// } +// } +// } + +// ++it; +// } +// return dynamic_cast(vbox); +//} + //TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) @@ -349,15 +426,15 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) break; case LPE_ERASE: - if (std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { + //if (std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0) { elemref->deleteObject(); - } + //} break; case LPE_VISIBILITY: css = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); - if (!this->isVisible() && std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { + if (!this->isVisible()/* && std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0*/) { css->setAttribute("display", "none"); } else { css->setAttribute("display", NULL); @@ -382,8 +459,6 @@ void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { if( !split_elements) { - center_point *= postmul; - previous_center = center_point; // cycle through all parameters. Most parameters will not need transformation, but path and point params do. for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { Parameter * param = *it; @@ -406,10 +481,15 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) start_point.param_update_default(point_a); end_point.param_setValue(point_b); end_point.param_update_default(point_b); - center_point = point_c; + center_point.param_setValue(point_c); previous_center = center_point; - id_origin.param_setValue(Glib::ustring(lpeitem->getId())); - id_origin.write_to_SVG(); +// SPLPEItem * splpeitem = const_cast(lpeitem); +// if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet +// const char * mirror_a = g_strdup(Glib::ustring("mirror-a-").append(this->getRepr()->attribute("id")).c_str()); +// splpeitem->setAttribute("id", mirror_a); +// first_lpe.param_setValue(this->getRepr()->attribute("id")); +// first_lpe.write_to_SVG(); +// } } @@ -560,41 +640,6 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) return path_out; } - -Gtk::Widget *LPEMirrorSymmetry::newWidget() -{ - // use manage here, because after deletion of Effect object, others might - // still be pointing to this widget. - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - - vbox->set_border_width(5); - vbox->set_homogeneous(false); - vbox->set_spacing(2); - - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter *param = *it; - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - if (param->param_key != "id_origin") { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - } - - ++it; - } - return dynamic_cast(vbox); -} - void LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) { @@ -610,43 +655,6 @@ LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector hp_vec.push_back(helper); } -void -LPEMirrorSymmetry::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) -{ - SPKnotShapeType knot_shape = SP_KNOT_SHAPE_CIRCLE; - SPKnotModeType knot_mode = SP_KNOT_MODE_XOR; - guint32 knot_color = 0x0000ff00; - { - KnotHolderEntity *c = new MS::KnotHolderEntityCenterMirrorSymmetry(this); - c->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the center"), knot_shape, knot_mode, knot_color ); - knotholder->add(c); - } -}; - -namespace MS { - -using namespace Geom; - -void -KnotHolderEntityCenterMirrorSymmetry::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) -{ - LPEMirrorSymmetry* lpe = dynamic_cast(_effect); - Geom::Point const s = snap_knot_position(p, state); - lpe->center_point = s; - // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. - sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); -} - -Geom::Point -KnotHolderEntityCenterMirrorSymmetry::knot_get() const -{ - LPEMirrorSymmetry const *lpe = dynamic_cast(_effect); - return lpe->center_point; -} - -} // namespace CR - } //namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 7b090ed82..12ceebaf8 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -15,10 +15,10 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ -#include + #include "live_effects/effect.h" -#include "live_effects/parameter/text.h" #include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" #include "live_effects/parameter/path.h" #include "live_effects/parameter/enum.h" @@ -27,11 +27,6 @@ namespace Inkscape { namespace LivePathEffect { -namespace MS { -// we need a separate namespace to avoid clashes with LPEPerpBisector -class KnotHolderEntityCenterMirrorSymmetry; -} - enum ModeType { MT_V, MT_H, @@ -51,14 +46,13 @@ public: virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); - virtual Gtk::Widget *newWidget(); +// virtual Gtk::Widget * newWidget(); void processObjects(LpeAction lpe_action); - /* the knotholder entity classes must be declared friends */ - friend class MS::KnotHolderEntityCenterMirrorSymmetry; - void createMirror(SPLPEItem *origin, Geom::Affine transform, const char * id); + void createMirror(SPLPEItem *origin, Geom::Affine transform); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); +// void syncMirror(SPLPEItem *origin, const char * id); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...); - void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); + bool allow_split(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -72,13 +66,11 @@ private: BoolParam split_elements; PointParam start_point; PointParam end_point; - TextParam id_origin; + PointParam center_point; Geom::Line line_separation; Geom::Point previous_center; - Geom::Point center_point; - bool actual; std::vector elements; - SPObject * ms_container; + SPObject * container; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); }; diff --git a/src/live_effects/lpe-offset.cpp b/src/live_effects/lpe-offset.cpp index a0fa46c3f..057f404e0 100644 --- a/src/live_effects/lpe-offset.cpp +++ b/src/live_effects/lpe-offset.cpp @@ -11,13 +11,12 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-offset.h" #include "sp-shape.h" #include "display/curve.h" - #include <2geom/elliptical-arc.h> +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-parallel.cpp b/src/live_effects/lpe-parallel.cpp index 9cd8ecf46..276749c43 100644 --- a/src/live_effects/lpe-parallel.cpp +++ b/src/live_effects/lpe-parallel.cpp @@ -11,14 +11,15 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-parallel.h" #include "sp-shape.h" #include "display/curve.h" #include "knotholder.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-path_length.cpp b/src/live_effects/lpe-path_length.cpp index 6ec1e0ede..a06dbde98 100644 --- a/src/live_effects/lpe-path_length.cpp +++ b/src/live_effects/lpe-path_length.cpp @@ -11,10 +11,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-path_length.h" #include "util/units.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 15c2817c4..9cfeffee7 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -12,6 +12,8 @@ #include "knotholder.h" #include +// TODO due to internal breakage in glibmm headers, this must be last: +#include using std::vector; diff --git a/src/live_effects/lpe-perp_bisector.cpp b/src/live_effects/lpe-perp_bisector.cpp index f69dae6a1..bce22250a 100644 --- a/src/live_effects/lpe-perp_bisector.cpp +++ b/src/live_effects/lpe-perp_bisector.cpp @@ -11,9 +11,6 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - -#include - #include "live_effects/lpe-perp_bisector.h" #include "display/curve.h" #include "sp-path.h" @@ -21,6 +18,9 @@ #include "knotholder.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Inkscape { namespace LivePathEffect { namespace PB { diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index 6a6b59519..e834c0e86 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -20,6 +20,9 @@ #include "display/curve.h" #include +// TODO due to internal breakage in glibmm headers, this must be last: +#include + using namespace Geom; namespace Inkscape { diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index cb4e43d87..2c6d66cee 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -11,8 +11,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ #include -#include - #include "persp3d.h" //#include "transf_mat_3x4.h" #include "document-private.h" @@ -23,6 +21,9 @@ #include "desktop.h" #include +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 329a00756..e9f3975c7 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -25,6 +25,9 @@ #include <2geom/circle.h> #include "helper/geom.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Geom { // should all be moved to 2geom at some point diff --git a/src/live_effects/lpe-recursiveskeleton.cpp b/src/live_effects/lpe-recursiveskeleton.cpp index ed0c915ce..aa0db920b 100644 --- a/src/live_effects/lpe-recursiveskeleton.cpp +++ b/src/live_effects/lpe-recursiveskeleton.cpp @@ -10,12 +10,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-recursiveskeleton.h" #include <2geom/bezier-to-sbasis.h> +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-rough-hatches.cpp b/src/live_effects/lpe-rough-hatches.cpp index 2fb65b349..3cc8658ea 100644 --- a/src/live_effects/lpe-rough-hatches.cpp +++ b/src/live_effects/lpe-rough-hatches.cpp @@ -13,7 +13,6 @@ */ #include "ui/widget/scalar.h" -#include #include "live_effects/lpe-rough-hatches.h" #include "sp-item.h" @@ -23,6 +22,8 @@ #include <2geom/sbasis-math.h> #include <2geom/bezier-to-sbasis.h> +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 3a486ff10..c6edffd9b 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -13,11 +13,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include "live_effects/lpe-roughen.h" #include "display/curve.h" #include #include "helper/geom.h" + // TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index dbdb91e62..bab06022f 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -12,7 +12,6 @@ #ifndef INKSCAPE_LPE_ROUGHEN_H #define INKSCAPE_LPE_ROUGHEN_H -#include #include "live_effects/effect.h" #include "live_effects/parameter/enum.h" #include "live_effects/parameter/parameter.h" diff --git a/src/live_effects/lpe-ruler.cpp b/src/live_effects/lpe-ruler.cpp index 3a2d78b2c..60c2a3e1c 100644 --- a/src/live_effects/lpe-ruler.cpp +++ b/src/live_effects/lpe-ruler.cpp @@ -12,7 +12,8 @@ */ #include "live_effects/lpe-ruler.h" - +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp index 170b6dccb..7c298d0e7 100644 --- a/src/live_effects/lpe-show_handles.cpp +++ b/src/live_effects/lpe-show_handles.cpp @@ -6,6 +6,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include "live_effects/lpe-show_handles.h" #include <2geom/sbasis-to-bezier.h> #include <2geom/svg-path-parser.h> @@ -13,6 +14,7 @@ #include "desktop-style.h" #include "style.h" #include "svg/svg.h" + // TODO due to internal breakage in glibmm headers, this must be last: #include diff --git a/src/live_effects/lpe-show_handles.h b/src/live_effects/lpe-show_handles.h index 3eda04649..c46abd2c2 100644 --- a/src/live_effects/lpe-show_handles.h +++ b/src/live_effects/lpe-show_handles.h @@ -8,7 +8,6 @@ * Copyright (C) Jabier Arraiza Cenoz 2014 * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include "helper/geom-nodetype.h" #include "live_effects/effect.h" #include "live_effects/lpegroupbbox.h" diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index ec21e10d2..8bdb19b4f 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -2,6 +2,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include "live_effects/lpe-simplify.h" #include "display/curve.h" #include "helper/geom.h" @@ -9,6 +10,7 @@ #include "svg/svg.h" #include "ui/tools/node-tool.h" #include "ui/icon-names.h" + // TODO due to internal breakage in glibmm headers, this must be last: #include diff --git a/src/live_effects/lpe-simplify.h b/src/live_effects/lpe-simplify.h index 8135561af..6c407f572 100644 --- a/src/live_effects/lpe-simplify.h +++ b/src/live_effects/lpe-simplify.h @@ -6,7 +6,6 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include "live_effects/effect.h" #include "live_effects/parameter/togglebutton.h" #include "live_effects/lpegroupbbox.h" diff --git a/src/live_effects/lpe-skeleton.cpp b/src/live_effects/lpe-skeleton.cpp index 7d34db699..adc4a3493 100644 --- a/src/live_effects/lpe-skeleton.cpp +++ b/src/live_effects/lpe-skeleton.cpp @@ -20,8 +20,7 @@ #include "live_effects/lpe-skeleton.h" -// You might need to include other 2geom files. You can add them here: - +// TODO due to internal breakage in glibmm headers, this must be last: #include namespace Inkscape { diff --git a/src/live_effects/lpe-sketch.cpp b/src/live_effects/lpe-sketch.cpp index 95e2f6f0d..e01516f2e 100644 --- a/src/live_effects/lpe-sketch.cpp +++ b/src/live_effects/lpe-sketch.cpp @@ -13,13 +13,14 @@ #include "live_effects/lpe-sketch.h" -#include - // You might need to include other 2geom files. You can add them here: #include <2geom/sbasis-math.h> #include <2geom/bezier-to-sbasis.h> #include <2geom/path-intersection.h> +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-tangent_to_curve.cpp b/src/live_effects/lpe-tangent_to_curve.cpp index b308ef8d7..76d4ea71b 100644 --- a/src/live_effects/lpe-tangent_to_curve.cpp +++ b/src/live_effects/lpe-tangent_to_curve.cpp @@ -13,13 +13,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-tangent_to_curve.h" #include "sp-path.h" #include "display/curve.h" #include "knotholder.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index f6f6b33dc..4ffc41691 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -26,6 +26,8 @@ #include "svg/svg.h" #include "knotholder.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include template inline bool withinRange(T value, T low, T high) { diff --git a/src/live_effects/lpe-test-doEffect-stack.cpp b/src/live_effects/lpe-test-doEffect-stack.cpp index c7ecf6481..324893706 100644 --- a/src/live_effects/lpe-test-doEffect-stack.cpp +++ b/src/live_effects/lpe-test-doEffect-stack.cpp @@ -4,10 +4,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-test-doEffect-stack.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include + using std::memcpy; namespace Inkscape { diff --git a/src/live_effects/lpe-text_label.cpp b/src/live_effects/lpe-text_label.cpp index 602a6897c..709d05e18 100644 --- a/src/live_effects/lpe-text_label.cpp +++ b/src/live_effects/lpe-text_label.cpp @@ -11,10 +11,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-text_label.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 78db622f2..e1f36eee7 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -20,6 +20,7 @@ // TODO due to internal breakage in glibmm headers, this must be last: #include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index 2486f3366..47e2a1cec 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -5,7 +5,7 @@ */ #include "live_effects/lpe-vonkoch.h" - +// TODO due to internal breakage in glibmm headers, this must be last: #include //using std::vector; diff --git a/src/live_effects/parameter/fontbutton.cpp b/src/live_effects/parameter/fontbutton.cpp index ff8ab76a0..64c203093 100644 --- a/src/live_effects/parameter/fontbutton.cpp +++ b/src/live_effects/parameter/fontbutton.cpp @@ -4,7 +4,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ - +#include #include "ui/widget/registered-widget.h" #include "live_effects/parameter/fontbutton.h" #include "live_effects/effect.h" diff --git a/src/live_effects/parameter/fontbutton.h b/src/live_effects/parameter/fontbutton.h index 387ad130b..df47251a2 100644 --- a/src/live_effects/parameter/fontbutton.h +++ b/src/live_effects/parameter/fontbutton.h @@ -8,7 +8,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ #include -#include #include "live_effects/parameter/parameter.h" namespace Inkscape { diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index ff43c2ca3..ed00092b2 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -74,8 +74,7 @@ static char const preferences_skeleton[] = " \n" "\n" " \n" +" bounding_box=\"0\">\n" " \n" " \n" " \n" @@ -88,7 +87,7 @@ static char const preferences_skeleton[] = " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 96dcdbe30..7b2507b5e 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -584,12 +584,13 @@ sp_item_group_ungroup (SPGroup *group, std::vector &children, bool do_d SPText * text = dynamic_cast(citem); if (text) { //this causes a change in text-on-path appearance when there is a non-conformal transform, see bug #1594565 - double scale = (ctrans.expansionX() + ctrans.expansionY()) / 2.0; SPTextPath * text_path = dynamic_cast(text->firstChild()); if (!text_path) { nrepr->setAttribute("transform", affinestr); } else { - sp_recursive_scale_text_size(nrepr, scale); + // The following breaks roundtripping group -> ungroup + // double scale = (ctrans.expansionX() + ctrans.expansionY()) / 2.0; + // sp_recursive_scale_text_size(nrepr, scale); Geom::Affine ttrans = ctrans.inverse() * SP_ITEM(text)->transform * ctrans; gchar *affinestr = sp_svg_transform_write(ttrans); nrepr->setAttribute("transform", affinestr); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 9cf9dadc1..98428512f 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -607,7 +607,7 @@ bool SPLPEItem::hasPathEffect() const return true; } -bool SPLPEItem::hasPathEffectOfType(int const type) const +bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const { if (path_effect_list->empty()) { return false; @@ -619,7 +619,9 @@ bool SPLPEItem::hasPathEffectOfType(int const type) const if (lpeobj) { Inkscape::LivePathEffect::Effect const* lpe = lpeobj->get_lpe(); if (lpe && (lpe->effectType() == type)) { - return true; + if (is_ready || lpe->isReady()) { + return true; + } } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 9e5cb3329..db4a0c7a3 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -73,7 +73,7 @@ public: bool pathEffectsEnabled() const; bool hasPathEffect() const; - bool hasPathEffectOfType(int const type) const; + bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index f2604976e..f192d0e44 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -1198,7 +1198,7 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb ry = arc->ry.computed; start = arc->start; end = arc->end; - if( end == start ) { + if( end <= start ) { end += 2.0 * M_PI; } } @@ -2026,7 +2026,7 @@ guint SPMeshNodeArray::side_arc( std::vector corners ) { { case 'L': case 'l': - std::cout << "SPMeshNodeArray::arc_sides: Can't convert straight lines to arcs."; + std::cerr << "SPMeshNodeArray::side_arc: Can't convert straight lines to arcs." << std::endl; break; case 'C': @@ -2052,15 +2052,15 @@ guint SPMeshNodeArray::side_arc( std::vector corners ) { ++arced; } else { - std::cout << "SPMeshNodeArray::arc_sides: No crossing, can't turn into arc." << std::endl; + std::cerr << "SPMeshNodeArray::side_arc: No crossing, can't turn into arc." << std::endl; } } else { - std::cout << "SPMeshNodeArray::arc_sides: Handles parallel, can't turn into arc." << std::endl; + std::cerr << "SPMeshNodeArray::side_arc: Handles parallel, can't turn into arc." << std::endl; } break; } default: - std::cout << "SPMeshNodeArray::arc_sides: Invalid path type: " << n[1]->path_type << std::endl; + std::cerr << "SPMeshNodeArray::side_arc: Invalid path type: " << n[1]->path_type << std::endl; } } } diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index 56939cc30..ff5d623c2 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -1084,7 +1084,8 @@ sp_tweak_dilate (TweakTool *tc, Geom::Point event_p, Geom::Point p, Geom::Point double move_force = get_move_force(tc); double color_force = MIN(sqrt(path_force)/20.0, 1); - auto items= selection->items(); +// auto items= selection->items(); + std::vector items(selection->items().begin(), selection->items().end()); for(auto i=items.begin();i!=items.end(); ++i){ SPItem *item = *i; diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index f7b7a6ec9..ea0faf1df 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -67,76 +67,79 @@ static bool blocked = false; //## Mesh ## //######################## -/* - * Get the current selection and dragger status from the desktop - */ -void ms_read_selection( Inkscape::Selection *selection, - SPMeshGradient *&ms_selected, - bool &ms_selected_multi, - SPMeshType &ms_type, - bool &ms_type_multi ) + +// Get a list of selected meshes taking into account fill/stroke toggles +std::vector ms_get_dt_selected_gradients(Inkscape::Selection *selection) { + std::vector ms_selected; + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool edit_fill = prefs->getBool("/tools/mesh/edit_fill", true); + bool edit_stroke = prefs->getBool("/tools/mesh/edit_stroke", true); - // Read desktop selection - bool first = true; - ms_type = SP_MESH_TYPE_COONS; - auto itemlist= selection->items(); for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; + SPItem *item = *i;// get the items gradient, not the getVector() version SPStyle *style = item->style; - if (style && (style->fill.isPaintserver())) { - SPPaintServer *server = item->style->getFillPaintServer(); - if ( SP_IS_MESHGRADIENT(server) ) { - - SPMeshGradient *gradient = SP_MESHGRADIENT(server); // ->getVector(); - SPMeshType type = gradient->type; + if (style) { - if (gradient != ms_selected) { - if (ms_selected) { - ms_selected_multi = true; - } else { - ms_selected = gradient; - } + + if (edit_fill && style->fill.isPaintserver()) { + SPPaintServer *server = item->style->getFillPaintServer(); + SPMeshGradient *mesh = dynamic_cast(server); + if (mesh) { + ms_selected.push_back(mesh); } - if( type != ms_type ) { - if (ms_type != SP_MESH_TYPE_COONS && !first) { - ms_type_multi = true; - } else { - ms_type = type; - } + } + + if (edit_stroke && style->stroke.isPaintserver()) { + SPPaintServer *server = item->style->getStrokePaintServer(); + SPMeshGradient *mesh = dynamic_cast(server); + if (mesh) { + ms_selected.push_back(mesh); } - first = false; } } - if (style && (style->stroke.isPaintserver())) { - SPPaintServer *server = item->style->getStrokePaintServer(); - if ( SP_IS_MESHGRADIENT(server) ) { + } + return ms_selected; +} - SPMeshGradient *gradient = SP_MESHGRADIENT(server); // ->getVector(); - SPMeshType type = gradient->type; - if (gradient != ms_selected) { - if (ms_selected) { - ms_selected_multi = true; - } else { - ms_selected = gradient; - } - } - if( type != ms_type ) { - if (ms_type != SP_MESH_TYPE_COONS && !first) { - ms_type_multi = true; - } else { - ms_type = type; - } - } - first = false; +/* + * Get the current selection status from the desktop + */ +void ms_read_selection( Inkscape::Selection *selection, + SPMeshGradient *&ms_selected, + bool &ms_selected_multi, + SPMeshType &ms_type, + bool &ms_type_multi ) +{ + ms_selected = NULL; + ms_selected_multi = false; + ms_type = SP_MESH_TYPE_COONS; + ms_type_multi = false; + + bool first = true; + + // Read desktop selection, taking into account fill/stroke toggles + std::vector meshes = ms_get_dt_selected_gradients( selection ); + for (auto i = meshes.begin(); i != meshes.end(); ++i) { + if (first) { + ms_selected = (*i); + ms_type = (*i)->type; + first = false; + } else { + if (ms_selected != (*i)) { + ms_selected_multi = true; + } + if (ms_type != (*i)->type) { + ms_type_multi = true; } } } - } +} /* * Core function, setup all the widgets whenever something changes on the desktop @@ -173,7 +176,7 @@ static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointe // std::cout << " type: " << ms_type << std::endl; EgeSelectOneAction* type = (EgeSelectOneAction *) g_object_get_data(G_OBJECT(widget), "mesh_select_type_action"); - gtk_action_set_sensitive( GTK_ACTION(type), (ms_selected && !ms_selected_multi) ); + gtk_action_set_sensitive( GTK_ACTION(type), (ms_selected && !ms_type_multi) ); if (ms_selected) { blocked = TRUE; ege_select_one_action_set_active( type, ms_type ); @@ -204,34 +207,6 @@ static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GObject *widg ms_tb_selection_changed(NULL, widget); } -void ms_get_dt_selected_gradient(Inkscape::Selection *selection, SPMeshGradient *&ms_selected) -{ - SPMeshGradient *gradient = 0; - - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i;// get the items gradient, not the getVector() version - SPStyle *style = item->style; - SPPaintServer *server = 0; - - if (style && (style->fill.isPaintserver())) { - server = item->style->getFillPaintServer(); - } - if (style && (style->stroke.isPaintserver())) { - server = item->style->getStrokePaintServer(); - } - - if ( SP_IS_MESHGRADIENT(server) ) { - gradient = SP_MESHGRADIENT(server); - } - } - - if (gradient) { - ms_selected = gradient; - } -} - - /* * Callback functions for user actions */ @@ -296,18 +271,17 @@ static void ms_type_changed(EgeSelectOneAction *act, GtkWidget *widget) SPDesktop *desktop = static_cast(g_object_get_data(G_OBJECT(widget), "desktop")); Inkscape::Selection *selection = desktop->getSelection(); - SPMeshGradient *gradient = 0; - ms_get_dt_selected_gradient(selection, gradient); + std::vector meshes = ms_get_dt_selected_gradients(selection); - if (gradient) { - SPMeshType type = (SPMeshType) ege_select_one_action_get_active(act); + SPMeshType type = (SPMeshType) ege_select_one_action_get_active(act); + for (auto i = meshes.begin(); i != meshes.end(); ++i) { // std::cout << " type: " << type << std::endl; - gradient->type = type; - gradient->type_set = true; - gradient->updateRepr(); - - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, - _("Set mesh type")); + (*i)->type = type; + (*i)->type_set = true; + (*i)->updateRepr(); + } + if (!meshes.empty() ) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH,_("Set mesh type")); } } @@ -366,7 +340,7 @@ static void ms_toggle_handles(void) } } -static void ms_toggle_fill_stroke(void) +static void ms_toggle_fill_stroke(InkToggleAction * /*act*/, gpointer data) { MeshTool *mt = get_mesh_tool(); if (mt) { @@ -374,6 +348,7 @@ static void ms_toggle_fill_stroke(void) drag->updateDraggers(); drag->updateLines(); drag->updateLevels(); + ms_tb_selection_changed(NULL, data); // Need to update Type widget } } @@ -507,7 +482,7 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/edit_fill"); g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), 0); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), holder); } /* Edit stroke mesh */ @@ -520,7 +495,7 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/edit_stroke"); g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), 0); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), holder); } /* Show/hide side and tensor handles */ diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 114d946bb..784c467f1 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -117,6 +117,8 @@ static void sp_print_fontstyle( SPStyle *query ) { } #endif +static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false); + // Font family static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) { @@ -225,8 +227,35 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje sp_repr_css_set_property (css, "font-size", osfs.str().c_str()); // Apply font size to selected objects. + // Calling sp_desktop_set_style will result in a call to TextTool::_styleSet() which + // will set the style on selected text inside the element. If we want to set + // the style on the outer objects we need to bypass this call. + bool outer = prefs->getInt("/tools/text/outer_style", false); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); + if (outer) { + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (dynamic_cast(*i) || dynamic_cast(*i)) { + SPItem *item = *i; + + // Scale by inverse of accumulated parent transform + SPCSSAttr *css_set = sp_repr_css_attr_new(); + sp_repr_css_merge(css_set, css); + Geom::Affine const local(item->i2doc_affine()); + double const ex(local.descrim()); + if ( (ex != 0.0) && (ex != 1.0) ) { + sp_css_attr_scale(css_set, 1/ex); + } + + item->changeCSS(css_set,"style"); + + sp_repr_css_attr_unref(css_set); + } + } + } else { + sp_desktop_set_style (desktop, css, true, true); + } // If no selected objects, set default. SPStyle query(SP_ACTIVE_DOCUMENT); @@ -281,6 +310,40 @@ static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObj g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } +// Changes selection to only text outer elements. +static void sp_text_outer_style_changed( InkToggleAction*act, GObject *tbl ) +{ + bool outer = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(act) ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/text/outer_style", outer); + + // Update widgets to reflect new state of Text Outer Style button. + sp_text_toolbox_selection_changed( NULL, tbl ); +} + +// Unset line height on selection's inner text objects (tspan, etc.). +static void sp_text_lineheight_unset_changed( InkToggleAction*act, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_unset_property(css, "line-height"); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css); + + sp_repr_css_attr_unref(css); + + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Unset line height.")); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + // Handles both Superscripts and Subscripts static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) { @@ -549,9 +612,34 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); - // Apply line-height to selected objects. + // Apply line-height to selected objects. See comment in font size function. + bool outer = prefs->getInt("/tools/text/outer_style", false); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, false); + if (outer) { + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (dynamic_cast(*i) || dynamic_cast(*i)) { + SPItem *item = *i; + + // Scale by inverse of accumulated parent transform + SPCSSAttr *css_set = sp_repr_css_attr_new(); + sp_repr_css_merge(css_set, css); + Geom::Affine const local(item->i2doc_affine()); + double const ex(local.descrim()); + if ( (ex != 0.0) && (ex != 1.0) ) { + sp_css_attr_scale(css_set, 1/ex); + } + + item->changeCSS(css_set,"style"); + + sp_repr_css_attr_unref(css_set); + } + } + } else { + sp_desktop_set_style (desktop, css, true, true); + } + // Only need to save for undo if a text item has been changed. @@ -652,7 +740,7 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) double font_size = 0; int count = 0; for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (SP_IS_TEXT (*i)) { + if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT(*i)) { double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); font_size += (*i)->style->font_size.computed * doc_scale; ++count; @@ -681,7 +769,7 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) double font_size = 0; int count = 0; for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (SP_IS_TEXT (*i)) { + if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT (*i)) { double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); font_size += (*i)->style->font_size.computed * doc_scale; ++count; @@ -1073,7 +1161,7 @@ static void sp_text_set_sizes(GtkListStore* model_size, int unit) * It is called whenever a text selection is changed, including stepping cursor * through text, or setting focus to text. */ -static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false) // don't bother to update font list if subsel changed +static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection) // don't bother to update font list if subsel changed { #ifdef DEBUG_TEXT static int count = 0; @@ -1082,12 +1170,11 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << "sp_text_toolbox_selection_changed: start " << count << std::endl; - std::cout << " Selected items:" << std::endl; - for (GSList const *items = SP_ACTIVE_DESKTOP->getSelection()->itemList(); - items != NULL; - items = items->next) - { - const gchar* id = reinterpret_cast(items->data)->getId(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist0= selection->items(); + for(auto i=itemlist0.begin();i!=itemlist0.end(); ++i) { + const gchar* id = (*i)->getId(); std::cout << " " << id << std::endl; } Glib::ustring selected_text = sp_text_get_selected_text((SP_ACTIVE_DESKTOP)->event_context); @@ -1129,8 +1216,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ gboolean isFlow = false; auto itemlist= SP_ACTIVE_DESKTOP->getSelection()->items(); for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - // const gchar* id = reinterpret_cast(items->data)->getId(); - // std::cout << " " << id << std::endl; + // std::cout << " " << ((*i)->getId()?(*i)->getId():"null") << std::endl; if( SP_IS_FLOWTEXT(*i)) { isFlow = true; // std::cout << " Found flowed text" << std::endl; @@ -1148,10 +1234,26 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ SPStyle query(SP_ACTIVE_DOCUMENT); int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); - int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); int result_wmode = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); + // Calling sp_desktop_query_style will result in a call to TextTool::_styleQueried(). + // This returns the style of the selected text inside the element... which + // is often the style of one or more s. If we want the style of the outer + // objects then we need to bypass the call to TextTool::_styleQueried(). + // The desktop selection never includes the elements inside the element. + int result_numbers = 0; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + bool outer = prefs->getInt("/tools/text/outer_style", false); + if (outer) { + Inkscape::Selection *selection = desktop->getSelection(); + std::vector vec(selection->items().begin(), selection->items().end()); + result_numbers = sp_desktop_query_style_from_list (vec, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + } else { + result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + } + /* * If no text in selection (querying returned nothing), read the style from * the /tools/text preferencess (default style for new texts). Return if @@ -1326,7 +1428,13 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } // Save unit so we can do convertions between new/old units. g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(line_height_unit)); - + + // Enable and turn on only if selection includes an object with line height set. + InkToggleAction* lineHeightUnset = + INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextLineHeightUnsetAction")); + gtk_action_set_sensitive(GTK_ACTION(lineHeightUnset), query.line_height.set ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(lineHeightUnset), query.line_height.set ); + // Word spacing double wordSpacing; if (query.word_spacing.normal) wordSpacing = 0.0; @@ -2021,6 +2129,32 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje g_object_set( G_OBJECT(eact), "iconId", "text_rotation", NULL ); } + /* Text line height unset */ + { + InkToggleAction* act = ink_toggle_action_new( "TextLineHeightUnsetAction", // Name + _("Unset line height"), // Label + _("If enabled, line height is set on part of selection. Click to unset."), + INKSCAPE_ICON("paint-unknown"), + secondarySize ); // Icon size + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_lineheight_unset_changed), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/line_height_unset", false) ); + g_object_set_data( holder, "TextLineHeightUnsetAction", act ); + } + + /* Text outer style */ + { + InkToggleAction* act = ink_toggle_action_new( "TextOuterStyleAction", // Name + _("Show outer style"), // Label + _("Show style of outermost text element. The 'font-size' and 'line-height' values of the outermost text element determine the minimum line spacing in the block."), + INKSCAPE_ICON("text_outer_style"), + secondarySize ); // Icon size + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_outer_style_changed), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/outer_style", false) ); + g_object_set_data( holder, "TextOuterStyleAction", act ); + } + // Is this necessary to call? Shouldn't hurt. sp_text_toolbox_selection_changed(desktop->getSelection(), holder); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 53de2d342..a3db3c33d 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -508,18 +508,19 @@ static gchar const * ui_descr = " " " " - " " " " -// " " -// " " + " " + " " + " " + " " + " " + " " " " " " " " " " " " " " - " " - " " " " " " " " -- cgit v1.2.3 From 323abf91b94beccd3dd2a3d617344dbc81523840 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 19 Dec 2016 00:37:46 +0100 Subject: working on reflections (bzr r15295.1.27) --- src/helper/geom.cpp | 7 + src/helper/geom.h | 2 +- src/live_effects/lpe-measure-line.cpp | 9 +- src/live_effects/lpe-mirror_symmetry.cpp | 317 ++++++++++++++----------------- src/live_effects/lpe-mirror_symmetry.h | 13 +- src/live_effects/parameter/bool.cpp | 3 +- src/live_effects/parameter/text.cpp | 3 +- 7 files changed, 167 insertions(+), 187 deletions(-) (limited to 'src') diff --git a/src/helper/geom.cpp b/src/helper/geom.cpp index 42c494c00..e1f05c3ce 100644 --- a/src/helper/geom.cpp +++ b/src/helper/geom.cpp @@ -843,6 +843,13 @@ recursive_bezier4(const double x1, const double y1, recursive_bezier4(x1234, y1234, x234, y234, x34, y34, x4, y4, m_points, level + 1); } +void +swap(Geom::Point &A, Geom::Point &B){ + Geom::Point tmp = A; + A = B; + B = tmp; +} + /* Local Variables: mode:c++ diff --git a/src/helper/geom.h b/src/helper/geom.h index d49e2070c..b3d907e51 100644 --- a/src/helper/geom.h +++ b/src/helper/geom.h @@ -32,7 +32,7 @@ void recursive_bezier4(const double x1, const double y1, const double x2, const const double x3, const double y3, const double x4, const double y4, std::vector &pointlist, int level); - +void swap(Geom::Point &A, Geom::Point &B); #endif // INKSCAPE_HELPER_GEOM_H /* diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index 8847b78aa..3feb6ff08 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -23,6 +23,7 @@ #include "svg/svg-color.h" #include "svg/svg.h" #include "display/curve.h" +#include "helper/geom.h" #include "2geom/affine.h" #include "path-chemistry.h" #include "style.h" @@ -169,12 +170,6 @@ LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) : LPEMeasureLine::~LPEMeasureLine() {} -void swap(Geom::Point &A, Geom::Point &B){ - Geom::Point tmp = A; - A = B; - B = tmp; -} - void LPEMeasureLine::createArrowMarker(const char * mode) { @@ -535,7 +530,7 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { if ((Glib::ustring(format.param_getSVGValue()).empty())) { format.param_setValue(Glib::ustring("{measure}{unit}")); - this->upd_params = true; + format.write_to_SVG(); } size_t ncurves = pathvector.curveCount(); if (ncurves != (size_t)curve_linked.param_get_max()) { diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index f34421df2..3676013e0 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -25,6 +25,7 @@ #include "helper/geom.h" #include "2geom/path-intersection.h" #include "2geom/affine.h" +#include "helper/geom.h" #include "uri.h" #include "uri-references.h" #include "path-chemistry.h" @@ -58,7 +59,8 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints. Group result to apply nested"), "split_elements", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust the start of mirroring")), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), - center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) + center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), + id_origin("hidden", "hidden store the id of the first LPEItem", "id_origin", &wr, this,"") { show_orig_path = true; registerParameter(&mode); @@ -70,27 +72,80 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : registerParameter(&start_point); registerParameter(&end_point); registerParameter(¢er_point); + registerParameter(&id_origin); + id_origin.param_hide_canvas_text(); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); split_gap.param_set_digits(2); apply_to_clippath_and_mask = true; previous_center = Geom::Point(0,0); + other = NULL; + last_transform = Geom::identity(); } LPEMirrorSymmetry::~LPEMirrorSymmetry() { } +void +LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) +{ + last_transform = Geom::identity(); + if (split_elements) { + if (discard_orig_path) { + discard_orig_path.param_setValue(false); + discard_orig_path.write_to_SVG(); + std::cout << _("You can't discard original paths on split elements"); + } + container = dynamic_cast(sp_lpe_item->parent); + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); + Inkscape::XML::Node *root_origin = doc->getReprRoot(); + if (root_origin != root) { + return; + } + Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); + Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); + // Geom::Point gap(split_gap,0); +// Geom::Translate m1(point_a[0], point_a[1]); +// double hyp = Geom::distance(point_a, point_b); +// double cos = 0; +// double sin = 0; +// if (hyp > 0) { +// cos = (point_b[0] - point_a[0]) / hyp; +// sin = (point_b[1] - point_a[1]) / hyp; +// } +// Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); +// Geom::Point dir = unit_vector(point_b - point_a); +// Geom::Point offset = (point_a + point_b)/2 + Geom::rot90(dir.ccw()) * split_gap; +// line_separation *= Geom::Translate(offset); +// Geom::Scale sca(1.0, -1.0); +// m = m1.inverse() * m2; +// m = m * sca; +// m = m * m2.inverse(); +// m = m * m1; + m = m * sp_lpe_item->transform; +// if (std::strcmp(sp_lpe_item->getId(), origin) != 0) { + createMirror(m); +// } else { +// createMirror(sp_lpe_item, m, mirror); +// } + } else { + processObjects(LPE_ERASE); + elements.clear(); + other = NULL; + } +} + void LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { - SPLPEItem * splpeitem = const_cast(lpeitem); if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { Inkscape::Selection *sel = desktop->getSelection(); if ( sel && !sel->isEmpty()) { SPItem *item = sel->singleItem(); if (item) { - if(std::strcmp(splpeitem->getId(),item->getId()) != 0) { + if(std::strcmp(sp_lpe_item->getId(),item->getId()) != 0) { return; } } @@ -98,7 +153,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } using namespace Geom; original_bbox(lpeitem); - Geom::Affine m = Geom::identity();//lpeitem->transform; Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); if (mode == MT_Y) { @@ -113,7 +167,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) start_point.param_setValue(point_a); end_point.param_setValue(point_b); } - line_separation.setPoints(point_a, point_b); if ( mode == MT_X || mode == MT_Y ) { start_point.param_setValue(point_a); end_point.param_setValue(point_b); @@ -122,9 +175,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point trans = center_point - previous_center; start_point.param_setValue(start_point * trans); end_point.param_setValue(end_point * trans); - line_separation.setPoints(start_point, end_point); - } else { - line_separation.setPoints(start_point, end_point); } } else if ( mode == MT_V){ if(SP_ACTIVE_DESKTOP){ @@ -136,7 +186,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point ep = Geom::Point(view_box_rect.width()/2.0, view_box_rect.height()); ep *= i2anc_affine(SP_OBJECT(lpeitem), SP_OBJECT(SP_ACTIVE_DESKTOP->currentLayer()->parent)) .inverse(); end_point.param_setValue(ep); - line_separation.setPoints(start_point, end_point); } } else { //horizontal page if(SP_ACTIVE_DESKTOP){ @@ -148,7 +197,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point ep = Geom::Point(view_box_rect.width(), view_box_rect.height()/2.0); ep *= i2anc_affine(SP_OBJECT(lpeitem), SP_OBJECT(SP_ACTIVE_DESKTOP->currentLayer()->parent)) .inverse(); end_point.param_setValue(ep); - line_separation.setPoints(start_point, end_point); } } @@ -156,49 +204,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) if (!are_near(previous_center, center_point,0.01)) { center_point.param_setValue(previous_center); } - if (split_elements && allow_split()) { - container = dynamic_cast(splpeitem->parent); - SPDocument * doc = SP_ACTIVE_DOCUMENT; - Inkscape::XML::Node *root = splpeitem->document->getReprRoot(); - Inkscape::XML::Node *root_origin = doc->getReprRoot(); - if (root_origin != root) { - return; - } - const char * mirror = g_strdup(Glib::ustring("mirror-b-").append(this->getRepr()->attribute("id")).c_str()); -// if (std::strcmp(splpeitem->getId(), mirror_b) == 0) { -// syncMirror(splpeitem, mirror_a); -// } else { - Geom::Point point_a(line_separation.initialPoint()); - Geom::Point point_b(line_separation.finalPoint()); - Geom::Point gap(split_gap,0); - Geom::Translate m1(point_a[0], point_a[1]); - double hyp = Geom::distance(point_a, point_b); - double cos = 0; - double sin = 0; - if (hyp > 0) { - cos = (point_b[0] - point_a[0]) / hyp; - sin = (point_b[1] - point_a[1]) / hyp; - } - Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); - Geom::Point dir = unit_vector(point_b - point_a); - Geom::Point offset = (point_a + point_b)/2 + dir.ccw() * split_gap; - line_separation *= Geom::Translate(offset); - Geom::Scale sca(1.0, -1.0); - m = m1.inverse() * m2; - m = m * sca; - m = m * m2.inverse(); - m = m * m1; - m = m * splpeitem->transform; - createMirror(splpeitem, m); - //} - } else { - if (!allow_split()) { - std::cout << "Only one operation of split allowed. Group results to nested effects.\n"; - split_elements.param_setValue(false); - } - processObjects(LPE_ERASE); - elements.clear(); - } } //void @@ -264,21 +269,22 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c } void -LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform) +LPEMirrorSymmetry::createMirror(Geom::Affine transform) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - const char * id; - Glib::ustring idbase = Glib::ustring(sp_lpe_item->getId()); - size_t pos = idbase.find("-mirror"); - if (pos <= idbase.size()) { - id = g_strdup(idbase.substr(pos).c_str()); + const char * id_origin_char = id_origin.param_getSVGValue(); + const char * mirror = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); + const char * elemref_id; + if (std::strcmp(sp_lpe_item->getId(), mirror) == 0) { + elemref_id = id_origin_char; } else { - id = g_strdup(idbase.append("-mirror").c_str()); - elements.clear(); - elements.push_back(id); + elemref_id = mirror; } + elements.clear(); + elements.push_back(id_origin_char); + elements.push_back(mirror); Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); - Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); + Inkscape::URI SVGElem_uri(Glib::ustring("#").append(elemref_id).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); SPObject *elemref= NULL; @@ -286,97 +292,72 @@ LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform) if (elemref = SVGElemRef->getObject()) { phantom = elemref->getRepr(); } else { - phantom = origin->getRepr()->duplicate(xml_doc); + phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); } - phantom->setAttribute("id", id); + phantom->setAttribute("id", elemref_id); if (!elemref) { elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required - elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); + cloneAttrbutes(SP_OBJECT(sp_lpe_item), elemref, true, "inkscape:original-d", "d", "inkscape:path-effect", NULL); //NULL required + //transform *= last_transform; + //if (transform != Geom::identity()) { + if (elemref_id == mirror) { + elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); + } else { + sp_lpe_item->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); + } + //} if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); - copy->setAttribute("id", id); - container->appendChildRepr(copy); + copy->setAttribute("id", elemref_id); + other = container->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); + } else { + other = elemref; } + } } -//void -//LPEMirrorSymmetry::syncMirror(SPLPEItem *origin, const char * id) -//{ -// if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { -// Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); -// Inkscape::URI SVGElem_uri(Glib::ustring("#").append(id).c_str()); -// Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); -// SVGElemRef->attach(SVGElem_uri); -// SPObject *elemref= NULL; -// Inkscape::XML::Node *phantom = NULL; -// if (elemref = SVGElemRef->getObject()) { -// cloneAttrbutes(SP_OBJECT(origin), elemref, true, "inkscape:original-d", "inkscape:path-effect", NULL); //NULL required -// } -// } -//} - -bool -LPEMirrorSymmetry::allow_split(){ - if (sp_lpe_item->path_effect_list->empty()) { - return false; - } - size_t count = 0; - for (PathEffectList::const_iterator it = sp_lpe_item->path_effect_list->begin(); it != sp_lpe_item->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::LPEMirrorSymmetry * ms = dynamic_cast(lpeobj->get_lpe()); - if (ms && ms->split_elements) { - count++; +Gtk::Widget * +LPEMirrorSymmetry::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + if (param->param_key == "id_origin") { + ++it; + continue; + } + Gtk::Widget * widg = param->param_newWidget(); + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } } } + + ++it; } - return count <= 1; + this->upd_params = false; + return dynamic_cast(vbox); } -//Gtk::Widget * -//LPEMirrorSymmetry::newWidget() -//{ -// // use manage here, because after deletion of Effect object, others might -// // still be pointing to this widget. -// Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - -// vbox->set_border_width(5); -// std::vector::iterator it = param_vector.begin(); -// while (it != param_vector.end()) { -// if ((*it)->widget_is_visible) { -// Parameter *param = *it; -// Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); -// if (widg) { -// if (param->param_key == "split_elements") { -// Gtk::CheckButton *widg_registered = Gtk::manage(dynamic_cast(widg)); -// if (!allow_split()) { -// widg_registered->set_sensitive("false"); -// } -// widg = dynamic_cast(widg_registered); -// } -// Glib::ustring *tip = param->param_getTooltip(); -// vbox->pack_start(*widg, true, true, 2); -// if (tip) { -// widg->set_tooltip_text(*tip); -// } else { -// widg->set_tooltip_text(""); -// widg->set_has_tooltip(false); -// } -// } -// } - -// ++it; -// } -// return dynamic_cast(vbox); -//} - //TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) @@ -458,13 +439,21 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { - if( !split_elements) { - // cycle through all parameters. Most parameters will not need transformation, but path and point params do. - for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { - Parameter * param = *it; - param->param_transform_multiply(postmul, set); - } + // cycle through all parameters. Most parameters will not need transformation, but path and point params do. + for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { + Parameter * param = *it; + param->param_transform_multiply(postmul, set); } + previous_center = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); +// Geom::Affine m = Geom::identity(); +// m *= sp_lpe_item->transform; +// m *= postmul; +// sp_lpe_item->transform = m; + last_transform *= postmul; + sp_lpe_item_update_patheffect(sp_lpe_item, false, false); +// if (other) { +// sp_lpe_item_update_patheffect(SP_LPE_ITEM(other), false, false); +// } } void @@ -483,13 +472,11 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) end_point.param_update_default(point_b); center_point.param_setValue(point_c); previous_center = center_point; -// SPLPEItem * splpeitem = const_cast(lpeitem); -// if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet -// const char * mirror_a = g_strdup(Glib::ustring("mirror-a-").append(this->getRepr()->attribute("id")).c_str()); -// splpeitem->setAttribute("id", mirror_a); -// first_lpe.param_setValue(this->getRepr()->attribute("id")); -// first_lpe.write_to_SVG(); -// } + SPLPEItem * splpeitem = const_cast(lpeitem); + if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet + id_origin.param_setValue(lpeitem->getRepr()->attribute("id")); + id_origin.write_to_SVG(); + } } @@ -506,26 +493,10 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) path_out = pathv_to_linear_and_cubic_beziers(path_in); } - Geom::Point point_a(line_separation.initialPoint()); - Geom::Point point_b(line_separation.finalPoint()); - - Geom::Translate m1(point_a[0], point_a[1]); - double hyp = Geom::distance(point_a, point_b); - double cos = 0; - double sin = 0; - if (hyp > 0) { - cos = (point_b[0] - point_a[0]) / hyp; - sin = (point_b[1] - point_a[1]) / hyp; - } - Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); - Geom::Scale sca(1.0, -1.0); + Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); + Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); - Geom::Affine m = m1.inverse() * m2; - m = m * sca; - m = m * m2.inverse(); - m = m * m1; - - if (fuse_paths && (!discard_orig_path || split_elements )) { + if (fuse_paths && !discard_orig_path) { for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -550,7 +521,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) } Geom::Point s = start_point; Geom::Point e = end_point; - double dir = line_separation.angle(); + double dir = ls.angle(); double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); double size_divider = Geom::distance(center_point, bbox) + diagonal; @@ -577,7 +548,9 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) if (position == 1) { Geom::Path mirror = portion.reversed() * m; if (split_elements) { - portion.close(); + if(i!=0 || original.closed()) { + portion.close(); + } } else { mirror.setInitial(portion.finalPoint()); portion.append(mirror); @@ -626,7 +599,9 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) } if (cs.size() == 0 && position == 1) { tmp_path.push_back(original); - tmp_path.push_back(original * m); + if ( !split_elements) { + tmp_path.push_back(original * m); + } } path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 12ceebaf8..b05871cd0 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -42,17 +42,16 @@ public: virtual ~LPEMirrorSymmetry(); virtual void doOnApply (SPLPEItem const* lpeitem); virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doAfterEffect (SPLPEItem const* lpeitem); virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); -// virtual Gtk::Widget * newWidget(); + virtual Gtk::Widget * newWidget(); void processObjects(LpeAction lpe_action); - void createMirror(SPLPEItem *origin, Geom::Affine transform); -// void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); -// void syncMirror(SPLPEItem *origin, const char * id); + void createMirror(Geom::Affine transform); + // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...); - bool allow_split(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -67,10 +66,12 @@ private: PointParam start_point; PointParam end_point; PointParam center_point; - Geom::Line line_separation; + TextParam id_origin; Geom::Point previous_center; std::vector elements; SPObject * container; + SPObject * other; + Geom::Affine last_transform; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); }; diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index af99ef362..813c06b4e 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -72,7 +72,7 @@ BoolParam::param_newWidget() checkwdg->setActive(value); checkwdg->setProgrammatically = false; checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change bool parameter")); - + param_effect->upd_params = false; return dynamic_cast (checkwdg); } else { return NULL; @@ -82,6 +82,7 @@ BoolParam::param_newWidget() void BoolParam::param_setValue(bool newvalue) { + param_effect->upd_params = true; value = newvalue; } diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 8cab68ad0..5c4cdf4c6 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -125,13 +125,14 @@ TextParam::param_newWidget() rsu->setProgrammatically = false; rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change text parameter")); - + param_effect->upd_params = false; return dynamic_cast (rsu); } void TextParam::param_setValue(const Glib::ustring newvalue) { + param_effect->upd_params = true; value = newvalue; if (!_hide_canvas_text) { sp_canvastext_set_text (canvas_text, newvalue.c_str()); -- cgit v1.2.3 From 69c944a3622fe17cddb8caa4a515b7535807d1bd Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 19 Dec 2016 22:59:28 +0100 Subject: Fix minor bug (bzr r15295.1.30) --- src/live_effects/lpe-mirror_symmetry.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 65177579d..f2238eab6 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -375,6 +375,7 @@ LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) void LPEMirrorSymmetry::processObjects(LpeAction lpe_action) { + SPDocument * document = SP_ACTIVE_DOCUMENT; for (std::vector::iterator el_it = elements.begin(); el_it != elements.end(); ++el_it) { const char * id = *el_it; -- cgit v1.2.3 From 440735f0a9b66cf638e3932c456a8fbfe214e2cd Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 20 Dec 2016 01:29:00 +0100 Subject: Fix strings in mirror symetry and copy rotate LPE (bzr r15295.1.31) --- src/live_effects/lpe-mirror_symmetry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index f2238eab6..744ab58e5 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -57,10 +57,10 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints. Group result to apply nested"), "split_elements", &wr, this, false), - start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust the start of mirroring")), + start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust start of mirroring")), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), - id_origin("hidden", "hidden store the id of the first LPEItem", "id_origin", &wr, this,"") + id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,"") { show_orig_path = true; registerParameter(&mode); -- cgit v1.2.3 From 0f1a4f260fe919cc77033cf62b9d15a330f32ab5 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 26 Dec 2016 10:24:58 +0100 Subject: fixing things (bzr r15295.1.38) --- src/live_effects/lpe-mirror_symmetry.cpp | 100 ++++++++++++++++++------------- src/live_effects/lpe-mirror_symmetry.h | 1 + 2 files changed, 58 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index aedb4e11f..5464c2bad 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -26,6 +26,7 @@ #include "2geom/path-intersection.h" #include "2geom/affine.h" #include "helper/geom.h" +#include "sp-lpe-item.h" #include "uri.h" #include "uri-references.h" #include "path-chemistry.h" @@ -87,9 +88,31 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry() { } +bool +LPEMirrorSymmetry::isCurrentLPEItem() { + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::Selection *sel = desktop->getSelection(); + if ( sel && !sel->isEmpty()) { + SPItem *item = sel->singleItem(); + if (item) { + if(sp_lpe_item && std::strcmp(sp_lpe_item->getId(),item->getId()) == 0) { + return true; + } + } + } + } + return false; +} + void LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) { + std::cout << sp_lpe_item->getId() << "111111111111111111111111111111\n"; + std::cout << lpeitem->getId() << "22222222222222222222222222222222222222222\n"; + if (!isCurrentLPEItem()) { + return; + } + std::cout << "dgagsdgsdgsdgsdgsdgsdgsdgsd\n"; last_transform = Geom::identity(); if (split_elements) { if (discard_orig_path) { @@ -126,6 +149,7 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) // m = m * m1; m = m * sp_lpe_item->transform; // if (std::strcmp(sp_lpe_item->getId(), origin) != 0) { +std::cout << m << "m\n"; createMirror(m); // } else { // createMirror(sp_lpe_item, m, mirror); @@ -140,19 +164,12 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) void LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { - if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - Inkscape::Selection *sel = desktop->getSelection(); - if ( sel && !sel->isEmpty()) { - SPItem *item = sel->singleItem(); - if (item) { - if(std::strcmp(sp_lpe_item->getId(),item->getId()) != 0) { - return; - } - } - } - } + using namespace Geom; original_bbox(lpeitem); + if (!isCurrentLPEItem()) { + return; + } //center_point->param_set_liveupdate(false); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); @@ -164,7 +181,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) point_a = Geom::Point(center_point[X],boundingbox_Y.min()); point_b = Geom::Point(center_point[X],boundingbox_Y.max()); } - if ((Geom::Point)start_point == (Geom::Point)end_point && (Geom::Point)start_point == Geom::Point(0,0)) { + if ((Geom::Point)start_point == (Geom::Point)end_point) { start_point.param_setValue(point_a, true); end_point.param_setValue(point_b, true); previous_center = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); @@ -274,16 +291,9 @@ LPEMirrorSymmetry::createMirror(Geom::Affine transform) { SPDocument * document = SP_ACTIVE_DOCUMENT; const char * id_origin_char = id_origin.param_getSVGValue(); - const char * mirror = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); - const char * elemref_id; - if (std::strcmp(sp_lpe_item->getId(), mirror) == 0) { - elemref_id = id_origin_char; - } else { - elemref_id = mirror; - } + const char * elemref_id = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); elements.clear(); - elements.push_back(id_origin_char); - elements.push_back(mirror); + elements.push_back(elemref_id); Inkscape::XML::Document *xml_doc = document->getReprDoc(); SPObject *elemref= NULL; Inkscape::XML::Node *phantom = NULL; @@ -297,14 +307,16 @@ LPEMirrorSymmetry::createMirror(Geom::Affine transform) elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneAttrbutes(SP_OBJECT(sp_lpe_item), elemref, true, "inkscape:original-d", "d", "inkscape:path-effect", NULL); //NULL required + cloneAttrbutes(SP_OBJECT(sp_lpe_item), elemref, true, "d", NULL); //NULL required //transform *= last_transform; //if (transform != Geom::identity()) { - if (elemref_id == mirror) { - elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); - } else { - sp_lpe_item->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); - } + elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); + Inkscape::LivePathEffect::LPEObjectReference* lperef = SP_LPE_ITEM(elemref)->getCurrentLPEReference(); + if (lperef) { + PathEffectList * new_list = SP_LPE_ITEM(elemref)->path_effect_list; + new_list->remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list + elemref->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); + } //} if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); @@ -331,7 +343,7 @@ LPEMirrorSymmetry::newWidget() while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter * param = *it; - if (param->param_key == "id_origin") { + if (param->param_key == "id_origin" || param->param_key == "center_point") { ++it; continue; } @@ -432,21 +444,23 @@ void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { // cycle through all parameters. Most parameters will not need transformation, but path and point params do. - for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { - Parameter * param = *it; - param->param_transform_multiply(postmul, set); + if (isCurrentLPEItem()) { + for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { + Parameter * param = *it; + param->param_transform_multiply(postmul, set); + } + previous_center = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); + + // Geom::Affine m = Geom::identity(); + // m *= sp_lpe_item->transform; + // m *= postmul; + // sp_lpe_item->transform = m; + //last_transform *= postmul; + sp_lpe_item_update_patheffect(sp_lpe_item, false, false); + // if (other) { + // sp_lpe_item_update_patheffect(SP_LPE_ITEM(other), false, false); + // } } - previous_center = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); - -// Geom::Affine m = Geom::identity(); -// m *= sp_lpe_item->transform; -// m *= postmul; -// sp_lpe_item->transform = m; - last_transform *= postmul; - sp_lpe_item_update_patheffect(sp_lpe_item, false, false); -// if (other) { -// sp_lpe_item_update_patheffect(SP_LPE_ITEM(other), false, false); -// } } @@ -477,7 +491,7 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) Geom::PathVector LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) { - if (split_elements && !fuse_paths) { + if (split_elements && !fuse_paths || !isCurrentLPEItem()) { return path_in; } Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index b05871cd0..765f2740f 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -50,6 +50,7 @@ public: virtual Gtk::Widget * newWidget(); void processObjects(LpeAction lpe_action); void createMirror(Geom::Affine transform); + bool isCurrentLPEItem(); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...); -- cgit v1.2.3 From 50714133d92da517b5185385ea4c553408c80e54 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Wed, 28 Dec 2016 09:42:19 +0100 Subject: First attemp working (bzr r15356.1.1) --- src/live_effects/CMakeLists.txt | 6 ++ src/live_effects/effect.cpp | 10 +- src/live_effects/effect.h | 1 + src/live_effects/lpe-clone-original.cpp | 169 ++++++++++++++++++++++++++++++-- src/live_effects/lpe-clone-original.h | 20 +++- src/sp-ellipse.cpp | 13 ++- src/sp-item-group.cpp | 37 ++++--- src/sp-lpe-item.cpp | 21 ++-- src/sp-lpe-item.h | 3 +- src/sp-object.cpp | 14 +++ src/sp-object.h | 3 + src/sp-path.cpp | 4 +- src/ui/clipboard.cpp | 2 + 13 files changed, 261 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 784317090..5ffccc7c0 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -60,6 +60,9 @@ set(live_effects_SRC parameter/array.cpp parameter/bool.cpp parameter/filletchamferpointarray.cpp + parameter/item-reference.cpp + parameter/item.cpp + parameter/originalitem.cpp parameter/originalpath.cpp parameter/originalpatharray.cpp parameter/parameter.cpp @@ -142,6 +145,9 @@ set(live_effects_SRC parameter/bool.h parameter/enum.h parameter/filletchamferpointarray.h + parameter/item.h + parameter/item-reference.h + parameter/originalitem.h parameter/originalpath.h parameter/originalpatharray.h parameter/parameter.h diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 5cc0d6f20..cfd393b87 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -116,7 +116,7 @@ const Util::EnumData LPETypeData[] = { {RULER, N_("Ruler"), "ruler"}, /* 0.91 */ {POWERSTROKE, N_("Power stroke"), "powerstroke"}, - {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, + {CLONE_ORIGINAL, N_("Clone original"), "clone_original"}, /* 0.92 */ {SIMPLIFY, N_("Simplify"), "simplify"}, {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, @@ -457,8 +457,7 @@ void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) //printf("(SPLPEITEM*) %p\n", sp_lpe_item); SPShape * shape = dynamic_cast(sp_lpe_item); if(shape){ - sp_curve = shape->getCurve(); - pathvector_before_effect = sp_curve->get_pathvector(); + setSPCurve(shape->getCurve()); } doBeforeEffect(lpeitem); if (apply_to_clippath_and_mask && SP_IS_GROUP(sp_lpe_item)) { @@ -468,6 +467,11 @@ void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) update_helperpath(); } +void Effect::setSPCurve(SPCurve *curve) +{ + sp_curve = curve; + pathvector_before_effect = curve->get_pathvector(); +} /** * Effects can have a parameter path set before they are applied by accepting a nonzero number of * mouse clicks. This method activates the pen context, which waits for the specified number of diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 1997ff0ca..e975deb05 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -73,6 +73,7 @@ public: static int acceptsNumClicks(EffectType type); int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } void doAcceptPathPreparations(SPLPEItem *lpeitem); + void setSPCurve(SPCurve *curve); /* * isReady() indicates whether all preparations which are necessary to apply the LPE are done, diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 10418a02d..be8bc9e0d 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -6,6 +6,11 @@ #include "live_effects/lpe-clone-original.h" #include "display/curve.h" +#include "svg/path-string.h" +#include "svg/svg.h" +#include +#include "xml/sp-css-attr.h" + // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -14,9 +19,148 @@ namespace LivePathEffect { LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : Effect(lpeobject), - linked_path(_("Linked path:"), _("Path from which to take the original path data"), "linkedpath", &wr, this) + linked_item(_("Linked Item:"), _("Item from which to take the original data"), "linked_item", &wr, this), + preserve_position(_("Preserve position"), _("Preserve position"), "preserve_position", &wr, this, false), + attributes("Attributes linked", "Attributes linked", "attributes", &wr, this,""), + style_attributes("Style attributes linked", "Style attributes linked", "style_attributes", &wr, this,"") { - registerParameter( dynamic_cast(&linked_path) ); + registerParameter(&linked_item); + registerParameter(&attributes); + registerParameter(&style_attributes); + registerParameter(&preserve_position); + attributes.param_hide_canvas_text(); + style_attributes.param_hide_canvas_text(); + apply_to_clippath_and_mask = true; +} + +void +LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...) +{ + va_list args; + va_start(args, first_attribute); + SPDocument * document = SP_ACTIVE_DOCUMENT; + if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { + std::vector< SPObject * > childs = origin->childList(true); + size_t index = 0; + for (std::vector::iterator obj_it = childs.begin(); + obj_it != childs.end(); ++obj_it) { + SPObject *dest_child = dest->nthChild(index); + cloneAttrbutes(*obj_it, dest_child, live, first_attribute, args); + index++; + } + } + SPShape * shape_origin = SP_SHAPE(origin); + SPShape * shape_dest = SP_SHAPE(dest); + for (const char* att = first_attribute; att != NULL; att = va_arg(args, const char*)) { + std::vector elems; + boost::split(elems, att, boost::is_any_of(",")); + for (std::vector::const_iterator atts = elems.begin(); + atts != elems.end(); ++atts) { + const char* attribute = (*atts).c_str(); + if ( std::strcmp(attribute, "transform") == 0 ) { + Geom::Affine affine_dest = Geom::identity(); + sp_svg_transform_read(SP_ITEM(dest)->getAttribute("transform"), &affine_dest); + dest->getRepr()->setAttribute(attribute, origin->getRepr()->attribute(attribute)); + if (preserve_position) { + Geom::Affine affine_origin = Geom::identity(); + sp_svg_transform_read(SP_ITEM(origin)->getAttribute("transform"), &affine_origin); + SP_ITEM(dest)->transform = Geom::Translate(affine_dest.translation()) * Geom::Translate(affine_origin.translation()).inverse() * affine_origin; + } + } else if ( shape_dest && shape_origin && live && (std::strcmp(attribute, "d") == 0 || std::strcmp(attribute, "inkscape:original-d") == 0)) { + SPCurve *c = NULL; + if (std::strcmp(attribute, "d") == 0) { + c = shape_origin->getCurve(); + } else { + c = shape_origin->getCurveBeforeLPE(); + } + if (c) { + Geom::PathVector c_pv = c->get_pathvector(); + if (preserve_position) { + Geom::OptRect orig_bbox = SP_ITEM(origin)->geometricBounds(); + if (orig_bbox) { + c_pv *= Geom::Translate(Geom::Point(boundingbox_X.min(), boundingbox_Y.min()) - (*orig_bbox).corner(0)); + } + } + c->set_pathvector(c_pv); + shape_dest->setCurveInsync(c, TRUE); + dest->getRepr()->setAttribute(attribute, sp_svg_write_path(c_pv)); + c->unref(); + } else { + dest->getRepr()->setAttribute(attribute, NULL); + } + } else { + dest->getRepr()->setAttribute(attribute, origin->getRepr()->attribute(attribute)); + } + } + } + va_end(args); +} + +void +LPECloneOriginal::cloneStyleAttrbutes(SPObject *origin, SPObject *dest, const char * first_attribute, ...) +{ + va_list args; + va_start(args, first_attribute); + + if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { + std::vector< SPObject * > childs = origin->childList(true); + size_t index = 0; + for (std::vector::iterator obj_it = childs.begin(); + obj_it != childs.end(); ++obj_it) { + SPObject *dest_child = dest->nthChild(index); + cloneStyleAttrbutes(*obj_it, dest_child, first_attribute, args); + index++; + } + } + SPCSSAttr *css_origin = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css_origin, origin->getRepr()->attribute("style")); + SPCSSAttr *css_dest = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css_dest, dest->getRepr()->attribute("style")); + for (const char* att = first_attribute; att != NULL; att = va_arg(args, const char*)) { + std::vector elems; + boost::split(elems, att, boost::is_any_of(",")); + for (std::vector::const_iterator atts = elems.begin(); + atts != elems.end(); ++atts) { + const char* attribute = (*atts).c_str(); + const char* origin_attribute = sp_repr_css_property(css_origin, attribute, ""); + if (origin_attribute == "") { + sp_repr_css_set_property (css_dest, attribute, NULL); + } else { + sp_repr_css_set_property (css_dest, attribute, origin_attribute); + } + } + Glib::ustring css_str; + sp_repr_css_write_string(css_dest,css_str); + dest->getRepr()->setAttribute("style", css_str.c_str()); + } + va_end(args); +} + +void +LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ + original_bbox(lpeitem); + if (linked_item.linksToItem() && sp_lpe_item) { + cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, attributes.param_getSVGValue(), NULL); //NULL required + cloneStyleAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), style_attributes.param_getSVGValue(), NULL); //NULL required + SPShape * shape = dynamic_cast(sp_lpe_item); + if(shape){ + this->setSPCurve(shape->getCurve()); + } + } +} + +void +LPECloneOriginal::doOnApply(SPLPEItem const* lpeitem){ + Glib::ustring attributes_value("d,transform"); + attributes.param_setValue(attributes_value); + attributes.write_to_SVG(); + Glib::ustring style_attributes_value("opacity,border-width"); + style_attributes.param_setValue(style_attributes_value); + style_attributes.write_to_SVG(); +} + +void +LPECloneOriginal::doAfterEffect (SPLPEItem const* lpeitem){ } LPECloneOriginal::~LPECloneOriginal() @@ -26,12 +170,21 @@ LPECloneOriginal::~LPECloneOriginal() void LPECloneOriginal::doEffect (SPCurve * curve) { - if ( linked_path.linksToPath() ) { - Geom::PathVector linked_pathv = linked_path.get_pathvector(); - if ( !linked_pathv.empty() ) { - curve->set_pathvector(linked_pathv); - } - } +// std::vector elems; +// const char * attrs = attributes.param_getSVGValue(); +// boost::split(elems, attrs, boost::is_any_of(",")); +// bool has_d = false; +// for (std::vector::const_iterator atts = elems.begin(); +// atts != elems.end(); ++atts) { +// const char* attribute = (*atts).c_str(); +// if (std::strcmp(attribute, "d") == 0) { +// has_d = true; +// } +// } +// if (linked_item.linksToItem() && has_d) { +// curve->reset(); +// } + curve->set_pathvector(pathvector_before_effect); } } // namespace LivePathEffect diff --git a/src/live_effects/lpe-clone-original.h b/src/live_effects/lpe-clone-original.h index abf65ded8..148590695 100644 --- a/src/live_effects/lpe-clone-original.h +++ b/src/live_effects/lpe-clone-original.h @@ -10,22 +10,32 @@ */ #include "live_effects/effect.h" -#include "live_effects/parameter/originalpath.h" +#include "live_effects/parameter/originalitem.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/point.h" +#include "live_effects/parameter/text.h" +#include "live_effects/lpegroupbbox.h" namespace Inkscape { namespace LivePathEffect { -class LPECloneOriginal : public Effect { +class LPECloneOriginal : public Effect, GroupBBoxEffect { public: LPECloneOriginal(LivePathEffectObject *lpeobject); virtual ~LPECloneOriginal(); virtual void doEffect (SPCurve * curve); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doAfterEffect (SPLPEItem const* lpeitem); + virtual void doOnApply(SPLPEItem const* lpeitem); + void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...); + void cloneStyleAttrbutes(SPObject *origin, SPObject *dest, const char * first_attribute, ...); private: - OriginalPathParam linked_path; - -private: + OriginalItemParam linked_item; + BoolParam preserve_position; + TextParam attributes; + TextParam style_attributes; LPECloneOriginal(const LPECloneOriginal&); LPECloneOriginal& operator=(const LPECloneOriginal&); }; diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index ed1e2b504..9589d6fce 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -445,11 +445,20 @@ void SPGenericEllipse::set_shape() if (hasPathEffect() && pathEffectsEnabled()) { SPCurve *c_lpe = curve->copy(); bool success = this->performPathEffect(c_lpe); - + if (success) { this->setCurveInsync(c_lpe, TRUE); + } else { + Inkscape::XML::Node *repr = this->getRepr(); + if (gchar const * value = repr->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); + if (oldcurve) { + this->setCurveInsync(oldcurve, TRUE); + oldcurve->unref(); + } + } } - c_lpe->unref(); } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 7b2507b5e..808d475c7 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -950,25 +950,36 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) } else { c = subShape->getCurve(); } - + bool success = false; // only run LPEs when the shape has a curve defined if (c) { c->transform(i2anc_affine(subitem, topgroup)); - topgroup->performPathEffect(c); + success = topgroup->performPathEffect(c, subShape); c->transform(i2anc_affine(subitem, topgroup).inverse()); - subShape->setCurve(c, TRUE); - - if (write) { + if (c && success) { + subShape->setCurve(c, TRUE); + if (write) { + Inkscape::XML::Node *repr = subitem->getRepr(); + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); + #ifdef GROUP_VERBOSE + g_message("sp_group_perform_patheffect writes 'd' attribute"); + #endif + g_free(str); + } + c->unref(); + } else { + // LPE was unsuccesfull or doeffect stack return null. Read the old 'd'-attribute. Inkscape::XML::Node *repr = subitem->getRepr(); - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); -#ifdef GROUP_VERBOSE - g_message("sp_group_perform_patheffect writes 'd' attribute"); -#endif - g_free(str); + if (gchar const * value = repr->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); + if (oldcurve) { + subShape->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } } - - c->unref(); } } } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index e2f61bfb5..f5c930404 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -209,7 +209,7 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { +bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { if (!curve) { return false; @@ -244,9 +244,11 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { if (!SP_IS_GROUP(this)) { lpe->doBeforeEffect_impl(this); } - + if (SP_IS_GROUP(this) && current) { + lpe->setSPCurve(current->getCurve()); + } try { - lpe->doEffect(curve); + lpe->doEffect(curve); } catch (std::exception & e) { g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); @@ -695,10 +697,10 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) try { if(SP_IS_GROUP(this)){ c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(c, true); + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); } else { - success = this->performPathEffect(c, true); + success = this->performPathEffect(c, NULL, true); } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -709,12 +711,13 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) success = false; } Inkscape::XML::Node *repr = clip_mask->getRepr(); - if (success) { + // This c check allow to not apply LPE if curve is NULL after performPathEffect used in clone.obgets LPE + if (success && c) { gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); g_free(str); } else { - // LPE was unsuccesfull. Read the old 'd'-attribute. + // LPE was unsuccesfull or doeffect stack return null.. Read the old 'd'-attribute. if (gchar const * value = repr->attribute("d")) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); @@ -724,7 +727,9 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) } } } - c->unref(); + if (c) { + c->unref(); + } } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 9e5cb3329..9cf868cf2 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -23,6 +23,7 @@ class LivePathEffectObject; class SPCurve; +class SPShape; class SPDesktop; namespace Inkscape{ @@ -69,7 +70,7 @@ public: virtual void update_patheffect(bool write); - bool performPathEffect(SPCurve *curve, bool is_clip_or_mask = false); + bool performPathEffect(SPCurve *curve, SPShape *current = NULL, bool is_clip_or_mask = false); bool pathEffectsEnabled() const; bool hasPathEffect() const; diff --git a/src/sp-object.cpp b/src/sp-object.cpp index e9c60fc7d..c2122e109 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -773,6 +773,20 @@ void SPObject::appendChild(Inkscape::XML::Node *child) { repr->appendChild(child); } +SPObject* SPObject::nthChild(unsigned index) { + g_assert(this->repr); + if (hasChildren()) { + std::vector l; + unsigned counter = 0; + for (auto& child: children) { + if (counter == index) { + return &child; + } + } + } + return NULL; +} + void SPObject::addChild(Inkscape::XML::Node *child, Inkscape::XML::Node * prev) { g_assert(this->repr); diff --git a/src/sp-object.h b/src/sp-object.h index 9abbd324b..d145e966b 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -318,6 +318,9 @@ public: SPObject *lastChild() { return children.empty() ? nullptr : &children.back(); } SPObject const *lastChild() const { return children.empty() ? nullptr : &children.back(); } + SPObject *nthChild(unsigned index); + SPObject const *nthChild(unsigned index) const; + enum Action { ActionGeneral, ActionBBox, ActionUpdate, ActionShow }; /** diff --git a/src/sp-path.cpp b/src/sp-path.cpp index b593b7937..0a2ce4c09 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -354,9 +354,9 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); if (gchar const * value = repr->attribute("d")) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new SPCurve(pv); - if (oldcurve) { - this->setCurve(oldcurve, TRUE); + this->setCurveInsync(oldcurve, TRUE); + repr->setAttribute("d", value); oldcurve->unref(); } } diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index a8e708597..42fc2fab4 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -410,6 +410,8 @@ const gchar *ClipboardManagerImpl::getFirstObjectID() strcmp(ch->name(), "svg:use") && strcmp(ch->name(), "svg:text") && strcmp(ch->name(), "svg:image") && + strcmp(ch->name(), "svg:ellipse") && + strcmp(ch->name(), "svg:circle") && strcmp(ch->name(), "svg:rect") ) { ch = ch->next(); -- cgit v1.2.3 From dade3a4aa7da7579145341ee8e63149de053d99a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 28 Dec 2016 17:39:41 +0100 Subject: Fixing transforms and adding scale (bzr r15356.2.1) --- src/live_effects/lpe-clone-original.cpp | 25 +++++++++++++++++-------- src/live_effects/lpe-clone-original.h | 1 + 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index be8bc9e0d..d702e98d5 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -20,14 +20,19 @@ namespace LivePathEffect { LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : Effect(lpeobject), linked_item(_("Linked Item:"), _("Item from which to take the original data"), "linked_item", &wr, this), + scale(_("Scale %"), _("Scale item %"), "scale", &wr, this, 100.0), preserve_position(_("Preserve position"), _("Preserve position"), "preserve_position", &wr, this, false), attributes("Attributes linked", "Attributes linked", "attributes", &wr, this,""), style_attributes("Style attributes linked", "Style attributes linked", "style_attributes", &wr, this,"") { registerParameter(&linked_item); + registerParameter(&scale); registerParameter(&attributes); registerParameter(&style_attributes); registerParameter(&preserve_position); + scale.param_set_range(0.01, 999999.0); + scale.param_set_increments(1, 1); + scale.param_set_digits(2); attributes.param_hide_canvas_text(); style_attributes.param_hide_canvas_text(); apply_to_clippath_and_mask = true; @@ -58,13 +63,12 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co atts != elems.end(); ++atts) { const char* attribute = (*atts).c_str(); if ( std::strcmp(attribute, "transform") == 0 ) { - Geom::Affine affine_dest = Geom::identity(); - sp_svg_transform_read(SP_ITEM(dest)->getAttribute("transform"), &affine_dest); + Geom::Affine affine_dest = SP_ITEM(dest)->transform; dest->getRepr()->setAttribute(attribute, origin->getRepr()->attribute(attribute)); + Geom::Affine affine_origin = Geom::identity(); + sp_svg_transform_read(SP_ITEM(origin)->getAttribute("transform"), &affine_origin); if (preserve_position) { - Geom::Affine affine_origin = Geom::identity(); - sp_svg_transform_read(SP_ITEM(origin)->getAttribute("transform"), &affine_origin); - SP_ITEM(dest)->transform = Geom::Translate(affine_dest.translation()) * Geom::Translate(affine_origin.translation()).inverse() * affine_origin; + SP_ITEM(dest)->transform = Geom::Translate(affine_dest.translation()) * Geom::Translate(affine_origin.translation()).inverse() * affine_origin ; } } else if ( shape_dest && shape_origin && live && (std::strcmp(attribute, "d") == 0 || std::strcmp(attribute, "inkscape:original-d") == 0)) { SPCurve *c = NULL; @@ -75,11 +79,16 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co } if (c) { Geom::PathVector c_pv = c->get_pathvector(); - if (preserve_position) { - Geom::OptRect orig_bbox = SP_ITEM(origin)->geometricBounds(); - if (orig_bbox) { + Geom::OptRect orig_bbox = SP_ITEM(origin)->geometricBounds(); + if (orig_bbox) { + if (preserve_position) { c_pv *= Geom::Translate(Geom::Point(boundingbox_X.min(), boundingbox_Y.min()) - (*orig_bbox).corner(0)); } + if (scale != 100.0) { + double scale_affine = scale/100.0; + Geom::Affine scale = Geom::Affine(Geom::Scale(scale_affine)); + c_pv *= Geom::Translate((*orig_bbox).corner(0)) * scale * Geom::Translate((*orig_bbox).corner(0)).inverse(); + } } c->set_pathvector(c_pv); shape_dest->setCurveInsync(c, TRUE); diff --git a/src/live_effects/lpe-clone-original.h b/src/live_effects/lpe-clone-original.h index 148590695..bec835ae1 100644 --- a/src/live_effects/lpe-clone-original.h +++ b/src/live_effects/lpe-clone-original.h @@ -33,6 +33,7 @@ public: private: OriginalItemParam linked_item; + ScalarParam scale; BoolParam preserve_position; TextParam attributes; TextParam style_attributes; -- cgit v1.2.3 From fd45bf5cbe22dddb7b016a3025f3553dbb0f1e27 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 28 Dec 2016 17:42:27 +0100 Subject: Fixing scale (bzr r15356.2.2) --- src/live_effects/lpe-clone-original.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index d702e98d5..04afe00e2 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -87,7 +87,7 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co if (scale != 100.0) { double scale_affine = scale/100.0; Geom::Affine scale = Geom::Affine(Geom::Scale(scale_affine)); - c_pv *= Geom::Translate((*orig_bbox).corner(0)) * scale * Geom::Translate((*orig_bbox).corner(0)).inverse(); + c_pv *= Geom::Translate((*orig_bbox).corner(0)).inverse() * scale * Geom::Translate((*orig_bbox).corner(0)); } } c->set_pathvector(c_pv); -- cgit v1.2.3 From 50fca17129701b09a9049e4469ca39d0c06c15a7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 28 Dec 2016 17:46:37 +0100 Subject: Fixing scale (bzr r15356.2.3) --- src/live_effects/lpe-clone-original.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 04afe00e2..4ba752b85 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -87,7 +87,11 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co if (scale != 100.0) { double scale_affine = scale/100.0; Geom::Affine scale = Geom::Affine(Geom::Scale(scale_affine)); - c_pv *= Geom::Translate((*orig_bbox).corner(0)).inverse() * scale * Geom::Translate((*orig_bbox).corner(0)); + if (preserve_position) { + c_pv *= Geom::Translate(Geom::Point(boundingbox_X.min(), boundingbox_Y.min()) - (*orig_bbox).corner(0)).inverse() * scale * Geom::Translate(Geom::Point(boundingbox_X.min(), boundingbox_Y.min()) - (*orig_bbox).corner(0)); + } else { + c_pv *= Geom::Translate((*orig_bbox).corner(0)).inverse() * scale * Geom::Translate((*orig_bbox).corner(0)); + } } } c->set_pathvector(c_pv); -- cgit v1.2.3 From f69e17d45c7311cb8430caa03f4f41be63ac9279 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Thu, 29 Dec 2016 21:32:45 +0100 Subject: Add sp_shape to LPE chain and fixing transforms (bzr r15356.1.4) --- src/live_effects/effect.cpp | 41 ++++++++++++++++++++------------- src/live_effects/effect.h | 9 ++++---- src/live_effects/lpe-clone-original.cpp | 33 ++++++++++++++++++-------- src/live_effects/lpe-clone-original.h | 4 +++- src/sp-lpe-item.cpp | 6 ++--- 5 files changed, 60 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index cfd393b87..81a512d23 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -356,7 +356,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), - sp_curve(NULL), + sp_shape(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden { @@ -392,9 +392,9 @@ Effect::doOnApply (SPLPEItem const*/*lpeitem*/) } void -Effect::setSelectedNodePoints(std::vector sNP) +Effect::setSelectedNodePoints(std::vector selected_np) { - selectedNodesPoints = sNP; + selected_nodes_points = selected_np; } void @@ -404,16 +404,16 @@ Effect::setCurrentZoom(double cZ) } bool -Effect::isNodePointSelected(Geom::Point const &nodePoint) const +Effect::isNodePointSelected(Geom::Point const &node_point) const { - if (selectedNodesPoints.size() > 0) { + if (selected_nodes_points.size() > 0) { using Geom::X; using Geom::Y; - for (std::vector::const_iterator i = selectedNodesPoints.begin(); - i != selectedNodesPoints.end(); ++i) { + for (std::vector::const_iterator i = selected_nodes_points.begin(); + i != selected_nodes_points.end(); ++i) { Geom::Point p = *i; Geom::Affine transformCoordinate = sp_lpe_item->i2dt_affine(); - Geom::Point p2(nodePoint[X],nodePoint[Y]); + Geom::Point p2(node_point[X], node_point[Y]); p2 *= transformCoordinate; if (Geom::are_near(p, p2, 0.01)) { return true; @@ -446,20 +446,24 @@ void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - /*sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); - pathvector_before_effect = sp_curve->get_pathvector();*/ + SPShape * shape = dynamic_cast(sp_lpe_item); + if(shape){ + setCurrentShape(shape); + } doOnApply(lpeitem); } void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - //printf("(SPLPEITEM*) %p\n", sp_lpe_item); + //Groups set shape in performPathEffect before each call to doEffect SPShape * shape = dynamic_cast(sp_lpe_item); if(shape){ - setSPCurve(shape->getCurve()); + setCurrentShape(shape); } + //printf("(SPLPEITEM*) %p\n", sp_lpe_item); doBeforeEffect(lpeitem); + if (apply_to_clippath_and_mask && SP_IS_GROUP(sp_lpe_item)) { sp_lpe_item->apply_to_clippath(sp_lpe_item); sp_lpe_item->apply_to_mask(sp_lpe_item); @@ -467,10 +471,15 @@ void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) update_helperpath(); } -void Effect::setSPCurve(SPCurve *curve) -{ - sp_curve = curve; - pathvector_before_effect = curve->get_pathvector(); +void Effect::setCurrentShape(SPShape * shape){ + if(shape){ + sp_shape = shape; + if (!(sp_curve = sp_shape->getCurve())) { + // oops + return; + } + pathvector_before_effect = sp_curve->get_pathvector(); + } } /** * Effects can have a parameter path set before they are applied by accepting a nonzero number of diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index e975deb05..5dfa3de29 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -73,8 +73,8 @@ public: static int acceptsNumClicks(EffectType type); int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } void doAcceptPathPreparations(SPLPEItem *lpeitem); - void setSPCurve(SPCurve *curve); - + SPShape * getCurrentShape(){ return sp_shape; }; + void setCurrentShape(SPShape * shape); /* * isReady() indicates whether all preparations which are necessary to apply the LPE are done, * e.g., waiting for a parameter path either before the effect is created or when it needs a @@ -164,9 +164,10 @@ protected: // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each. bool concatenate_before_pwd2; - SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. + SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them.z + SPShape * sp_shape; // these get stored in doBeforeEffect_impl before doEffect chain, or in performPathEffects on groups, and derived classes may do as they please with them. double current_zoom; - std::vector selectedNodesPoints; + std::vector selected_nodes_points; SPCurve * sp_curve; Geom::PathVector pathvector_before_effect; private: diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 7072ad161..8176f3811 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -37,10 +37,12 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : attributes.param_hide_canvas_text(); style_attributes.param_hide_canvas_text(); apply_to_clippath_and_mask = true; + preserve_position_changed = !preserve_position; + preserve_affine = Geom::identity(); } void -LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes) +LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes, bool root) { SPDocument * document = SP_ACTIVE_DOCUMENT; if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { @@ -49,7 +51,7 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneAttrbutes(*obj_it, dest_child, live, attributes, style_attributes); + cloneAttrbutes(*obj_it, dest_child, live, attributes, style_attributes, false); index++; } } @@ -65,7 +67,15 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co Geom::Affine affine_origin = SP_ITEM(origin)->transform; //dest->getRepr()->setAttribute(attribute, origin->getRepr()->attribute(attribute)); if (preserve_position) { - SP_ITEM(dest)->transform = Geom::Translate(affine_dest.translation()) * Geom::Translate(affine_origin.translation()).inverse() * affine_origin ; + Geom::Affine dest_affine = Geom::identity(); + if (root) { + dest_affine *= Geom::Translate(preserve_affine.translation()); + preserve_affine = Geom::identity(); + } + dest_affine *= Geom::Translate(affine_dest.translation()); + dest_affine *= Geom::Translate(affine_origin.translation()).inverse(); + dest_affine *= affine_origin; + SP_ITEM(dest)->transform = dest_affine; } else { SP_ITEM(dest)->transform = affine_origin ; } @@ -131,6 +141,12 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co void LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ original_bbox(lpeitem); + if ( preserve_position_changed != preserve_position ) { + if (!preserve_position) { + preserve_affine = SP_ITEM(sp_lpe_item)->transform; + } + preserve_position_changed = preserve_position; + } if (linked_path.linksToPath()) { //Legacy staff Glib::ustring attributes_value("d"); attributes.param_setValue(attributes_value); @@ -142,11 +158,7 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ linked_path.param_readSVGValue(""); } if (linked_item.linksToItem()) { - cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue()); - SPShape * shape = dynamic_cast(sp_lpe_item); - if(shape){ - this->setSPCurve(shape->getCurve()); - } + cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true); } } @@ -205,7 +217,10 @@ LPECloneOriginal::~LPECloneOriginal() void LPECloneOriginal::doEffect (SPCurve * curve) { - curve->set_pathvector(pathvector_before_effect); + SPShape * shape = getCurrentShape(); + if(shape){ + curve->set_pathvector(shape->getCurve()->get_pathvector()); + } } } // namespace LivePathEffect diff --git a/src/live_effects/lpe-clone-original.h b/src/live_effects/lpe-clone-original.h index e232135eb..e8a9a7419 100644 --- a/src/live_effects/lpe-clone-original.h +++ b/src/live_effects/lpe-clone-original.h @@ -29,7 +29,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void doOnApply(SPLPEItem const* lpeitem); virtual Gtk::Widget * newWidget(); - void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes); + void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes, bool root); private: OriginalPathParam linked_path; @@ -38,6 +38,8 @@ private: BoolParam preserve_position; TextParam attributes; TextParam style_attributes; + bool preserve_position_changed; + Geom::Affine preserve_affine; LPECloneOriginal(const LPECloneOriginal&); LPECloneOriginal& operator=(const LPECloneOriginal&); }; diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index f5c930404..c7a800041 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -241,12 +241,12 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip } if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { // Groups have their doBeforeEffect called elsewhere + if (SP_IS_GROUP(this) && current) { + lpe->setCurrentShape(current); + } if (!SP_IS_GROUP(this)) { lpe->doBeforeEffect_impl(this); } - if (SP_IS_GROUP(this) && current) { - lpe->setSPCurve(current->getCurve()); - } try { lpe->doEffect(curve); } -- cgit v1.2.3 From 3c16d15761bac73cba9b81b49efe8e71306a5766 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 30 Dec 2016 19:14:55 +0100 Subject: Fixing clips and masks (bzr r15356.1.6) --- src/live_effects/lpe-clone-original.cpp | 36 +++++++++++++++++++++++---------- src/sp-lpe-item.cpp | 4 ++-- 2 files changed, 27 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 8176f3811..81e6809f1 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -8,6 +8,8 @@ #include "display/curve.h" #include "svg/path-string.h" #include "svg/svg.h" +#include "sp-clippath.h" +#include "sp-mask.h" #include "xml/sp-css-attr.h" // TODO due to internal breakage in glibmm headers, this must be last: @@ -36,9 +38,9 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : scale.param_set_digits(2); attributes.param_hide_canvas_text(); style_attributes.param_hide_canvas_text(); - apply_to_clippath_and_mask = true; preserve_position_changed = !preserve_position; preserve_affine = Geom::identity(); + apply_to_clippath_and_mask = true; } void @@ -60,6 +62,13 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co SPShape * shape_dest = SP_SHAPE(dest); gchar ** attarray = g_strsplit(attributes, ",", 0); gchar ** iter = attarray; +// if (SP_IS_CLIPPATH(SP_ITEM(origin)->parent) || SP_IS_MASK(SP_ITEM(origin)->parent)) { +// Geom::Affine dest_affine = Geom::identity(); +// if (root && preserve_position) { +// dest_affine *= Geom::Translate(preserve_affine.translation()); +// } +// SP_ITEM(SP_ITEM(dest)->parent)->transform = dest_affine; +// } while (*iter != NULL) { const char* attribute = (*iter); if ( std::strcmp(attribute, "transform") == 0 ) { @@ -69,11 +78,12 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co if (preserve_position) { Geom::Affine dest_affine = Geom::identity(); if (root) { + std::cout << "root" << preserve_affine.translation() << "\n"; dest_affine *= Geom::Translate(preserve_affine.translation()); - preserve_affine = Geom::identity(); + //preserve_affine = Geom::identity(); + dest_affine *= Geom::Translate(affine_dest.translation()); + dest_affine *= Geom::Translate(affine_origin.translation()).inverse(); } - dest_affine *= Geom::Translate(affine_dest.translation()); - dest_affine *= Geom::Translate(affine_origin.translation()).inverse(); dest_affine *= affine_origin; SP_ITEM(dest)->transform = dest_affine; } else { @@ -89,7 +99,7 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co if (c) { Geom::PathVector c_pv = c->get_pathvector(); Geom::OptRect orig_bbox = SP_ITEM(origin)->geometricBounds(); - if (orig_bbox) { + if (orig_bbox && root) { if (scale != 100.0) { double scale_affine = scale/100.0; Geom::Scale scale = Geom::Scale(scale_affine); @@ -141,12 +151,6 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co void LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ original_bbox(lpeitem); - if ( preserve_position_changed != preserve_position ) { - if (!preserve_position) { - preserve_affine = SP_ITEM(sp_lpe_item)->transform; - } - preserve_position_changed = preserve_position; - } if (linked_path.linksToPath()) { //Legacy staff Glib::ustring attributes_value("d"); attributes.param_setValue(attributes_value); @@ -158,6 +162,16 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ linked_path.param_readSVGValue(""); } if (linked_item.linksToItem()) { + if (preserve_position) { + preserve_affine = SP_ITEM(sp_lpe_item)->transform; + } +// if ( preserve_position_changed != preserve_position ) { +// if (!preserve_position) { +// preserve_affine = SP_ITEM(sp_lpe_item)->transform; +// preserve_affine *= Geom::Translate(SP_ITEM(linked_item.getObject())->transform.translation()).inverse(); +// } +// preserve_position_changed = preserve_position; +// } cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true); } } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index c7a800041..2dd7cec5a 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -241,7 +241,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip } if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { // Groups have their doBeforeEffect called elsewhere - if (SP_IS_GROUP(this) && current) { + if (current) { lpe->setCurrentShape(current); } if (!SP_IS_GROUP(this)) { @@ -700,7 +700,7 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); } else { - success = this->performPathEffect(c, NULL, true); + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); -- cgit v1.2.3 From 088070b65c83f9a6a7d1d268e8a794776cc648a8 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sun, 1 Jan 2017 03:21:07 +0100 Subject: Fixing transforms,clips... (bzr r15356.1.8) --- src/live_effects/lpe-clone-original.cpp | 150 ++++++++++++++++++++++---------- src/live_effects/lpe-clone-original.h | 5 +- src/live_effects/lpe-copy_rotate.cpp | 1 - src/sp-path.cpp | 27 +++--- 4 files changed, 123 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 81e6809f1..76cc56b8f 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -24,6 +24,7 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : linked_item(_("Linked Item:"), _("Item from which to take the original data"), "linked_item", &wr, this), scale(_("Scale %"), _("Scale item %"), "scale", &wr, this, 100.0), preserve_position(_("Preserve position"), _("Preserve position"), "preserve_position", &wr, this, false), + use_center(_("Relative center of element"), _("Relative center of element"), "use_center", &wr, this, true), attributes("Attributes linked", "Attributes linked", "attributes", &wr, this,""), style_attributes("Style attributes linked", "Style attributes linked", "style_attributes", &wr, this,"") { @@ -33,14 +34,28 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : registerParameter(&attributes); registerParameter(&style_attributes); registerParameter(&preserve_position); + registerParameter(&use_center); scale.param_set_range(0.01, 999999.0); scale.param_set_increments(1, 1); scale.param_set_digits(2); attributes.param_hide_canvas_text(); style_attributes.param_hide_canvas_text(); - preserve_position_changed = !preserve_position; + preserve_position_changed = preserve_position; preserve_affine = Geom::identity(); - apply_to_clippath_and_mask = true; +} + +bool hasLinkedTransform( const char * attributes) { + gchar ** attarray = g_strsplit(attributes, ",", 0); + gchar ** iter = attarray; + bool has_linked_transform = false; + while (*iter != NULL) { + const char* attribute = (*iter); + if ( std::strcmp(attribute, "transform") == 0 ) { + has_linked_transform = true; + } + iter++; + } + return has_linked_transform; } void @@ -53,41 +68,69 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneAttrbutes(*obj_it, dest_child, live, attributes, style_attributes, false); + cloneAttrbutes((*obj_it), dest_child, live, attributes, style_attributes, false); index++; } } //Attributes SPShape * shape_origin = SP_SHAPE(origin); + SPPath * path_origin = SP_PATH(origin); SPShape * shape_dest = SP_SHAPE(dest); + SPMask *mask_origin = SP_ITEM(origin)->mask_ref->getObject(); + SPMask *mask_dest = SP_ITEM(dest)->mask_ref->getObject(); + if(mask_origin && mask_dest) { + std::vector mask_list = mask_origin->childList(true); + std::vector mask_list_dest = mask_dest->childList(true); + if (mask_list.size() == mask_list_dest.size()) { + size_t i = 0; + for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { + SPObject * mask_data = *iter; + SPObject * mask_dest_data = mask_list_dest[i]; + cloneAttrbutes(mask_data, mask_dest_data, live, attributes, style_attributes, false); + i++; + } + } + } + SPClipPath *clippath_origin = SP_ITEM(origin)->clip_ref->getObject(); + SPClipPath *clippath_dest = SP_ITEM(dest)->clip_ref->getObject(); + if(clippath_origin && clippath_dest) { + std::vector clippath_list = clippath_origin->childList(true); + std::vector clippath_list_dest = clippath_dest->childList(true); + if (clippath_list.size() == clippath_list_dest.size()) { + size_t i = 0; + for ( std::vector::const_iterator iter=clippath_list.begin();iter!=clippath_list.end();++iter) { + SPObject * clippath_data = *iter; + SPObject * clippath_dest_data = clippath_list_dest[i]; + cloneAttrbutes(clippath_data, clippath_dest_data, live, attributes, style_attributes, false); + i++; + } + } + } gchar ** attarray = g_strsplit(attributes, ",", 0); gchar ** iter = attarray; -// if (SP_IS_CLIPPATH(SP_ITEM(origin)->parent) || SP_IS_MASK(SP_ITEM(origin)->parent)) { -// Geom::Affine dest_affine = Geom::identity(); -// if (root && preserve_position) { -// dest_affine *= Geom::Translate(preserve_affine.translation()); -// } -// SP_ITEM(SP_ITEM(dest)->parent)->transform = dest_affine; -// } + Geom::Affine affine_dest = Geom::identity(); + Geom::Affine affine_origin = Geom::identity(); + Geom::Affine affine_previous = Geom::identity(); + sp_svg_transform_read(SP_ITEM(dest)->getAttribute("transform"), &affine_dest); + sp_svg_transform_read(SP_ITEM(origin)->getAttribute("transform"), &affine_origin); while (*iter != NULL) { const char* attribute = (*iter); if ( std::strcmp(attribute, "transform") == 0 ) { - Geom::Affine affine_dest = SP_ITEM(dest)->transform; - Geom::Affine affine_origin = SP_ITEM(origin)->transform; - //dest->getRepr()->setAttribute(attribute, origin->getRepr()->attribute(attribute)); if (preserve_position) { Geom::Affine dest_affine = Geom::identity(); if (root) { - std::cout << "root" << preserve_affine.translation() << "\n"; - dest_affine *= Geom::Translate(preserve_affine.translation()); - //preserve_affine = Geom::identity(); - dest_affine *= Geom::Translate(affine_dest.translation()); + dest_affine *= affine_origin; + if (preserve_affine == Geom::identity()) { + dest_affine *= Geom::Translate(affine_dest.translation()); + } dest_affine *= Geom::Translate(affine_origin.translation()).inverse(); - } - dest_affine *= affine_origin; - SP_ITEM(dest)->transform = dest_affine; + dest_affine *= Geom::Translate(preserve_affine.translation()); + affine_previous = preserve_affine; + preserve_affine = Geom::identity(); + SP_ITEM(dest)->getRepr()->setAttribute("transform",sp_svg_transform_write(dest_affine)); + } } else { - SP_ITEM(dest)->transform = affine_origin ; + SP_ITEM(dest)->getRepr()->setAttribute("transform",sp_svg_transform_write(affine_origin)); } } else if ( shape_dest && shape_origin && live && (std::strcmp(attribute, "d") == 0 || std::strcmp(attribute, "inkscape:original-d") == 0)) { SPCurve *c = NULL; @@ -99,21 +142,33 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co if (c) { Geom::PathVector c_pv = c->get_pathvector(); Geom::OptRect orig_bbox = SP_ITEM(origin)->geometricBounds(); - if (orig_bbox && root) { + Geom::OptRect dest_bbox = SP_ITEM(dest)->geometricBounds(); + if (dest_bbox && orig_bbox && root) { + Geom::Point orig_point = (*orig_bbox).corner(0); + Geom::Point dest_point = (*dest_bbox).corner(0); + if (use_center) { + orig_point = (*orig_bbox).midpoint(); + dest_point = (*dest_bbox).midpoint(); + } if (scale != 100.0) { double scale_affine = scale/100.0; Geom::Scale scale = Geom::Scale(scale_affine); - c_pv *= Geom::Translate((*orig_bbox).midpoint()).inverse(); + c_pv *= Geom::Translate(orig_point).inverse(); c_pv *= scale; - c_pv *= Geom::Translate((*orig_bbox).midpoint()); + c_pv *= Geom::Translate(orig_point); } - if (preserve_position) { - c_pv *= Geom::Translate(Geom::Point(boundingbox_X.middle(), boundingbox_Y.middle()) - (*orig_bbox).midpoint()); + if (preserve_position && hasLinkedTransform(attributes)) { + c_pv *= Geom::Translate(dest_point - orig_point); } } + c_pv *= i2anc_affine(dest, sp_lpe_item); c->set_pathvector(c_pv); - shape_dest->setCurveInsync(c, TRUE); - dest->getRepr()->setAttribute(attribute, sp_svg_write_path(c_pv)); + if (!path_origin) { + shape_dest->setCurveInsync(c, TRUE); + dest->getRepr()->setAttribute(attribute, sp_svg_write_path(c_pv)); + } else { + shape_dest->setCurve(c, TRUE); + } c->unref(); } else { dest->getRepr()->setAttribute(attribute, NULL); @@ -124,8 +179,6 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co iter++; } g_strfreev (attarray); - - //Style Attributes SPCSSAttr *css_origin = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(css_origin, origin->getRepr()->attribute("style")); SPCSSAttr *css_dest = sp_repr_css_attr_new(); @@ -161,17 +214,14 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ linked_item.param_readSVGValue(linked_path.param_getSVGValue()); linked_path.param_readSVGValue(""); } + if (linked_item.linksToItem()) { - if (preserve_position) { - preserve_affine = SP_ITEM(sp_lpe_item)->transform; + if ( preserve_position_changed != preserve_position ) { + if (!preserve_position) { + sp_svg_transform_read(SP_ITEM(sp_lpe_item)->getAttribute("transform"), &preserve_affine); + } + preserve_position_changed = preserve_position; } -// if ( preserve_position_changed != preserve_position ) { -// if (!preserve_position) { -// preserve_affine = SP_ITEM(sp_lpe_item)->transform; -// preserve_affine *= Geom::Translate(SP_ITEM(linked_item.getObject())->transform.translation()).inverse(); -// } -// preserve_position_changed = preserve_position; -// } cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true); } } @@ -219,7 +269,7 @@ LPECloneOriginal::doOnApply(SPLPEItem const* lpeitem){ Glib::ustring attributes_value("d,transform"); attributes.param_setValue(attributes_value); attributes.write_to_SVG(); - Glib::ustring style_attributes_value("opacity,border-width"); + Glib::ustring style_attributes_value("opacity,stroke-width"); style_attributes.param_setValue(style_attributes_value); style_attributes.write_to_SVG(); } @@ -229,11 +279,23 @@ LPECloneOriginal::~LPECloneOriginal() } -void LPECloneOriginal::doEffect (SPCurve * curve) +void +LPECloneOriginal::transform_multiply(Geom::Affine const& postmul, bool set) +{ + if (linked_item.linksToItem()) { + bool changed = false; + linked_item.getObject()->requestModified(SP_OBJECT_MODIFIED_FLAG); + } +} + +void +LPECloneOriginal::doEffect (SPCurve * curve) { - SPShape * shape = getCurrentShape(); - if(shape){ - curve->set_pathvector(shape->getCurve()->get_pathvector()); + if (linked_item.linksToItem()) { + SPShape * shape = getCurrentShape(); + if(shape){ + curve->set_pathvector(shape->getCurve()->get_pathvector()); + } } } diff --git a/src/live_effects/lpe-clone-original.h b/src/live_effects/lpe-clone-original.h index e8a9a7419..064fe84b2 100644 --- a/src/live_effects/lpe-clone-original.h +++ b/src/live_effects/lpe-clone-original.h @@ -24,10 +24,10 @@ class LPECloneOriginal : public Effect, GroupBBoxEffect { public: LPECloneOriginal(LivePathEffectObject *lpeobject); virtual ~LPECloneOriginal(); - + virtual void doOnApply(SPLPEItem const* lpeitem); virtual void doEffect (SPCurve * curve); virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void doOnApply(SPLPEItem const* lpeitem); + virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual Gtk::Widget * newWidget(); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes, bool root); @@ -36,6 +36,7 @@ private: OriginalItemParam linked_item; ScalarParam scale; BoolParam preserve_position; + BoolParam use_center; TextParam attributes; TextParam style_attributes; bool preserve_position_changed; diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 3dd35696a..aafd2c094 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -122,7 +122,6 @@ void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { // cycle through all parameters. Most parameters will not need transformation, but path and point params do. - for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { Parameter * param = *it; param->param_transform_multiply(postmul, set); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 0a2ce4c09..6c69f3463 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -289,10 +289,23 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { if (!_curve) { // 0 nodes, nothing to transform return Geom::identity(); } + // Adjust stroke + this->adjust_stroke(transform.descrim()); + + // Adjust pattern fill + this->adjust_pattern(transform); + + // Adjust gradient fill + this->adjust_gradient(transform); + + // Adjust LPE + this->adjust_livepatheffect(transform); // Transform the original-d path if this is a valid LPE this, other else the (ordinary) path if (_curve_before_lpe && hasPathEffectRecursive()) { - if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) || this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH)) { + if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) || + this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH)) + { // if path has the CLONE_ORIGINAL LPE applied, don't write the transform to the pathdata, but write it 'unoptimized' // also if the effect is type BEND PATH to fix bug #179842 return transform; @@ -303,18 +316,6 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { _curve->transform(transform); } - // Adjust stroke - this->adjust_stroke(transform.descrim()); - - // Adjust pattern fill - this->adjust_pattern(transform); - - // Adjust gradient fill - this->adjust_gradient(transform); - - // Adjust LPE - this->adjust_livepatheffect(transform); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); // nothing remains - we've written all of the transform, so return identity -- cgit v1.2.3 From ba0a43458620f76e235fc9d61539582d7887311f Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 2 Jan 2017 00:30:14 +0100 Subject: attemt to mirror (bzr r15356.1.11) --- src/live_effects/lpe-clone-original.cpp | 26 +++++++++++++++++--------- src/live_effects/lpe-clone-original.h | 1 + src/live_effects/parameter/item.cpp | 26 ++++++++++++++++---------- src/live_effects/parameter/originalitem.cpp | 15 +++++++++++++++ src/live_effects/parameter/originalitem.h | 2 ++ 5 files changed, 51 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 76cc56b8f..4fc74b275 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -24,6 +24,7 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : linked_item(_("Linked Item:"), _("Item from which to take the original data"), "linked_item", &wr, this), scale(_("Scale %"), _("Scale item %"), "scale", &wr, this, 100.0), preserve_position(_("Preserve position"), _("Preserve position"), "preserve_position", &wr, this, false), + inverse(_("Inverse clone"), _("Use LPE item as origin. Destructive"), "inverse", &wr, this, false), use_center(_("Relative center of element"), _("Relative center of element"), "use_center", &wr, this, true), attributes("Attributes linked", "Attributes linked", "attributes", &wr, this,""), style_attributes("Style attributes linked", "Style attributes linked", "style_attributes", &wr, this,"") @@ -34,6 +35,7 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : registerParameter(&attributes); registerParameter(&style_attributes); registerParameter(&preserve_position); + registerParameter(&inverse); registerParameter(&use_center); scale.param_set_range(0.01, 999999.0); scale.param_set_increments(1, 1); @@ -132,13 +134,9 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co } else { SP_ITEM(dest)->getRepr()->setAttribute("transform",sp_svg_transform_write(affine_origin)); } - } else if ( shape_dest && shape_origin && live && (std::strcmp(attribute, "d") == 0 || std::strcmp(attribute, "inkscape:original-d") == 0)) { + } else if ( shape_dest && shape_origin && live && (std::strcmp(attribute, "d") == 0)) { SPCurve *c = NULL; - if (std::strcmp(attribute, "d") == 0) { - c = shape_origin->getCurve(); - } else { - c = shape_origin->getCurveBeforeLPE(); - } + c = shape_origin->getCurve(); if (c) { Geom::PathVector c_pv = c->get_pathvector(); Geom::OptRect orig_bbox = SP_ITEM(origin)->geometricBounds(); @@ -161,7 +159,12 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co c_pv *= Geom::Translate(dest_point - orig_point); } } - c_pv *= i2anc_affine(dest, sp_lpe_item); + if (inverse) { + c_pv *= i2anc_affine(origin, sp_lpe_item); + origin->getRepr()->setAttribute("inkscape:original-d", sp_svg_write_path(c_pv)); + } else { + c_pv *= i2anc_affine(dest, sp_lpe_item); + } c->set_pathvector(c_pv); if (!path_origin) { shape_dest->setCurveInsync(c, TRUE); @@ -203,7 +206,6 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co void LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ - original_bbox(lpeitem); if (linked_path.linksToPath()) { //Legacy staff Glib::ustring attributes_value("d"); attributes.param_setValue(attributes_value); @@ -222,7 +224,13 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ } preserve_position_changed = preserve_position; } - cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true); + if (inverse) { + linked_item.param_quit_listening(); + cloneAttrbutes(SP_OBJECT(sp_lpe_item), linked_item.getObject(), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true); + } else { + linked_item.param_start_listening(linked_item.getObject()); + cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true); + } } } diff --git a/src/live_effects/lpe-clone-original.h b/src/live_effects/lpe-clone-original.h index 064fe84b2..aad6e9fa9 100644 --- a/src/live_effects/lpe-clone-original.h +++ b/src/live_effects/lpe-clone-original.h @@ -36,6 +36,7 @@ private: OriginalItemParam linked_item; ScalarParam scale; BoolParam preserve_position; + BoolParam inverse; BoolParam use_center; TextParam attributes; TextParam style_attributes; diff --git a/src/live_effects/parameter/item.cpp b/src/live_effects/parameter/item.cpp index 8caea4e26..0a46ec7ce 100644 --- a/src/live_effects/parameter/item.cpp +++ b/src/live_effects/parameter/item.cpp @@ -135,25 +135,31 @@ ItemParam::addCanvasIndicators(SPLPEItem const*/*lpeitem*/, std::vectorconnectDelete(sigc::mem_fun(*this, &ItemParam::linked_delete)); - linked_modified_connection = to->connectModified(sigc::mem_fun(*this, &ItemParam::linked_modified)); - if (SP_IS_ITEM(to)) { - linked_transformed_connection = SP_ITEM(to)->connectTransformed(sigc::mem_fun(*this, &ItemParam::linked_transformed)); + if (!linked_delete_connection.connected() || force) { + std::cout << "111111111111111111\n"; + linked_delete_connection = to->connectDelete(sigc::mem_fun(*this, &ItemParam::linked_delete)); + linked_modified_connection = to->connectModified(sigc::mem_fun(*this, &ItemParam::linked_modified)); + if (SP_IS_ITEM(to)) { + linked_transformed_connection = SP_ITEM(to)->connectTransformed(sigc::mem_fun(*this, &ItemParam::linked_transformed)); + } + linked_modified(to, SP_OBJECT_MODIFIED_FLAG); // simulate linked_modified signal, so that path data is updated } - linked_modified(to, SP_OBJECT_MODIFIED_FLAG); // simulate linked_modified signal, so that path data is updated } void ItemParam::quit_listening(void) { - linked_modified_connection.disconnect(); - linked_delete_connection.disconnect(); - linked_transformed_connection.disconnect(); + if (linked_delete_connection.connected()) { + std::cout << "2222222222222222222222\n"; + linked_modified_connection.disconnect(); + linked_delete_connection.disconnect(); + linked_transformed_connection.disconnect(); + } } void @@ -161,7 +167,7 @@ ItemParam::ref_changed(SPObject */*old_ref*/, SPObject *new_ref) { quit_listening(); if ( new_ref ) { - start_listening(new_ref); + start_listening(new_ref, true); } } diff --git a/src/live_effects/parameter/originalitem.cpp b/src/live_effects/parameter/originalitem.cpp index 015fa0bd4..dc7f2d634 100644 --- a/src/live_effects/parameter/originalitem.cpp +++ b/src/live_effects/parameter/originalitem.cpp @@ -83,6 +83,21 @@ OriginalItemParam::param_newWidget() return dynamic_cast (_widget); } +void +OriginalItemParam::param_start_listening(SPObject * to) +{ + if ( to == NULL ) { + return; + } + start_listening(to, false); +} + +void +OriginalItemParam::param_quit_listening(void) +{ + quit_listening(); +} + void OriginalItemParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) { diff --git a/src/live_effects/parameter/originalitem.h b/src/live_effects/parameter/originalitem.h index 9c67571e8..5478a1e4b 100644 --- a/src/live_effects/parameter/originalitem.h +++ b/src/live_effects/parameter/originalitem.h @@ -26,6 +26,8 @@ public: bool linksToItem() const { return (href != NULL); } SPItem * getObject() const { return ref.getObject(); } + void param_start_listening(SPObject * to); + void param_quit_listening(void); virtual Gtk::Widget * param_newWidget(); -- cgit v1.2.3 From de63ebfb86a6908b5aaad019ae1358cdf483ce17 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 2 Jan 2017 01:14:22 +0100 Subject: attemt to mirror (bzr r15295.1.42) --- src/live_effects/lpe-mirror_symmetry.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index f83025afc..ba3891529 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -325,12 +325,12 @@ LPEMirrorSymmetry::createMirror(Geom::Affine transform) //transform *= last_transform; //if (transform != Geom::identity()) { elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); - Inkscape::LivePathEffect::LPEObjectReference* lperef = SP_LPE_ITEM(elemref)->getCurrentLPEReference(); - if (lperef) { - PathEffectList * new_list = SP_LPE_ITEM(elemref)->path_effect_list; - new_list->remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list - elemref->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); - } +// Inkscape::LivePathEffect::LPEObjectReference* lperef = SP_LPE_ITEM(elemref)->getCurrentLPEReference(); +// if (lperef) { +// PathEffectList * new_list = SP_LPE_ITEM(elemref)->path_effect_list; +// new_list->remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list +// elemref->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); +// } //} if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); -- cgit v1.2.3 From 0a19b6fbad1ada089488541e60f195a0943c01a8 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 2 Jan 2017 13:14:36 +0100 Subject: Fix inverse clone (bzr r15356.1.12) --- src/live_effects/lpe-clone-original.cpp | 18 ++++++++++-------- src/live_effects/parameter/item.cpp | 26 ++++++++++---------------- src/live_effects/parameter/originalitem.cpp | 21 ++++----------------- src/live_effects/parameter/originalitem.h | 5 ++--- 4 files changed, 26 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 4fc74b275..33abd685a 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -24,7 +24,7 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : linked_item(_("Linked Item:"), _("Item from which to take the original data"), "linked_item", &wr, this), scale(_("Scale %"), _("Scale item %"), "scale", &wr, this, 100.0), preserve_position(_("Preserve position"), _("Preserve position"), "preserve_position", &wr, this, false), - inverse(_("Inverse clone"), _("Use LPE item as origin. Destructive"), "inverse", &wr, this, false), + inverse(_("Inverse clone"), _("Use LPE item as origin"), "inverse", &wr, this, false), use_center(_("Relative center of element"), _("Relative center of element"), "use_center", &wr, this, true), attributes("Attributes linked", "Attributes linked", "attributes", &wr, this,""), style_attributes("Style attributes linked", "Style attributes linked", "style_attributes", &wr, this,"") @@ -136,7 +136,11 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co } } else if ( shape_dest && shape_origin && live && (std::strcmp(attribute, "d") == 0)) { SPCurve *c = NULL; - c = shape_origin->getCurve(); + if (inverse) { + c = shape_origin->getCurveBeforeLPE(); + } else { + c = shape_origin->getCurve(); + } if (c) { Geom::PathVector c_pv = c->get_pathvector(); Geom::OptRect orig_bbox = SP_ITEM(origin)->geometricBounds(); @@ -155,13 +159,12 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co c_pv *= scale; c_pv *= Geom::Translate(orig_point); } - if (preserve_position && hasLinkedTransform(attributes)) { + if (preserve_position) { c_pv *= Geom::Translate(dest_point - orig_point); } } if (inverse) { c_pv *= i2anc_affine(origin, sp_lpe_item); - origin->getRepr()->setAttribute("inkscape:original-d", sp_svg_write_path(c_pv)); } else { c_pv *= i2anc_affine(dest, sp_lpe_item); } @@ -218,17 +221,16 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ } if (linked_item.linksToItem()) { - if ( preserve_position_changed != preserve_position ) { + linked_item.setInverse(inverse); + if ( preserve_position_changed != preserve_position ) { if (!preserve_position) { sp_svg_transform_read(SP_ITEM(sp_lpe_item)->getAttribute("transform"), &preserve_affine); } preserve_position_changed = preserve_position; } if (inverse) { - linked_item.param_quit_listening(); cloneAttrbutes(SP_OBJECT(sp_lpe_item), linked_item.getObject(), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true); } else { - linked_item.param_start_listening(linked_item.getObject()); cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true); } } @@ -299,7 +301,7 @@ LPECloneOriginal::transform_multiply(Geom::Affine const& postmul, bool set) void LPECloneOriginal::doEffect (SPCurve * curve) { - if (linked_item.linksToItem()) { + if (linked_item.linksToItem() && !inverse) { SPShape * shape = getCurrentShape(); if(shape){ curve->set_pathvector(shape->getCurve()->get_pathvector()); diff --git a/src/live_effects/parameter/item.cpp b/src/live_effects/parameter/item.cpp index 0a46ec7ce..8caea4e26 100644 --- a/src/live_effects/parameter/item.cpp +++ b/src/live_effects/parameter/item.cpp @@ -135,31 +135,25 @@ ItemParam::addCanvasIndicators(SPLPEItem const*/*lpeitem*/, std::vectorconnectDelete(sigc::mem_fun(*this, &ItemParam::linked_delete)); - linked_modified_connection = to->connectModified(sigc::mem_fun(*this, &ItemParam::linked_modified)); - if (SP_IS_ITEM(to)) { - linked_transformed_connection = SP_ITEM(to)->connectTransformed(sigc::mem_fun(*this, &ItemParam::linked_transformed)); - } - linked_modified(to, SP_OBJECT_MODIFIED_FLAG); // simulate linked_modified signal, so that path data is updated + linked_delete_connection = to->connectDelete(sigc::mem_fun(*this, &ItemParam::linked_delete)); + linked_modified_connection = to->connectModified(sigc::mem_fun(*this, &ItemParam::linked_modified)); + if (SP_IS_ITEM(to)) { + linked_transformed_connection = SP_ITEM(to)->connectTransformed(sigc::mem_fun(*this, &ItemParam::linked_transformed)); } + linked_modified(to, SP_OBJECT_MODIFIED_FLAG); // simulate linked_modified signal, so that path data is updated } void ItemParam::quit_listening(void) { - if (linked_delete_connection.connected()) { - std::cout << "2222222222222222222222\n"; - linked_modified_connection.disconnect(); - linked_delete_connection.disconnect(); - linked_transformed_connection.disconnect(); - } + linked_modified_connection.disconnect(); + linked_delete_connection.disconnect(); + linked_transformed_connection.disconnect(); } void @@ -167,7 +161,7 @@ ItemParam::ref_changed(SPObject */*old_ref*/, SPObject *new_ref) { quit_listening(); if ( new_ref ) { - start_listening(new_ref, true); + start_listening(new_ref); } } diff --git a/src/live_effects/parameter/originalitem.cpp b/src/live_effects/parameter/originalitem.cpp index dc7f2d634..053062128 100644 --- a/src/live_effects/parameter/originalitem.cpp +++ b/src/live_effects/parameter/originalitem.cpp @@ -83,26 +83,13 @@ OriginalItemParam::param_newWidget() return dynamic_cast (_widget); } -void -OriginalItemParam::param_start_listening(SPObject * to) -{ - if ( to == NULL ) { - return; - } - start_listening(to, false); -} - -void -OriginalItemParam::param_quit_listening(void) -{ - quit_listening(); -} - void OriginalItemParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) { - emit_changed(); - SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); + if (!inverse) { + emit_changed(); + SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); + } } void diff --git a/src/live_effects/parameter/originalitem.h b/src/live_effects/parameter/originalitem.h index 5478a1e4b..58d04e05a 100644 --- a/src/live_effects/parameter/originalitem.h +++ b/src/live_effects/parameter/originalitem.h @@ -23,11 +23,9 @@ public: Inkscape::UI::Widget::Registry* wr, Effect* effect); virtual ~OriginalItemParam(); - + void setInverse(bool inversed) { inverse = inversed; } bool linksToItem() const { return (href != NULL); } SPItem * getObject() const { return ref.getObject(); } - void param_start_listening(SPObject * to); - void param_quit_listening(void); virtual Gtk::Widget * param_newWidget(); @@ -38,6 +36,7 @@ protected: void on_select_original_button_click(); private: + bool inverse; OriginalItemParam(const OriginalItemParam&); OriginalItemParam& operator=(const OriginalItemParam&); }; -- cgit v1.2.3 From f61f13c62dd0c8e87f89492508acfebad6b32f83 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 2 Jan 2017 16:03:00 +0100 Subject: End defining, bug fixing.... (bzr r15295.1.44) --- src/live_effects/lpe-mirror_symmetry.cpp | 85 ++++++----------------------- src/live_effects/lpe-mirror_symmetry.h | 6 +- src/live_effects/parameter/originalitem.cpp | 21 ++++++- src/live_effects/parameter/originalitem.h | 2 +- 4 files changed, 43 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index ba3891529..bd77db53c 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -52,18 +52,20 @@ MTConverter(ModeTypeData, MT_END); LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), + mirror_item(_("Mirror item:"), _("Mirror item"), "mirror_item", &wr, this), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, 0), discard_orig_path(_("Discard original path"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), - split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints. Group result to apply nested"), "split_elements", &wr, this, false), + split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints. Whith fuse don't work on shapes"), "split_elements", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust start of mirroring")), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,"") { show_orig_path = true; + registerParameter(&mirror_item); registerParameter(&mode); registerParameter(&split_gap); registerParameter(&discard_orig_path); @@ -107,12 +109,9 @@ LPEMirrorSymmetry::isCurrentLPEItem() { void LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) { - std::cout << sp_lpe_item->getId() << "111111111111111111111111111111\n"; - std::cout << lpeitem->getId() << "22222222222222222222222222222222222222222\n"; if (!isCurrentLPEItem()) { return; } - std::cout << "dgagsdgsdgsdgsdgsdgsdgsdgsd\n"; last_transform = Geom::identity(); if (split_elements) { if (discard_orig_path) { @@ -129,31 +128,11 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) } Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); - // Geom::Point gap(split_gap,0); -// Geom::Translate m1(point_a[0], point_a[1]); -// double hyp = Geom::distance(point_a, point_b); -// double cos = 0; -// double sin = 0; -// if (hyp > 0) { -// cos = (point_b[0] - point_a[0]) / hyp; -// sin = (point_b[1] - point_a[1]) / hyp; -// } -// Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); -// Geom::Point dir = unit_vector(point_b - point_a); -// Geom::Point offset = (point_a + point_b)/2 + Geom::rot90(dir.ccw()) * split_gap; -// line_separation *= Geom::Translate(offset); -// Geom::Scale sca(1.0, -1.0); -// m = m1.inverse() * m2; -// m = m * sca; -// m = m * m2.inverse(); -// m = m * m1; + Geom::Point dir = rot90(unit_vector((Geom::Point)start_point - (Geom::Point)end_point)); + Geom::Point gap = dir * split_gap; + m *= Geom::Translate(gap); m = m * sp_lpe_item->transform; -// if (std::strcmp(sp_lpe_item->getId(), origin) != 0) { -std::cout << m << "m\n"; - createMirror(m); -// } else { -// createMirror(sp_lpe_item, m, mirror); -// } + toMirror(m); } else { processObjects(LPE_ERASE); elements.clear(); @@ -238,44 +217,23 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) previous_center = center_point; } -//void -//LPEMirrorSymmetry::cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...) -//{ -// va_list args; -// va_start(args, first_attribute); - -// if ( origin->name() == "svg:g" && origin->childCount() == dest->childCount() ) { -// Inkscape::XML::Node * node_it = origin->firstChild(); -// size_t index = 0; -// while (node_it != origin->lastChild()) { -// cloneAttrbutes(node_it, dest->nthChild(index), first_attribute, live, args); -// node_it = node_it->next(); -// index++; -// } -// } -// while(const char * att = va_arg(args, const char *)) { -// dest->setAttribute(att,origin->attribute(att)); -// } -// va_end(args); -//} - void -LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...) +LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes) { - va_list args; - va_start(args, first_attribute); - if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { std::vector< SPObject * > childs = origin->childList(true); size_t index = 0; for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneAttrbutes(*obj_it, dest_child, live, first_attribute, args); + cloneAttrbutes(*obj_it, dest_child, live, attributes); index++; } } - for (const char* att = first_attribute; att != NULL; att = va_arg(args, const char*)) { + gchar ** attarray = g_strsplit(attributes, ",", 0); + gchar ** iter = attarray; + while (*iter != NULL) { + const char* att = (*iter); SPShape * shape = SP_SHAPE(origin); if (shape) { if ( live && (att == "d" || att == "inkscape:original-d")) { @@ -296,12 +254,12 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c dest->getRepr()->setAttribute(att,origin->getRepr()->attribute(att)); } } + iter++; } - va_end(args); } void -LPEMirrorSymmetry::createMirror(Geom::Affine transform) +LPEMirrorSymmetry::toMirror(Geom::Affine transform) { SPDocument * document = SP_ACTIVE_DOCUMENT; const char * id_origin_char = id_origin.param_getSVGValue(); @@ -320,18 +278,11 @@ LPEMirrorSymmetry::createMirror(Geom::Affine transform) if (!elemref) { elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); + mirror_item.param_write(elemref_id); } - cloneAttrbutes(SP_OBJECT(sp_lpe_item), elemref, true, "d", NULL); //NULL required - //transform *= last_transform; - //if (transform != Geom::identity()) { + elemref->getRepr()->setAttribute("inkscape:path-effect", ""); + cloneAttrbutes(SP_OBJECT(sp_lpe_item), elemref, true, "d"); elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); -// Inkscape::LivePathEffect::LPEObjectReference* lperef = SP_LPE_ITEM(elemref)->getCurrentLPEReference(); -// if (lperef) { -// PathEffectList * new_list = SP_LPE_ITEM(elemref)->path_effect_list; -// new_list->remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list -// elemref->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); -// } - //} if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); copy->setAttribute("id", elemref_id); diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 765f2740f..03ff56842 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -17,6 +17,7 @@ */ #include "live_effects/effect.h" +#include "live_effects/parameter/originalitem.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" @@ -49,15 +50,16 @@ public: virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); void processObjects(LpeAction lpe_action); - void createMirror(Geom::Affine transform); + void toMirror(Geom::Affine transform); bool isCurrentLPEItem(); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); - void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * first_attribute, ...); + void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: + OriginalItemParam mirror_item; EnumParam mode; ScalarParam split_gap; BoolParam discard_orig_path; diff --git a/src/live_effects/parameter/originalitem.cpp b/src/live_effects/parameter/originalitem.cpp index 053062128..07c8bd27c 100644 --- a/src/live_effects/parameter/originalitem.cpp +++ b/src/live_effects/parameter/originalitem.cpp @@ -83,12 +83,31 @@ OriginalItemParam::param_newWidget() return dynamic_cast (_widget); } +void +OriginalItemParam::param_write(const gchar * iid) +{ + Glib::ustring itemid(iid); + + if (itemid.empty()) { + return; + } + // add '#' at start to make it an uri. + itemid.insert(itemid.begin(), '#'); + if ( href && strcmp(itemid.c_str(), href) == 0 ) { + // no change, do nothing + return; + } else { + param_write_to_repr(itemid.c_str()); + } +} + void OriginalItemParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) { if (!inverse) { emit_changed(); - SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); + LivePathEffectObject* lpeobj = param_effect->getLPEObj(); + SP_OBJECT(lpeobj)->requestModified(SP_OBJECT_MODIFIED_FLAG); } } diff --git a/src/live_effects/parameter/originalitem.h b/src/live_effects/parameter/originalitem.h index 58d04e05a..86e223cea 100644 --- a/src/live_effects/parameter/originalitem.h +++ b/src/live_effects/parameter/originalitem.h @@ -26,7 +26,7 @@ public: void setInverse(bool inversed) { inverse = inversed; } bool linksToItem() const { return (href != NULL); } SPItem * getObject() const { return ref.getObject(); } - + void param_write(const gchar * iid); virtual Gtk::Widget * param_newWidget(); protected: -- cgit v1.2.3 From 661acc453184bfe673a759794049c494a1477de5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 2 Jan 2017 20:10:32 +0100 Subject: Fixing paths (bzr r15295.1.46) --- src/live_effects/lpe-mirror_symmetry.cpp | 56 +++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index bd77db53c..0436ed877 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -220,6 +220,8 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) void LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { std::vector< SPObject * > childs = origin->childList(true); size_t index = 0; @@ -235,6 +237,11 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c while (*iter != NULL) { const char* att = (*iter); SPShape * shape = SP_SHAPE(origin); + SPPath * path = SP_PATH(dest); + if (!path && !SP_IS_GROUP(dest)) { + Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); + dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); + } if (shape) { if ( live && (att == "d" || att == "inkscape:original-d")) { SPCurve *c = NULL; @@ -262,11 +269,11 @@ void LPEMirrorSymmetry::toMirror(Geom::Affine transform) { SPDocument * document = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); const char * id_origin_char = id_origin.param_getSVGValue(); const char * elemref_id = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); elements.clear(); elements.push_back(elemref_id); - Inkscape::XML::Document *xml_doc = document->getReprDoc(); SPObject *elemref= NULL; Inkscape::XML::Node *phantom = NULL; if (elemref = document->getObjectById(elemref_id)) { @@ -275,12 +282,44 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform) phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); } phantom->setAttribute("id", elemref_id); + phantom->setAttribute("inkscape:path-effect", NULL); + phantom->setAttribute("sodipodi:type", NULL); + phantom->setAttribute("sodipodi:rx", NULL); + phantom->setAttribute("sodipodi:ry", NULL); + phantom->setAttribute("sodipodi:cx", NULL); + phantom->setAttribute("sodipodi:cy", NULL); + phantom->setAttribute("sodipodi:end", NULL); + phantom->setAttribute("sodipodi:start", NULL); + phantom->setAttribute("inkscape:flatsided", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("inkscape:rounded", NULL); + phantom->setAttribute("sodipodi:arg1", NULL); + phantom->setAttribute("sodipodi:arg2", NULL); + phantom->setAttribute("sodipodi:r1", NULL); + phantom->setAttribute("sodipodi:r2", NULL); + phantom->setAttribute("sodipodi:sides", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("sodipodi:argument", NULL); + phantom->setAttribute("sodipodi:expansion", NULL); + phantom->setAttribute("sodipodi:radius", NULL); + phantom->setAttribute("sodipodi:revolution", NULL); + phantom->setAttribute("sodipodi:t0", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("x", NULL); + phantom->setAttribute("y", NULL); + phantom->setAttribute("rx", NULL); + phantom->setAttribute("ry", NULL); + phantom->setAttribute("width", NULL); + phantom->setAttribute("height", NULL); if (!elemref) { elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); mirror_item.param_write(elemref_id); + } else { + elemref->updateRepr(xml_doc, phantom, SP_OBJECT_WRITE_ALL); } - elemref->getRepr()->setAttribute("inkscape:path-effect", ""); cloneAttrbutes(SP_OBJECT(sp_lpe_item), elemref, true, "d"); elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); if (elemref->parent != container) { @@ -513,6 +552,10 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) double time_end = crossed[i]; if (time_start != time_end && time_end - time_start > Geom::EPSILON) { Geom::Path portion = original.portion(time_start, time_end); + Geom::Path next_portion = portion; + if (crossed.size() > i+1) { + next_portion = original.portion(time_end, crossed[i+1]); + } if (!portion.empty()) { Geom::Point middle = portion.pointAt((double)portion.size()/2.0); position = Geom::sgn(Geom::cross(e - s, middle - s)); @@ -522,8 +565,9 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) if (position == 1) { Geom::Path mirror = portion.reversed() * m; if (split_elements) { - if(i!=0 || original.closed()) { - portion.close(); + if (crossed.size() > i+1) { + portion.appendNew( next_portion.finalPoint() ); + i++; } } else { mirror.setInitial(portion.finalPoint()); @@ -533,7 +577,9 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) portion.close(); } } - tmp_path.push_back(portion); + if (split_elements) { + tmp_path.push_back(portion); + } } portion.clear(); } -- cgit v1.2.3 From ea0de461574893c3b21e4653d0185cec501e0efe Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 2 Jan 2017 21:18:59 +0100 Subject: Remove clone original code (bzr r15295.1.47) --- src/live_effects/CMakeLists.txt | 6 - src/live_effects/effect.cpp | 41 ++-- src/live_effects/effect.h | 8 +- src/live_effects/lpe-clone-original.cpp | 289 +------------------------- src/live_effects/lpe-clone-original.h | 24 +-- src/live_effects/parameter/item-reference.cpp | 44 ---- src/live_effects/parameter/item-reference.h | 56 ----- src/live_effects/parameter/item.cpp | 246 ---------------------- src/live_effects/parameter/item.h | 79 ------- src/live_effects/parameter/originalitem.cpp | 148 ------------- src/live_effects/parameter/originalitem.h | 49 ----- src/sp-ellipse.cpp | 13 +- src/sp-item-group.cpp | 37 ++-- src/sp-lpe-item.cpp | 21 +- src/sp-lpe-item.h | 3 +- src/sp-path.cpp | 31 ++- src/ui/clipboard.cpp | 2 - 17 files changed, 67 insertions(+), 1030 deletions(-) delete mode 100644 src/live_effects/parameter/item-reference.cpp delete mode 100644 src/live_effects/parameter/item-reference.h delete mode 100644 src/live_effects/parameter/item.cpp delete mode 100644 src/live_effects/parameter/item.h delete mode 100644 src/live_effects/parameter/originalitem.cpp delete mode 100644 src/live_effects/parameter/originalitem.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 5ffccc7c0..784317090 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -60,9 +60,6 @@ set(live_effects_SRC parameter/array.cpp parameter/bool.cpp parameter/filletchamferpointarray.cpp - parameter/item-reference.cpp - parameter/item.cpp - parameter/originalitem.cpp parameter/originalpath.cpp parameter/originalpatharray.cpp parameter/parameter.cpp @@ -145,9 +142,6 @@ set(live_effects_SRC parameter/bool.h parameter/enum.h parameter/filletchamferpointarray.h - parameter/item.h - parameter/item-reference.h - parameter/originalitem.h parameter/originalpath.h parameter/originalpatharray.h parameter/parameter.h diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 81a512d23..5cc0d6f20 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -116,7 +116,7 @@ const Util::EnumData LPETypeData[] = { {RULER, N_("Ruler"), "ruler"}, /* 0.91 */ {POWERSTROKE, N_("Power stroke"), "powerstroke"}, - {CLONE_ORIGINAL, N_("Clone original"), "clone_original"}, + {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, /* 0.92 */ {SIMPLIFY, N_("Simplify"), "simplify"}, {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, @@ -356,7 +356,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), - sp_shape(NULL), + sp_curve(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden { @@ -392,9 +392,9 @@ Effect::doOnApply (SPLPEItem const*/*lpeitem*/) } void -Effect::setSelectedNodePoints(std::vector selected_np) +Effect::setSelectedNodePoints(std::vector sNP) { - selected_nodes_points = selected_np; + selectedNodesPoints = sNP; } void @@ -404,16 +404,16 @@ Effect::setCurrentZoom(double cZ) } bool -Effect::isNodePointSelected(Geom::Point const &node_point) const +Effect::isNodePointSelected(Geom::Point const &nodePoint) const { - if (selected_nodes_points.size() > 0) { + if (selectedNodesPoints.size() > 0) { using Geom::X; using Geom::Y; - for (std::vector::const_iterator i = selected_nodes_points.begin(); - i != selected_nodes_points.end(); ++i) { + for (std::vector::const_iterator i = selectedNodesPoints.begin(); + i != selectedNodesPoints.end(); ++i) { Geom::Point p = *i; Geom::Affine transformCoordinate = sp_lpe_item->i2dt_affine(); - Geom::Point p2(node_point[X], node_point[Y]); + Geom::Point p2(nodePoint[X],nodePoint[Y]); p2 *= transformCoordinate; if (Geom::are_near(p, p2, 0.01)) { return true; @@ -446,24 +446,21 @@ void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - SPShape * shape = dynamic_cast(sp_lpe_item); - if(shape){ - setCurrentShape(shape); - } + /*sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); + pathvector_before_effect = sp_curve->get_pathvector();*/ doOnApply(lpeitem); } void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - //Groups set shape in performPathEffect before each call to doEffect + //printf("(SPLPEITEM*) %p\n", sp_lpe_item); SPShape * shape = dynamic_cast(sp_lpe_item); if(shape){ - setCurrentShape(shape); + sp_curve = shape->getCurve(); + pathvector_before_effect = sp_curve->get_pathvector(); } - //printf("(SPLPEITEM*) %p\n", sp_lpe_item); doBeforeEffect(lpeitem); - if (apply_to_clippath_and_mask && SP_IS_GROUP(sp_lpe_item)) { sp_lpe_item->apply_to_clippath(sp_lpe_item); sp_lpe_item->apply_to_mask(sp_lpe_item); @@ -471,16 +468,6 @@ void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) update_helperpath(); } -void Effect::setCurrentShape(SPShape * shape){ - if(shape){ - sp_shape = shape; - if (!(sp_curve = sp_shape->getCurve())) { - // oops - return; - } - pathvector_before_effect = sp_curve->get_pathvector(); - } -} /** * Effects can have a parameter path set before they are applied by accepting a nonzero number of * mouse clicks. This method activates the pen context, which waits for the specified number of diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index b1dc0eabb..bc56c2390 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -79,8 +79,7 @@ public: static int acceptsNumClicks(EffectType type); int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } void doAcceptPathPreparations(SPLPEItem *lpeitem); - SPShape * getCurrentShape(){ return sp_shape; }; - void setCurrentShape(SPShape * shape); + /* * isReady() indicates whether all preparations which are necessary to apply the LPE are done, * e.g., waiting for a parameter path either before the effect is created or when it needs a @@ -170,10 +169,9 @@ protected: // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each. bool concatenate_before_pwd2; - SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them.z - SPShape * sp_shape; // these get stored in doBeforeEffect_impl before doEffect chain, or in performPathEffects on groups, and derived classes may do as they please with them. + SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. double current_zoom; - std::vector selected_nodes_points; + std::vector selectedNodesPoints; SPCurve * sp_curve; Geom::PathVector pathvector_before_effect; private: diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 33abd685a..10418a02d 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -6,12 +6,6 @@ #include "live_effects/lpe-clone-original.h" #include "display/curve.h" -#include "svg/path-string.h" -#include "svg/svg.h" -#include "sp-clippath.h" -#include "sp-mask.h" -#include "xml/sp-css-attr.h" - // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -20,268 +14,9 @@ namespace LivePathEffect { LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : Effect(lpeobject), - linked_path("LEGACY FALLBACK", "LEGACY FALLBACK", "linkedpath", &wr, this), - linked_item(_("Linked Item:"), _("Item from which to take the original data"), "linked_item", &wr, this), - scale(_("Scale %"), _("Scale item %"), "scale", &wr, this, 100.0), - preserve_position(_("Preserve position"), _("Preserve position"), "preserve_position", &wr, this, false), - inverse(_("Inverse clone"), _("Use LPE item as origin"), "inverse", &wr, this, false), - use_center(_("Relative center of element"), _("Relative center of element"), "use_center", &wr, this, true), - attributes("Attributes linked", "Attributes linked", "attributes", &wr, this,""), - style_attributes("Style attributes linked", "Style attributes linked", "style_attributes", &wr, this,"") -{ - registerParameter(&linked_path); - registerParameter(&linked_item); - registerParameter(&scale); - registerParameter(&attributes); - registerParameter(&style_attributes); - registerParameter(&preserve_position); - registerParameter(&inverse); - registerParameter(&use_center); - scale.param_set_range(0.01, 999999.0); - scale.param_set_increments(1, 1); - scale.param_set_digits(2); - attributes.param_hide_canvas_text(); - style_attributes.param_hide_canvas_text(); - preserve_position_changed = preserve_position; - preserve_affine = Geom::identity(); -} - -bool hasLinkedTransform( const char * attributes) { - gchar ** attarray = g_strsplit(attributes, ",", 0); - gchar ** iter = attarray; - bool has_linked_transform = false; - while (*iter != NULL) { - const char* attribute = (*iter); - if ( std::strcmp(attribute, "transform") == 0 ) { - has_linked_transform = true; - } - iter++; - } - return has_linked_transform; -} - -void -LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes, bool root) + linked_path(_("Linked path:"), _("Path from which to take the original path data"), "linkedpath", &wr, this) { - SPDocument * document = SP_ACTIVE_DOCUMENT; - if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { - std::vector< SPObject * > childs = origin->childList(true); - size_t index = 0; - for (std::vector::iterator obj_it = childs.begin(); - obj_it != childs.end(); ++obj_it) { - SPObject *dest_child = dest->nthChild(index); - cloneAttrbutes((*obj_it), dest_child, live, attributes, style_attributes, false); - index++; - } - } - //Attributes - SPShape * shape_origin = SP_SHAPE(origin); - SPPath * path_origin = SP_PATH(origin); - SPShape * shape_dest = SP_SHAPE(dest); - SPMask *mask_origin = SP_ITEM(origin)->mask_ref->getObject(); - SPMask *mask_dest = SP_ITEM(dest)->mask_ref->getObject(); - if(mask_origin && mask_dest) { - std::vector mask_list = mask_origin->childList(true); - std::vector mask_list_dest = mask_dest->childList(true); - if (mask_list.size() == mask_list_dest.size()) { - size_t i = 0; - for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { - SPObject * mask_data = *iter; - SPObject * mask_dest_data = mask_list_dest[i]; - cloneAttrbutes(mask_data, mask_dest_data, live, attributes, style_attributes, false); - i++; - } - } - } - SPClipPath *clippath_origin = SP_ITEM(origin)->clip_ref->getObject(); - SPClipPath *clippath_dest = SP_ITEM(dest)->clip_ref->getObject(); - if(clippath_origin && clippath_dest) { - std::vector clippath_list = clippath_origin->childList(true); - std::vector clippath_list_dest = clippath_dest->childList(true); - if (clippath_list.size() == clippath_list_dest.size()) { - size_t i = 0; - for ( std::vector::const_iterator iter=clippath_list.begin();iter!=clippath_list.end();++iter) { - SPObject * clippath_data = *iter; - SPObject * clippath_dest_data = clippath_list_dest[i]; - cloneAttrbutes(clippath_data, clippath_dest_data, live, attributes, style_attributes, false); - i++; - } - } - } - gchar ** attarray = g_strsplit(attributes, ",", 0); - gchar ** iter = attarray; - Geom::Affine affine_dest = Geom::identity(); - Geom::Affine affine_origin = Geom::identity(); - Geom::Affine affine_previous = Geom::identity(); - sp_svg_transform_read(SP_ITEM(dest)->getAttribute("transform"), &affine_dest); - sp_svg_transform_read(SP_ITEM(origin)->getAttribute("transform"), &affine_origin); - while (*iter != NULL) { - const char* attribute = (*iter); - if ( std::strcmp(attribute, "transform") == 0 ) { - if (preserve_position) { - Geom::Affine dest_affine = Geom::identity(); - if (root) { - dest_affine *= affine_origin; - if (preserve_affine == Geom::identity()) { - dest_affine *= Geom::Translate(affine_dest.translation()); - } - dest_affine *= Geom::Translate(affine_origin.translation()).inverse(); - dest_affine *= Geom::Translate(preserve_affine.translation()); - affine_previous = preserve_affine; - preserve_affine = Geom::identity(); - SP_ITEM(dest)->getRepr()->setAttribute("transform",sp_svg_transform_write(dest_affine)); - } - } else { - SP_ITEM(dest)->getRepr()->setAttribute("transform",sp_svg_transform_write(affine_origin)); - } - } else if ( shape_dest && shape_origin && live && (std::strcmp(attribute, "d") == 0)) { - SPCurve *c = NULL; - if (inverse) { - c = shape_origin->getCurveBeforeLPE(); - } else { - c = shape_origin->getCurve(); - } - if (c) { - Geom::PathVector c_pv = c->get_pathvector(); - Geom::OptRect orig_bbox = SP_ITEM(origin)->geometricBounds(); - Geom::OptRect dest_bbox = SP_ITEM(dest)->geometricBounds(); - if (dest_bbox && orig_bbox && root) { - Geom::Point orig_point = (*orig_bbox).corner(0); - Geom::Point dest_point = (*dest_bbox).corner(0); - if (use_center) { - orig_point = (*orig_bbox).midpoint(); - dest_point = (*dest_bbox).midpoint(); - } - if (scale != 100.0) { - double scale_affine = scale/100.0; - Geom::Scale scale = Geom::Scale(scale_affine); - c_pv *= Geom::Translate(orig_point).inverse(); - c_pv *= scale; - c_pv *= Geom::Translate(orig_point); - } - if (preserve_position) { - c_pv *= Geom::Translate(dest_point - orig_point); - } - } - if (inverse) { - c_pv *= i2anc_affine(origin, sp_lpe_item); - } else { - c_pv *= i2anc_affine(dest, sp_lpe_item); - } - c->set_pathvector(c_pv); - if (!path_origin) { - shape_dest->setCurveInsync(c, TRUE); - dest->getRepr()->setAttribute(attribute, sp_svg_write_path(c_pv)); - } else { - shape_dest->setCurve(c, TRUE); - } - c->unref(); - } else { - dest->getRepr()->setAttribute(attribute, NULL); - } - } else { - dest->getRepr()->setAttribute(attribute, origin->getRepr()->attribute(attribute)); - } - iter++; - } - g_strfreev (attarray); - SPCSSAttr *css_origin = sp_repr_css_attr_new(); - sp_repr_css_attr_add_from_string(css_origin, origin->getRepr()->attribute("style")); - SPCSSAttr *css_dest = sp_repr_css_attr_new(); - sp_repr_css_attr_add_from_string(css_dest, dest->getRepr()->attribute("style")); - gchar ** styleattarray = g_strsplit(style_attributes, ",", 0); - gchar ** styleiter = styleattarray; - while (*styleiter != NULL) { - const char* attribute = (*styleiter); - const char* origin_attribute = sp_repr_css_property(css_origin, attribute, ""); - if (origin_attribute == "") { - sp_repr_css_set_property (css_dest, attribute, NULL); - } else { - sp_repr_css_set_property (css_dest, attribute, origin_attribute); - } - styleiter++; - } - g_strfreev (styleattarray); - Glib::ustring css_str; - sp_repr_css_write_string(css_dest,css_str); - dest->getRepr()->setAttribute("style", css_str.c_str()); -} - -void -LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ - if (linked_path.linksToPath()) { //Legacy staff - Glib::ustring attributes_value("d"); - attributes.param_setValue(attributes_value); - attributes.write_to_SVG(); - Glib::ustring style_attributes_value(""); - style_attributes.param_setValue(style_attributes_value); - style_attributes.write_to_SVG(); - linked_item.param_readSVGValue(linked_path.param_getSVGValue()); - linked_path.param_readSVGValue(""); - } - - if (linked_item.linksToItem()) { - linked_item.setInverse(inverse); - if ( preserve_position_changed != preserve_position ) { - if (!preserve_position) { - sp_svg_transform_read(SP_ITEM(sp_lpe_item)->getAttribute("transform"), &preserve_affine); - } - preserve_position_changed = preserve_position; - } - if (inverse) { - cloneAttrbutes(SP_OBJECT(sp_lpe_item), linked_item.getObject(), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true); - } else { - cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true); - } - } -} - - -Gtk::Widget * -LPECloneOriginal::newWidget() -{ - // use manage here, because after deletion of Effect object, others might - // still be pointing to this widget. - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - vbox->set_border_width(5); - vbox->set_homogeneous(false); - vbox->set_spacing(2); - - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter * param = *it; - if (param->param_key == "linkedpath") { - ++it; - continue; - } - Gtk::Widget * widg = param->param_newWidget(); - Glib::ustring * tip = param->param_getTooltip(); - if (widg) { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - - ++it; - } - this->upd_params = false; - return dynamic_cast(vbox); -} - -void -LPECloneOriginal::doOnApply(SPLPEItem const* lpeitem){ - Glib::ustring attributes_value("d,transform"); - attributes.param_setValue(attributes_value); - attributes.write_to_SVG(); - Glib::ustring style_attributes_value("opacity,stroke-width"); - style_attributes.param_setValue(style_attributes_value); - style_attributes.write_to_SVG(); + registerParameter( dynamic_cast(&linked_path) ); } LPECloneOriginal::~LPECloneOriginal() @@ -289,22 +24,12 @@ LPECloneOriginal::~LPECloneOriginal() } -void -LPECloneOriginal::transform_multiply(Geom::Affine const& postmul, bool set) -{ - if (linked_item.linksToItem()) { - bool changed = false; - linked_item.getObject()->requestModified(SP_OBJECT_MODIFIED_FLAG); - } -} - -void -LPECloneOriginal::doEffect (SPCurve * curve) +void LPECloneOriginal::doEffect (SPCurve * curve) { - if (linked_item.linksToItem() && !inverse) { - SPShape * shape = getCurrentShape(); - if(shape){ - curve->set_pathvector(shape->getCurve()->get_pathvector()); + if ( linked_path.linksToPath() ) { + Geom::PathVector linked_pathv = linked_path.get_pathvector(); + if ( !linked_pathv.empty() ) { + curve->set_pathvector(linked_pathv); } } } diff --git a/src/live_effects/lpe-clone-original.h b/src/live_effects/lpe-clone-original.h index aad6e9fa9..abf65ded8 100644 --- a/src/live_effects/lpe-clone-original.h +++ b/src/live_effects/lpe-clone-original.h @@ -10,38 +10,22 @@ */ #include "live_effects/effect.h" -#include "live_effects/parameter/originalitem.h" #include "live_effects/parameter/originalpath.h" -#include "live_effects/parameter/parameter.h" -#include "live_effects/parameter/point.h" -#include "live_effects/parameter/text.h" -#include "live_effects/lpegroupbbox.h" namespace Inkscape { namespace LivePathEffect { -class LPECloneOriginal : public Effect, GroupBBoxEffect { +class LPECloneOriginal : public Effect { public: LPECloneOriginal(LivePathEffectObject *lpeobject); virtual ~LPECloneOriginal(); - virtual void doOnApply(SPLPEItem const* lpeitem); + virtual void doEffect (SPCurve * curve); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void transform_multiply(Geom::Affine const& postmul, bool set); - virtual Gtk::Widget * newWidget(); - void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes, bool root); private: OriginalPathParam linked_path; - OriginalItemParam linked_item; - ScalarParam scale; - BoolParam preserve_position; - BoolParam inverse; - BoolParam use_center; - TextParam attributes; - TextParam style_attributes; - bool preserve_position_changed; - Geom::Affine preserve_affine; + +private: LPECloneOriginal(const LPECloneOriginal&); LPECloneOriginal& operator=(const LPECloneOriginal&); }; diff --git a/src/live_effects/parameter/item-reference.cpp b/src/live_effects/parameter/item-reference.cpp deleted file mode 100644 index a775d93b7..000000000 --- a/src/live_effects/parameter/item-reference.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * The reference corresponding to href of LPE Item parameter. - * - * Copyright (C) 2008 Johan Engelen - * - * Released under GNU GPL, read the file 'COPYING' for more information. - */ - -#include "live_effects/parameter/item-reference.h" - -#include "sp-shape.h" -#include "sp-text.h" -#include "sp-item-group.h" - -namespace Inkscape { -namespace LivePathEffect { - -bool ItemReference::_acceptObject(SPObject * const obj) const -{ - if (SP_IS_SHAPE(obj) || SP_IS_TEXT(obj) || SP_IS_GROUP(obj)) { - /* Refuse references to lpeobject */ - if (obj == getOwner()) { - return false; - } - // TODO: check whether the referred item has this LPE applied, if so: deny deny deny! - return URIReference::_acceptObject(obj); - } else { - return false; - } -} - -} // namespace LivePathEffect -} // namespace Inkscape - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/item-reference.h b/src/live_effects/parameter/item-reference.h deleted file mode 100644 index 91231455a..000000000 --- a/src/live_effects/parameter/item-reference.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef SEEN_LPE_ITEM_REFERENCE_H -#define SEEN_LPE_ITEM_REFERENCE_H - -/* - * Copyright (C) 2008-2012 Authors - * Authors: Johan Engelen - * Abhishek Sharma - * - * Released under GNU GPL, read the file 'COPYING' for more information. - */ - -#include - -class SPItem; -namespace Inkscape { -namespace XML { class Node; } - -namespace LivePathEffect { - -/** - * The reference corresponding to href of LPE ItemParam. - */ -class ItemReference : public Inkscape::URIReference { -public: - ItemReference(SPObject *owner) : URIReference(owner) {} - - SPItem *getObject() const { - return (SPItem *)URIReference::getObject(); - } - -protected: - virtual bool _acceptObject(SPObject * const obj) const; - -private: - ItemReference(const ItemReference&); - ItemReference& operator=(const ItemReference&); -}; - -} // namespace LivePathEffect - -} // namespace Inkscape - - - -#endif /* !SEEN_LPE_PATH_REFERENCE_H */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/item.cpp b/src/live_effects/parameter/item.cpp deleted file mode 100644 index 8caea4e26..000000000 --- a/src/live_effects/parameter/item.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) Johan Engelen 2007 - * Abhishek Sharma - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "ui/widget/point.h" -#include - -#include "live_effects/parameter/item.h" -#include "live_effects/effect.h" -#include "svg/svg.h" - -#include "widgets/icon.h" -#include -#include "selection-chemistry.h" -#include "xml/repr.h" -#include "desktop.h" -#include "inkscape.h" -#include "message-stack.h" - -// clipboard support -#include "ui/clipboard.h" -// required for linking to other paths -#include "uri.h" - -#include -#include -#include "ui/icon-names.h" - -namespace Inkscape { - -namespace LivePathEffect { - -ItemParam::ItemParam( const Glib::ustring& label, const Glib::ustring& tip, - const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, const gchar * default_value) - : Parameter(label, tip, key, wr, effect), - changed(true), - href(NULL), - ref( (SPObject*)effect->getLPEObj() ) -{ - defvalue = g_strdup(default_value); - ref_changed_connection = ref.changedSignal().connect(sigc::mem_fun(*this, &ItemParam::ref_changed)); -} - -ItemParam::~ItemParam() -{ - remove_link(); - g_free(defvalue); -} - -void -ItemParam::param_set_default() -{ - param_readSVGValue(defvalue); -} - - -void -ItemParam::param_set_and_write_default() -{ - param_write_to_repr(defvalue); -} - -bool -ItemParam::param_readSVGValue(const gchar * strvalue) -{ - if (strvalue) { - remove_link(); - if (strvalue[0] == '#') { - if (href) - g_free(href); - href = g_strdup(strvalue); - try { - ref.attach(Inkscape::URI(href)); - //lp:1299948 - SPItem* i = ref.getObject(); - if (i) { - linked_modified_callback(i, SP_OBJECT_MODIFIED_FLAG); - } // else: document still processing new events. Repr of the linked object not created yet. - } catch (Inkscape::BadURIException &e) { - g_warning("%s", e.what()); - ref.detach(); - } - } - emit_changed(); - return true; - } - - return false; -} - -gchar * -ItemParam::param_getSVGValue() const -{ - return g_strdup(href); -} - -Gtk::Widget * -ItemParam::param_newWidget() -{ - Gtk::HBox * _widget = Gtk::manage(new Gtk::HBox()); - Gtk::Widget* pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-clone"), Inkscape::ICON_SIZE_BUTTON) ); - Gtk::Button * pButton = Gtk::manage(new Gtk::Button()); - Gtk::Label* pLabel = Gtk::manage(new Gtk::Label(param_label)); - static_cast(_widget)->pack_start(*pLabel, true, true); - pLabel->set_tooltip_text(param_tooltip); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &ItemParam::on_link_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Link to item on clipboard")); - - static_cast(_widget)->show_all_children(); - - return dynamic_cast (_widget); -} - -void -ItemParam::emit_changed() -{ - changed = true; - signal_item_changed.emit(); -} - - -void -ItemParam::addCanvasIndicators(SPLPEItem const*/*lpeitem*/, std::vector &hp_vec) -{ -} - - -void -ItemParam::start_listening(SPObject * to) -{ - if ( to == NULL ) { - return; - } - linked_delete_connection = to->connectDelete(sigc::mem_fun(*this, &ItemParam::linked_delete)); - linked_modified_connection = to->connectModified(sigc::mem_fun(*this, &ItemParam::linked_modified)); - if (SP_IS_ITEM(to)) { - linked_transformed_connection = SP_ITEM(to)->connectTransformed(sigc::mem_fun(*this, &ItemParam::linked_transformed)); - } - linked_modified(to, SP_OBJECT_MODIFIED_FLAG); // simulate linked_modified signal, so that path data is updated -} - -void -ItemParam::quit_listening(void) -{ - linked_modified_connection.disconnect(); - linked_delete_connection.disconnect(); - linked_transformed_connection.disconnect(); -} - -void -ItemParam::ref_changed(SPObject */*old_ref*/, SPObject *new_ref) -{ - quit_listening(); - if ( new_ref ) { - start_listening(new_ref); - } -} - -void -ItemParam::remove_link() -{ - if (href) { - ref.detach(); - g_free(href); - href = NULL; - } -} - -void -ItemParam::linked_delete(SPObject */*deleted*/) -{ - quit_listening(); - remove_link(); -} - -void ItemParam::linked_modified(SPObject *linked_obj, guint flags) -{ - linked_modified_callback(linked_obj, flags); -} - -void ItemParam::linked_transformed(Geom::Affine const *rel_transf, SPItem *moved_item) -{ - linked_transformed_callback(rel_transf, moved_item); -} - -void -ItemParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) -{ - emit_changed(); - SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); -} - -void -ItemParam::on_link_button_click() -{ - Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); - const gchar * iid = cm->getFirstObjectID(); - if (!iid) { - return; - } - - Glib::ustring itemid(iid); - - if (itemid.empty()) { - return; - } - - // add '#' at start to make it an uri. - itemid.insert(itemid.begin(), '#'); - if ( href && strcmp(itemid.c_str(), href) == 0 ) { - // no change, do nothing - return; - } else { - // TODO: - // check if id really exists in document, or only in clipboard document: if only in clipboard then invalid - // check if linking to object to which LPE is applied (maybe delegated to PathReference - - param_write_to_repr(itemid.c_str()); - DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, - _("Link item parameter to path")); - } -} - -} /* namespace LivePathEffect */ - -} /* namespace Inkscape */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/item.h b/src/live_effects/parameter/item.h deleted file mode 100644 index 6c719d451..000000000 --- a/src/live_effects/parameter/item.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_ITEM_H -#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_ITEM_H - -/* - * Inkscape::LivePathEffectParameters - * -* Copyright (C) Johan Engelen 2007 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include - - -#include "live_effects/parameter/parameter.h" -#include "live_effects/parameter/item-reference.h" -#include -#include - -namespace Inkscape { - -namespace LivePathEffect { - -class ItemParam : public Parameter { -public: - ItemParam ( const Glib::ustring& label, - const Glib::ustring& tip, - const Glib::ustring& key, - Inkscape::UI::Widget::Registry* wr, - Effect* effect, - const gchar * default_value = ""); - virtual ~ItemParam(); - virtual Gtk::Widget * param_newWidget(); - - virtual bool param_readSVGValue(const gchar * strvalue); - virtual gchar * param_getSVGValue() const; - - virtual void param_set_default(); - void param_set_and_write_default(); - virtual void addCanvasIndicators(SPLPEItem const* lpeitem, std::vector &hp_vec); - - sigc::signal signal_item_pasted; - sigc::signal signal_item_changed; - bool changed; /* this gets set whenever the path is changed (this is set to true, and then the signal_item_changed signal is emitted). - * the user must set it back to false if she wants to use it sensibly */ -protected: - - gchar * href; // contains link to other object, e.g. "#path2428", NULL if ItemParam contains pathdata itself - ItemReference ref; - sigc::connection ref_changed_connection; - sigc::connection linked_delete_connection; - sigc::connection linked_modified_connection; - sigc::connection linked_transformed_connection; - void ref_changed(SPObject *old_ref, SPObject *new_ref); - void remove_link(); - void start_listening(SPObject * to); - void quit_listening(void); - void linked_delete(SPObject *deleted); - void linked_modified(SPObject *linked_obj, guint flags); - void linked_transformed(Geom::Affine const *rel_transf, SPItem *moved_item); - virtual void linked_modified_callback(SPObject *linked_obj, guint flags); - virtual void linked_transformed_callback(Geom::Affine const * /*rel_transf*/, SPItem * /*moved_item*/) {}; - void on_link_button_click(); - - void emit_changed(); - - gchar * defvalue; - -private: - ItemParam(const ItemParam&); - ItemParam& operator=(const ItemParam&); -}; - - -} //namespace LivePathEffect - -} //namespace Inkscape - -#endif diff --git a/src/live_effects/parameter/originalitem.cpp b/src/live_effects/parameter/originalitem.cpp deleted file mode 100644 index 07c8bd27c..000000000 --- a/src/live_effects/parameter/originalitem.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) Johan Engelen 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include "live_effects/parameter/originalitem.h" - -#include "widgets/icon.h" -#include -#include -#include - -#include "uri.h" -#include "sp-shape.h" -#include "sp-text.h" -#include "display/curve.h" -#include "live_effects/effect.h" - -#include "inkscape.h" -#include "desktop.h" -#include "selection.h" -#include "ui/icon-names.h" - -namespace Inkscape { - -namespace LivePathEffect { - -OriginalItemParam::OriginalItemParam( const Glib::ustring& label, const Glib::ustring& tip, - const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect) - : ItemParam(label, tip, key, wr, effect, "") -{ -} - -OriginalItemParam::~OriginalItemParam() -{ - -} - -Gtk::Widget * -OriginalItemParam::param_newWidget() -{ - Gtk::HBox *_widget = Gtk::manage(new Gtk::HBox()); - - { // Label - Gtk::Label *pLabel = Gtk::manage(new Gtk::Label(param_label)); - static_cast(_widget)->pack_start(*pLabel, true, true); - pLabel->set_tooltip_text(param_tooltip); - } - - { // Paste item to link button - Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-paste"), Inkscape::ICON_SIZE_BUTTON) ); - Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalItemParam::on_link_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Link to item")); - } - - { // Select original button - Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon("edit-select-original", Inkscape::ICON_SIZE_BUTTON) ); - Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalItemParam::on_select_original_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Select original")); - } - - static_cast(_widget)->show_all_children(); - - return dynamic_cast (_widget); -} - -void -OriginalItemParam::param_write(const gchar * iid) -{ - Glib::ustring itemid(iid); - - if (itemid.empty()) { - return; - } - // add '#' at start to make it an uri. - itemid.insert(itemid.begin(), '#'); - if ( href && strcmp(itemid.c_str(), href) == 0 ) { - // no change, do nothing - return; - } else { - param_write_to_repr(itemid.c_str()); - } -} - -void -OriginalItemParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) -{ - if (!inverse) { - emit_changed(); - LivePathEffectObject* lpeobj = param_effect->getLPEObj(); - SP_OBJECT(lpeobj)->requestModified(SP_OBJECT_MODIFIED_FLAG); - } -} - -void -OriginalItemParam::linked_transformed_callback(Geom::Affine const * /*rel_transf*/, SPItem * /*moved_item*/) -{ -/** \todo find good way to compensate for referenced item transform, like done for normal clones. - * See sp-use.cpp: sp_use_move_compensate */ -} - - -void -OriginalItemParam::on_select_original_button_click() -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - SPItem *original = ref.getObject(); - if (desktop == NULL || original == NULL) { - return; - } - Inkscape::Selection *selection = desktop->getSelection(); - selection->clear(); - selection->set(original); -} - -} /* namespace LivePathEffect */ - -} /* namespace Inkscape */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/originalitem.h b/src/live_effects/parameter/originalitem.h deleted file mode 100644 index 86e223cea..000000000 --- a/src/live_effects/parameter/originalitem.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_ORIGINAL_ITEM_H -#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_ORIGINAL_ITEM_H - -/* - * Inkscape::LiveItemEffectParameters - * -* Copyright (C) Johan Engelen 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "live_effects/parameter/item.h" - -namespace Inkscape { - -namespace LivePathEffect { - -class OriginalItemParam: public ItemParam { -public: - OriginalItemParam ( const Glib::ustring& label, - const Glib::ustring& tip, - const Glib::ustring& key, - Inkscape::UI::Widget::Registry* wr, - Effect* effect); - virtual ~OriginalItemParam(); - void setInverse(bool inversed) { inverse = inversed; } - bool linksToItem() const { return (href != NULL); } - SPItem * getObject() const { return ref.getObject(); } - void param_write(const gchar * iid); - virtual Gtk::Widget * param_newWidget(); - -protected: - virtual void linked_modified_callback(SPObject *linked_obj, guint flags); - virtual void linked_transformed_callback(Geom::Affine const *rel_transf, SPItem *moved_item); - - void on_select_original_button_click(); - -private: - bool inverse; - OriginalItemParam(const OriginalItemParam&); - OriginalItemParam& operator=(const OriginalItemParam&); -}; - - -} //namespace LivePathEffect - -} //namespace Inkscape - -#endif diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 9589d6fce..ed1e2b504 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -445,20 +445,11 @@ void SPGenericEllipse::set_shape() if (hasPathEffect() && pathEffectsEnabled()) { SPCurve *c_lpe = curve->copy(); bool success = this->performPathEffect(c_lpe); - + if (success) { this->setCurveInsync(c_lpe, TRUE); - } else { - Inkscape::XML::Node *repr = this->getRepr(); - if (gchar const * value = repr->attribute("d")) { - Geom::PathVector pv = sp_svg_read_pathv(value); - SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); - if (oldcurve) { - this->setCurveInsync(oldcurve, TRUE); - oldcurve->unref(); - } - } } + c_lpe->unref(); } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 808d475c7..7b2507b5e 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -950,36 +950,25 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) } else { c = subShape->getCurve(); } - bool success = false; + // only run LPEs when the shape has a curve defined if (c) { c->transform(i2anc_affine(subitem, topgroup)); - success = topgroup->performPathEffect(c, subShape); + topgroup->performPathEffect(c); c->transform(i2anc_affine(subitem, topgroup).inverse()); - if (c && success) { - subShape->setCurve(c, TRUE); - if (write) { - Inkscape::XML::Node *repr = subitem->getRepr(); - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); - #ifdef GROUP_VERBOSE - g_message("sp_group_perform_patheffect writes 'd' attribute"); - #endif - g_free(str); - } - c->unref(); - } else { - // LPE was unsuccesfull or doeffect stack return null. Read the old 'd'-attribute. + subShape->setCurve(c, TRUE); + + if (write) { Inkscape::XML::Node *repr = subitem->getRepr(); - if (gchar const * value = repr->attribute("d")) { - Geom::PathVector pv = sp_svg_read_pathv(value); - SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); - if (oldcurve) { - subShape->setCurve(oldcurve, TRUE); - oldcurve->unref(); - } - } + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); +#ifdef GROUP_VERBOSE + g_message("sp_group_perform_patheffect writes 'd' attribute"); +#endif + g_free(str); } + + c->unref(); } } } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index fb640c50c..98428512f 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -212,7 +212,7 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { +bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { if (!curve) { return false; @@ -244,14 +244,12 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip } if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { // Groups have their doBeforeEffect called elsewhere - if (current) { - lpe->setCurrentShape(current); - } if (!SP_IS_GROUP(this)) { lpe->doBeforeEffect_impl(this); } + try { - lpe->doEffect(curve); + lpe->doEffect(curve); } catch (std::exception & e) { g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); @@ -702,10 +700,10 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) try { if(SP_IS_GROUP(this)){ c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + success = this->performPathEffect(c, true); c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); } else { - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + success = this->performPathEffect(c, true); } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -716,13 +714,12 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) success = false; } Inkscape::XML::Node *repr = clip_mask->getRepr(); - // This c check allow to not apply LPE if curve is NULL after performPathEffect used in clone.obgets LPE - if (success && c) { + if (success) { gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); g_free(str); } else { - // LPE was unsuccesfull or doeffect stack return null.. Read the old 'd'-attribute. + // LPE was unsuccesfull. Read the old 'd'-attribute. if (gchar const * value = repr->attribute("d")) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); @@ -732,9 +729,7 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) } } } - if (c) { - c->unref(); - } + c->unref(); } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 0f198c49c..db4a0c7a3 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -23,7 +23,6 @@ class LivePathEffectObject; class SPCurve; -class SPShape; class SPDesktop; namespace Inkscape{ @@ -70,7 +69,7 @@ public: virtual void update_patheffect(bool write); - bool performPathEffect(SPCurve *curve, SPShape *current = NULL, bool is_clip_or_mask = false); + bool performPathEffect(SPCurve *curve, bool is_clip_or_mask = false); bool pathEffectsEnabled() const; bool hasPathEffect() const; diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 6c69f3463..b593b7937 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -289,23 +289,10 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { if (!_curve) { // 0 nodes, nothing to transform return Geom::identity(); } - // Adjust stroke - this->adjust_stroke(transform.descrim()); - - // Adjust pattern fill - this->adjust_pattern(transform); - - // Adjust gradient fill - this->adjust_gradient(transform); - - // Adjust LPE - this->adjust_livepatheffect(transform); // Transform the original-d path if this is a valid LPE this, other else the (ordinary) path if (_curve_before_lpe && hasPathEffectRecursive()) { - if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) || - this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH)) - { + if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) || this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH)) { // if path has the CLONE_ORIGINAL LPE applied, don't write the transform to the pathdata, but write it 'unoptimized' // also if the effect is type BEND PATH to fix bug #179842 return transform; @@ -316,6 +303,18 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { _curve->transform(transform); } + // Adjust stroke + this->adjust_stroke(transform.descrim()); + + // Adjust pattern fill + this->adjust_pattern(transform); + + // Adjust gradient fill + this->adjust_gradient(transform); + + // Adjust LPE + this->adjust_livepatheffect(transform); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); // nothing remains - we've written all of the transform, so return identity @@ -355,9 +354,9 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); if (gchar const * value = repr->attribute("d")) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new SPCurve(pv); + if (oldcurve) { - this->setCurveInsync(oldcurve, TRUE); - repr->setAttribute("d", value); + this->setCurve(oldcurve, TRUE); oldcurve->unref(); } } diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 42fc2fab4..a8e708597 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -410,8 +410,6 @@ const gchar *ClipboardManagerImpl::getFirstObjectID() strcmp(ch->name(), "svg:use") && strcmp(ch->name(), "svg:text") && strcmp(ch->name(), "svg:image") && - strcmp(ch->name(), "svg:ellipse") && - strcmp(ch->name(), "svg:circle") && strcmp(ch->name(), "svg:rect") ) { ch = ch->next(); -- cgit v1.2.3 From 1154b598331b962b3ea6b5f0daabf632b538fe12 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 3 Jan 2017 15:58:20 +0100 Subject: Fixing some bugs (bzr r15295.1.48) --- src/live_effects/lpe-mirror_symmetry.cpp | 246 +++++++++++++++---------------- src/live_effects/lpe-mirror_symmetry.h | 5 - src/sp-item-group.cpp | 9 ++ 3 files changed, 131 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 0436ed877..05380c568 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -52,7 +52,6 @@ MTConverter(ModeTypeData, MT_END); LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), - mirror_item(_("Mirror item:"), _("Mirror item"), "mirror_item", &wr, this), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, 0), discard_orig_path(_("Discard original path"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), @@ -65,7 +64,6 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,"") { show_orig_path = true; - registerParameter(&mirror_item); registerParameter(&mode); registerParameter(&split_gap); registerParameter(&discard_orig_path); @@ -82,43 +80,22 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : split_gap.param_set_digits(2); apply_to_clippath_and_mask = true; previous_center = Geom::Point(0,0); - other = NULL; - last_transform = Geom::identity(); } LPEMirrorSymmetry::~LPEMirrorSymmetry() { } -bool -LPEMirrorSymmetry::isCurrentLPEItem() { - if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - Inkscape::Selection *sel = desktop->getSelection(); - if ( sel && !sel->isEmpty()) { - SPItem *item = sel->singleItem(); - if (item) { - if(sp_lpe_item && std::strcmp(sp_lpe_item->getId(),item->getId()) == 0) { - return true; - } - } - } - } - return false; -} - void LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) { - if (!isCurrentLPEItem()) { - return; - } - last_transform = Geom::identity(); if (split_elements) { - if (discard_orig_path) { - discard_orig_path.param_setValue(false); - discard_orig_path.write_to_SVG(); - std::cout << _("You can't discard original paths on split elements"); - } +// if (discard_orig_path) { +// discard_orig_path.param_setValue(false); +// discard_orig_path.write_to_SVG(); +// std::cout << _("You can't discard original paths on split elements"); +// return; +// } container = dynamic_cast(sp_lpe_item->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); @@ -136,7 +113,6 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) } else { processObjects(LPE_ERASE); elements.clear(); - other = NULL; } } @@ -146,9 +122,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) using namespace Geom; original_bbox(lpeitem); - if (!isCurrentLPEItem()) { - return; - } //center_point->param_set_liveupdate(false); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); @@ -240,20 +213,17 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c SPPath * path = SP_PATH(dest); if (!path && !SP_IS_GROUP(dest)) { Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); - dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); + dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); } - if (shape) { - if ( live && (att == "d" || att == "inkscape:original-d")) { + path = SP_PATH(dest); + if (path && shape) { + if ( live && att == "d") { SPCurve *c = NULL; - if (att == "d") { - c = shape->getCurve(); - } else { - c = shape->getCurveBeforeLPE(); - } + c = shape->getCurve(); if (c) { + path->setCurve(c, TRUE); dest->getRepr()->setAttribute(att,sp_svg_write_path(c->get_pathvector())); - c->reset(); - g_free(c); + c->unref(); } else { dest->getRepr()->setAttribute(att,NULL); } @@ -280,56 +250,52 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform) phantom = elemref->getRepr(); } else { phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); + phantom->setAttribute("inkscape:path-effect", NULL); + phantom->setAttribute("inkscape:original-d", NULL); + phantom->setAttribute("sodipodi:type", NULL); + phantom->setAttribute("sodipodi:rx", NULL); + phantom->setAttribute("sodipodi:ry", NULL); + phantom->setAttribute("sodipodi:cx", NULL); + phantom->setAttribute("sodipodi:cy", NULL); + phantom->setAttribute("sodipodi:end", NULL); + phantom->setAttribute("sodipodi:start", NULL); + phantom->setAttribute("inkscape:flatsided", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("inkscape:rounded", NULL); + phantom->setAttribute("sodipodi:arg1", NULL); + phantom->setAttribute("sodipodi:arg2", NULL); + phantom->setAttribute("sodipodi:r1", NULL); + phantom->setAttribute("sodipodi:r2", NULL); + phantom->setAttribute("sodipodi:sides", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("sodipodi:argument", NULL); + phantom->setAttribute("sodipodi:expansion", NULL); + phantom->setAttribute("sodipodi:radius", NULL); + phantom->setAttribute("sodipodi:revolution", NULL); + phantom->setAttribute("sodipodi:t0", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("x", NULL); + phantom->setAttribute("y", NULL); + phantom->setAttribute("rx", NULL); + phantom->setAttribute("ry", NULL); + phantom->setAttribute("width", NULL); + phantom->setAttribute("height", NULL); } phantom->setAttribute("id", elemref_id); - phantom->setAttribute("inkscape:path-effect", NULL); - phantom->setAttribute("sodipodi:type", NULL); - phantom->setAttribute("sodipodi:rx", NULL); - phantom->setAttribute("sodipodi:ry", NULL); - phantom->setAttribute("sodipodi:cx", NULL); - phantom->setAttribute("sodipodi:cy", NULL); - phantom->setAttribute("sodipodi:end", NULL); - phantom->setAttribute("sodipodi:start", NULL); - phantom->setAttribute("inkscape:flatsided", NULL); - phantom->setAttribute("inkscape:randomized", NULL); - phantom->setAttribute("inkscape:rounded", NULL); - phantom->setAttribute("sodipodi:arg1", NULL); - phantom->setAttribute("sodipodi:arg2", NULL); - phantom->setAttribute("sodipodi:r1", NULL); - phantom->setAttribute("sodipodi:r2", NULL); - phantom->setAttribute("sodipodi:sides", NULL); - phantom->setAttribute("inkscape:randomized", NULL); - phantom->setAttribute("sodipodi:argument", NULL); - phantom->setAttribute("sodipodi:expansion", NULL); - phantom->setAttribute("sodipodi:radius", NULL); - phantom->setAttribute("sodipodi:revolution", NULL); - phantom->setAttribute("sodipodi:t0", NULL); - phantom->setAttribute("inkscape:randomized", NULL); - phantom->setAttribute("inkscape:randomized", NULL); - phantom->setAttribute("inkscape:randomized", NULL); - phantom->setAttribute("x", NULL); - phantom->setAttribute("y", NULL); - phantom->setAttribute("rx", NULL); - phantom->setAttribute("ry", NULL); - phantom->setAttribute("width", NULL); - phantom->setAttribute("height", NULL); if (!elemref) { elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); - mirror_item.param_write(elemref_id); - } else { - elemref->updateRepr(xml_doc, phantom, SP_OBJECT_WRITE_ALL); } cloneAttrbutes(SP_OBJECT(sp_lpe_item), elemref, true, "d"); elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); copy->setAttribute("id", elemref_id); - other = container->appendChildRepr(copy); + container->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); - } else { - other = elemref; } } @@ -416,9 +382,7 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) break; case LPE_ERASE: - //if (std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0) { - elemref->deleteObject(); - //} + elemref->deleteObject(); break; case LPE_VISIBILITY: @@ -448,24 +412,12 @@ void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { // cycle through all parameters. Most parameters will not need transformation, but path and point params do. - if (isCurrentLPEItem()) { - for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { - Parameter * param = *it; - param->param_transform_multiply(postmul, set); - } - previous_center = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); - - // Geom::Affine m = Geom::identity(); - // m *= sp_lpe_item->transform; - // m *= postmul; - // sp_lpe_item->transform = m; - //last_transform *= postmul; - sp_lpe_item_update_patheffect(sp_lpe_item, false, false); - // if (other) { - // sp_lpe_item_update_patheffect(SP_LPE_ITEM(other), false, false); - // } + for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { + Parameter * param = *it; + param->param_transform_multiply(postmul, set); } - + previous_center = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); + sp_lpe_item_update_patheffect(sp_lpe_item, false, false); } void @@ -495,7 +447,17 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) Geom::PathVector LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) { - if (split_elements && !fuse_paths || !isCurrentLPEItem()) { + if (split_elements && !fuse_paths) { + if (SP_IS_SHAPE(sp_lpe_item)) { + SPCurve *c = NULL; + if (!path_in.empty()) { + c->set_pathvector(path_in); + if (c) { + SP_SHAPE(sp_lpe_item)->setCurveInsync(c, TRUE); + c->unref(); + } + } + } return path_in; } Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); @@ -516,7 +478,8 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) if (path_it->empty()) { continue; } - Geom::PathVector tmp_path; + Geom::PathVector tmp_pathvector; + Geom::Path tmp_path; double time_start = 0.0; int position = 0; bool end_open = false; @@ -552,10 +515,6 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) double time_end = crossed[i]; if (time_start != time_end && time_end - time_start > Geom::EPSILON) { Geom::Path portion = original.portion(time_start, time_end); - Geom::Path next_portion = portion; - if (crossed.size() > i+1) { - next_portion = original.portion(time_end, crossed[i+1]); - } if (!portion.empty()) { Geom::Point middle = portion.pointAt((double)portion.size()/2.0); position = Geom::sgn(Geom::cross(e - s, middle - s)); @@ -565,20 +524,24 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) if (position == 1) { Geom::Path mirror = portion.reversed() * m; if (split_elements) { - if (crossed.size() > i+1) { - portion.appendNew( next_portion.finalPoint() ); - i++; + if (!tmp_path.empty()) { + tmp_path.appendNew( portion.initialPoint() ); } } else { mirror.setInitial(portion.finalPoint()); portion.append(mirror); - if(i!=0) { + if(i != 0) { portion.setFinal(portion.initialPoint()); portion.close(); } } - if (split_elements) { - tmp_path.push_back(portion); + if (!split_elements) { + tmp_pathvector.push_back(portion); + } else { + if (!tmp_path.empty()) { + portion.setInitial(tmp_path.finalPoint()); + } + tmp_path.append(portion); } } portion.clear(); @@ -602,36 +565,71 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) portion = portion.reversed(); } if (!original.closed()) { - tmp_path.push_back(portion); + if (!split_elements) { + tmp_pathvector.push_back(portion); + } else { + portion.setInitial(tmp_path.finalPoint()); + tmp_path.append(portion); + tmp_pathvector.push_back(tmp_path); + } } else { - if (cs.size() > 1 && tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { - portion.setFinal(tmp_path[0].initialPoint()); - portion.setInitial(tmp_path[0].finalPoint()); - tmp_path[0].append(portion); + if (!split_elements) { + if (cs.size() > 1 && tmp_pathvector.size() > 0 && tmp_pathvector[0].size() > 0 ) { + portion.setFinal(tmp_pathvector[0].initialPoint()); + portion.setInitial(tmp_pathvector[0].finalPoint()); + tmp_pathvector[0].append(portion); + } else { + tmp_pathvector.push_back(portion); + } + tmp_pathvector[0].close(); } else { - tmp_path.push_back(portion); + portion.setInitial(tmp_path.finalPoint()); + tmp_path.append(portion); + tmp_path.close(); } - tmp_path[0].close(); } portion.clear(); } } } +// if (cs.size()!=0 && position == 0) { +// if (split_elements && original.closed()) { +// tmp_path.appendNew( tmp_path.initialPoint() ); +// tmp_path.close(); +// } +// } if (cs.size() == 0 && position == 1) { - tmp_path.push_back(original); + tmp_pathvector.push_back(original); if ( !split_elements) { - tmp_path.push_back(original * m); + tmp_pathvector.push_back(original * m); + } + } + if (split_elements) { + if (split_elements && original.closed()) { + tmp_path.appendNew( tmp_path.initialPoint() ); + tmp_path.close(); } + tmp_pathvector.push_back(tmp_path); + tmp_path.clear(); } - path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); - tmp_path.clear(); + path_out.insert(path_out.end(), tmp_pathvector.begin(), tmp_pathvector.end()); + tmp_pathvector.clear(); } } else if (!fuse_paths || discard_orig_path) { for (size_t i = 0; i < original_pathv.size(); ++i) { path_out.push_back(original_pathv[i] * m); } } - +// if (SP_IS_SHAPE(sp_lpe_item)) { +// SPCurve *c = NULL; +// if (!path_out.empty()) { +// c->set_pathvector(path_out); +// if (c) { +// SP_SHAPE(sp_lpe_item)->setCurve(c, TRUE); +// c->unref(); +// } +// } +// } return path_out; } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 03ff56842..0680e5be8 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -17,7 +17,6 @@ */ #include "live_effects/effect.h" -#include "live_effects/parameter/originalitem.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" @@ -51,7 +50,6 @@ public: virtual Gtk::Widget * newWidget(); void processObjects(LpeAction lpe_action); void toMirror(Geom::Affine transform); - bool isCurrentLPEItem(); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes); @@ -59,7 +57,6 @@ protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: - OriginalItemParam mirror_item; EnumParam mode; ScalarParam split_gap; BoolParam discard_orig_path; @@ -73,8 +70,6 @@ private: Geom::Point previous_center; std::vector elements; SPObject * container; - SPObject * other; - Geom::Affine last_transform; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); }; diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 7b2507b5e..b9a8fb83f 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -925,6 +925,15 @@ void SPGroup::update_patheffect(bool write) { } sp_group_perform_patheffect(this, this, write); + + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + + if (lpeobj && lpeobj->get_lpe()) { + lpeobj->get_lpe()->doAfterEffect(this); + } + } } } -- cgit v1.2.3 From 4943de681c1bdd831b828beab9ceb1f31f58b60a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 3 Jan 2017 17:43:32 +0100 Subject: Fixing broken things (bzr r15295.1.49) --- src/live_effects/lpe-mirror_symmetry.cpp | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 05380c568..576c7df5e 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -448,16 +448,6 @@ Geom::PathVector LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) { if (split_elements && !fuse_paths) { - if (SP_IS_SHAPE(sp_lpe_item)) { - SPCurve *c = NULL; - if (!path_in.empty()) { - c->set_pathvector(path_in); - if (c) { - SP_SHAPE(sp_lpe_item)->setCurveInsync(c, TRUE); - c->unref(); - } - } - } return path_in; } Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); @@ -592,12 +582,6 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) } } } -// if (cs.size()!=0 && position == 0) { -// if (split_elements && original.closed()) { -// tmp_path.appendNew( tmp_path.initialPoint() ); -// tmp_path.close(); -// } -// } if (cs.size() == 0 && position == 1) { tmp_pathvector.push_back(original); if ( !split_elements) { @@ -620,16 +604,6 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) path_out.push_back(original_pathv[i] * m); } } -// if (SP_IS_SHAPE(sp_lpe_item)) { -// SPCurve *c = NULL; -// if (!path_out.empty()) { -// c->set_pathvector(path_out); -// if (c) { -// SP_SHAPE(sp_lpe_item)->setCurve(c, TRUE); -// c->unref(); -// } -// } -// } return path_out; } -- cgit v1.2.3 From 72a83bc13438724d098533b7d54da814cc7ef4ff Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Wed, 4 Jan 2017 21:38:05 +0100 Subject: Fixing some bugs (bzr r15295.1.50) --- src/live_effects/effect.h | 7 ++--- src/live_effects/lpe-mirror_symmetry.cpp | 54 +++++++++++++++++--------------- src/live_effects/lpe-mirror_symmetry.h | 2 +- src/sp-lpe-item.cpp | 2 ++ 4 files changed, 34 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index bc56c2390..9a2d4c67d 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -19,7 +19,7 @@ class SPDocument; class SPDesktop; class SPItem; -class LivePathEffectObject; +class LivePathEffectObject; class SPLPEItem; class KnotHolder; class KnotHolderEntity; @@ -132,7 +132,8 @@ public: bool erase_extra_objects; // set this to false allow retain extra generated objects, see measure line LPE bool upd_params; BoolParam is_visible; - + SPCurve * sp_curve; + Geom::PathVector pathvector_before_effect; protected: Effect(LivePathEffectObject *lpeobject); @@ -172,8 +173,6 @@ protected: SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. double current_zoom; std::vector selectedNodesPoints; - SPCurve * sp_curve; - Geom::PathVector pathvector_before_effect; private: bool provides_own_flash_paths; // if true, the standard flash path is suppressed diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 576c7df5e..07a0d8b0c 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -89,7 +89,7 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry() void LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) { - if (split_elements) { + if (split_elements && !discard_orig_path) { // if (discard_orig_path) { // discard_orig_path.param_setValue(false); // discard_orig_path.write_to_SVG(); @@ -191,7 +191,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } void -LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes) +LPEMirrorSymmetry::cloneD(SPObject *origin, SPObject *dest, bool live, bool root) { SPDocument * document = SP_ACTIVE_DOCUMENT; Inkscape::XML::Document *xml_doc = document->getReprDoc(); @@ -201,37 +201,35 @@ LPEMirrorSymmetry::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, c for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneAttrbutes(*obj_it, dest_child, live, attributes); + cloneD(*obj_it, dest_child, live, false); index++; } } - gchar ** attarray = g_strsplit(attributes, ",", 0); - gchar ** iter = attarray; - while (*iter != NULL) { - const char* att = (*iter); - SPShape * shape = SP_SHAPE(origin); - SPPath * path = SP_PATH(dest); - if (!path && !SP_IS_GROUP(dest)) { - Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); - dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); - } + SPShape * shape = SP_SHAPE(origin); + SPPath * path = SP_PATH(dest); + if (!path && !SP_IS_GROUP(dest)) { + Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); + dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); path = SP_PATH(dest); - if (path && shape) { - if ( live && att == "d") { - SPCurve *c = NULL; + } + if (path && shape) { + if ( live) { + SPCurve *c = NULL; + if (root) { + c = new SPCurve(); + c->set_pathvector(pathvector_before_effect); + } else { c = shape->getCurve(); - if (c) { - path->setCurve(c, TRUE); - dest->getRepr()->setAttribute(att,sp_svg_write_path(c->get_pathvector())); - c->unref(); - } else { - dest->getRepr()->setAttribute(att,NULL); - } + } + if (c) { + path->setCurve(c, TRUE); + c->unref(); } else { - dest->getRepr()->setAttribute(att,origin->getRepr()->attribute(att)); + dest->getRepr()->setAttribute("d", NULL); } + } else { + dest->getRepr()->setAttribute("d", origin->getRepr()->attribute("d")); } - iter++; } } @@ -288,7 +286,7 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform) elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneAttrbutes(SP_OBJECT(sp_lpe_item), elemref, true, "d"); + cloneD(SP_OBJECT(sp_lpe_item), elemref, true, true); elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); @@ -553,6 +551,10 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) mirror.setInitial(portion.finalPoint()); portion.append(mirror); portion = portion.reversed(); + } else { + if (!tmp_path.empty()) { + tmp_path.appendNew( portion.initialPoint() ); + } } if (!original.closed()) { if (!split_elements) { diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 0680e5be8..c39cf3e04 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -51,7 +51,7 @@ public: void processObjects(LpeAction lpe_action); void toMirror(Geom::Affine transform); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); - void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes); + void cloneD(SPObject *origin, SPObject *dest, bool live, bool root); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 98428512f..7ad428383 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -260,6 +260,8 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { return false; } if (!SP_IS_GROUP(this)) { + lpe->pathvector_before_effect = curve->get_pathvector(); + lpe->sp_curve->set_pathvector(lpe->pathvector_before_effect); lpe->doAfterEffect(this); } } -- cgit v1.2.3 From 9d0a8be3ea0673e7a453c16ddb77fdcf1ee47f4d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 5 Jan 2017 12:46:24 +0100 Subject: Fixing mirror on split (bzr r15295.1.51) --- src/live_effects/lpe-mirror_symmetry.cpp | 113 ++++++++++++++----------------- 1 file changed, 50 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 07a0d8b0c..987444ed4 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -455,11 +455,40 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) path_out = pathv_to_linear_and_cubic_beziers(path_in); } - Geom::Line line_separation((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (line_separation.vector(), (Geom::Point)start_point); - - if (fuse_paths && !discard_orig_path) { + if (split_elements && fuse_paths) { + Geom::OptRect bbox = path_in->boundsFast(); + bbox *= scale(1.2); + Geom::Path p(Geom::Point(bbox->left(), bbox->top())); + p.appendNew(Geom::Point(bbox->right(), bbox->top())); + p.appendNew(Geom::Point(bbox->right(), bbox->bottom())); + p.appendNew(Geom::Point(bbox->left(), bbox->bottom())); + p.appendNew(Geom::Point(bbox->left(), bbox->top())); + p.close(); + p *= Geom::translate(bbox->middle_point()).inverse(); + p *= Geom::rotate(line_separation.angle()); + p *= Geom::translate(bbox->middle_point()); + bbox = p->boundsFast(); + p.clear(); + p(Geom::Point(bbox->left(), bbox->top())); + p.appendNew(Geom::Point(bbox->right(), bbox->top())); + p.appendNew(Geom::Point(bbox->right(), bbox->bottom())); + p.appendNew(Geom::Point(bbox->left(), bbox->bottom())); + p.appendNew(Geom::Point(bbox->left(), bbox->top())); + p.close(); + Geom::Point base(bbox->right(), bbox->top()); + if (oposite_fuse) { + base = Geom::Point(bbox->left(), bbox->top()); + } + p *= Geom::translate(base - line_separation.pointAt(nearest_time(base, line_separation))); + Geom::PathVector pv_bbox; + pv_bbox.push_back(p); + Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(pv_bbox, path_in); + if (pig && !path_in.empty() && !pv_bbox.empty()) { + path_out = pig->getBminusA(); + } + } else if (fuse_paths && !discard_orig_path) { for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -467,7 +496,6 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) continue; } Geom::PathVector tmp_pathvector; - Geom::Path tmp_path; double time_start = 0.0; int position = 0; bool end_open = false; @@ -511,26 +539,13 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) } if (position == 1) { Geom::Path mirror = portion.reversed() * m; - if (split_elements) { - if (!tmp_path.empty()) { - tmp_path.appendNew( portion.initialPoint() ); - } - } else { - mirror.setInitial(portion.finalPoint()); - portion.append(mirror); - if(i != 0) { - portion.setFinal(portion.initialPoint()); - portion.close(); - } - } - if (!split_elements) { - tmp_pathvector.push_back(portion); - } else { - if (!tmp_path.empty()) { - portion.setInitial(tmp_path.finalPoint()); - } - tmp_path.append(portion); + mirror.setInitial(portion.finalPoint()); + portion.append(mirror); + if(i != 0) { + portion.setFinal(portion.initialPoint()); + portion.close(); } + tmp_pathvector.push_back(portion); } portion.clear(); } @@ -546,39 +561,21 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) Geom::Path portion = original.portion(time_start, original.size()); if (!portion.empty()) { portion = portion.reversed(); - if (!split_elements) { - Geom::Path mirror = portion.reversed() * m; - mirror.setInitial(portion.finalPoint()); - portion.append(mirror); - portion = portion.reversed(); - } else { - if (!tmp_path.empty()) { - tmp_path.appendNew( portion.initialPoint() ); - } - } + Geom::Path mirror = portion.reversed() * m; + mirror.setInitial(portion.finalPoint()); + portion.append(mirror); + portion = portion.reversed(); if (!original.closed()) { - if (!split_elements) { - tmp_pathvector.push_back(portion); - } else { - portion.setInitial(tmp_path.finalPoint()); - tmp_path.append(portion); - tmp_pathvector.push_back(tmp_path); - } + tmp_pathvector.push_back(portion); } else { - if (!split_elements) { - if (cs.size() > 1 && tmp_pathvector.size() > 0 && tmp_pathvector[0].size() > 0 ) { - portion.setFinal(tmp_pathvector[0].initialPoint()); - portion.setInitial(tmp_pathvector[0].finalPoint()); - tmp_pathvector[0].append(portion); - } else { - tmp_pathvector.push_back(portion); - } - tmp_pathvector[0].close(); + if (cs.size() > 1 && tmp_pathvector.size() > 0 && tmp_pathvector[0].size() > 0 ) { + portion.setFinal(tmp_pathvector[0].initialPoint()); + portion.setInitial(tmp_pathvector[0].finalPoint()); + tmp_pathvector[0].append(portion); } else { - portion.setInitial(tmp_path.finalPoint()); - tmp_path.append(portion); - tmp_path.close(); + tmp_pathvector.push_back(portion); } + tmp_pathvector[0].close(); } portion.clear(); } @@ -586,17 +583,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) } if (cs.size() == 0 && position == 1) { tmp_pathvector.push_back(original); - if ( !split_elements) { - tmp_pathvector.push_back(original * m); - } - } - if (split_elements) { - if (split_elements && original.closed()) { - tmp_path.appendNew( tmp_path.initialPoint() ); - tmp_path.close(); - } - tmp_pathvector.push_back(tmp_path); - tmp_path.clear(); + tmp_pathvector.push_back(original * m); } path_out.insert(path_out.end(), tmp_pathvector.begin(), tmp_pathvector.end()); tmp_pathvector.clear(); -- cgit v1.2.3 From a8857b9bea3e09e8d22c454a0773d14111936426 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 5 Jan 2017 13:24:27 +0100 Subject: Workingcd ../mirror_improvements! (bzr r15295.1.53) --- src/live_effects/lpe-mirror_symmetry.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 987444ed4..e4a3c7657 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -23,6 +23,7 @@ #include "svg/svg.h" #include "sp-defs.h" #include "helper/geom.h" +#include "2geom/intersection-graph.h" #include "2geom/path-intersection.h" #include "2geom/affine.h" #include "helper/geom.h" @@ -458,30 +459,33 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) Geom::Line line_separation((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (line_separation.vector(), (Geom::Point)start_point); if (split_elements && fuse_paths) { - Geom::OptRect bbox = path_in->boundsFast(); - bbox *= scale(1.2); + Geom::OptRect bbox = sp_lpe_item->geometricBounds(); Geom::Path p(Geom::Point(bbox->left(), bbox->top())); p.appendNew(Geom::Point(bbox->right(), bbox->top())); p.appendNew(Geom::Point(bbox->right(), bbox->bottom())); p.appendNew(Geom::Point(bbox->left(), bbox->bottom())); p.appendNew(Geom::Point(bbox->left(), bbox->top())); p.close(); - p *= Geom::translate(bbox->middle_point()).inverse(); - p *= Geom::rotate(line_separation.angle()); - p *= Geom::translate(bbox->middle_point()); - bbox = p->boundsFast(); + p *= Geom::Translate(bbox->midpoint()).inverse(); + p *= Geom::Scale(1.2); + p *= Geom::Rotate(line_separation.angle()); + p *= Geom::Translate(bbox->midpoint()); + bbox = p.boundsFast(); p.clear(); - p(Geom::Point(bbox->left(), bbox->top())); + p.start(Geom::Point(bbox->left(), bbox->top())); p.appendNew(Geom::Point(bbox->right(), bbox->top())); p.appendNew(Geom::Point(bbox->right(), bbox->bottom())); p.appendNew(Geom::Point(bbox->left(), bbox->bottom())); p.appendNew(Geom::Point(bbox->left(), bbox->top())); p.close(); - Geom::Point base(bbox->right(), bbox->top()); + p *= Geom::Translate(bbox->midpoint()).inverse(); + p *= Geom::Rotate(line_separation.angle()); + p *= Geom::Translate(bbox->midpoint()); + Geom::Point base(p.pointAt(3)); if (oposite_fuse) { - base = Geom::Point(bbox->left(), bbox->top()); + base = p.pointAt(0); } - p *= Geom::translate(base - line_separation.pointAt(nearest_time(base, line_separation))); + p *= Geom::Translate(line_separation.pointAt(line_separation.nearestTime(base)) - base); Geom::PathVector pv_bbox; pv_bbox.push_back(p); Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(pv_bbox, path_in); -- cgit v1.2.3 From 52fe6e55a494d146bc2b1ad3b7a46e43a57bf311 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 5 Jan 2017 17:49:13 +0100 Subject: Bug fixes and add a slight gap to no line in middle (bzr r15295.1.55) --- src/live_effects/lpe-mirror_symmetry.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index e4a3c7657..1fd007de3 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -54,7 +54,7 @@ MTConverter(ModeTypeData, MT_END); LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), - split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, 0), + split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, -0.001), discard_orig_path(_("Discard original path"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), @@ -78,7 +78,7 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : id_origin.param_hide_canvas_text(); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); - split_gap.param_set_digits(2); + split_gap.param_set_digits(5); apply_to_clippath_and_mask = true; previous_center = Geom::Point(0,0); } @@ -91,12 +91,6 @@ void LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) { if (split_elements && !discard_orig_path) { -// if (discard_orig_path) { -// discard_orig_path.param_setValue(false); -// discard_orig_path.write_to_SVG(); -// std::cout << _("You can't discard original paths on split elements"); -// return; -// } container = dynamic_cast(sp_lpe_item->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); @@ -488,8 +482,8 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) p *= Geom::Translate(line_separation.pointAt(line_separation.nearestTime(base)) - base); Geom::PathVector pv_bbox; pv_bbox.push_back(p); - Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(pv_bbox, path_in); - if (pig && !path_in.empty() && !pv_bbox.empty()) { + Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(pv_bbox, original_pathv); + if (pig && !original_pathv.empty() && !pv_bbox.empty()) { path_out = pig->getBminusA(); } } else if (fuse_paths && !discard_orig_path) { -- cgit v1.2.3 From 7bedd224ace433cf4c1a829ba38f6a3c388227e6 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Thu, 5 Jan 2017 20:03:50 +0100 Subject: Adding base (bzr r15392.1.1) --- src/helper/geom.cpp | 7 +++++++ src/helper/geom.h | 2 +- src/live_effects/effect.h | 15 ++++++++++----- src/live_effects/lpe-measure-line.cpp | 9 +++------ src/live_effects/lpe-measure-line.h | 6 ------ src/live_effects/parameter/bool.cpp | 3 ++- src/live_effects/parameter/text.cpp | 3 ++- src/sp-item-group.cpp | 9 +++++++++ src/sp-lpe-item.cpp | 13 ++++++++++--- src/sp-lpe-item.h | 2 +- src/sp-object.cpp | 15 +++++++++++++++ src/sp-object.h | 3 +++ 12 files changed, 63 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/helper/geom.cpp b/src/helper/geom.cpp index 42c494c00..e1f05c3ce 100644 --- a/src/helper/geom.cpp +++ b/src/helper/geom.cpp @@ -843,6 +843,13 @@ recursive_bezier4(const double x1, const double y1, recursive_bezier4(x1234, y1234, x234, y234, x34, y34, x4, y4, m_points, level + 1); } +void +swap(Geom::Point &A, Geom::Point &B){ + Geom::Point tmp = A; + A = B; + B = tmp; +} + /* Local Variables: mode:c++ diff --git a/src/helper/geom.h b/src/helper/geom.h index d49e2070c..b3d907e51 100644 --- a/src/helper/geom.h +++ b/src/helper/geom.h @@ -32,7 +32,7 @@ void recursive_bezier4(const double x1, const double y1, const double x2, const const double x3, const double y3, const double x4, const double y4, std::vector &pointlist, int level); - +void swap(Geom::Point &A, Geom::Point &B); #endif // INKSCAPE_HELPER_GEOM_H /* diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 1997ff0ca..9a2d4c67d 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -19,7 +19,7 @@ class SPDocument; class SPDesktop; class SPItem; -class LivePathEffectObject; +class LivePathEffectObject; class SPLPEItem; class KnotHolder; class KnotHolderEntity; @@ -44,6 +44,12 @@ enum LPEPathFlashType { DEFAULT }; +enum LpeAction { + LPE_ERASE = 0, + LPE_TO_OBJECTS, + LPE_VISIBILITY +}; + class Effect { public: static Effect* New(EffectType lpenr, LivePathEffectObject *lpeobj); @@ -125,7 +131,9 @@ public: bool apply_to_clippath_and_mask; bool erase_extra_objects; // set this to false allow retain extra generated objects, see measure line LPE bool upd_params; - + BoolParam is_visible; + SPCurve * sp_curve; + Geom::PathVector pathvector_before_effect; protected: Effect(LivePathEffectObject *lpeobject); @@ -150,7 +158,6 @@ protected: bool _provides_knotholder_entities; int oncanvasedit_it; - BoolParam is_visible; bool show_orig_path; // set this to true in derived effects to automatically have the original // path displayed as helperpath @@ -166,8 +173,6 @@ protected: SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. double current_zoom; std::vector selectedNodesPoints; - SPCurve * sp_curve; - Geom::PathVector pathvector_before_effect; private: bool provides_own_flash_paths; // if true, the standard flash path is suppressed diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index af2a8e919..e07335e1c 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -21,7 +21,9 @@ #include "svg/svg-color.h" #include "svg/svg.h" #include "display/curve.h" +#include "helper/geom.h" #include "2geom/affine.h" +#include "path-chemistry.h" #include "style.h" #include "sp-root.h" #include "sp-defs.h" @@ -165,12 +167,6 @@ LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) : LPEMeasureLine::~LPEMeasureLine() {} -void swap(Geom::Point &A, Geom::Point &B){ - Geom::Point tmp = A; - A = B; - B = tmp; -} - void LPEMeasureLine::createArrowMarker(const char * mode) { @@ -668,6 +664,7 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) } } +//TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMeasureLine::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) { diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h index c69921a4d..cb531affe 100644 --- a/src/live_effects/lpe-measure-line.h +++ b/src/live_effects/lpe-measure-line.h @@ -35,12 +35,6 @@ enum OrientationMethod { OM_END }; -enum LpeAction { - LPE_ERASE = 0, - LPE_TO_OBJECTS, - LPE_VISIBILITY -}; - class LPEMeasureLine : public Effect { public: LPEMeasureLine(LivePathEffectObject *lpeobject); diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index af99ef362..813c06b4e 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -72,7 +72,7 @@ BoolParam::param_newWidget() checkwdg->setActive(value); checkwdg->setProgrammatically = false; checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change bool parameter")); - + param_effect->upd_params = false; return dynamic_cast (checkwdg); } else { return NULL; @@ -82,6 +82,7 @@ BoolParam::param_newWidget() void BoolParam::param_setValue(bool newvalue) { + param_effect->upd_params = true; value = newvalue; } diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 8cab68ad0..5c4cdf4c6 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -125,13 +125,14 @@ TextParam::param_newWidget() rsu->setProgrammatically = false; rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change text parameter")); - + param_effect->upd_params = false; return dynamic_cast (rsu); } void TextParam::param_setValue(const Glib::ustring newvalue) { + param_effect->upd_params = true; value = newvalue; if (!_hide_canvas_text) { sp_canvastext_set_text (canvas_text, newvalue.c_str()); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 7b2507b5e..b9a8fb83f 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -925,6 +925,15 @@ void SPGroup::update_patheffect(bool write) { } sp_group_perform_patheffect(this, this, write); + + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + + if (lpeobj && lpeobj->get_lpe()) { + lpeobj->get_lpe()->doAfterEffect(this); + } + } } } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index e2f61bfb5..7ad428383 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -24,6 +24,7 @@ #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" #include "live_effects/lpe-measure-line.h" +#include "live_effects/lpe-mirror_symmetry.h" #include "sp-path.h" #include "sp-item-group.h" @@ -126,7 +127,9 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { if (!value) { LivePathEffectObject *lpeobj = (*it)->lpeobject; Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); - if (dynamic_cast(lpe)){ + if (dynamic_cast(lpe) || + dynamic_cast(lpe) ) + { lpe->doOnRemove(this); } } @@ -257,6 +260,8 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { return false; } if (!SP_IS_GROUP(this)) { + lpe->pathvector_before_effect = curve->get_pathvector(); + lpe->sp_curve->set_pathvector(lpe->pathvector_before_effect); lpe->doAfterEffect(this); } } @@ -604,7 +609,7 @@ bool SPLPEItem::hasPathEffect() const return true; } -bool SPLPEItem::hasPathEffectOfType(int const type) const +bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const { if (path_effect_list->empty()) { return false; @@ -616,7 +621,9 @@ bool SPLPEItem::hasPathEffectOfType(int const type) const if (lpeobj) { Inkscape::LivePathEffect::Effect const* lpe = lpeobj->get_lpe(); if (lpe && (lpe->effectType() == type)) { - return true; + if (is_ready || lpe->isReady()) { + return true; + } } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 9e5cb3329..db4a0c7a3 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -73,7 +73,7 @@ public: bool pathEffectsEnabled() const; bool hasPathEffect() const; - bool hasPathEffectOfType(int const type) const; + bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; diff --git a/src/sp-object.cpp b/src/sp-object.cpp index e9c60fc7d..222626162 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -773,6 +773,21 @@ void SPObject::appendChild(Inkscape::XML::Node *child) { repr->appendChild(child); } +SPObject* SPObject::nthChild(unsigned index) { + g_assert(this->repr); + if (hasChildren()) { + std::vector l; + unsigned counter = 0; + for (auto& child: children) { + if (counter == index) { + return &child; + } + counter++; + } + } + return NULL; +} + void SPObject::addChild(Inkscape::XML::Node *child, Inkscape::XML::Node * prev) { g_assert(this->repr); diff --git a/src/sp-object.h b/src/sp-object.h index 9abbd324b..d145e966b 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -318,6 +318,9 @@ public: SPObject *lastChild() { return children.empty() ? nullptr : &children.back(); } SPObject const *lastChild() const { return children.empty() ? nullptr : &children.back(); } + SPObject *nthChild(unsigned index); + SPObject const *nthChild(unsigned index) const; + enum Action { ActionGeneral, ActionBBox, ActionUpdate, ActionShow }; /** -- cgit v1.2.3 From 8b32064865a8da5aaf043e603148a2402f9b7602 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Fri, 6 Jan 2017 23:57:27 +0100 Subject: base of effect (bzr r15392.1.2) --- src/live_effects/lpe-copy_rotate.cpp | 229 ++++++++++++++++++++++++++++++++++- src/live_effects/lpe-copy_rotate.h | 12 ++ 2 files changed, 238 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 813f25d3d..963b31807 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -17,6 +17,12 @@ #include <2geom/sbasis-to-bezier.h> #include <2geom/intersection-graph.h> #include "live_effects/lpe-copy_rotate.h" +#include "display/curve.h" +#include "svg/path-string.h" +#include "svg/svg.h" +#include "path-chemistry.h" +#include "style.h" +#include "xml/sp-css-attr.h" // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -45,9 +51,12 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : starting_angle(_("Starting angle"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 60.0), num_copies(_("Number of copies"), _("Number of copies of the original path"), "num_copies", &wr, this, 6), + split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, -0.001), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), fuse_paths(_("Kaleidoskope"), _("Kaleidoskope by helper line, use fill-rule: evenodd for best result"), "fuse_paths", &wr, this, false), join_paths(_("Join paths"), _("Join paths, use fill-rule: evenodd for best result"), "join_paths", &wr, this, false), + split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints. Whith fuse don't work on shapes"), "split_elements", &wr, this, false), + id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,""), dist_angle_handle(100.0) { show_orig_path = true; @@ -60,8 +69,14 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : registerParameter(&starting_point); registerParameter(&rotation_angle); registerParameter(&num_copies); + registerParameter(&split_gap); + registerParameter(&split_elements); + registerParameter(&id_origin); registerParameter(&origin); - + id_origin.param_hide_canvas_text(); + split_gap.param_set_range(-999999.0, 999999.0); + split_gap.param_set_increments(0.1, 0.1); + split_gap.param_set_digits(5); num_copies.param_make_integer(true); num_copies.param_set_range(0, 1000); apply_to_clippath_and_mask = true; @@ -72,6 +87,137 @@ LPECopyRotate::~LPECopyRotate() } +void +LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) +{ + if (split_elements) { + container = dynamic_cast(sp_lpe_item->parent); + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); + Inkscape::XML::Node *root_origin = doc->getReprRoot(); + if (root_origin != root) { + return; + } +// Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); +// Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); +// Geom::Point dir = rot90(unit_vector((Geom::Point)start_point - (Geom::Point)end_point)); +// Geom::Point gap = dir * split_gap; +// m *= Geom::Translate(gap); +// m = m * sp_lpe_item->transform; +// toMirror(m); + } else { + processObjects(LPE_ERASE); + elements.clear(); + } +} + +void +LPECopyRotate::cloneD(SPObject *origin, SPObject *dest, bool live, bool root) +{ + SPDocument * document = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { + std::vector< SPObject * > childs = origin->childList(true); + size_t index = 0; + for (std::vector::iterator obj_it = childs.begin(); + obj_it != childs.end(); ++obj_it) { + SPObject *dest_child = dest->nthChild(index); + cloneD(*obj_it, dest_child, live, false); + index++; + } + } + SPShape * shape = SP_SHAPE(origin); + SPPath * path = SP_PATH(dest); + if (!path && !SP_IS_GROUP(dest)) { + Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); + dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); + path = SP_PATH(dest); + } + if (path && shape) { + if ( live) { + SPCurve *c = NULL; + if (root) { + c = new SPCurve(); + c->set_pathvector(pathvector_before_effect); + } else { + c = shape->getCurve(); + } + if (c) { + path->setCurve(c, TRUE); + c->unref(); + } else { + dest->getRepr()->setAttribute("d", NULL); + } + } else { + dest->getRepr()->setAttribute("d", origin->getRepr()->attribute("d")); + } + } +} + +void +LPECopyRotate::toMirror(Geom::Affine transform) +{ + SPDocument * document = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + const char * id_origin_char = id_origin.param_getSVGValue(); + const char * elemref_id = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); + elements.clear(); + elements.push_back(elemref_id); + SPObject *elemref= NULL; + Inkscape::XML::Node *phantom = NULL; + if (elemref = document->getObjectById(elemref_id)) { + phantom = elemref->getRepr(); + } else { + phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); + phantom->setAttribute("inkscape:path-effect", NULL); + phantom->setAttribute("inkscape:original-d", NULL); + phantom->setAttribute("sodipodi:type", NULL); + phantom->setAttribute("sodipodi:rx", NULL); + phantom->setAttribute("sodipodi:ry", NULL); + phantom->setAttribute("sodipodi:cx", NULL); + phantom->setAttribute("sodipodi:cy", NULL); + phantom->setAttribute("sodipodi:end", NULL); + phantom->setAttribute("sodipodi:start", NULL); + phantom->setAttribute("inkscape:flatsided", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("inkscape:rounded", NULL); + phantom->setAttribute("sodipodi:arg1", NULL); + phantom->setAttribute("sodipodi:arg2", NULL); + phantom->setAttribute("sodipodi:r1", NULL); + phantom->setAttribute("sodipodi:r2", NULL); + phantom->setAttribute("sodipodi:sides", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("sodipodi:argument", NULL); + phantom->setAttribute("sodipodi:expansion", NULL); + phantom->setAttribute("sodipodi:radius", NULL); + phantom->setAttribute("sodipodi:revolution", NULL); + phantom->setAttribute("sodipodi:t0", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("inkscape:randomized", NULL); + phantom->setAttribute("x", NULL); + phantom->setAttribute("y", NULL); + phantom->setAttribute("rx", NULL); + phantom->setAttribute("ry", NULL); + phantom->setAttribute("width", NULL); + phantom->setAttribute("height", NULL); + } + phantom->setAttribute("id", elemref_id); + if (!elemref) { + elemref = container->appendChildRepr(phantom); + Inkscape::GC::release(phantom); + } + cloneD(SP_OBJECT(sp_lpe_item), elemref, true, true); + elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); + if (elemref->parent != container) { + Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); + copy->setAttribute("id", elemref_id); + container->appendChildRepr(copy); + Inkscape::GC::release(copy); + elemref->deleteObject(); + } +} + Gtk::Widget * LPECopyRotate::newWidget() { // use manage here, because after deletion of Effect object, others might @@ -89,7 +235,7 @@ Gtk::Widget * LPECopyRotate::newWidget() Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); Glib::ustring *tip = param->param_getTooltip(); if (widg) { - if (param->param_key != "starting_point") { + if (param->param_key == "id_origin" || param->param_key != "starting_point") { vbox->pack_start(*widg, true, true, 2); if (tip) { widg->set_tooltip_text(*tip); @@ -119,17 +265,22 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) origin.param_update_default(A); dist_angle_handle = L2(B - A); dir = unit_vector(B - A); + SPLPEItem * splpeitem = const_cast(lpeitem); + if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet + id_origin.param_setValue(lpeitem->getRepr()->attribute("id")); + id_origin.write_to_SVG(); + } } void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { // cycle through all parameters. Most parameters will not need transformation, but path and point params do. - for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { Parameter * param = *it; param->param_transform_multiply(postmul, set); } + sp_lpe_item_update_patheffect(sp_lpe_item, false, false); } void @@ -449,6 +600,78 @@ LPECopyRotate::resetDefaults(SPItem const* item) original_bbox(SP_LPE_ITEM(item)); } + +//TODO: Migrate the tree next function to effect.cpp/h to avoid duplication +void +LPECopyRotate::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) +{ + processObjects(LPE_VISIBILITY); +} + +void +LPECopyRotate::doOnRemove (SPLPEItem const* /*lpeitem*/) +{ + //unset "erase_extra_objects" hook on sp-lpe-item.cpp + if (!erase_extra_objects) { + processObjects(LPE_TO_OBJECTS); + return; + } + processObjects(LPE_ERASE); +} + +void +LPECopyRotate::processObjects(LpeAction lpe_action) +{ + SPDocument * document = SP_ACTIVE_DOCUMENT; + for (std::vector::iterator el_it = elements.begin(); + el_it != elements.end(); ++el_it) { + const char * id = *el_it; + if (!id || strlen(id) == 0) { + return; + } + SPObject *elemref = NULL; + if (elemref = document->getObjectById(id)) { + Inkscape::XML::Node * elemnode = elemref->getRepr(); + std::vector item_list; + item_list.push_back(SP_ITEM(elemref)); + std::vector item_to_select; + std::vector item_selected; + SPCSSAttr *css; + Glib::ustring css_str; + switch (lpe_action){ + case LPE_TO_OBJECTS: + if (elemnode->attribute("inkscape:path-effect")) { + sp_item_list_to_curves(item_list, item_selected, item_to_select); + } + elemnode->setAttribute("sodipodi:insensitive", NULL); + break; + + case LPE_ERASE: + elemref->deleteObject(); + break; + + case LPE_VISIBILITY: + css = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); + if (!this->isVisible()/* && std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0*/) { + css->setAttribute("display", "none"); + } else { + css->setAttribute("display", NULL); + } + sp_repr_css_write_string(css,css_str); + elemnode->setAttribute("style", css_str.c_str()); + break; + + default: + break; + } + } + } + if (lpe_action == LPE_ERASE || lpe_action == LPE_TO_OBJECTS) { + elements.clear(); + } +} + } //namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index c2ae2daf1..d398700ee 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -15,6 +15,7 @@ */ #include "live_effects/effect.h" +#include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" #include "live_effects/lpegroupbbox.h" @@ -28,11 +29,17 @@ public: virtual void doOnApply (SPLPEItem const* lpeitem); virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doAfterEffect (SPLPEItem const* lpeitem); virtual void setFusion(Geom::PathVector &path_in, Geom::Path divider, double sizeDivider); virtual void split(Geom::PathVector &path_in, Geom::Path const ÷r); virtual void resetDefaults(SPItem const* item); virtual void transform_multiply(Geom::Affine const& postmul, bool set); + virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); + virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); + void processObjects(LpeAction lpe_action); + void toMirror(Geom::Affine transform); + void cloneD(SPObject *origin, SPObject *dest, bool live, bool root); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -42,9 +49,12 @@ private: ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; + ScalarParam split_gap; BoolParam copies_to_360; BoolParam fuse_paths; BoolParam join_paths; + BoolParam split_elements; + TextParam id_origin; Geom::Point A; Geom::Point B; Geom::Point dir; @@ -52,6 +62,8 @@ private: Geom::Point rot_pos; Geom::Point previous_start_point; double dist_angle_handle; + std::vector elements; + SPObject * container; LPECopyRotate(const LPECopyRotate&); LPECopyRotate& operator=(const LPECopyRotate&); }; -- cgit v1.2.3 From 949e58535cd5189f1b140a1b3968d40c17d5515f Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sat, 7 Jan 2017 19:08:18 +0100 Subject: Some naming fix and headers (bzr r15295.1.57) --- src/live_effects/lpe-mirror_symmetry.cpp | 13 +++++-------- src/live_effects/lpe-mirror_symmetry.h | 3 +-- 2 files changed, 6 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 1fd007de3..e51812a38 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -28,10 +28,7 @@ #include "2geom/affine.h" #include "helper/geom.h" #include "sp-lpe-item.h" -#include "uri.h" -#include "uri-references.h" #include "path-chemistry.h" -#include "knotholder.h" #include "style.h" #include "xml/sp-css-attr.h" @@ -58,7 +55,7 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : discard_orig_path(_("Discard original path"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), - split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints. Whith fuse don't work on shapes"), "split_elements", &wr, this, false), + split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust start of mirroring")), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), @@ -70,7 +67,7 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : registerParameter(&discard_orig_path); registerParameter(&fuse_paths); registerParameter(&oposite_fuse); - registerParameter(&split_elements); + registerParameter(&split_items); registerParameter(&start_point); registerParameter(&end_point); registerParameter(¢er_point); @@ -90,7 +87,7 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry() void LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) { - if (split_elements && !discard_orig_path) { + if (split_items && !discard_orig_path) { container = dynamic_cast(sp_lpe_item->parent); SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); @@ -440,7 +437,7 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) Geom::PathVector LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) { - if (split_elements && !fuse_paths) { + if (split_items && !fuse_paths) { return path_in; } Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); @@ -452,7 +449,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) Geom::Line line_separation((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (line_separation.vector(), (Geom::Point)start_point); - if (split_elements && fuse_paths) { + if (split_items && fuse_paths) { Geom::OptRect bbox = sp_lpe_item->geometricBounds(); Geom::Path p(Geom::Point(bbox->left(), bbox->top())); p.appendNew(Geom::Point(bbox->right(), bbox->top())); diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index c39cf3e04..2122a41e4 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -20,7 +20,6 @@ #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" -#include "live_effects/parameter/path.h" #include "live_effects/parameter/enum.h" #include "live_effects/lpegroupbbox.h" @@ -62,7 +61,7 @@ private: BoolParam discard_orig_path; BoolParam fuse_paths; BoolParam oposite_fuse; - BoolParam split_elements; + BoolParam split_items; PointParam start_point; PointParam end_point; PointParam center_point; -- cgit v1.2.3 From 2a434d30cbf94a89598f6a2ae7e0c5943a245dae Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sat, 7 Jan 2017 19:59:44 +0100 Subject: Some naming fix and headers (bzr r15295.1.59) --- src/live_effects/lpe-mirror_symmetry.cpp | 12 ++++++------ src/live_effects/lpe-mirror_symmetry.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index e51812a38..a8b1e321d 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -104,7 +104,7 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) toMirror(m); } else { processObjects(LPE_ERASE); - elements.clear(); + items.clear(); } } @@ -232,8 +232,8 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform) Inkscape::XML::Document *xml_doc = document->getReprDoc(); const char * id_origin_char = id_origin.param_getSVGValue(); const char * elemref_id = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); - elements.clear(); - elements.push_back(elemref_id); + items.clear(); + items.push_back(elemref_id); SPObject *elemref= NULL; Inkscape::XML::Node *phantom = NULL; if (elemref = document->getObjectById(elemref_id)) { @@ -348,8 +348,8 @@ void LPEMirrorSymmetry::processObjects(LpeAction lpe_action) { SPDocument * document = SP_ACTIVE_DOCUMENT; - for (std::vector::iterator el_it = elements.begin(); - el_it != elements.end(); ++el_it) { + for (std::vector::iterator el_it = items.begin(); + el_it != items.end(); ++el_it) { const char * id = *el_it; if (!id || strlen(id) == 0) { return; @@ -393,7 +393,7 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action) } } if (lpe_action == LPE_ERASE || lpe_action == LPE_TO_OBJECTS) { - elements.clear(); + items.clear(); } } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 2122a41e4..5a6db5062 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -67,7 +67,7 @@ private: PointParam center_point; TextParam id_origin; Geom::Point previous_center; - std::vector elements; + std::vector items; SPObject * container; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); -- cgit v1.2.3 From c71315ca4dd98551ee180f97fe6e303f131fbbea Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sun, 8 Jan 2017 02:57:46 +0100 Subject: Fix offset gap (bzr r15295.1.60) --- src/live_effects/lpe-mirror_symmetry.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index a8b1e321d..3e46422a0 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -97,9 +97,6 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) } Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); - Geom::Point dir = rot90(unit_vector((Geom::Point)start_point - (Geom::Point)end_point)); - Geom::Point gap = dir * split_gap; - m *= Geom::Translate(gap); m = m * sp_lpe_item->transform; toMirror(m); } else { @@ -483,6 +480,10 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) if (pig && !original_pathv.empty() && !pv_bbox.empty()) { path_out = pig->getBminusA(); } + Geom::Point dir = rot90(unit_vector((Geom::Point)start_point - (Geom::Point)end_point)); + Geom::Point gap = dir * split_gap; + m *= Geom::Translate(gap); + path_out *= m; } else if (fuse_paths && !discard_orig_path) { for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) -- cgit v1.2.3 From 48f06b976cdce2e2ba847ab5e2da5dc3f3883075 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sat, 14 Jan 2017 23:31:01 +0100 Subject: Fixed wroken. now working (bzr r15392.1.5) --- src/live_effects/lpe-copy_rotate.cpp | 45 +++++++++++++++++++++++++++--------- src/live_effects/lpe-copy_rotate.h | 6 +++-- 2 files changed, 38 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 438cb1c49..42ca531b4 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -82,6 +82,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : num_copies.param_make_integer(true); apply_to_clippath_and_mask = true; previous_num_copies = num_copies; + reset = false; } LPECopyRotate::~LPECopyRotate() @@ -144,7 +145,7 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) t = m * r * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)).inverse() * Geom::Translate(origin); } t *= sp_lpe_item->transform; - toItem(t, i-1); + toItem(t, i-1, reset); rest ++; } } else { @@ -152,9 +153,10 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) Geom::Rotate rot(-(Geom::rad_from_deg(rotation_angle * i))); Geom::Affine t = m * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)) * Geom::Translate(origin); t *= sp_lpe_item->transform; - toItem(t, i - 1); + toItem(t, i - 1, reset); } } + reset = false; } else { processObjects(LPE_ERASE); items.clear(); @@ -165,7 +167,7 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) } void -LPECopyRotate::cloneD(SPObject *origin, SPObject *dest, bool root) +LPECopyRotate::cloneD(SPObject *origin, SPObject *dest, bool root, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; Inkscape::XML::Document *xml_doc = document->getReprDoc(); @@ -175,7 +177,7 @@ LPECopyRotate::cloneD(SPObject *origin, SPObject *dest, bool root) for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneD(*obj_it, dest_child, false); + cloneD(*obj_it, dest_child, false, reset); index++; } } @@ -200,11 +202,14 @@ LPECopyRotate::cloneD(SPObject *origin, SPObject *dest, bool root) } else { dest->getRepr()->setAttribute("d", NULL); } + if (reset) { + dest->getRepr()->setAttribute("style", shape->getRepr()->attribute("style")); + } } } void -LPECopyRotate::toItem(Geom::Affine transform, size_t i) +LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; Inkscape::XML::Document *xml_doc = document->getReprDoc(); @@ -255,9 +260,9 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i) elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - SP_ITEM(elemref)->setHidden(false); - cloneD(SP_OBJECT(sp_lpe_item), elemref, true); + cloneD(SP_OBJECT(sp_lpe_item), elemref, true, reset); elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); + SP_ITEM(elemref)->setHidden(false); if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); copy->setAttribute("id", elemref_id); @@ -267,6 +272,12 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i) } } +void +LPECopyRotate::resetStyles(){ + reset = true; + doAfterEffect(sp_lpe_item); +} + Gtk::Widget * LPECopyRotate::newWidget() { // use manage here, because after deletion of Effect object, others might @@ -276,7 +287,15 @@ Gtk::Widget * LPECopyRotate::newWidget() vbox->set_border_width(5); vbox->set_homogeneous(false); vbox->set_spacing(2); - + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); + Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + vbox_expander->set_border_width(0); + vbox_expander->set_spacing(2); + Gtk::Button * reset_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset styles")))); + reset_button->signal_clicked().connect(sigc::mem_fun (*this,&LPECopyRotate::resetStyles)); + reset_button->set_size_request(140,30); + vbox->pack_start(*hbox, true,true,2); + hbox->pack_start(*reset_button, false, false,2); std::vector::iterator it = param_vector.begin(); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { @@ -733,10 +752,14 @@ LPECopyRotate::processObjects(LpeAction lpe_action) Glib::ustring css_str; switch (lpe_action){ case LPE_TO_OBJECTS: - if (elemnode->attribute("inkscape:path-effect")) { - sp_item_list_to_curves(item_list, item_selected, item_to_select); + if (SP_ITEM(elemref)->isHidden()) { + elemref->deleteObject(); + } else { + if (elemnode->attribute("inkscape:path-effect")) { + sp_item_list_to_curves(item_list, item_selected, item_to_select); + } + elemnode->setAttribute("sodipodi:insensitive", NULL); } - elemnode->setAttribute("sodipodi:insensitive", NULL); break; case LPE_ERASE: diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 62cceacf4..3dba83fee 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -40,8 +40,9 @@ public: virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); void processObjects(LpeAction lpe_action); - void toItem(Geom::Affine transform, size_t i); - void cloneD(SPObject *origin, SPObject *dest, bool root); + void toItem(Geom::Affine transform, size_t i, bool reset); + void cloneD(SPObject *origin, SPObject *dest, bool root, bool reset); + void resetStyles(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -66,6 +67,7 @@ private: double dist_angle_handle; double previous_num_copies; std::vector items; + bool reset; SPObject * container; LPECopyRotate(const LPECopyRotate&); LPECopyRotate& operator=(const LPECopyRotate&); -- cgit v1.2.3 From 6e57767d7d58f47b2f921cd45a7675eab1bca02c Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sun, 15 Jan 2017 13:51:37 +0100 Subject: Remove unnecesatry text parameter (bzr r15392.1.6) --- src/live_effects/lpe-copy_rotate.cpp | 15 +++------------ src/live_effects/lpe-copy_rotate.h | 1 - 2 files changed, 3 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 42ca531b4..a074665b5 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -57,7 +57,6 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : fuse_paths(_("Kaleidoskope"), _("Kaleidoskope by helper line, use fill-rule: evenodd for best result"), "fuse_paths", &wr, this, false), join_paths(_("Join paths"), _("Join paths, use fill-rule: evenodd for best result"), "join_paths", &wr, this, false), split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), - id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,""), dist_angle_handle(100.0) { show_orig_path = true; @@ -72,9 +71,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : registerParameter(&rotation_angle); registerParameter(&num_copies); registerParameter(&split_gap); - registerParameter(&id_origin); registerParameter(&origin); - id_origin.param_hide_canvas_text(); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); split_gap.param_set_digits(5); @@ -108,7 +105,7 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) if (numcopies_gap > 0 && num_copies != 0) { guint counter = num_copies - 1; while (numcopies_gap > 0) { - const char * id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(id_origin.param_getSVGValue()).c_str()); + const char * id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); if (!id || strlen(id) == 0) { return; } @@ -213,8 +210,7 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; Inkscape::XML::Document *xml_doc = document->getReprDoc(); - const char * id_origin_char = id_origin.param_getSVGValue(); - const char * elemref_id = g_strdup(Glib::ustring("rotated-").append(std::to_string(i)).append("-").append(id_origin_char).c_str()); + const char * elemref_id = g_strdup(Glib::ustring("rotated-").append(std::to_string(i)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); items.push_back(elemref_id); SPObject *elemref= NULL; Inkscape::XML::Node *phantom = NULL; @@ -303,7 +299,7 @@ Gtk::Widget * LPECopyRotate::newWidget() Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); Glib::ustring *tip = param->param_getTooltip(); if (widg) { - if (param->param_key == "id_origin" || param->param_key != "starting_point") { + if (param->param_key != "starting_point") { vbox->pack_start(*widg, true, true, 2); if (tip) { widg->set_tooltip_text(*tip); @@ -333,11 +329,6 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) origin.param_update_default(A); dist_angle_handle = L2(B - A); dir = unit_vector(B - A); - SPLPEItem * splpeitem = const_cast(lpeitem); - if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet - id_origin.param_setValue(lpeitem->getRepr()->attribute("id")); - id_origin.write_to_SVG(); - } } void diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 3dba83fee..6d6d06c4d 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -57,7 +57,6 @@ private: BoolParam fuse_paths; BoolParam join_paths; BoolParam split_items; - TextParam id_origin; Geom::Point A; Geom::Point B; Geom::Point dir; -- cgit v1.2.3 From 2a398a6073bf3fb0497a774760a4cebb54bb7e2c Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sun, 22 Jan 2017 03:06:22 +0100 Subject: Add multiwidget fixes (bzr r15356.1.15) --- src/live_effects/lpe-clone-original.cpp | 21 ++++++++++++++++----- src/live_effects/lpe-clone-original.h | 3 ++- 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index da93a5093..db697552a 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -32,8 +32,8 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : paintorder(_("Clone paint order"), _("Clone paint order"), "paintorder", &wr, this, false), opacity(_("Clone opacity"), _("Clone opacity"), "opacity", &wr, this, false), filter(_("Clone filter"), _("Clone filter"), "filter", &wr, this, false), - attributes("Attributes linked", "Attributes linked", "attributes", &wr, this,""), - style_attributes("Style attributes linked", "Style attributes linked", "style_attributes", &wr, this,""), + attributes("Attributes linked", "Attributes linked, comma separated atributes", "attributes", &wr, this,""), + style_attributes("Style attributes linked", "Style attributes linked, comma separated atributes", "style_attributes", &wr, this,""), expanded(false) { registerParameter(&linked_path); @@ -237,14 +237,14 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ } preserve_position_changed = preserve_position; } - Glib::ustring attr = Glib::ustring(attributes.param_getSVGValue()); + Glib::ustring attr = Glib::ustring(attributes.param_getSVGValue()).append(","); if (d) { attr.append("d,"); } if (transform) { attr.append("transform,"); } - Glib::ustring style_attr = Glib::ustring(style_attributes.param_getSVGValue()); + Glib::ustring style_attr = Glib::ustring(style_attributes.param_getSVGValue()).append(","); if (fill) { style_attr.append("fill,").append("fill-rule,"); } @@ -315,12 +315,23 @@ LPECloneOriginal::newWidget() expander = Gtk::manage(new Gtk::Expander(Glib::ustring(_("Show attributes override")))); expander->add(*vbox_expander); expander->set_expanded(expanded); - expander->property_expanded().signal_changed().connect(sigc::mem_fun(*this, &LPEMeasureLine::onExpanderChanged) ); + expander->property_expanded().signal_changed().connect(sigc::mem_fun(*this, &LPECloneOriginal::onExpanderChanged) ); vbox->pack_start(*expander, true, true, 2); this->upd_params = false; return dynamic_cast(vbox); } +void +LPECloneOriginal::onExpanderChanged() +{ + expanded = expander->get_expanded(); + if(expanded) { + expander->set_label (Glib::ustring(_("Hide attributes override"))); + } else { + expander->set_label (Glib::ustring(_("Show attributes override"))); + } +} + LPECloneOriginal::~LPECloneOriginal() { diff --git a/src/live_effects/lpe-clone-original.h b/src/live_effects/lpe-clone-original.h index c5080ad0e..0ff5eb01d 100644 --- a/src/live_effects/lpe-clone-original.h +++ b/src/live_effects/lpe-clone-original.h @@ -8,7 +8,7 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - +#include #include "live_effects/effect.h" #include "live_effects/parameter/originalitem.h" #include "live_effects/parameter/originalpath.h" @@ -28,6 +28,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual Gtk::Widget * newWidget(); + void onExpanderChanged(); void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes, bool root); private: -- cgit v1.2.3 From 30fb0365f10bec566c7e57eea4ac5439d2cf325a Mon Sep 17 00:00:00 2001 From: "alexandru.roman" Date: Mon, 23 Jan 2017 19:53:21 +0100 Subject: fix nodes reverting back during editing Fixed bugs: - https://launchpad.net/bugs/1270989 (bzr r15435) --- src/ui/tool/transform-handle-set.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp index 33015fe11..083a7d0ba 100644 --- a/src/ui/tool/transform-handle-set.cpp +++ b/src/ui/tool/transform-handle-set.cpp @@ -183,6 +183,11 @@ void TransformHandle::ungrabbed(GdkEventButton *) _setState(_state); endTransform(); _th.signal_commit.emit(getCommitEvent()); + + //updates the positions of the nodes + Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(_th._desktop->event_context); + ControlPointSelection* selection = nt->_selected_nodes; + selection->setOriginalPoints(); } -- cgit v1.2.3 From e06fb0c25cc352df40b77a1988b5045426e7ef2d Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 24 Jan 2017 01:02:46 +0100 Subject: Fixing to merge (bzr r15392.1.8) --- src/document-undo.cpp | 3 ++ src/live_effects/effect.cpp | 21 +++++++++++-- src/live_effects/effect.h | 3 ++ src/live_effects/lpe-copy_rotate.cpp | 1 + src/live_effects/lpe-measure-line.cpp | 58 +++-------------------------------- src/live_effects/lpe-measure-line.h | 2 -- src/sp-item-group.cpp | 37 ++++++++++++++-------- src/sp-lpe-item.cpp | 20 +++++++----- src/sp-lpe-item.h | 3 +- 9 files changed, 70 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 9c534dd58..113d09d66 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -160,6 +160,7 @@ void Inkscape::DocumentUndo::maybeDone(SPDocument *doc, const gchar *key, const sp_repr_begin_transaction (doc->rdoc); return; } + if (key && !doc->actionkey.empty() && (doc->actionkey == key) && !doc->priv->undo.empty()) { (doc->priv->undo.back())->event = sp_repr_coalesce_log ((doc->priv->undo.back())->event, log); @@ -169,6 +170,7 @@ void Inkscape::DocumentUndo::maybeDone(SPDocument *doc, const gchar *key, const doc->priv->history_size++; doc->priv->undoStackObservers.notifyUndoCommitEvent(event); } + if ( key ) { doc->actionkey = key; } else { @@ -179,6 +181,7 @@ void Inkscape::DocumentUndo::maybeDone(SPDocument *doc, const gchar *key, const doc->setModifiedSinceSave(); sp_repr_begin_transaction (doc->rdoc); + doc->priv->commit_signal.emit(); } diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 227f91594..3cfeface8 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -356,6 +356,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), + sp_shape(NULL), sp_curve(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden @@ -480,6 +481,17 @@ Effect::processObjects(LpeAction lpe_action) } } +void Effect::setCurrentShape(SPShape * shape){ + if(shape){ + sp_shape = shape; + if (!(sp_curve = sp_shape->getCurve())) { + // oops + return; + } + pathvector_before_effect = sp_curve->get_pathvector(); + } +} + /** * Is performed each time before the effect is updated. */ @@ -503,8 +515,12 @@ void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - /*sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); - pathvector_before_effect = sp_curve->get_pathvector();*/ + sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); + pathvector_before_effect = sp_curve->get_pathvector(); + SPShape * shape = dynamic_cast(sp_lpe_item); + if(shape){ + setCurrentShape(shape); + } doOnApply(lpeitem); } @@ -514,6 +530,7 @@ void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) //printf("(SPLPEITEM*) %p\n", sp_lpe_item); SPShape * shape = dynamic_cast(sp_lpe_item); if(shape){ + setCurrentShape(shape); sp_curve = shape->getCurve(); pathvector_before_effect = sp_curve->get_pathvector(); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 2f42ab3f6..f5e41d50e 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -79,6 +79,8 @@ public: static int acceptsNumClicks(EffectType type); int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } void doAcceptPathPreparations(SPLPEItem *lpeitem); + SPShape * getCurrentShape(){ return sp_shape; }; + void setCurrentShape(SPShape * shape); void processObjects(LpeAction lpe_action); /* @@ -172,6 +174,7 @@ protected: bool concatenate_before_pwd2; SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. + SPShape * sp_shape; // these get stored in doBeforeEffect_impl before doEffect chain, or in performPathEffects on groups, and derived classes may do as they please with them. std::vector items; double current_zoom; std::vector selectedNodesPoints; diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index a4d844fdd..33c4d6e5b 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -588,6 +588,7 @@ LPECopyRotate::doEffect_path (Geom::PathVector const & path_in) triangle.push_back(divider); Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(triangle, path_out); if (pig && ! path_out.empty() && !triangle.empty()) { + //TODO: Here can produce a crash because some knows problems in new boolops code path_out = pig->getIntersection(); } Geom::Affine r = Geom::identity(); diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index e07335e1c..38f93ebb4 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -225,7 +225,7 @@ LPEMeasureLine::createArrowMarker(const char * mode) elemref = SP_OBJECT(document->getDefs()->appendChildRepr(arrow)); Inkscape::GC::release(arrow); } - elements.push_back(mode); + items.push_back(mode); } void @@ -365,7 +365,7 @@ LPEMeasureLine::createTextLabel(Geom::Point pos, double length, Geom::Coord angl copy->setAttribute("id", id); elemref = elemref_copy; } - elements.push_back(id); + items.push_back(id); Geom::OptRect bounds = SP_ITEM(elemref)->bounds(SPItem::GEOMETRIC_BBOX); if (bounds) { anotation_width = bounds->width() * 1.4; @@ -479,7 +479,7 @@ LPEMeasureLine::createLine(Geom::Point start,Geom::Point end, const char * id, b elemref->deleteObject(); copy->setAttribute("id", id); } - elements.push_back(id); + items.push_back(id); } void @@ -531,7 +531,7 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) sp_lpe_item->getCurrentLPE() != this){ return; } - elements.clear(); + items.clear(); start_stored = start; end_stored = end; Geom::Point hstart = start; @@ -677,60 +677,12 @@ LPEMeasureLine::doOnRemove (SPLPEItem const* /*lpeitem*/) //unset "erase_extra_objects" hook on sp-lpe-item.cpp if (!erase_extra_objects) { processObjects(LPE_TO_OBJECTS); - elements.clear(); + items.clear(); return; } processObjects(LPE_ERASE); } -void -LPEMeasureLine::processObjects(LpeAction lpe_action) -{ - SPDocument * document = SP_ACTIVE_DOCUMENT; - for (std::vector::iterator el_it = elements.begin(); - el_it != elements.end(); ++el_it) { - const char * id = *el_it; - if (!id || strlen(id) == 0) { - return; - } - SPObject *elemref = NULL; - if (elemref = document->getObjectById(id)) { - SPCSSAttr *css; - Glib::ustring css_str; - switch (lpe_action){ - case LPE_TO_OBJECTS: - elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); - elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); - break; - - case LPE_ERASE: - if (std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { - elemref->deleteObject(); - } - break; - - case LPE_VISIBILITY: - css = sp_repr_css_attr_new(); - sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); - if (!this->isVisible() && std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { - css->setAttribute("display", "none"); - } else { - css->setAttribute("display", NULL); - } - sp_repr_css_write_string(css,css_str); - elemref->getRepr()->setAttribute("style", css_str.c_str()); - break; - - default: - break; - } - } - } - if (lpe_action == LPE_ERASE) { - elements.clear(); - } -} - Gtk::Widget *LPEMeasureLine::newWidget() { // use manage here, because after deletion of Effect object, others might diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h index cb531affe..724c0d924 100644 --- a/src/live_effects/lpe-measure-line.h +++ b/src/live_effects/lpe-measure-line.h @@ -45,7 +45,6 @@ public: virtual void doEffect (SPCurve * curve){}; //stop the chain virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Geom::PathVector doEffect_path(Geom::PathVector const &path_in); - void processObjects(LpeAction lpe_action); void createLine(Geom::Point start,Geom::Point end, const char * id, bool main, bool overflow, bool remove, bool arrows = false); void createTextLabel(Geom::Point pos, double length, Geom::Coord angle, bool remove, bool valid); void onExpanderChanged(); @@ -86,7 +85,6 @@ private: double arrow_gap; Geom::Point start_stored; Geom::Point end_stored; - std::vector elements; /* Geom::Affine affine_over;*/ LPEMeasureLine(const LPEMeasureLine &); LPEMeasureLine &operator=(const LPEMeasureLine &); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index b9a8fb83f..70787708e 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -959,25 +959,36 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) } else { c = subShape->getCurve(); } - + bool success = false; // only run LPEs when the shape has a curve defined if (c) { c->transform(i2anc_affine(subitem, topgroup)); - topgroup->performPathEffect(c); + success = topgroup->performPathEffect(c, subShape); c->transform(i2anc_affine(subitem, topgroup).inverse()); - subShape->setCurve(c, TRUE); - if (write) { - Inkscape::XML::Node *repr = subitem->getRepr(); - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); -#ifdef GROUP_VERBOSE - g_message("sp_group_perform_patheffect writes 'd' attribute"); -#endif - g_free(str); + if (c && success) { + subShape->setCurve(c, TRUE); + if (write) { + Inkscape::XML::Node *repr = subitem->getRepr(); + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); + #ifdef GROUP_VERBOSE + g_message("sp_group_perform_patheffect writes 'd' attribute"); + #endif + g_free(str); + } + c->unref(); + } else { + // LPE was unsuccesfull or doeffect stack return null. Read the old 'd'-attribute. + if (gchar const * value = repr->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); + if (oldcurve) { + subShape->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } } - - c->unref(); } } } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 1ee62b2db..00671b936 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -214,7 +214,7 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { +bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { if (!curve) { return false; @@ -246,12 +246,15 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { } if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { // Groups have their doBeforeEffect called elsewhere + if (current) { + lpe->setCurrentShape(current); + } if (!SP_IS_GROUP(this)) { lpe->doBeforeEffect_impl(this); } try { - lpe->doEffect(curve); + lpe->doEffect(curve); } catch (std::exception & e) { g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); @@ -704,10 +707,10 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) try { if(SP_IS_GROUP(this)){ c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(c, true); + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); } else { - success = this->performPathEffect(c, true); + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -718,12 +721,13 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) success = false; } Inkscape::XML::Node *repr = clip_mask->getRepr(); - if (success) { + // This c check allow to not apply LPE if curve is NULL after performPathEffect used in clone.obgets LPE + if (success && c) { gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); g_free(str); } else { - // LPE was unsuccesfull. Read the old 'd'-attribute. + // LPE was unsuccesfull or doeffect stack return null.. Read the old 'd'-attribute. if (gchar const * value = repr->attribute("d")) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); @@ -733,7 +737,9 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) } } } - c->unref(); + if (c) { + c->unref(); + } } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index db4a0c7a3..0f198c49c 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -23,6 +23,7 @@ class LivePathEffectObject; class SPCurve; +class SPShape; class SPDesktop; namespace Inkscape{ @@ -69,7 +70,7 @@ public: virtual void update_patheffect(bool write); - bool performPathEffect(SPCurve *curve, bool is_clip_or_mask = false); + bool performPathEffect(SPCurve *curve, SPShape *current = NULL, bool is_clip_or_mask = false); bool pathEffectsEnabled() const; bool hasPathEffect() const; -- cgit v1.2.3 From ba053c48cdcd8b4995f188d80887d46c41f97b3d Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 24 Jan 2017 01:37:00 +0100 Subject: Remove some code and make dependant of rotate copies (bzr r15356.1.17) --- src/live_effects/effect.cpp | 39 ++++++++++++------------------------ src/live_effects/effect.h | 8 +++----- src/live_effects/lpe-copy_rotate.cpp | 1 + src/sp-ellipse.cpp | 13 ++---------- src/sp-item-group.cpp | 37 ++++++++++++---------------------- src/sp-lpe-item.cpp | 21 ++++++++----------- src/sp-lpe-item.h | 3 +-- src/sp-object.cpp | 15 -------------- src/sp-object.h | 3 --- src/ui/clipboard.cpp | 2 -- 10 files changed, 41 insertions(+), 101 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 81a512d23..9d9381294 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -356,7 +356,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), - sp_shape(NULL), + sp_curve(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden { @@ -392,9 +392,9 @@ Effect::doOnApply (SPLPEItem const*/*lpeitem*/) } void -Effect::setSelectedNodePoints(std::vector selected_np) +Effect::setSelectedNodePoints(std::vector sNP) { - selected_nodes_points = selected_np; + selectedNodesPoints = sNP; } void @@ -404,16 +404,16 @@ Effect::setCurrentZoom(double cZ) } bool -Effect::isNodePointSelected(Geom::Point const &node_point) const +Effect::isNodePointSelected(Geom::Point const &nodePoint) const { - if (selected_nodes_points.size() > 0) { + if (selectedNodesPoints.size() > 0) { using Geom::X; using Geom::Y; - for (std::vector::const_iterator i = selected_nodes_points.begin(); - i != selected_nodes_points.end(); ++i) { + for (std::vector::const_iterator i = selectedNodesPoints.begin(); + i != selectedNodesPoints.end(); ++i) { Geom::Point p = *i; Geom::Affine transformCoordinate = sp_lpe_item->i2dt_affine(); - Geom::Point p2(node_point[X], node_point[Y]); + Geom::Point p2(nodePoint[X],nodePoint[Y]); p2 *= transformCoordinate; if (Geom::are_near(p, p2, 0.01)) { return true; @@ -446,24 +446,21 @@ void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - SPShape * shape = dynamic_cast(sp_lpe_item); - if(shape){ - setCurrentShape(shape); - } + /*sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); + pathvector_before_effect = sp_curve->get_pathvector();*/ doOnApply(lpeitem); } void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - //Groups set shape in performPathEffect before each call to doEffect + //printf("(SPLPEITEM*) %p\n", sp_lpe_item); SPShape * shape = dynamic_cast(sp_lpe_item); if(shape){ - setCurrentShape(shape); + sp_curve = shape->getCurve(); + pathvector_before_effect = sp_curve->get_pathvector(); } - //printf("(SPLPEITEM*) %p\n", sp_lpe_item); doBeforeEffect(lpeitem); - if (apply_to_clippath_and_mask && SP_IS_GROUP(sp_lpe_item)) { sp_lpe_item->apply_to_clippath(sp_lpe_item); sp_lpe_item->apply_to_mask(sp_lpe_item); @@ -471,16 +468,6 @@ void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) update_helperpath(); } -void Effect::setCurrentShape(SPShape * shape){ - if(shape){ - sp_shape = shape; - if (!(sp_curve = sp_shape->getCurve())) { - // oops - return; - } - pathvector_before_effect = sp_curve->get_pathvector(); - } -} /** * Effects can have a parameter path set before they are applied by accepting a nonzero number of * mouse clicks. This method activates the pen context, which waits for the specified number of diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 5dfa3de29..1997ff0ca 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -73,8 +73,7 @@ public: static int acceptsNumClicks(EffectType type); int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } void doAcceptPathPreparations(SPLPEItem *lpeitem); - SPShape * getCurrentShape(){ return sp_shape; }; - void setCurrentShape(SPShape * shape); + /* * isReady() indicates whether all preparations which are necessary to apply the LPE are done, * e.g., waiting for a parameter path either before the effect is created or when it needs a @@ -164,10 +163,9 @@ protected: // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each. bool concatenate_before_pwd2; - SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them.z - SPShape * sp_shape; // these get stored in doBeforeEffect_impl before doEffect chain, or in performPathEffects on groups, and derived classes may do as they please with them. + SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. double current_zoom; - std::vector selected_nodes_points; + std::vector selectedNodesPoints; SPCurve * sp_curve; Geom::PathVector pathvector_before_effect; private: diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 250f6aa29..813f25d3d 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -125,6 +125,7 @@ void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { // cycle through all parameters. Most parameters will not need transformation, but path and point params do. + for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { Parameter * param = *it; param->param_transform_multiply(postmul, set); diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 9589d6fce..ed1e2b504 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -445,20 +445,11 @@ void SPGenericEllipse::set_shape() if (hasPathEffect() && pathEffectsEnabled()) { SPCurve *c_lpe = curve->copy(); bool success = this->performPathEffect(c_lpe); - + if (success) { this->setCurveInsync(c_lpe, TRUE); - } else { - Inkscape::XML::Node *repr = this->getRepr(); - if (gchar const * value = repr->attribute("d")) { - Geom::PathVector pv = sp_svg_read_pathv(value); - SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); - if (oldcurve) { - this->setCurveInsync(oldcurve, TRUE); - oldcurve->unref(); - } - } } + c_lpe->unref(); } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 808d475c7..7b2507b5e 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -950,36 +950,25 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) } else { c = subShape->getCurve(); } - bool success = false; + // only run LPEs when the shape has a curve defined if (c) { c->transform(i2anc_affine(subitem, topgroup)); - success = topgroup->performPathEffect(c, subShape); + topgroup->performPathEffect(c); c->transform(i2anc_affine(subitem, topgroup).inverse()); - if (c && success) { - subShape->setCurve(c, TRUE); - if (write) { - Inkscape::XML::Node *repr = subitem->getRepr(); - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); - #ifdef GROUP_VERBOSE - g_message("sp_group_perform_patheffect writes 'd' attribute"); - #endif - g_free(str); - } - c->unref(); - } else { - // LPE was unsuccesfull or doeffect stack return null. Read the old 'd'-attribute. + subShape->setCurve(c, TRUE); + + if (write) { Inkscape::XML::Node *repr = subitem->getRepr(); - if (gchar const * value = repr->attribute("d")) { - Geom::PathVector pv = sp_svg_read_pathv(value); - SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); - if (oldcurve) { - subShape->setCurve(oldcurve, TRUE); - oldcurve->unref(); - } - } + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); +#ifdef GROUP_VERBOSE + g_message("sp_group_perform_patheffect writes 'd' attribute"); +#endif + g_free(str); } + + c->unref(); } } } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 2dd7cec5a..e2f61bfb5 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -209,7 +209,7 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { +bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { if (!curve) { return false; @@ -241,14 +241,12 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip } if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { // Groups have their doBeforeEffect called elsewhere - if (current) { - lpe->setCurrentShape(current); - } if (!SP_IS_GROUP(this)) { lpe->doBeforeEffect_impl(this); } + try { - lpe->doEffect(curve); + lpe->doEffect(curve); } catch (std::exception & e) { g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); @@ -697,10 +695,10 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) try { if(SP_IS_GROUP(this)){ c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + success = this->performPathEffect(c, true); c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); } else { - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + success = this->performPathEffect(c, true); } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -711,13 +709,12 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) success = false; } Inkscape::XML::Node *repr = clip_mask->getRepr(); - // This c check allow to not apply LPE if curve is NULL after performPathEffect used in clone.obgets LPE - if (success && c) { + if (success) { gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); g_free(str); } else { - // LPE was unsuccesfull or doeffect stack return null.. Read the old 'd'-attribute. + // LPE was unsuccesfull. Read the old 'd'-attribute. if (gchar const * value = repr->attribute("d")) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); @@ -727,9 +724,7 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) } } } - if (c) { - c->unref(); - } + c->unref(); } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 9cf868cf2..9e5cb3329 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -23,7 +23,6 @@ class LivePathEffectObject; class SPCurve; -class SPShape; class SPDesktop; namespace Inkscape{ @@ -70,7 +69,7 @@ public: virtual void update_patheffect(bool write); - bool performPathEffect(SPCurve *curve, SPShape *current = NULL, bool is_clip_or_mask = false); + bool performPathEffect(SPCurve *curve, bool is_clip_or_mask = false); bool pathEffectsEnabled() const; bool hasPathEffect() const; diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 0dc301c49..75f4657ef 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -775,21 +775,6 @@ void SPObject::appendChild(Inkscape::XML::Node *child) { repr->appendChild(child); } -SPObject* SPObject::nthChild(unsigned index) { - g_assert(this->repr); - if (hasChildren()) { - std::vector l; - unsigned counter = 0; - for (auto& child: children) { - if (counter == index) { - return &child; - } - counter++; - } - } - return NULL; -} - void SPObject::addChild(Inkscape::XML::Node *child, Inkscape::XML::Node * prev) { g_assert(this->repr); diff --git a/src/sp-object.h b/src/sp-object.h index d145e966b..9abbd324b 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -318,9 +318,6 @@ public: SPObject *lastChild() { return children.empty() ? nullptr : &children.back(); } SPObject const *lastChild() const { return children.empty() ? nullptr : &children.back(); } - SPObject *nthChild(unsigned index); - SPObject const *nthChild(unsigned index) const; - enum Action { ActionGeneral, ActionBBox, ActionUpdate, ActionShow }; /** diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 2e866a9d1..c1e824c1e 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -410,8 +410,6 @@ const gchar *ClipboardManagerImpl::getFirstObjectID() strcmp(ch->name(), "svg:use") && strcmp(ch->name(), "svg:text") && strcmp(ch->name(), "svg:image") && - strcmp(ch->name(), "svg:ellipse") && - strcmp(ch->name(), "svg:circle") && strcmp(ch->name(), "svg:rect") ) { ch = ch->next(); -- cgit v1.2.3 From e282eca29c2cd9b97247db78f2375c8a64071d9c Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 24 Jan 2017 01:44:29 +0100 Subject: Some bug fix to prepare merge (bzr r15392.1.9) --- src/live_effects/effect.cpp | 2 ++ src/live_effects/lpe-copy_rotate.cpp | 1 - src/live_effects/lpe-measure-line.cpp | 1 - src/live_effects/parameter/parameter.cpp | 3 +++ src/ui/widget/registered-widget.h | 2 +- 5 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 3cfeface8..a0ab0d41c 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -70,6 +70,8 @@ #include "ui/tools/node-tool.h" #include "ui/tools-switch.h" #include "knotholder.h" +#include "path-chemistry.h" +#include "xml/sp-css-attr.h" #include "live_effects/lpeobject.h" #include "display/curve.h" diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 33c4d6e5b..b81451487 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -20,7 +20,6 @@ #include "display/curve.h" #include "svg/path-string.h" #include "svg/svg.h" -#include "path-chemistry.h" #include "style.h" #include "helper/geom.h" #include "xml/sp-css-attr.h" diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index 38f93ebb4..ef87be81c 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -664,7 +664,6 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) } } -//TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMeasureLine::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) { diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 76aa05bae..befac4df1 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -198,6 +198,9 @@ ScalarParam::param_set_increments(double step, double page) inc_page = page; } + + + } /* namespace LivePathEffect */ } /* namespace Inkscape */ diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index 7266233dc..f66d5cbf2 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -50,7 +50,7 @@ class Registry; template class RegisteredWidget : public W { public: - void set_undo_parameters(const unsigned int _event_type, Glib::ustring const _event_description) + void set_undo_parameters(const unsigned int _event_type, Glib::ustring _event_description) { event_type = _event_type; event_description = _event_description; -- cgit v1.2.3 From 6d832f1da88ad485979c2c480dbd7576db486807 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 24 Jan 2017 01:57:50 +0100 Subject: Fixes some compiling bug (bzr r15392.1.10) --- src/live_effects/lpe-copy_rotate.cpp | 65 ++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index b81451487..61ea7e171 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -23,6 +23,7 @@ #include "style.h" #include "helper/geom.h" #include "xml/sp-css-attr.h" +#include "path-chemistry.h" // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -218,38 +219,38 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) } else { phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); std::vector attrs; - attrs->push_back("inkscape:path-effect"); - attrs->push_back("inkscape:original-d"); - attrs->push_back("sodipodi:type"); - attrs->push_back("sodipodi:rx"); - attrs->push_back("sodipodi:ry"); - attrs->push_back("sodipodi:cx"); - attrs->push_back("sodipodi:cy"); - attrs->push_back("sodipodi:end"); - attrs->push_back("sodipodi:start"); - attrs->push_back("inkscape:flatsided"); - attrs->push_back("inkscape:randomized"); - attrs->push_back("inkscape:rounded"); - attrs->push_back("sodipodi:arg1"); - attrs->push_back("sodipodi:arg2"); - attrs->push_back("sodipodi:r1"); - attrs->push_back("sodipodi:r2"); - attrs->push_back("sodipodi:sides"); - attrs->push_back("inkscape:randomized"); - attrs->push_back("sodipodi:argument"); - attrs->push_back("sodipodi:expansion"); - attrs->push_back("sodipodi:radius"); - attrs->push_back("sodipodi:revolution"); - attrs->push_back("sodipodi:t0"); - attrs->push_back("inkscape:randomized"); - attrs->push_back("inkscape:randomized"); - attrs->push_back("inkscape:randomized"); - attrs->push_back("x"); - attrs->push_back("y"); - attrs->push_back("rx"); - attrs->push_back("ry"); - attrs->push_back("width"); - attrs->push_back("height"); + attrs.push_back("inkscape:path-effect"); + attrs.push_back("inkscape:original-d"); + attrs.push_back("sodipodi:type"); + attrs.push_back("sodipodi:rx"); + attrs.push_back("sodipodi:ry"); + attrs.push_back("sodipodi:cx"); + attrs.push_back("sodipodi:cy"); + attrs.push_back("sodipodi:end"); + attrs.push_back("sodipodi:start"); + attrs.push_back("inkscape:flatsided"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:rounded"); + attrs.push_back("sodipodi:arg1"); + attrs.push_back("sodipodi:arg2"); + attrs.push_back("sodipodi:r1"); + attrs.push_back("sodipodi:r2"); + attrs.push_back("sodipodi:sides"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("sodipodi:argument"); + attrs.push_back("sodipodi:expansion"); + attrs.push_back("sodipodi:radius"); + attrs.push_back("sodipodi:revolution"); + attrs.push_back("sodipodi:t0"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("x"); + attrs.push_back("y"); + attrs.push_back("rx"); + attrs.push_back("ry"); + attrs.push_back("width"); + attrs.push_back("height"); phantom->setAttribute("id", elemref_id); for(const char * attr : attrs) { phantom->setAttribute(attr, NULL); -- cgit v1.2.3 From 05e33ba9f32f76d8cdb1feeeec5dd62f6d6d6811 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 24 Jan 2017 01:58:33 +0100 Subject: Fixes some compiling bug (bzr r15295.1.64) --- src/live_effects/lpe-mirror_symmetry.cpp | 64 ++++++++++++++++---------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index e94ad496e..0defeb900 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -238,38 +238,38 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform) } else { phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); std::vector attrs; - attrs->push_back("inkscape:path-effect"); - attrs->push_back("inkscape:original-d"); - attrs->push_back("sodipodi:type"); - attrs->push_back("sodipodi:rx"); - attrs->push_back("sodipodi:ry"); - attrs->push_back("sodipodi:cx"); - attrs->push_back("sodipodi:cy"); - attrs->push_back("sodipodi:end"); - attrs->push_back("sodipodi:start"); - attrs->push_back("inkscape:flatsided"); - attrs->push_back("inkscape:randomized"); - attrs->push_back("inkscape:rounded"); - attrs->push_back("sodipodi:arg1"); - attrs->push_back("sodipodi:arg2"); - attrs->push_back("sodipodi:r1"); - attrs->push_back("sodipodi:r2"); - attrs->push_back("sodipodi:sides"); - attrs->push_back("inkscape:randomized"); - attrs->push_back("sodipodi:argument"); - attrs->push_back("sodipodi:expansion"); - attrs->push_back("sodipodi:radius"); - attrs->push_back("sodipodi:revolution"); - attrs->push_back("sodipodi:t0"); - attrs->push_back("inkscape:randomized"); - attrs->push_back("inkscape:randomized"); - attrs->push_back("inkscape:randomized"); - attrs->push_back("x"); - attrs->push_back("y"); - attrs->push_back("rx"); - attrs->push_back("ry"); - attrs->push_back("width"); - attrs->push_back("height"); + attrs.push_back("inkscape:path-effect"); + attrs.push_back("inkscape:original-d"); + attrs.push_back("sodipodi:type"); + attrs.push_back("sodipodi:rx"); + attrs.push_back("sodipodi:ry"); + attrs.push_back("sodipodi:cx"); + attrs.push_back("sodipodi:cy"); + attrs.push_back("sodipodi:end"); + attrs.push_back("sodipodi:start"); + attrs.push_back("inkscape:flatsided"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:rounded"); + attrs.push_back("sodipodi:arg1"); + attrs.push_back("sodipodi:arg2"); + attrs.push_back("sodipodi:r1"); + attrs.push_back("sodipodi:r2"); + attrs.push_back("sodipodi:sides"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("sodipodi:argument"); + attrs.push_back("sodipodi:expansion"); + attrs.push_back("sodipodi:radius"); + attrs.push_back("sodipodi:revolution"); + attrs.push_back("sodipodi:t0"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("x"); + attrs.push_back("y"); + attrs.push_back("rx"); + attrs.push_back("ry"); + attrs.push_back("width"); + attrs.push_back("height"); for(const char * attr : attrs) { phantom->setAttribute(attr, NULL); } -- cgit v1.2.3 From 6569c9330cb3f5378d01c4fe43c13f69d537561e Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 24 Jan 2017 08:17:30 +0100 Subject: Bug fixes (bzr r15392.1.11) --- src/2geom/intersection-graph.cpp | 6 +++--- src/live_effects/lpe-copy_rotate.cpp | 16 +++++++++++++--- src/sp-item-group.cpp | 7 +++---- 3 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/2geom/intersection-graph.cpp b/src/2geom/intersection-graph.cpp index d469d3ffc..cac010942 100644 --- a/src/2geom/intersection-graph.cpp +++ b/src/2geom/intersection-graph.cpp @@ -410,10 +410,10 @@ PathVector PathIntersectionGraph::_getResult(bool enter_a, bool enter_b) assert(!result.back().empty()); } - /*if (n_processed != size() * 2) { + if (n_processed != size() * 2) { std::cerr << "Processed " << n_processed << " intersections, expected " << (size() * 2) << std::endl; - }*/ - assert(n_processed == size() * 2); + } + //assert(n_processed == size() * 2); return result; } diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 61ea7e171..fbc7933e7 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -119,7 +119,17 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) } previous_num_copies = num_copies; } - + SPObject *elemref = NULL; + char * id = g_strdup(Glib::ustring("rotated-").append("1").append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + guint counter = 0; + while(elemref = document->getObjectById(id)) { + if (SP_ITEM(elemref)->isHidden()) { + items.push_back(id); + } + id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + counter++; + } + g_free(id); double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); @@ -354,7 +364,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if (copies_to_360) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if (fuse_paths && rotation_angle * num_copies > 360 && rotation_angle > 0) { + if (fuse_paths && rotation_angle * num_copies > 360.1 && rotation_angle > 0) { num_copies.param_set_value(floor(360/rotation_angle)); } if (fuse_paths && copies_to_360) { @@ -616,7 +626,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - if (num_copies == 1 && !fuse_paths) { + if ((num_copies == 1 && !fuse_paths) || split_items) { return pwd2_in; } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 70787708e..f2c0d2f2c 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -965,16 +965,15 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) c->transform(i2anc_affine(subitem, topgroup)); success = topgroup->performPathEffect(c, subShape); c->transform(i2anc_affine(subitem, topgroup).inverse()); - + Inkscape::XML::Node *repr = subitem->getRepr(); if (c && success) { subShape->setCurve(c, TRUE); if (write) { - Inkscape::XML::Node *repr = subitem->getRepr(); gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); - #ifdef GROUP_VERBOSE +#ifdef GROUP_VERBOSE g_message("sp_group_perform_patheffect writes 'd' attribute"); - #endif +#endif g_free(str); } c->unref(); -- cgit v1.2.3 From 2630f312c74dd106a6f911045dbaed401bd12bbc Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 24 Jan 2017 08:18:21 +0100 Subject: Bug fixes (bzr r15295.1.65) --- src/live_effects/lpe-mirror_symmetry.cpp | 54 -------------------------------- src/live_effects/lpe-mirror_symmetry.h | 2 -- 2 files changed, 56 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 0defeb900..f35f3096f 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -345,60 +345,6 @@ LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) processObjects(LPE_ERASE); } -void -LPEMirrorSymmetry::processObjects(LpeAction lpe_action) -{ - SPDocument * document = SP_ACTIVE_DOCUMENT; - for (std::vector::iterator el_it = items.begin(); - el_it != items.end(); ++el_it) { - const char * id = *el_it; - if (!id || strlen(id) == 0) { - return; - } - SPObject *elemref = NULL; - if (elemref = document->getObjectById(id)) { - Inkscape::XML::Node * elemnode = elemref->getRepr(); - std::vector item_list; - item_list.push_back(SP_ITEM(elemref)); - std::vector item_to_select; - std::vector item_selected; - SPCSSAttr *css; - Glib::ustring css_str; - switch (lpe_action){ - case LPE_TO_OBJECTS: - if (elemnode->attribute("inkscape:path-effect")) { - sp_item_list_to_curves(item_list, item_selected, item_to_select); - } - elemnode->setAttribute("sodipodi:insensitive", NULL); - break; - - case LPE_ERASE: - elemref->deleteObject(); - break; - - case LPE_VISIBILITY: - css = sp_repr_css_attr_new(); - sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); - if (!this->isVisible()/* && std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0*/) { - css->setAttribute("display", "none"); - } else { - css->setAttribute("display", NULL); - } - sp_repr_css_write_string(css,css_str); - elemnode->setAttribute("style", css_str.c_str()); - break; - - default: - break; - } - } - } - if (lpe_action == LPE_ERASE || lpe_action == LPE_TO_OBJECTS) { - items.clear(); - } -} - - void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 5a6db5062..592a11894 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -47,7 +47,6 @@ public: virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); - void processObjects(LpeAction lpe_action); void toMirror(Geom::Affine transform); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); void cloneD(SPObject *origin, SPObject *dest, bool live, bool root); @@ -67,7 +66,6 @@ private: PointParam center_point; TextParam id_origin; Geom::Point previous_center; - std::vector items; SPObject * container; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); -- cgit v1.2.3 From 51c576f161ca3d3ef7f352f67f6091022eb1aca2 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Tue, 24 Jan 2017 09:46:52 +0100 Subject: [Bug #1658397] Object > Arrange > Polar Coordinates dialog text. Fixed bugs: - https://launchpad.net/bugs/1658397 (bzr r15437) --- src/ui/dialog/polar-arrange-tab.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp index c51881a96..9485b6ba3 100644 --- a/src/ui/dialog/polar-arrange-tab.cpp +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -43,14 +43,14 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) anchorPointLabel.set_alignment(Gtk::ALIGN_START); pack_start(anchorPointLabel, false, false); - anchorBoundingBoxRadio.set_label(C_("Polar arrange tab", "Object's bounding box:")); + anchorBoundingBoxRadio.set_label(C_("Polar arrange tab", "Objects' bounding boxes:")); anchorRadioGroup = anchorBoundingBoxRadio.get_group(); anchorBoundingBoxRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_anchor_radio_changed)); pack_start(anchorBoundingBoxRadio, false, false); pack_start(anchorSelector, false, false); - anchorObjectPivotRadio.set_label(C_("Polar arrange tab", "Object's rotational center")); + anchorObjectPivotRadio.set_label(C_("Polar arrange tab", "Objects' rotational centers")); anchorObjectPivotRadio.set_group(anchorRadioGroup); anchorObjectPivotRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_anchor_radio_changed)); pack_start(anchorObjectPivotRadio, false, false); -- cgit v1.2.3 From 7fecbddd1fb8b57f9c6efd3204645e33d9b38d09 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 24 Jan 2017 10:32:24 +0100 Subject: update to trunk (bzr r15356.1.18) --- src/2geom/intersection-graph.cpp | 6 +- src/helper/geom.cpp | 7 + src/helper/geom.h | 2 +- src/live_effects/effect.cpp | 88 +++++++- src/live_effects/effect.h | 20 +- src/live_effects/lpe-copy_rotate.cpp | 306 ++++++++++++++++++++++++++- src/live_effects/lpe-copy_rotate.h | 14 ++ src/live_effects/lpe-measure-line.cpp | 66 +----- src/live_effects/lpe-measure-line.h | 8 - src/live_effects/lpe-mirror_symmetry.cpp | 342 +++++++++++++++++++++++++------ src/live_effects/lpe-mirror_symmetry.h | 13 +- src/live_effects/parameter/bool.cpp | 3 +- src/live_effects/parameter/text.cpp | 3 +- src/sp-item-group.cpp | 43 ++-- src/sp-lpe-item.cpp | 35 +++- src/sp-lpe-item.h | 5 +- src/sp-object.cpp | 15 ++ src/sp-object.h | 3 + src/sp-path.cpp | 31 ++- src/ui/dialog/polar-arrange-tab.cpp | 4 +- 20 files changed, 812 insertions(+), 202 deletions(-) (limited to 'src') diff --git a/src/2geom/intersection-graph.cpp b/src/2geom/intersection-graph.cpp index d469d3ffc..cac010942 100644 --- a/src/2geom/intersection-graph.cpp +++ b/src/2geom/intersection-graph.cpp @@ -410,10 +410,10 @@ PathVector PathIntersectionGraph::_getResult(bool enter_a, bool enter_b) assert(!result.back().empty()); } - /*if (n_processed != size() * 2) { + if (n_processed != size() * 2) { std::cerr << "Processed " << n_processed << " intersections, expected " << (size() * 2) << std::endl; - }*/ - assert(n_processed == size() * 2); + } + //assert(n_processed == size() * 2); return result; } diff --git a/src/helper/geom.cpp b/src/helper/geom.cpp index 42c494c00..e1f05c3ce 100644 --- a/src/helper/geom.cpp +++ b/src/helper/geom.cpp @@ -843,6 +843,13 @@ recursive_bezier4(const double x1, const double y1, recursive_bezier4(x1234, y1234, x234, y234, x34, y34, x4, y4, m_points, level + 1); } +void +swap(Geom::Point &A, Geom::Point &B){ + Geom::Point tmp = A; + A = B; + B = tmp; +} + /* Local Variables: mode:c++ diff --git a/src/helper/geom.h b/src/helper/geom.h index d49e2070c..b3d907e51 100644 --- a/src/helper/geom.h +++ b/src/helper/geom.h @@ -32,7 +32,7 @@ void recursive_bezier4(const double x1, const double y1, const double x2, const const double x3, const double y3, const double x4, const double y4, std::vector &pointlist, int level); - +void swap(Geom::Point &A, Geom::Point &B); #endif // INKSCAPE_HELPER_GEOM_H /* diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 9d9381294..50e2aa353 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -70,6 +70,8 @@ #include "ui/tools/node-tool.h" #include "ui/tools-switch.h" #include "knotholder.h" +#include "path-chemistry.h" +#include "xml/sp-css-attr.h" #include "live_effects/lpeobject.h" #include "display/curve.h" @@ -356,6 +358,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), + sp_shape(NULL), sp_curve(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden @@ -392,15 +395,15 @@ Effect::doOnApply (SPLPEItem const*/*lpeitem*/) } void -Effect::setSelectedNodePoints(std::vector sNP) +Effect::setCurrentZoom(double cZ) { - selectedNodesPoints = sNP; + current_zoom = cZ; } void -Effect::setCurrentZoom(double cZ) +Effect::setSelectedNodePoints(std::vector sNP) { - current_zoom = cZ; + selectedNodesPoints = sNP; } bool @@ -423,6 +426,74 @@ Effect::isNodePointSelected(Geom::Point const &nodePoint) const return false; } +void +Effect::processObjects(LpeAction lpe_action) +{ + SPDocument * document = SP_ACTIVE_DOCUMENT; + for (std::vector::iterator el_it = items.begin(); + el_it != items.end(); ++el_it) { + const char * id = *el_it; + if (!id || strlen(id) == 0) { + return; + } + SPObject *elemref = NULL; + if (elemref = document->getObjectById(id)) { + Inkscape::XML::Node * elemnode = elemref->getRepr(); + std::vector item_list; + item_list.push_back(SP_ITEM(elemref)); + std::vector item_to_select; + std::vector item_selected; + SPCSSAttr *css; + Glib::ustring css_str; + switch (lpe_action){ + case LPE_TO_OBJECTS: + if (SP_ITEM(elemref)->isHidden()) { + elemref->deleteObject(); + } else { + if (elemnode->attribute("inkscape:path-effect")) { + sp_item_list_to_curves(item_list, item_selected, item_to_select); + } + elemnode->setAttribute("sodipodi:insensitive", NULL); + } + break; + + case LPE_ERASE: + elemref->deleteObject(); + break; + + case LPE_VISIBILITY: + css = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); + if (!this->isVisible()/* && std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0*/) { + css->setAttribute("display", "none"); + } else { + css->setAttribute("display", NULL); + } + sp_repr_css_write_string(css,css_str); + elemnode->setAttribute("style", css_str.c_str()); + break; + + default: + break; + } + } + } + if (lpe_action == LPE_ERASE || lpe_action == LPE_TO_OBJECTS) { + items.clear(); + } +} + +void Effect::setCurrentShape(SPShape * shape){ + if(shape){ + sp_shape = shape; + if (!(sp_curve = sp_shape->getCurve())) { + // oops + return; + } + pathvector_before_effect = sp_curve->get_pathvector(); + } +} + /** * Is performed each time before the effect is updated. */ @@ -446,8 +517,12 @@ void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - /*sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); - pathvector_before_effect = sp_curve->get_pathvector();*/ + sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); + pathvector_before_effect = sp_curve->get_pathvector(); + SPShape * shape = dynamic_cast(sp_lpe_item); + if(shape){ + setCurrentShape(shape); + } doOnApply(lpeitem); } @@ -457,6 +532,7 @@ void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) //printf("(SPLPEITEM*) %p\n", sp_lpe_item); SPShape * shape = dynamic_cast(sp_lpe_item); if(shape){ + setCurrentShape(shape); sp_curve = shape->getCurve(); pathvector_before_effect = sp_curve->get_pathvector(); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 1997ff0ca..f5e41d50e 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -19,7 +19,7 @@ class SPDocument; class SPDesktop; class SPItem; -class LivePathEffectObject; +class LivePathEffectObject; class SPLPEItem; class KnotHolder; class KnotHolderEntity; @@ -44,6 +44,12 @@ enum LPEPathFlashType { DEFAULT }; +enum LpeAction { + LPE_ERASE = 0, + LPE_TO_OBJECTS, + LPE_VISIBILITY +}; + class Effect { public: static Effect* New(EffectType lpenr, LivePathEffectObject *lpeobj); @@ -73,6 +79,9 @@ public: static int acceptsNumClicks(EffectType type); int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } void doAcceptPathPreparations(SPLPEItem *lpeitem); + SPShape * getCurrentShape(){ return sp_shape; }; + void setCurrentShape(SPShape * shape); + void processObjects(LpeAction lpe_action); /* * isReady() indicates whether all preparations which are necessary to apply the LPE are done, @@ -125,7 +134,9 @@ public: bool apply_to_clippath_and_mask; bool erase_extra_objects; // set this to false allow retain extra generated objects, see measure line LPE bool upd_params; - + BoolParam is_visible; + SPCurve * sp_curve; + Geom::PathVector pathvector_before_effect; protected: Effect(LivePathEffectObject *lpeobject); @@ -150,7 +161,6 @@ protected: bool _provides_knotholder_entities; int oncanvasedit_it; - BoolParam is_visible; bool show_orig_path; // set this to true in derived effects to automatically have the original // path displayed as helperpath @@ -164,10 +174,10 @@ protected: bool concatenate_before_pwd2; SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. + SPShape * sp_shape; // these get stored in doBeforeEffect_impl before doEffect chain, or in performPathEffects on groups, and derived classes may do as they please with them. + std::vector items; double current_zoom; std::vector selectedNodesPoints; - SPCurve * sp_curve; - Geom::PathVector pathvector_before_effect; private: bool provides_own_flash_paths; // if true, the standard flash path is suppressed diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 813f25d3d..fbc7933e7 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -17,6 +17,13 @@ #include <2geom/sbasis-to-bezier.h> #include <2geom/intersection-graph.h> #include "live_effects/lpe-copy_rotate.h" +#include "display/curve.h" +#include "svg/path-string.h" +#include "svg/svg.h" +#include "style.h" +#include "helper/geom.h" +#include "xml/sp-css-attr.h" +#include "path-chemistry.h" // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -45,9 +52,11 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : starting_angle(_("Starting angle"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 60.0), num_copies(_("Number of copies"), _("Number of copies of the original path"), "num_copies", &wr, this, 6), + split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, -0.001), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), fuse_paths(_("Kaleidoskope"), _("Kaleidoskope by helper line, use fill-rule: evenodd for best result"), "fuse_paths", &wr, this, false), join_paths(_("Join paths"), _("Join paths, use fill-rule: evenodd for best result"), "join_paths", &wr, this, false), + split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), dist_angle_handle(100.0) { show_orig_path = true; @@ -56,15 +65,21 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : registerParameter(&copies_to_360); registerParameter(&fuse_paths); registerParameter(&join_paths); + registerParameter(&split_items); registerParameter(&starting_angle); registerParameter(&starting_point); registerParameter(&rotation_angle); registerParameter(&num_copies); + registerParameter(&split_gap); registerParameter(&origin); - + split_gap.param_set_range(-999999.0, 999999.0); + split_gap.param_set_increments(0.1, 0.1); + split_gap.param_set_digits(5); + num_copies.param_set_range(0, 999999); num_copies.param_make_integer(true); - num_copies.param_set_range(0, 1000); apply_to_clippath_and_mask = true; + previous_num_copies = num_copies; + reset = false; } LPECopyRotate::~LPECopyRotate() @@ -72,6 +87,207 @@ LPECopyRotate::~LPECopyRotate() } +void +LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) +{ + if (split_items) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + items.clear(); + container = dynamic_cast(sp_lpe_item->parent); + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); + Inkscape::XML::Node *root_origin = doc->getReprRoot(); + if (root_origin != root) { + return; + } + if (previous_num_copies != num_copies) { + gint numcopies_gap = previous_num_copies - num_copies; + if (numcopies_gap > 0 && num_copies != 0) { + guint counter = num_copies - 1; + while (numcopies_gap > 0) { + const char * id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + if (!id || strlen(id) == 0) { + return; + } + SPObject *elemref = NULL; + if (elemref = document->getObjectById(id)) { + SP_ITEM(elemref)->setHidden(true); + } + counter++; + numcopies_gap--; + } + } + previous_num_copies = num_copies; + } + SPObject *elemref = NULL; + char * id = g_strdup(Glib::ustring("rotated-").append("1").append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + guint counter = 0; + while(elemref = document->getObjectById(id)) { + if (SP_ITEM(elemref)->isHidden()) { + items.push_back(id); + } + id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + counter++; + } + g_free(id); + double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); + Geom::Point line_start = origin + dir * Geom::Rotate(-(Geom::rad_from_deg(starting_angle))) * size_divider; + Geom::Point line_end = origin + dir * Geom::Rotate(-(Geom::rad_from_deg(rotation_angle + starting_angle))) * size_divider; + Geom::Affine m = Geom::Translate(-origin) * Geom::Rotate(-(Geom::rad_from_deg(starting_angle))); + if (fuse_paths) { + size_t rest = 0; + for (size_t i = 1; i < num_copies; ++i) { + Geom::Affine r = Geom::identity(); + Geom::Point dir = unit_vector((Geom::Point)origin - Geom::middle_point(line_start,line_end)); + if( rest%2 == 0) { + r *= Geom::Rotate(Geom::Angle(dir)).inverse(); + r *= Geom::Scale(1, -1); + r *= Geom::Rotate(Geom::Angle(dir)); + } + Geom::Rotate rot(-(Geom::rad_from_deg(rotation_angle * i))); + Geom::Affine t = m * r * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)) * Geom::Translate(origin); + if( rest%2 == 0) { + t = m * r * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)).inverse() * Geom::Translate(origin); + } + t *= sp_lpe_item->transform; + toItem(t, i-1, reset); + rest ++; + } + } else { + for (size_t i = 1; i < num_copies; ++i) { + Geom::Rotate rot(-(Geom::rad_from_deg(rotation_angle * i))); + Geom::Affine t = m * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)) * Geom::Translate(origin); + t *= sp_lpe_item->transform; + toItem(t, i - 1, reset); + } + } + reset = false; + } else { + processObjects(LPE_ERASE); + items.clear(); + } + + std::cout << previous_num_copies << "previous_num_copies\n"; + std::cout << num_copies << "num_copies\n"; +} + +void +LPECopyRotate::cloneD(SPObject *origin, SPObject *dest, bool root, bool reset) +{ + SPDocument * document = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { + std::vector< SPObject * > childs = origin->childList(true); + size_t index = 0; + for (std::vector::iterator obj_it = childs.begin(); + obj_it != childs.end(); ++obj_it) { + SPObject *dest_child = dest->nthChild(index); + cloneD(*obj_it, dest_child, false, reset); + index++; + } + } + SPShape * shape = SP_SHAPE(origin); + SPPath * path = SP_PATH(dest); + if (!path && !SP_IS_GROUP(dest)) { + Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); + dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); + path = SP_PATH(dest); + } + if (path && shape) { + SPCurve *c = NULL; + if (root) { + c = new SPCurve(); + c->set_pathvector(pathvector_before_effect); + } else { + c = shape->getCurve(); + } + if (c) { + path->setCurve(c, TRUE); + c->unref(); + } else { + dest->getRepr()->setAttribute("d", NULL); + } + if (reset) { + dest->getRepr()->setAttribute("style", shape->getRepr()->attribute("style")); + } + } +} + +void +LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) +{ + SPDocument * document = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + const char * elemref_id = g_strdup(Glib::ustring("rotated-").append(std::to_string(i)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + items.push_back(elemref_id); + SPObject *elemref= NULL; + Inkscape::XML::Node *phantom = NULL; + if (elemref = document->getObjectById(elemref_id)) { + phantom = elemref->getRepr(); + } else { + phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); + std::vector attrs; + attrs.push_back("inkscape:path-effect"); + attrs.push_back("inkscape:original-d"); + attrs.push_back("sodipodi:type"); + attrs.push_back("sodipodi:rx"); + attrs.push_back("sodipodi:ry"); + attrs.push_back("sodipodi:cx"); + attrs.push_back("sodipodi:cy"); + attrs.push_back("sodipodi:end"); + attrs.push_back("sodipodi:start"); + attrs.push_back("inkscape:flatsided"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:rounded"); + attrs.push_back("sodipodi:arg1"); + attrs.push_back("sodipodi:arg2"); + attrs.push_back("sodipodi:r1"); + attrs.push_back("sodipodi:r2"); + attrs.push_back("sodipodi:sides"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("sodipodi:argument"); + attrs.push_back("sodipodi:expansion"); + attrs.push_back("sodipodi:radius"); + attrs.push_back("sodipodi:revolution"); + attrs.push_back("sodipodi:t0"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("x"); + attrs.push_back("y"); + attrs.push_back("rx"); + attrs.push_back("ry"); + attrs.push_back("width"); + attrs.push_back("height"); + phantom->setAttribute("id", elemref_id); + for(const char * attr : attrs) { + phantom->setAttribute(attr, NULL); + } + } + if (!elemref) { + elemref = container->appendChildRepr(phantom); + Inkscape::GC::release(phantom); + } + cloneD(SP_OBJECT(sp_lpe_item), elemref, true, reset); + elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); + SP_ITEM(elemref)->setHidden(false); + if (elemref->parent != container) { + Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); + copy->setAttribute("id", elemref_id); + container->appendChildRepr(copy); + Inkscape::GC::release(copy); + elemref->deleteObject(); + } +} + +void +LPECopyRotate::resetStyles(){ + reset = true; + doAfterEffect(sp_lpe_item); +} + Gtk::Widget * LPECopyRotate::newWidget() { // use manage here, because after deletion of Effect object, others might @@ -81,7 +297,15 @@ Gtk::Widget * LPECopyRotate::newWidget() vbox->set_border_width(5); vbox->set_homogeneous(false); vbox->set_spacing(2); - + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); + Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + vbox_expander->set_border_width(0); + vbox_expander->set_spacing(2); + Gtk::Button * reset_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset styles")))); + reset_button->signal_clicked().connect(sigc::mem_fun (*this,&LPECopyRotate::resetStyles)); + reset_button->set_size_request(140,30); + vbox->pack_start(*hbox, true,true,2); + hbox->pack_start(*reset_button, false, false,2); std::vector::iterator it = param_vector.begin(); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { @@ -125,11 +349,11 @@ void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { // cycle through all parameters. Most parameters will not need transformation, but path and point params do. - for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { Parameter * param = *it; param->param_transform_multiply(postmul, set); } + sp_lpe_item_update_patheffect(sp_lpe_item, false, false); } void @@ -140,17 +364,17 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if (copies_to_360) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if (fuse_paths && rotation_angle * num_copies > 360 && rotation_angle > 0) { + if (fuse_paths && rotation_angle * num_copies > 360.1 && rotation_angle > 0) { num_copies.param_set_value(floor(360/rotation_angle)); } if (fuse_paths && copies_to_360) { - num_copies.param_set_increments(2,2); + num_copies.param_set_increments(2.0,10.0); if ((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); rotation_angle.param_set_value(360.0/(double)num_copies); } } else { - num_copies.param_set_increments(1,1); + num_copies.param_set_increments(1.0, 10.0); } if (dist_angle_handle < 1.0) { @@ -352,12 +576,57 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s tmp_path.clear(); } +Geom::PathVector +LPECopyRotate::doEffect_path (Geom::PathVector const & path_in) +{ + Geom::PathVector path_out; + if (split_items && (fuse_paths || join_paths)) { + if (num_copies == 0) { + return path_out; + } + path_out = pathv_to_linear_and_cubic_beziers(path_in); + double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + Geom::OptRect bbox = sp_lpe_item->geometricBounds(); + double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); + Geom::Point line_start = origin + dir * Geom::Rotate(-(Geom::rad_from_deg(starting_angle))) * size_divider; + Geom::Point line_end = origin + dir * Geom::Rotate(-(Geom::rad_from_deg(rotation_angle + starting_angle))) * size_divider; + Geom::Path divider = Geom::Path(line_start); + divider.appendNew((Geom::Point)origin); + divider.appendNew(line_end); + divider.close(); + Geom::PathVector triangle; + triangle.push_back(divider); + Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(triangle, path_out); + if (pig && ! path_out.empty() && !triangle.empty()) { + //TODO: Here can produce a crash because some knows problems in new boolops code + path_out = pig->getIntersection(); + } + Geom::Affine r = Geom::identity(); + Geom::Point dir = unit_vector(Geom::middle_point(line_start,line_end) - (Geom::Point)origin); + Geom::Point gap = dir * split_gap; + r *= Geom::Translate(gap); + path_out *= r; + } else { + // default behavior + for (unsigned int i=0; i < path_in.size(); i++) { + Geom::Piecewise > pwd2_in = path_in[i].toPwSb(); + Geom::Piecewise > pwd2_out = doEffect_pwd2(pwd2_in); + Geom::PathVector path = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE); + // add the output path vector to the already accumulated vector: + for (unsigned int j=0; j < path.size(); j++) { + path_out.push_back(path[j]); + } + } + } + return pathv_to_linear_and_cubic_beziers(path_out); +} + Geom::Piecewise > LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { using namespace Geom; - if (num_copies == 1 && !fuse_paths) { + if ((num_copies == 1 && !fuse_paths) || split_items) { return pwd2_in; } @@ -373,10 +642,10 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p divider.appendNew(line_end); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-rad_from_deg(starting_angle)); + PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001)); if (fuse_paths) { Geom::PathVector path_out; Geom::PathVector tmp_path; - PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()) { continue; @@ -403,7 +672,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p output = paths_to_pw(path_out); } } else { - Geom::PathVector output_pv = path_from_piecewise(output , 0.01); + Geom::PathVector output_pv; for (int i = 0; i < num_copies; ++i) { Rotate rot(-rad_from_deg(rotation_angle * i)); Affine t = pre * rot * Translate(origin); @@ -449,6 +718,23 @@ LPECopyRotate::resetDefaults(SPItem const* item) original_bbox(SP_LPE_ITEM(item)); } +void +LPECopyRotate::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) +{ + processObjects(LPE_VISIBILITY); +} + +void +LPECopyRotate::doOnRemove (SPLPEItem const* /*lpeitem*/) +{ + //unset "erase_extra_objects" hook on sp-lpe-item.cpp + if (!erase_extra_objects) { + processObjects(LPE_TO_OBJECTS); + return; + } + processObjects(LPE_ERASE); +} + } //namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index c2ae2daf1..dbec2e1c3 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -15,6 +15,8 @@ */ #include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" #include "live_effects/lpegroupbbox.h" @@ -26,13 +28,20 @@ public: LPECopyRotate(LivePathEffectObject *lpeobject); virtual ~LPECopyRotate(); virtual void doOnApply (SPLPEItem const* lpeitem); + virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doAfterEffect (SPLPEItem const* lpeitem); virtual void setFusion(Geom::PathVector &path_in, Geom::Path divider, double sizeDivider); virtual void split(Geom::PathVector &path_in, Geom::Path const ÷r); virtual void resetDefaults(SPItem const* item); virtual void transform_multiply(Geom::Affine const& postmul, bool set); + virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); + virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); + void toItem(Geom::Affine transform, size_t i, bool reset); + void cloneD(SPObject *origin, SPObject *dest, bool root, bool reset); + void resetStyles(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -42,9 +51,11 @@ private: ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; + ScalarParam split_gap; BoolParam copies_to_360; BoolParam fuse_paths; BoolParam join_paths; + BoolParam split_items; Geom::Point A; Geom::Point B; Geom::Point dir; @@ -52,6 +63,9 @@ private: Geom::Point rot_pos; Geom::Point previous_start_point; double dist_angle_handle; + double previous_num_copies; + bool reset; + SPObject * container; LPECopyRotate(const LPECopyRotate&); LPECopyRotate& operator=(const LPECopyRotate&); }; diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index af2a8e919..ef87be81c 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -21,7 +21,9 @@ #include "svg/svg-color.h" #include "svg/svg.h" #include "display/curve.h" +#include "helper/geom.h" #include "2geom/affine.h" +#include "path-chemistry.h" #include "style.h" #include "sp-root.h" #include "sp-defs.h" @@ -165,12 +167,6 @@ LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) : LPEMeasureLine::~LPEMeasureLine() {} -void swap(Geom::Point &A, Geom::Point &B){ - Geom::Point tmp = A; - A = B; - B = tmp; -} - void LPEMeasureLine::createArrowMarker(const char * mode) { @@ -229,7 +225,7 @@ LPEMeasureLine::createArrowMarker(const char * mode) elemref = SP_OBJECT(document->getDefs()->appendChildRepr(arrow)); Inkscape::GC::release(arrow); } - elements.push_back(mode); + items.push_back(mode); } void @@ -369,7 +365,7 @@ LPEMeasureLine::createTextLabel(Geom::Point pos, double length, Geom::Coord angl copy->setAttribute("id", id); elemref = elemref_copy; } - elements.push_back(id); + items.push_back(id); Geom::OptRect bounds = SP_ITEM(elemref)->bounds(SPItem::GEOMETRIC_BBOX); if (bounds) { anotation_width = bounds->width() * 1.4; @@ -483,7 +479,7 @@ LPEMeasureLine::createLine(Geom::Point start,Geom::Point end, const char * id, b elemref->deleteObject(); copy->setAttribute("id", id); } - elements.push_back(id); + items.push_back(id); } void @@ -535,7 +531,7 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) sp_lpe_item->getCurrentLPE() != this){ return; } - elements.clear(); + items.clear(); start_stored = start; end_stored = end; Geom::Point hstart = start; @@ -680,60 +676,12 @@ LPEMeasureLine::doOnRemove (SPLPEItem const* /*lpeitem*/) //unset "erase_extra_objects" hook on sp-lpe-item.cpp if (!erase_extra_objects) { processObjects(LPE_TO_OBJECTS); - elements.clear(); + items.clear(); return; } processObjects(LPE_ERASE); } -void -LPEMeasureLine::processObjects(LpeAction lpe_action) -{ - SPDocument * document = SP_ACTIVE_DOCUMENT; - for (std::vector::iterator el_it = elements.begin(); - el_it != elements.end(); ++el_it) { - const char * id = *el_it; - if (!id || strlen(id) == 0) { - return; - } - SPObject *elemref = NULL; - if (elemref = document->getObjectById(id)) { - SPCSSAttr *css; - Glib::ustring css_str; - switch (lpe_action){ - case LPE_TO_OBJECTS: - elemref->getRepr()->setAttribute("inkscape:path-effect", NULL); - elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); - break; - - case LPE_ERASE: - if (std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { - elemref->deleteObject(); - } - break; - - case LPE_VISIBILITY: - css = sp_repr_css_attr_new(); - sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); - if (!this->isVisible() && std::strcmp(elemref->getId(),id_origin.param_getSVGValue()) != 0) { - css->setAttribute("display", "none"); - } else { - css->setAttribute("display", NULL); - } - sp_repr_css_write_string(css,css_str); - elemref->getRepr()->setAttribute("style", css_str.c_str()); - break; - - default: - break; - } - } - } - if (lpe_action == LPE_ERASE) { - elements.clear(); - } -} - Gtk::Widget *LPEMeasureLine::newWidget() { // use manage here, because after deletion of Effect object, others might diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h index c69921a4d..724c0d924 100644 --- a/src/live_effects/lpe-measure-line.h +++ b/src/live_effects/lpe-measure-line.h @@ -35,12 +35,6 @@ enum OrientationMethod { OM_END }; -enum LpeAction { - LPE_ERASE = 0, - LPE_TO_OBJECTS, - LPE_VISIBILITY -}; - class LPEMeasureLine : public Effect { public: LPEMeasureLine(LivePathEffectObject *lpeobject); @@ -51,7 +45,6 @@ public: virtual void doEffect (SPCurve * curve){}; //stop the chain virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Geom::PathVector doEffect_path(Geom::PathVector const &path_in); - void processObjects(LpeAction lpe_action); void createLine(Geom::Point start,Geom::Point end, const char * id, bool main, bool overflow, bool remove, bool arrows = false); void createTextLabel(Geom::Point pos, double length, Geom::Coord angle, bool remove, bool valid); void onExpanderChanged(); @@ -92,7 +85,6 @@ private: double arrow_gap; Geom::Point start_stored; Geom::Point end_stored; - std::vector elements; /* Geom::Affine affine_over;*/ LPEMeasureLine(const LPEMeasureLine &); LPEMeasureLine &operator=(const LPEMeasureLine &); diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 61b2b8b5c..7f0a93c52 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -15,11 +15,22 @@ */ #include +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" #include "live_effects/lpe-mirror_symmetry.h" -#include -#include +#include "display/curve.h" +#include "svg/path-string.h" +#include "svg/svg.h" +#include "sp-defs.h" #include "helper/geom.h" -#include <2geom/path-intersection.h> +#include "2geom/intersection-graph.h" +#include "2geom/path-intersection.h" +#include "2geom/affine.h" +#include "helper/geom.h" +#include "sp-lpe-item.h" +#include "path-chemistry.h" +#include "style.h" +#include "xml/sp-css-attr.h" // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -40,73 +51,69 @@ MTConverter(ModeTypeData, MT_END); LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), + split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, -0.001), discard_orig_path(_("Discard original path"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), + split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust start of mirroring")), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), - center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) + center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), + id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,"") { show_orig_path = true; registerParameter(&mode); - registerParameter( &discard_orig_path); - registerParameter( &fuse_paths); - registerParameter( &oposite_fuse); - registerParameter( &start_point); - registerParameter( &end_point); - registerParameter( ¢er_point); - previous_center = Geom::Point(0,0); + registerParameter(&split_gap); + registerParameter(&discard_orig_path); + registerParameter(&fuse_paths); + registerParameter(&oposite_fuse); + registerParameter(&split_items); + registerParameter(&start_point); + registerParameter(&end_point); + registerParameter(¢er_point); + registerParameter(&id_origin); + id_origin.param_hide_canvas_text(); + split_gap.param_set_range(-999999.0, 999999.0); + split_gap.param_set_increments(0.1, 0.1); + split_gap.param_set_digits(5); apply_to_clippath_and_mask = true; + previous_center = Geom::Point(0,0); } LPEMirrorSymmetry::~LPEMirrorSymmetry() { } -Gtk::Widget * LPEMirrorSymmetry::newWidget() +void +LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) { - // use manage here, because after deletion of Effect object, others might - // still be pointing to this widget. - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - - vbox->set_border_width(5); - vbox->set_homogeneous(false); - vbox->set_spacing(2); - - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter *param = *it; - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - if (param->param_key != "center_point") { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } + if (split_items && !discard_orig_path) { + container = dynamic_cast(sp_lpe_item->parent); + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); + Inkscape::XML::Node *root_origin = doc->getReprRoot(); + if (root_origin != root) { + return; } - - ++it; + Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); + Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); + m = m * sp_lpe_item->transform; + toMirror(m); + } else { + processObjects(LPE_ERASE); + items.clear(); } - return dynamic_cast(vbox); } - void LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { + using namespace Geom; original_bbox(lpeitem); //center_point->param_set_liveupdate(false); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); - Point point_c(boundingbox_X.max(), boundingbox_Y.middle()); if (mode == MT_Y) { point_a = Geom::Point(boundingbox_X.min(),center_point[Y]); point_b = Geom::Point(boundingbox_X.max(),center_point[Y]); @@ -172,6 +179,172 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) previous_center = center_point; } +void +LPEMirrorSymmetry::cloneD(SPObject *origin, SPObject *dest, bool live, bool root) +{ + SPDocument * document = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { + std::vector< SPObject * > childs = origin->childList(true); + size_t index = 0; + for (std::vector::iterator obj_it = childs.begin(); + obj_it != childs.end(); ++obj_it) { + SPObject *dest_child = dest->nthChild(index); + cloneD(*obj_it, dest_child, live, false); + index++; + } + } + SPShape * shape = SP_SHAPE(origin); + SPPath * path = SP_PATH(dest); + if (!path && !SP_IS_GROUP(dest)) { + Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); + dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); + path = SP_PATH(dest); + } + if (path && shape) { + if ( live) { + SPCurve *c = NULL; + if (root) { + c = new SPCurve(); + c->set_pathvector(pathvector_before_effect); + } else { + c = shape->getCurve(); + } + if (c) { + path->setCurve(c, TRUE); + c->unref(); + } else { + dest->getRepr()->setAttribute("d", NULL); + } + } else { + dest->getRepr()->setAttribute("d", origin->getRepr()->attribute("d")); + } + } +} + +void +LPEMirrorSymmetry::toMirror(Geom::Affine transform) +{ + SPDocument * document = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + const char * id_origin_char = id_origin.param_getSVGValue(); + const char * elemref_id = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); + items.clear(); + items.push_back(elemref_id); + SPObject *elemref= NULL; + Inkscape::XML::Node *phantom = NULL; + if (elemref = document->getObjectById(elemref_id)) { + phantom = elemref->getRepr(); + } else { + phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); + std::vector attrs; + attrs.push_back("inkscape:path-effect"); + attrs.push_back("inkscape:original-d"); + attrs.push_back("sodipodi:type"); + attrs.push_back("sodipodi:rx"); + attrs.push_back("sodipodi:ry"); + attrs.push_back("sodipodi:cx"); + attrs.push_back("sodipodi:cy"); + attrs.push_back("sodipodi:end"); + attrs.push_back("sodipodi:start"); + attrs.push_back("inkscape:flatsided"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:rounded"); + attrs.push_back("sodipodi:arg1"); + attrs.push_back("sodipodi:arg2"); + attrs.push_back("sodipodi:r1"); + attrs.push_back("sodipodi:r2"); + attrs.push_back("sodipodi:sides"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("sodipodi:argument"); + attrs.push_back("sodipodi:expansion"); + attrs.push_back("sodipodi:radius"); + attrs.push_back("sodipodi:revolution"); + attrs.push_back("sodipodi:t0"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("x"); + attrs.push_back("y"); + attrs.push_back("rx"); + attrs.push_back("ry"); + attrs.push_back("width"); + attrs.push_back("height"); + for(const char * attr : attrs) { + phantom->setAttribute(attr, NULL); + } + } + phantom->setAttribute("id", elemref_id); + if (!elemref) { + elemref = container->appendChildRepr(phantom); + Inkscape::GC::release(phantom); + } + cloneD(SP_OBJECT(sp_lpe_item), elemref, true, true); + elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); + if (elemref->parent != container) { + Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); + copy->setAttribute("id", elemref_id); + container->appendChildRepr(copy); + Inkscape::GC::release(copy); + elemref->deleteObject(); + } +} + +Gtk::Widget * +LPEMirrorSymmetry::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + if (param->param_key == "id_origin" || param->param_key == "center_point") { + ++it; + continue; + } + Gtk::Widget * widg = param->param_newWidget(); + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + this->upd_params = false; + return dynamic_cast(vbox); +} + +//TODO: Migrate the tree next function to effect.cpp/h to avoid duplication +void +LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) +{ + processObjects(LPE_VISIBILITY); +} + +void +LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) +{ + //unset "erase_extra_objects" hook on sp-lpe-item.cpp + if (!erase_extra_objects) { + processObjects(LPE_TO_OBJECTS); + return; + } + processObjects(LPE_ERASE); +} + void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { @@ -193,18 +366,26 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); Point point_c(boundingbox_X.max(), boundingbox_Y.middle()); - start_point.param_setValue(point_a, true); + start_point.param_setValue(point_a); start_point.param_update_default(point_a); - end_point.param_setValue(point_b, true); + end_point.param_setValue(point_b); end_point.param_update_default(point_b); center_point.param_setValue(point_c, true); previous_center = center_point; + SPLPEItem * splpeitem = const_cast(lpeitem); + if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet + id_origin.param_setValue(lpeitem->getRepr()->attribute("id")); + id_origin.write_to_SVG(); + } } Geom::PathVector LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) { + if (split_items && !fuse_paths) { + return path_in; + } Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); Geom::PathVector path_out; @@ -214,15 +395,51 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) Geom::Line line_separation((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (line_separation.vector(), (Geom::Point)start_point); - - if (fuse_paths && !discard_orig_path) { + if (split_items && fuse_paths) { + Geom::OptRect bbox = sp_lpe_item->geometricBounds(); + Geom::Path p(Geom::Point(bbox->left(), bbox->top())); + p.appendNew(Geom::Point(bbox->right(), bbox->top())); + p.appendNew(Geom::Point(bbox->right(), bbox->bottom())); + p.appendNew(Geom::Point(bbox->left(), bbox->bottom())); + p.appendNew(Geom::Point(bbox->left(), bbox->top())); + p.close(); + p *= Geom::Translate(bbox->midpoint()).inverse(); + p *= Geom::Scale(1.2); + p *= Geom::Rotate(line_separation.angle()); + p *= Geom::Translate(bbox->midpoint()); + bbox = p.boundsFast(); + p.clear(); + p.start(Geom::Point(bbox->left(), bbox->top())); + p.appendNew(Geom::Point(bbox->right(), bbox->top())); + p.appendNew(Geom::Point(bbox->right(), bbox->bottom())); + p.appendNew(Geom::Point(bbox->left(), bbox->bottom())); + p.appendNew(Geom::Point(bbox->left(), bbox->top())); + p.close(); + p *= Geom::Translate(bbox->midpoint()).inverse(); + p *= Geom::Rotate(line_separation.angle()); + p *= Geom::Translate(bbox->midpoint()); + Geom::Point base(p.pointAt(3)); + if (oposite_fuse) { + base = p.pointAt(0); + } + p *= Geom::Translate(line_separation.pointAt(line_separation.nearestTime(base)) - base); + Geom::PathVector pv_bbox; + pv_bbox.push_back(p); + Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(pv_bbox, original_pathv); + if (pig && !original_pathv.empty() && !pv_bbox.empty()) { + path_out = pig->getBminusA(); + } + Geom::Point dir = rot90(unit_vector((Geom::Point)end_point - (Geom::Point)start_point)); + Geom::Point gap = dir * split_gap; + path_out *= Geom::Translate(gap); + } else if (fuse_paths && !discard_orig_path) { for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()) { continue; } - Geom::PathVector tmp_path; + Geom::PathVector tmp_pathvector; double time_start = 0.0; int position = 0; bool end_open = false; @@ -268,11 +485,11 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) Geom::Path mirror = portion.reversed() * m; mirror.setInitial(portion.finalPoint()); portion.append(mirror); - if(i!=0) { + if(i != 0) { portion.setFinal(portion.initialPoint()); portion.close(); } - tmp_path.push_back(portion); + tmp_pathvector.push_back(portion); } portion.clear(); } @@ -293,36 +510,33 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) portion.append(mirror); portion = portion.reversed(); if (!original.closed()) { - tmp_path.push_back(portion); + tmp_pathvector.push_back(portion); } else { - if (cs.size() > 1 && tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { - portion.setFinal(tmp_path[0].initialPoint()); - portion.setInitial(tmp_path[0].finalPoint()); - tmp_path[0].append(portion); + if (cs.size() > 1 && tmp_pathvector.size() > 0 && tmp_pathvector[0].size() > 0 ) { + portion.setFinal(tmp_pathvector[0].initialPoint()); + portion.setInitial(tmp_pathvector[0].finalPoint()); + tmp_pathvector[0].append(portion); } else { - tmp_path.push_back(portion); + tmp_pathvector.push_back(portion); } - tmp_path[0].close(); + tmp_pathvector[0].close(); } portion.clear(); } } } if (cs.size() == 0 && position == 1) { - tmp_path.push_back(original); - tmp_path.push_back(original * m); + tmp_pathvector.push_back(original); + tmp_pathvector.push_back(original * m); } - path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); - tmp_path.clear(); + path_out.insert(path_out.end(), tmp_pathvector.begin(), tmp_pathvector.end()); + tmp_pathvector.clear(); } - } - - if (!fuse_paths || discard_orig_path) { + } else if (!fuse_paths || discard_orig_path) { for (size_t i = 0; i < original_pathv.size(); ++i) { path_out.push_back(original_pathv[i] * m); } } - return path_out; } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index b4967173a..592a11894 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -18,8 +18,8 @@ #include "live_effects/effect.h" #include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" -#include "live_effects/parameter/path.h" #include "live_effects/parameter/enum.h" #include "live_effects/lpegroupbbox.h" @@ -41,23 +41,32 @@ public: virtual ~LPEMirrorSymmetry(); virtual void doOnApply (SPLPEItem const* lpeitem); virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doAfterEffect (SPLPEItem const* lpeitem); virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); + virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); + virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); + void toMirror(Geom::Affine transform); + // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); + void cloneD(SPObject *origin, SPObject *dest, bool live, bool root); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: EnumParam mode; + ScalarParam split_gap; BoolParam discard_orig_path; BoolParam fuse_paths; BoolParam oposite_fuse; + BoolParam split_items; PointParam start_point; PointParam end_point; PointParam center_point; + TextParam id_origin; Geom::Point previous_center; - + SPObject * container; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); }; diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index af99ef362..813c06b4e 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -72,7 +72,7 @@ BoolParam::param_newWidget() checkwdg->setActive(value); checkwdg->setProgrammatically = false; checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change bool parameter")); - + param_effect->upd_params = false; return dynamic_cast (checkwdg); } else { return NULL; @@ -82,6 +82,7 @@ BoolParam::param_newWidget() void BoolParam::param_setValue(bool newvalue) { + param_effect->upd_params = true; value = newvalue; } diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 8cab68ad0..5c4cdf4c6 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -125,13 +125,14 @@ TextParam::param_newWidget() rsu->setProgrammatically = false; rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change text parameter")); - + param_effect->upd_params = false; return dynamic_cast (rsu); } void TextParam::param_setValue(const Glib::ustring newvalue) { + param_effect->upd_params = true; value = newvalue; if (!_hide_canvas_text) { sp_canvastext_set_text (canvas_text, newvalue.c_str()); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 7b2507b5e..f2c0d2f2c 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -925,6 +925,15 @@ void SPGroup::update_patheffect(bool write) { } sp_group_perform_patheffect(this, this, write); + + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + + if (lpeobj && lpeobj->get_lpe()) { + lpeobj->get_lpe()->doAfterEffect(this); + } + } } } @@ -950,25 +959,35 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) } else { c = subShape->getCurve(); } - + bool success = false; // only run LPEs when the shape has a curve defined if (c) { c->transform(i2anc_affine(subitem, topgroup)); - topgroup->performPathEffect(c); + success = topgroup->performPathEffect(c, subShape); c->transform(i2anc_affine(subitem, topgroup).inverse()); - subShape->setCurve(c, TRUE); - - if (write) { - Inkscape::XML::Node *repr = subitem->getRepr(); - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); + Inkscape::XML::Node *repr = subitem->getRepr(); + if (c && success) { + subShape->setCurve(c, TRUE); + if (write) { + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); #ifdef GROUP_VERBOSE - g_message("sp_group_perform_patheffect writes 'd' attribute"); + g_message("sp_group_perform_patheffect writes 'd' attribute"); #endif - g_free(str); + g_free(str); + } + c->unref(); + } else { + // LPE was unsuccesfull or doeffect stack return null. Read the old 'd'-attribute. + if (gchar const * value = repr->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); + if (oldcurve) { + subShape->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } } - - c->unref(); } } } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index e2f61bfb5..00671b936 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -24,6 +24,8 @@ #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" #include "live_effects/lpe-measure-line.h" +#include "live_effects/lpe-mirror_symmetry.h" +#include "live_effects/lpe-copy_rotate.h" #include "sp-path.h" #include "sp-item-group.h" @@ -126,7 +128,10 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { if (!value) { LivePathEffectObject *lpeobj = (*it)->lpeobject; Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); - if (dynamic_cast(lpe)){ + if (dynamic_cast(lpe) || + dynamic_cast(lpe) || + dynamic_cast(lpe) ) + { lpe->doOnRemove(this); } } @@ -209,7 +214,7 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { +bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { if (!curve) { return false; @@ -241,12 +246,15 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { } if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { // Groups have their doBeforeEffect called elsewhere + if (current) { + lpe->setCurrentShape(current); + } if (!SP_IS_GROUP(this)) { lpe->doBeforeEffect_impl(this); } try { - lpe->doEffect(curve); + lpe->doEffect(curve); } catch (std::exception & e) { g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); @@ -257,6 +265,8 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { return false; } if (!SP_IS_GROUP(this)) { + lpe->pathvector_before_effect = curve->get_pathvector(); + lpe->sp_curve->set_pathvector(lpe->pathvector_before_effect); lpe->doAfterEffect(this); } } @@ -604,7 +614,7 @@ bool SPLPEItem::hasPathEffect() const return true; } -bool SPLPEItem::hasPathEffectOfType(int const type) const +bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const { if (path_effect_list->empty()) { return false; @@ -616,7 +626,9 @@ bool SPLPEItem::hasPathEffectOfType(int const type) const if (lpeobj) { Inkscape::LivePathEffect::Effect const* lpe = lpeobj->get_lpe(); if (lpe && (lpe->effectType() == type)) { - return true; + if (is_ready || lpe->isReady()) { + return true; + } } } } @@ -695,10 +707,10 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) try { if(SP_IS_GROUP(this)){ c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(c, true); + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); } else { - success = this->performPathEffect(c, true); + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -709,12 +721,13 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) success = false; } Inkscape::XML::Node *repr = clip_mask->getRepr(); - if (success) { + // This c check allow to not apply LPE if curve is NULL after performPathEffect used in clone.obgets LPE + if (success && c) { gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); g_free(str); } else { - // LPE was unsuccesfull. Read the old 'd'-attribute. + // LPE was unsuccesfull or doeffect stack return null.. Read the old 'd'-attribute. if (gchar const * value = repr->attribute("d")) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); @@ -724,7 +737,9 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) } } } - c->unref(); + if (c) { + c->unref(); + } } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 9e5cb3329..0f198c49c 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -23,6 +23,7 @@ class LivePathEffectObject; class SPCurve; +class SPShape; class SPDesktop; namespace Inkscape{ @@ -69,11 +70,11 @@ public: virtual void update_patheffect(bool write); - bool performPathEffect(SPCurve *curve, bool is_clip_or_mask = false); + bool performPathEffect(SPCurve *curve, SPShape *current = NULL, bool is_clip_or_mask = false); bool pathEffectsEnabled() const; bool hasPathEffect() const; - bool hasPathEffectOfType(int const type) const; + bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 75f4657ef..0dc301c49 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -775,6 +775,21 @@ void SPObject::appendChild(Inkscape::XML::Node *child) { repr->appendChild(child); } +SPObject* SPObject::nthChild(unsigned index) { + g_assert(this->repr); + if (hasChildren()) { + std::vector l; + unsigned counter = 0; + for (auto& child: children) { + if (counter == index) { + return &child; + } + counter++; + } + } + return NULL; +} + void SPObject::addChild(Inkscape::XML::Node *child, Inkscape::XML::Node * prev) { g_assert(this->repr); diff --git a/src/sp-object.h b/src/sp-object.h index 9abbd324b..d145e966b 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -318,6 +318,9 @@ public: SPObject *lastChild() { return children.empty() ? nullptr : &children.back(); } SPObject const *lastChild() const { return children.empty() ? nullptr : &children.back(); } + SPObject *nthChild(unsigned index); + SPObject const *nthChild(unsigned index) const; + enum Action { ActionGeneral, ActionBBox, ActionUpdate, ActionShow }; /** diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 6c69f3463..b593b7937 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -289,23 +289,10 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { if (!_curve) { // 0 nodes, nothing to transform return Geom::identity(); } - // Adjust stroke - this->adjust_stroke(transform.descrim()); - - // Adjust pattern fill - this->adjust_pattern(transform); - - // Adjust gradient fill - this->adjust_gradient(transform); - - // Adjust LPE - this->adjust_livepatheffect(transform); // Transform the original-d path if this is a valid LPE this, other else the (ordinary) path if (_curve_before_lpe && hasPathEffectRecursive()) { - if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) || - this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH)) - { + if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) || this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH)) { // if path has the CLONE_ORIGINAL LPE applied, don't write the transform to the pathdata, but write it 'unoptimized' // also if the effect is type BEND PATH to fix bug #179842 return transform; @@ -316,6 +303,18 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { _curve->transform(transform); } + // Adjust stroke + this->adjust_stroke(transform.descrim()); + + // Adjust pattern fill + this->adjust_pattern(transform); + + // Adjust gradient fill + this->adjust_gradient(transform); + + // Adjust LPE + this->adjust_livepatheffect(transform); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); // nothing remains - we've written all of the transform, so return identity @@ -355,9 +354,9 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); if (gchar const * value = repr->attribute("d")) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new SPCurve(pv); + if (oldcurve) { - this->setCurveInsync(oldcurve, TRUE); - repr->setAttribute("d", value); + this->setCurve(oldcurve, TRUE); oldcurve->unref(); } } diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp index c51881a96..9485b6ba3 100644 --- a/src/ui/dialog/polar-arrange-tab.cpp +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -43,14 +43,14 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) anchorPointLabel.set_alignment(Gtk::ALIGN_START); pack_start(anchorPointLabel, false, false); - anchorBoundingBoxRadio.set_label(C_("Polar arrange tab", "Object's bounding box:")); + anchorBoundingBoxRadio.set_label(C_("Polar arrange tab", "Objects' bounding boxes:")); anchorRadioGroup = anchorBoundingBoxRadio.get_group(); anchorBoundingBoxRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_anchor_radio_changed)); pack_start(anchorBoundingBoxRadio, false, false); pack_start(anchorSelector, false, false); - anchorObjectPivotRadio.set_label(C_("Polar arrange tab", "Object's rotational center")); + anchorObjectPivotRadio.set_label(C_("Polar arrange tab", "Objects' rotational centers")); anchorObjectPivotRadio.set_group(anchorRadioGroup); anchorObjectPivotRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_anchor_radio_changed)); pack_start(anchorObjectPivotRadio, false, false); -- cgit v1.2.3 From 3867766478056535d7d22e5afd432ca670d9a73f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 24 Jan 2017 10:44:10 +0100 Subject: Fixing update to trunk (bzr r15356.1.20) --- src/live_effects/CMakeLists.txt | 6 + src/live_effects/parameter/item-reference.cpp | 44 +++++ src/live_effects/parameter/item-reference.h | 56 ++++++ src/live_effects/parameter/item.cpp | 246 ++++++++++++++++++++++++++ src/live_effects/parameter/item.h | 79 +++++++++ src/live_effects/parameter/originalitem.cpp | 129 ++++++++++++++ src/live_effects/parameter/originalitem.h | 49 +++++ 7 files changed, 609 insertions(+) create mode 100644 src/live_effects/parameter/item-reference.cpp create mode 100644 src/live_effects/parameter/item-reference.h create mode 100644 src/live_effects/parameter/item.cpp create mode 100644 src/live_effects/parameter/item.h create mode 100644 src/live_effects/parameter/originalitem.cpp create mode 100644 src/live_effects/parameter/originalitem.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 784317090..5ffccc7c0 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -60,6 +60,9 @@ set(live_effects_SRC parameter/array.cpp parameter/bool.cpp parameter/filletchamferpointarray.cpp + parameter/item-reference.cpp + parameter/item.cpp + parameter/originalitem.cpp parameter/originalpath.cpp parameter/originalpatharray.cpp parameter/parameter.cpp @@ -142,6 +145,9 @@ set(live_effects_SRC parameter/bool.h parameter/enum.h parameter/filletchamferpointarray.h + parameter/item.h + parameter/item-reference.h + parameter/originalitem.h parameter/originalpath.h parameter/originalpatharray.h parameter/parameter.h diff --git a/src/live_effects/parameter/item-reference.cpp b/src/live_effects/parameter/item-reference.cpp new file mode 100644 index 000000000..a775d93b7 --- /dev/null +++ b/src/live_effects/parameter/item-reference.cpp @@ -0,0 +1,44 @@ +/* + * The reference corresponding to href of LPE Item parameter. + * + * Copyright (C) 2008 Johan Engelen + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include "live_effects/parameter/item-reference.h" + +#include "sp-shape.h" +#include "sp-text.h" +#include "sp-item-group.h" + +namespace Inkscape { +namespace LivePathEffect { + +bool ItemReference::_acceptObject(SPObject * const obj) const +{ + if (SP_IS_SHAPE(obj) || SP_IS_TEXT(obj) || SP_IS_GROUP(obj)) { + /* Refuse references to lpeobject */ + if (obj == getOwner()) { + return false; + } + // TODO: check whether the referred item has this LPE applied, if so: deny deny deny! + return URIReference::_acceptObject(obj); + } else { + return false; + } +} + +} // namespace LivePathEffect +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/item-reference.h b/src/live_effects/parameter/item-reference.h new file mode 100644 index 000000000..91231455a --- /dev/null +++ b/src/live_effects/parameter/item-reference.h @@ -0,0 +1,56 @@ +#ifndef SEEN_LPE_ITEM_REFERENCE_H +#define SEEN_LPE_ITEM_REFERENCE_H + +/* + * Copyright (C) 2008-2012 Authors + * Authors: Johan Engelen + * Abhishek Sharma + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include + +class SPItem; +namespace Inkscape { +namespace XML { class Node; } + +namespace LivePathEffect { + +/** + * The reference corresponding to href of LPE ItemParam. + */ +class ItemReference : public Inkscape::URIReference { +public: + ItemReference(SPObject *owner) : URIReference(owner) {} + + SPItem *getObject() const { + return (SPItem *)URIReference::getObject(); + } + +protected: + virtual bool _acceptObject(SPObject * const obj) const; + +private: + ItemReference(const ItemReference&); + ItemReference& operator=(const ItemReference&); +}; + +} // namespace LivePathEffect + +} // namespace Inkscape + + + +#endif /* !SEEN_LPE_PATH_REFERENCE_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/item.cpp b/src/live_effects/parameter/item.cpp new file mode 100644 index 000000000..8caea4e26 --- /dev/null +++ b/src/live_effects/parameter/item.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (C) Johan Engelen 2007 + * Abhishek Sharma + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "ui/widget/point.h" +#include + +#include "live_effects/parameter/item.h" +#include "live_effects/effect.h" +#include "svg/svg.h" + +#include "widgets/icon.h" +#include +#include "selection-chemistry.h" +#include "xml/repr.h" +#include "desktop.h" +#include "inkscape.h" +#include "message-stack.h" + +// clipboard support +#include "ui/clipboard.h" +// required for linking to other paths +#include "uri.h" + +#include +#include +#include "ui/icon-names.h" + +namespace Inkscape { + +namespace LivePathEffect { + +ItemParam::ItemParam( const Glib::ustring& label, const Glib::ustring& tip, + const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, + Effect* effect, const gchar * default_value) + : Parameter(label, tip, key, wr, effect), + changed(true), + href(NULL), + ref( (SPObject*)effect->getLPEObj() ) +{ + defvalue = g_strdup(default_value); + ref_changed_connection = ref.changedSignal().connect(sigc::mem_fun(*this, &ItemParam::ref_changed)); +} + +ItemParam::~ItemParam() +{ + remove_link(); + g_free(defvalue); +} + +void +ItemParam::param_set_default() +{ + param_readSVGValue(defvalue); +} + + +void +ItemParam::param_set_and_write_default() +{ + param_write_to_repr(defvalue); +} + +bool +ItemParam::param_readSVGValue(const gchar * strvalue) +{ + if (strvalue) { + remove_link(); + if (strvalue[0] == '#') { + if (href) + g_free(href); + href = g_strdup(strvalue); + try { + ref.attach(Inkscape::URI(href)); + //lp:1299948 + SPItem* i = ref.getObject(); + if (i) { + linked_modified_callback(i, SP_OBJECT_MODIFIED_FLAG); + } // else: document still processing new events. Repr of the linked object not created yet. + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + ref.detach(); + } + } + emit_changed(); + return true; + } + + return false; +} + +gchar * +ItemParam::param_getSVGValue() const +{ + return g_strdup(href); +} + +Gtk::Widget * +ItemParam::param_newWidget() +{ + Gtk::HBox * _widget = Gtk::manage(new Gtk::HBox()); + Gtk::Widget* pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-clone"), Inkscape::ICON_SIZE_BUTTON) ); + Gtk::Button * pButton = Gtk::manage(new Gtk::Button()); + Gtk::Label* pLabel = Gtk::manage(new Gtk::Label(param_label)); + static_cast(_widget)->pack_start(*pLabel, true, true); + pLabel->set_tooltip_text(param_tooltip); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &ItemParam::on_link_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Link to item on clipboard")); + + static_cast(_widget)->show_all_children(); + + return dynamic_cast (_widget); +} + +void +ItemParam::emit_changed() +{ + changed = true; + signal_item_changed.emit(); +} + + +void +ItemParam::addCanvasIndicators(SPLPEItem const*/*lpeitem*/, std::vector &hp_vec) +{ +} + + +void +ItemParam::start_listening(SPObject * to) +{ + if ( to == NULL ) { + return; + } + linked_delete_connection = to->connectDelete(sigc::mem_fun(*this, &ItemParam::linked_delete)); + linked_modified_connection = to->connectModified(sigc::mem_fun(*this, &ItemParam::linked_modified)); + if (SP_IS_ITEM(to)) { + linked_transformed_connection = SP_ITEM(to)->connectTransformed(sigc::mem_fun(*this, &ItemParam::linked_transformed)); + } + linked_modified(to, SP_OBJECT_MODIFIED_FLAG); // simulate linked_modified signal, so that path data is updated +} + +void +ItemParam::quit_listening(void) +{ + linked_modified_connection.disconnect(); + linked_delete_connection.disconnect(); + linked_transformed_connection.disconnect(); +} + +void +ItemParam::ref_changed(SPObject */*old_ref*/, SPObject *new_ref) +{ + quit_listening(); + if ( new_ref ) { + start_listening(new_ref); + } +} + +void +ItemParam::remove_link() +{ + if (href) { + ref.detach(); + g_free(href); + href = NULL; + } +} + +void +ItemParam::linked_delete(SPObject */*deleted*/) +{ + quit_listening(); + remove_link(); +} + +void ItemParam::linked_modified(SPObject *linked_obj, guint flags) +{ + linked_modified_callback(linked_obj, flags); +} + +void ItemParam::linked_transformed(Geom::Affine const *rel_transf, SPItem *moved_item) +{ + linked_transformed_callback(rel_transf, moved_item); +} + +void +ItemParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) +{ + emit_changed(); + SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +void +ItemParam::on_link_button_click() +{ + Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); + const gchar * iid = cm->getFirstObjectID(); + if (!iid) { + return; + } + + Glib::ustring itemid(iid); + + if (itemid.empty()) { + return; + } + + // add '#' at start to make it an uri. + itemid.insert(itemid.begin(), '#'); + if ( href && strcmp(itemid.c_str(), href) == 0 ) { + // no change, do nothing + return; + } else { + // TODO: + // check if id really exists in document, or only in clipboard document: if only in clipboard then invalid + // check if linking to object to which LPE is applied (maybe delegated to PathReference + + param_write_to_repr(itemid.c_str()); + DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Link item parameter to path")); + } +} + +} /* namespace LivePathEffect */ + +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/item.h b/src/live_effects/parameter/item.h new file mode 100644 index 000000000..6c719d451 --- /dev/null +++ b/src/live_effects/parameter/item.h @@ -0,0 +1,79 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_ITEM_H +#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_ITEM_H + +/* + * Inkscape::LivePathEffectParameters + * +* Copyright (C) Johan Engelen 2007 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + + +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/item-reference.h" +#include +#include + +namespace Inkscape { + +namespace LivePathEffect { + +class ItemParam : public Parameter { +public: + ItemParam ( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect, + const gchar * default_value = ""); + virtual ~ItemParam(); + virtual Gtk::Widget * param_newWidget(); + + virtual bool param_readSVGValue(const gchar * strvalue); + virtual gchar * param_getSVGValue() const; + + virtual void param_set_default(); + void param_set_and_write_default(); + virtual void addCanvasIndicators(SPLPEItem const* lpeitem, std::vector &hp_vec); + + sigc::signal signal_item_pasted; + sigc::signal signal_item_changed; + bool changed; /* this gets set whenever the path is changed (this is set to true, and then the signal_item_changed signal is emitted). + * the user must set it back to false if she wants to use it sensibly */ +protected: + + gchar * href; // contains link to other object, e.g. "#path2428", NULL if ItemParam contains pathdata itself + ItemReference ref; + sigc::connection ref_changed_connection; + sigc::connection linked_delete_connection; + sigc::connection linked_modified_connection; + sigc::connection linked_transformed_connection; + void ref_changed(SPObject *old_ref, SPObject *new_ref); + void remove_link(); + void start_listening(SPObject * to); + void quit_listening(void); + void linked_delete(SPObject *deleted); + void linked_modified(SPObject *linked_obj, guint flags); + void linked_transformed(Geom::Affine const *rel_transf, SPItem *moved_item); + virtual void linked_modified_callback(SPObject *linked_obj, guint flags); + virtual void linked_transformed_callback(Geom::Affine const * /*rel_transf*/, SPItem * /*moved_item*/) {}; + void on_link_button_click(); + + void emit_changed(); + + gchar * defvalue; + +private: + ItemParam(const ItemParam&); + ItemParam& operator=(const ItemParam&); +}; + + +} //namespace LivePathEffect + +} //namespace Inkscape + +#endif diff --git a/src/live_effects/parameter/originalitem.cpp b/src/live_effects/parameter/originalitem.cpp new file mode 100644 index 000000000..053062128 --- /dev/null +++ b/src/live_effects/parameter/originalitem.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) Johan Engelen 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "live_effects/parameter/originalitem.h" + +#include "widgets/icon.h" +#include +#include +#include + +#include "uri.h" +#include "sp-shape.h" +#include "sp-text.h" +#include "display/curve.h" +#include "live_effects/effect.h" + +#include "inkscape.h" +#include "desktop.h" +#include "selection.h" +#include "ui/icon-names.h" + +namespace Inkscape { + +namespace LivePathEffect { + +OriginalItemParam::OriginalItemParam( const Glib::ustring& label, const Glib::ustring& tip, + const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, + Effect* effect) + : ItemParam(label, tip, key, wr, effect, "") +{ +} + +OriginalItemParam::~OriginalItemParam() +{ + +} + +Gtk::Widget * +OriginalItemParam::param_newWidget() +{ + Gtk::HBox *_widget = Gtk::manage(new Gtk::HBox()); + + { // Label + Gtk::Label *pLabel = Gtk::manage(new Gtk::Label(param_label)); + static_cast(_widget)->pack_start(*pLabel, true, true); + pLabel->set_tooltip_text(param_tooltip); + } + + { // Paste item to link button + Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-paste"), Inkscape::ICON_SIZE_BUTTON) ); + Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalItemParam::on_link_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Link to item")); + } + + { // Select original button + Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon("edit-select-original", Inkscape::ICON_SIZE_BUTTON) ); + Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalItemParam::on_select_original_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Select original")); + } + + static_cast(_widget)->show_all_children(); + + return dynamic_cast (_widget); +} + +void +OriginalItemParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) +{ + if (!inverse) { + emit_changed(); + SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); + } +} + +void +OriginalItemParam::linked_transformed_callback(Geom::Affine const * /*rel_transf*/, SPItem * /*moved_item*/) +{ +/** \todo find good way to compensate for referenced item transform, like done for normal clones. + * See sp-use.cpp: sp_use_move_compensate */ +} + + +void +OriginalItemParam::on_select_original_button_click() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPItem *original = ref.getObject(); + if (desktop == NULL || original == NULL) { + return; + } + Inkscape::Selection *selection = desktop->getSelection(); + selection->clear(); + selection->set(original); +} + +} /* namespace LivePathEffect */ + +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/originalitem.h b/src/live_effects/parameter/originalitem.h new file mode 100644 index 000000000..58d04e05a --- /dev/null +++ b/src/live_effects/parameter/originalitem.h @@ -0,0 +1,49 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_ORIGINAL_ITEM_H +#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_ORIGINAL_ITEM_H + +/* + * Inkscape::LiveItemEffectParameters + * +* Copyright (C) Johan Engelen 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/parameter/item.h" + +namespace Inkscape { + +namespace LivePathEffect { + +class OriginalItemParam: public ItemParam { +public: + OriginalItemParam ( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect); + virtual ~OriginalItemParam(); + void setInverse(bool inversed) { inverse = inversed; } + bool linksToItem() const { return (href != NULL); } + SPItem * getObject() const { return ref.getObject(); } + + virtual Gtk::Widget * param_newWidget(); + +protected: + virtual void linked_modified_callback(SPObject *linked_obj, guint flags); + virtual void linked_transformed_callback(Geom::Affine const *rel_transf, SPItem *moved_item); + + void on_select_original_button_click(); + +private: + bool inverse; + OriginalItemParam(const OriginalItemParam&); + OriginalItemParam& operator=(const OriginalItemParam&); +}; + + +} //namespace LivePathEffect + +} //namespace Inkscape + +#endif -- cgit v1.2.3 From 7b1f640dd11a7580f04ae50d2c0d7d62e301d9d7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 24 Jan 2017 12:00:13 +0100 Subject: Fix for bug on clone original LPE (bzr r15442) --- src/live_effects/lpe-clone-original.cpp | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index db697552a..31d5bab65 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -26,7 +26,7 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : preserve_position(_("Preserve position"), _("Preserve position"), "preserve_position", &wr, this, false), inverse(_("Inverse clone"), _("Use LPE item as origin"), "inverse", &wr, this, false), d(_("Clone shape -d-"), _("Clone shape -d-"), "d", &wr, this, true), - transform(_("Clone transforms"), _("Clone transforms"), "d", &wr, this, true), + transform(_("Clone transforms"), _("Clone transforms"), "transform", &wr, this, true), fill(_("Clone fill"), _("Clone fill"), "fill", &wr, this, false), stroke(_("Clone stroke"), _("Clone stroke"), "stroke", &wr, this, false), paintorder(_("Clone paint order"), _("Clone paint order"), "paintorder", &wr, this, false), @@ -59,20 +59,6 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) : preserve_affine = Geom::identity(); } -bool hasLinkedTransform( const char * attributes) { - gchar ** attarray = g_strsplit(attributes, ",", 0); - gchar ** iter = attarray; - bool has_linked_transform = false; - while (*iter != NULL) { - const char* attribute = (*iter); - if ( std::strcmp(attribute, "transform") == 0 ) { - has_linked_transform = true; - } - iter++; - } - return has_linked_transform; -} - void LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes, bool root) { @@ -237,14 +223,18 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ } preserve_position_changed = preserve_position; } - Glib::ustring attr = Glib::ustring(attributes.param_getSVGValue()).append(","); + Glib::ustring attr = ""; if (d) { attr.append("d,"); } if (transform) { attr.append("transform,"); } - Glib::ustring style_attr = Glib::ustring(style_attributes.param_getSVGValue()).append(","); + attr.append(Glib::ustring(attributes.param_getSVGValue()).append(",")); + if (attr.size() && !Glib::ustring(attributes.param_getSVGValue()).size()) { + attr.erase (attr.size()-1, 1); + } + Glib::ustring style_attr = ""; if (fill) { style_attr.append("fill,").append("fill-rule,"); } @@ -263,6 +253,10 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ if (opacity) { style_attr.append("opacity,"); } + if (style_attr.size() && !Glib::ustring(style_attributes.param_getSVGValue()).size()) { + style_attr.erase (style_attr.size()-1, 1); + } + style_attr.append(Glib::ustring(style_attributes.param_getSVGValue()).append(",")); if (inverse) { cloneAttrbutes(SP_OBJECT(sp_lpe_item), linked_item.getObject(), true, g_strdup(attr.c_str()), g_strdup(style_attr.c_str()), true); } else { -- cgit v1.2.3 From 0b1d6a94ad7b8caf7bc9bf7ef7c87ef7bad9ac43 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 24 Jan 2017 12:28:51 +0100 Subject: Fix a translation bug in rotate copies LPE (bzr r15443) --- src/live_effects/lpe-copy_rotate.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index fbc7933e7..42e055062 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -604,8 +604,7 @@ LPECopyRotate::doEffect_path (Geom::PathVector const & path_in) Geom::Affine r = Geom::identity(); Geom::Point dir = unit_vector(Geom::middle_point(line_start,line_end) - (Geom::Point)origin); Geom::Point gap = dir * split_gap; - r *= Geom::Translate(gap); - path_out *= r; + path_out *= Geom::Translate(gap); } else { // default behavior for (unsigned int i=0; i < path_in.size(); i++) { -- cgit v1.2.3 From 632c205171ef6734d166ed39b61e10a2b1566bf3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 25 Jan 2017 10:14:59 +0100 Subject: Comented one of the shortcuts for doc rotate because bad response now interactive mode onlu fire with CTRL+MMB (bzr r15445) --- src/ui/tools/tool-base.cpp | 32 ++++++++++++++++---------------- src/widgets/desktop-widget.cpp | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index ca700f652..aab256712 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -732,13 +732,13 @@ bool ToolBase::root_handler(GdkEvent* event) { break; case GDK_KEY_space: - if (event->key.state & GDK_CONTROL_MASK) { - sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); - desktop->canvas->startRotateTo(desktop->namedview->document_rotation); - this->rotating_mode = true; - this->message_context->set(Inkscape::INFORMATION_MESSAGE, - _("Space+mouse move to rotate canvas, use modifiers on screen to change snaps")); - } else { +// if (event->key.state & GDK_CONTROL_MASK) { +// sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); +// desktop->canvas->startRotateTo(desktop->namedview->document_rotation); +// this->rotating_mode = true; +// this->message_context->set(Inkscape::INFORMATION_MESSAGE, +// _("Space+mouse move to rotate canvas, use modifiers on screen to change snaps")); +// } else { within_tolerance = true; xp = yp = 0; if (!allow_panning) break; @@ -746,7 +746,7 @@ bool ToolBase::root_handler(GdkEvent* event) { this->space_panning = true; this->message_context->set(Inkscape::INFORMATION_MESSAGE, _("Space+mouse move to pan canvas")); - } +// } ret = TRUE; break; @@ -805,14 +805,14 @@ bool ToolBase::root_handler(GdkEvent* event) { switch (get_group0_keyval(&event->key)) { case GDK_KEY_space: - if (this->rotating_mode) { - desktop->canvas->clearRotateTo(); - this->rotating_mode = false; - ret = TRUE; - if (desktop->canvas->endRotateTo()) { - sp_repr_set_svg_double(desktop->namedview->getRepr(), "inkscape:document-rotation", angle); - } - } +// if (this->rotating_mode) { +// desktop->canvas->clearRotateTo(); +// this->rotating_mode = false; +// ret = TRUE; +// if (desktop->canvas->endRotateTo()) { +// sp_repr_set_svg_double(desktop->namedview->getRepr(), "inkscape:document-rotation", angle); +// } +// } if (within_tolerance) { // Space was pressed, but not panned sp_toggle_selector(desktop); diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 8dddb40eb..f0d0541c2 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -614,7 +614,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) // Rotate status spinbutton dtw->rotation_status = gtk_spin_button_new_with_range (-360.0,360.0, 1.0); - gtk_widget_set_tooltip_text (dtw->rotation_status, _("Rotation. Can be interactive with CTRL+SPACEBAR or CTRL+MMB")); + gtk_widget_set_tooltip_text (dtw->rotation_status, _("Rotation. Can be interactive with CTRL+MMB")); gtk_widget_set_size_request (dtw->rotation_status, STATUS_ROTATION_WIDTH, -1); gtk_entry_set_width_chars (GTK_ENTRY (dtw->rotation_status), 7); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dtw->rotation_status), FALSE); -- cgit v1.2.3