Merge lp:~inkscape.dev/inkscape/lattice2 into lp:~inkscape.dev/inkscape/trunk

Proposed by Jabiertxof
Status: Merged
Approved by: Jabiertxof
Approved revision: 12762
Merge reported by: su_v
Merged at revision: not available
Proposed branch: lp:~inkscape.dev/inkscape/lattice2
Merge into: lp:~inkscape.dev/inkscape/trunk
Diff against target: 1143 lines (+941/-6)
12 files modified
po/POTFILES.skip (+1/-0)
src/live_effects/Makefile_insert (+2/-0)
src/live_effects/effect-enum.h (+1/-0)
src/live_effects/effect.cpp (+16/-2)
src/live_effects/lpe-lattice.h (+0/-1)
src/live_effects/lpe-lattice2.cpp (+496/-0)
src/live_effects/lpe-lattice2.h (+92/-0)
src/live_effects/parameter/Makefile_insert (+2/-0)
src/live_effects/parameter/pointreseteable.cpp (+210/-0)
src/live_effects/parameter/pointreseteable.h (+74/-0)
src/ui/tools/node-tool.cpp (+45/-3)
src/ui/tools/node-tool.h (+2/-0)
To merge this branch: bzr merge lp:~inkscape.dev/inkscape/lattice2
Reviewer Review Type Date Requested Status
Martin Owens code Approve
Jabiertxof Needs Resubmitting
Review via email: mp+195889@code.launchpad.net

Description of the change

It improve lattice to a new live effet lattice 2, add the knots visibles on groups and make the helper paths show again

To post a comment you must log in.
lp:~inkscape.dev/inkscape/lattice2 updated
12742. By Jabiertxof <email address hidden>

update to trunk

12743. By Jabiertxof <email address hidden>

fixing update to trunk

12744. By Jabiertxof <email address hidden>

update to trunk

12745. By Jabiertxof <email address hidden>

update to trunk

12746. By Jabiertxof <email address hidden>

update to trunk

12747. By Jabiertxof <email address hidden>

update to trunk

Revision history for this message
Martin Owens (doctormo) wrote :

I've done a code review, but I need to have instructions about the testing proceedure. What it should do etc for a functional test.

Most of the code is good.

I'm unhappy about the lack of code reuse in lpe-lattice2.cpp/h there are so many grid points that all that code should be converted to using a vector or some kind and shortened. Normally this would be a nit-pick, but I believe the flatness in those files is bad enough to warrant a Needs Fixing.

review: Needs Fixing (code)
Revision history for this message
Martin Owens (doctormo) wrote :

On Fri, 2014-03-28 at 08:20 +0100, Jabiertxo Arraiza Cenoz wrote:
> There is a strange bug whith some groups that make necessary press
> reset
> grid at first step to show correct :(
>
> I'm going to change it to vector. Ping you when done.

Thanks for the quick reply Jabier.

The name presented to users is "Lattice Deformation 2", is this the best
description of what it does? how is this Lattice different from Lattice
Deformation 1?

Best Regards, Martin Owens

lp:~inkscape.dev/inkscape/lattice2 updated
12748. By Jabiertxof <email address hidden>

update to trunk

12749. By Jabiertxof <email address hidden>

update to trunk

12750. By root <email address hidden>

Refactor to simplify the code.

12751. By root <email address hidden>

update to trunk

Revision history for this message
Jabiertxof (jabiertxof) wrote :

> On Fri, 2014-03-28 at 08:20 +0100, Jabiertxo Arraiza Cenoz wrote:
> > There is a strange bug whith some groups that make necessary press
> > reset
> > grid at first step to show correct :(
> >
> > I'm going to change it to vector. Ping you when done.
>
> Thanks for the quick reply Jabier.
>
> The name presented to users is "Lattice Deformation 2", is this the best
> description of what it does? how is this Lattice different from Lattice
> Deformation 1?
>
> Best Regards, Martin Owens

Hi Martin, Think i respond to you but dont see here.
Latticce2 is the same of latticce with important changes and bugfixes. But the effect distorsion elements whith old lattice effect. I discuss whith suv about the name and finaly we select this, for the moment.

By the other way I refactor a lot the code but if need more, I need help moving the "PointReseteableParam" to an array,vector... because coulden`t inicializate the diferent
PointReseteableParam on constructor. But I spend a lot of time whith this and dont find another way than create a new pointparameter that handle points arrays.

TODO: add presets and collapse/expand to the pointparameter list

review: Needs Resubmitting
Revision history for this message
Jabiertxof (jabiertxof) wrote :

> On Fri, 2014-03-28 at 08:20 +0100, Jabiertxo Arraiza Cenoz wrote:
> > There is a strange bug whith some groups that make necessary press
> > reset
> > grid at first step to show correct :(

This bug is not related to lattice2: https://bugs.launchpad.net/inkscape/+bug/1299461

Revision history for this message
Martin Owens (doctormo) wrote :

OK, name is ok if it's been discussed before. Code will have to stand as is.

review: Approve (code)
lp:~inkscape.dev/inkscape/lattice2 updated
12752. By Jabiertxof <email address hidden>

update to knot changes

12753. By Jabiertxof <email address hidden>

Fixing redraw by Knot update

12754. By Jabiertxof <email address hidden>

update to trunk

12755. By Jabiertxof <email address hidden>

fix a bad applied patch to source

12756. By Jabiertxof <email address hidden>

removed extra var

12757. By Jabiertxof <email address hidden>

update to trunk

12758. By Jabiertxof <email address hidden>

Fix bug show by su_v in console execution

12759. By Jabiertxof <email address hidden>

update to trunk

12760. By Jabiertxof <email address hidden>

Removed unnecesary static var

12761. By Jabiertxof <email address hidden>

updates to helper paths

12762. By Jabiertxof <email address hidden>

update to trunk

Revision history for this message
su_v (suv-lp) wrote :

lattice2 was merged into experimental in r13355
http://bazaar.launchpad.net/~inkscape.dev/inkscape/experimental/revision/13355

experimental was merged into trunk in r13641
http://bazaar.launchpad.net/~inkscape.dev/inkscape/trunk/revision/13641

Changing status to 'Merged'.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'po/POTFILES.skip'
2--- po/POTFILES.skip 2010-01-14 08:13:09 +0000
3+++ po/POTFILES.skip 2014-05-13 06:54:02 +0000
4@@ -25,6 +25,7 @@
5 src/live_effects/lpe-tangent_to_curve.cpp
6 src/live_effects/lpe-test-doEffect-stack.cpp
7 src/live_effects/lpe-text_label.cpp
8+src/live_effects/lpe-lattice2.cpp
9 src/lpe-tool-context.cpp
10 src/ui/dialog/session-player.cpp
11 src/ui/dialog/whiteboard-connect.cpp
12
13=== modified file 'src/live_effects/Makefile_insert'
14--- src/live_effects/Makefile_insert 2012-03-23 21:02:03 +0000
15+++ src/live_effects/Makefile_insert 2014-05-13 06:54:02 +0000
16@@ -40,6 +40,8 @@
17 live_effects/lpe-test-doEffect-stack.h \
18 live_effects/lpe-lattice.cpp \
19 live_effects/lpe-lattice.h \
20+ live_effects/lpe-lattice2.cpp \
21+ live_effects/lpe-lattice2.h \
22 live_effects/lpe-envelope.cpp \
23 live_effects/lpe-envelope.h \
24 live_effects/lpe-spiro.cpp \
25
26=== modified file 'src/live_effects/effect-enum.h'
27--- src/live_effects/effect-enum.h 2012-01-12 21:06:16 +0000
28+++ src/live_effects/effect-enum.h 2014-05-13 06:54:02 +0000
29@@ -28,6 +28,7 @@
30 PERSPECTIVE_PATH,
31 SPIRO,
32 LATTICE,
33+ LATTICE2,
34 ENVELOPE,
35 CONSTRUCT_GRID,
36 PERP_BISECTOR,
37
38=== modified file 'src/live_effects/effect.cpp'
39--- src/live_effects/effect.cpp 2014-05-05 08:40:12 +0000
40+++ src/live_effects/effect.cpp 2014-05-13 06:54:02 +0000
41@@ -25,6 +25,7 @@
42 #include "live_effects/lpe-perspective_path.h"
43 #include "live_effects/lpe-spiro.h"
44 #include "live_effects/lpe-lattice.h"
45+#include "live_effects/lpe-lattice2.h"
46 #include "live_effects/lpe-envelope.h"
47 #include "live_effects/lpe-constructgrid.h"
48 #include "live_effects/lpe-perp_bisector.h"
49@@ -89,12 +90,12 @@
50 {CIRCLE_3PTS, N_("Circle by 3 points"), "circle_3pts"},
51 {DYNASTROKE, N_("Dynamic stroke"), "dynastroke"},
52 {EXTRUDE, N_("Extrude"), "extrude"},
53- {LATTICE, N_("Lattice Deformation"), "lattice"},
54 {LINE_SEGMENT, N_("Line Segment"), "line_segment"},
55 {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"},
56 {OFFSET, N_("Offset"), "offset"},
57 {PARALLEL, N_("Parallel"), "parallel"},
58 {PATH_LENGTH, N_("Path length"), "path_length"},
59+ {LATTICE, N_("Lattice Deformation"), "lattice"},
60 {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"},
61 {PERSPECTIVE_PATH, N_("Perspective path"), "perspective_path"},
62 {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"},
63@@ -120,6 +121,7 @@
64 /* 0.49 */
65 {POWERSTROKE, N_("Power stroke"), "powerstroke"},
66 {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"},
67+ {LATTICE2, N_("Lattice Deformation 2"), "lattice2"},
68 };
69 const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData));
70
71@@ -243,6 +245,9 @@
72 case CLONE_ORIGINAL:
73 neweffect = static_cast<Effect*> ( new LPECloneOriginal(lpeobj) );
74 break;
75+ case LATTICE2:
76+ neweffect = static_cast<Effect*> ( new LPELattice2(lpeobj) );
77+ break;
78 default:
79 g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr);
80 neweffect = NULL;
81@@ -496,7 +501,16 @@
82
83 if (!SP_IS_SHAPE(lpeitem)) {
84 // g_print ("How to handle helperpaths for non-shapes?\n"); // non-shapes are for example SPGroups.
85- return hp_vec;
86+// return hp_vec;
87+ }
88+
89+
90+ // TODO: we can probably optimize this by using a lot more references
91+ // rather than copying PathVectors all over the place
92+ if (SP_IS_SHAPE(lpeitem) && show_orig_path) {
93+ // add original path to helperpaths
94+ SPCurve* curve = SP_SHAPE(lpeitem)->getCurve ();
95+ hp_vec.push_back(curve->get_pathvector());
96 }
97
98 // add indicators provided by the effect itself
99
100=== modified file 'src/live_effects/lpe-lattice.h'
101--- src/live_effects/lpe-lattice.h 2014-03-27 01:33:44 +0000
102+++ src/live_effects/lpe-lattice.h 2014-05-13 06:54:02 +0000
103@@ -58,7 +58,6 @@
104 PointParam grid_point13;
105 PointParam grid_point14;
106 PointParam grid_point15;
107-
108 LPELattice(const LPELattice&);
109 LPELattice& operator=(const LPELattice&);
110 };
111
112=== added file 'src/live_effects/lpe-lattice2.cpp'
113--- src/live_effects/lpe-lattice2.cpp 1970-01-01 00:00:00 +0000
114+++ src/live_effects/lpe-lattice2.cpp 2014-05-13 06:54:02 +0000
115@@ -0,0 +1,496 @@
116+/** \file
117+ * LPE <lattice2> implementation
118+
119+ */
120+/*
121+ * Authors:
122+ * Johan Engelen <j.b.c.engelen@utwente.nl>
123+ * Steren Giannini
124+ * Noé Falzon
125+ * Victor Navez
126+ * ~suv
127+ * Jabiertxo Arraiza
128+*
129+* Copyright (C) 2007-2008 Authors
130+ *
131+ * Released under GNU GPL, read the file 'COPYING' for more information
132+ */
133+
134+#include "live_effects/lpe-lattice2.h"
135+
136+#include "sp-shape.h"
137+#include "sp-item.h"
138+#include "sp-path.h"
139+#include "display/curve.h"
140+#include "svg/svg.h"
141+
142+#include <2geom/sbasis.h>
143+#include <2geom/sbasis-2d.h>
144+#include <2geom/sbasis-geometric.h>
145+#include <2geom/bezier-to-sbasis.h>
146+#include <2geom/sbasis-to-bezier.h>
147+#include <2geom/d2.h>
148+#include <2geom/piecewise.h>
149+#include <2geom/transforms.h>
150+#include <tools-switch.h>
151+
152+#include "desktop.h" // TODO: should be factored out (see below)
153+
154+using namespace Geom;
155+
156+namespace Inkscape {
157+namespace LivePathEffect {
158+
159+LPELattice2::LPELattice2(LivePathEffectObject *lpeobject) :
160+ Effect(lpeobject),
161+ // initialise your parameters here:
162+ grid_point0(_("Control handle 0:"), _("Control handle 0 - Ctrl+Alt+Click to reset"), "gridpoint0", &wr, this),
163+ grid_point1(_("Control handle 1:"), _("Control handle 1 - Ctrl+Alt+Click to reset"), "gridpoint1", &wr, this),
164+ grid_point2(_("Control handle 2:"), _("Control handle 2 - Ctrl+Alt+Click to reset"), "gridpoint2", &wr, this),
165+ grid_point3(_("Control handle 3:"), _("Control handle 3 - Ctrl+Alt+Click to reset"), "gridpoint3", &wr, this),
166+ grid_point4(_("Control handle 4:"), _("Control handle 4 - Ctrl+Alt+Click to reset"), "gridpoint4", &wr, this),
167+ grid_point5(_("Control handle 5:"), _("Control handle 5 - Ctrl+Alt+Click to reset"), "gridpoint5", &wr, this),
168+ grid_point6(_("Control handle 6:"), _("Control handle 6 - Ctrl+Alt+Click to reset"), "gridpoint6", &wr, this),
169+ grid_point7(_("Control handle 7:"), _("Control handle 7 - Ctrl+Alt+Click to reset"), "gridpoint7", &wr, this),
170+ grid_point8x9(_("Control handle 8x9:"), _("Control handle 8x9 - Ctrl+Alt+Click to reset"), "gridpoint8x9", &wr, this),
171+ grid_point10x11(_("Control handle 10x11:"), _("Control handle 10x11 - Ctrl+Alt+Click to reset"), "gridpoint10x11", &wr, this),
172+ grid_point12(_("Control handle 12:"), _("Control handle 12 - Ctrl+Alt+Click to reset"), "gridpoint12", &wr, this),
173+ grid_point13(_("Control handle 13:"), _("Control handle 13 - Ctrl+Alt+Click to reset"), "gridpoint13", &wr, this),
174+ grid_point14(_("Control handle 14:"), _("Control handle 14 - Ctrl+Alt+Click to reset"), "gridpoint14", &wr, this),
175+ grid_point15(_("Control handle 15:"), _("Control handle 15 - Ctrl+Alt+Click to reset"), "gridpoint15", &wr, this),
176+ grid_point16(_("Control handle 16:"), _("Control handle 16 - Ctrl+Alt+Click to reset"), "gridpoint16", &wr, this),
177+ grid_point17(_("Control handle 17:"), _("Control handle 17 - Ctrl+Alt+Click to reset"), "gridpoint17", &wr, this),
178+ grid_point18(_("Control handle 18:"), _("Control handle 18 - Ctrl+Alt+Click to reset"), "gridpoint18", &wr, this),
179+ grid_point19(_("Control handle 19:"), _("Control handle 19 - Ctrl+Alt+Click to reset"), "gridpoint19", &wr, this),
180+ grid_point20x21(_("Control handle 20x21:"), _("Control handle 20x21 - Ctrl+Alt+Click to reset"), "gridpoint20x21", &wr, this),
181+ grid_point22x23(_("Control handle 22x23:"), _("Control handle 22x23 - Ctrl+Alt+Click to reset"), "gridpoint22x23", &wr, this),
182+ grid_point24x26(_("Control handle 24x26:"), _("Control handle 24x26 - Ctrl+Alt+Click to reset"), "gridpoint24x26", &wr, this),
183+ grid_point25x27(_("Control handle 25x27:"), _("Control handle 25x27 - Ctrl+Alt+Click to reset"), "gridpoint25x27", &wr, this),
184+ grid_point28x30(_("Control handle 28x30:"), _("Control handle 28x30 - Ctrl+Alt+Click to reset"), "gridpoint28x30", &wr, this),
185+ grid_point29x31(_("Control handle 29x31:"), _("Control handle 29x31 - Ctrl+Alt+Click to reset"), "gridpoint29x31", &wr, this),
186+ grid_point32x33x34x35(_("Control handle 32x33x34x35:"), _("Control handle 32x33x34x35 - Ctrl+Alt+Click to reset"), "gridpoint32x33x34x35", &wr, this)
187+
188+
189+{
190+ // register all your parameters here, so Inkscape knows which parameters this effect has:
191+ registerParameter( dynamic_cast<Parameter *>(&grid_point0) );
192+ registerParameter( dynamic_cast<Parameter *>(&grid_point1) );
193+ registerParameter( dynamic_cast<Parameter *>(&grid_point2) );
194+ registerParameter( dynamic_cast<Parameter *>(&grid_point3) );
195+ registerParameter( dynamic_cast<Parameter *>(&grid_point4) );
196+ registerParameter( dynamic_cast<Parameter *>(&grid_point5) );
197+ registerParameter( dynamic_cast<Parameter *>(&grid_point6) );
198+ registerParameter( dynamic_cast<Parameter *>(&grid_point7) );
199+ registerParameter( dynamic_cast<Parameter *>(&grid_point8x9) );
200+ registerParameter( dynamic_cast<Parameter *>(&grid_point10x11) );
201+ registerParameter( dynamic_cast<Parameter *>(&grid_point12) );
202+ registerParameter( dynamic_cast<Parameter *>(&grid_point13) );
203+ registerParameter( dynamic_cast<Parameter *>(&grid_point14) );
204+ registerParameter( dynamic_cast<Parameter *>(&grid_point15) );
205+ registerParameter( dynamic_cast<Parameter *>(&grid_point16) );
206+ registerParameter( dynamic_cast<Parameter *>(&grid_point17) );
207+ registerParameter( dynamic_cast<Parameter *>(&grid_point18) );
208+ registerParameter( dynamic_cast<Parameter *>(&grid_point19) );
209+ registerParameter( dynamic_cast<Parameter *>(&grid_point20x21) );
210+ registerParameter( dynamic_cast<Parameter *>(&grid_point22x23) );
211+ registerParameter( dynamic_cast<Parameter *>(&grid_point24x26) );
212+ registerParameter( dynamic_cast<Parameter *>(&grid_point25x27) );
213+ registerParameter( dynamic_cast<Parameter *>(&grid_point28x30) );
214+ registerParameter( dynamic_cast<Parameter *>(&grid_point29x31) );
215+ registerParameter( dynamic_cast<Parameter *>(&grid_point32x33x34x35) );
216+}
217+
218+LPELattice2::~LPELattice2()
219+{
220+}
221+
222+Geom::Piecewise<Geom::D2<Geom::SBasis> >
223+LPELattice2::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
224+{
225+ D2<SBasis2d> sb2;
226+
227+ //Initialisation of the sb2
228+ for(unsigned dim = 0; dim < 2; dim++) {
229+ sb2[dim].us = 3;
230+ sb2[dim].vs = 3;
231+ const int depth = sb2[dim].us*sb2[dim].vs;
232+ sb2[dim].resize(depth, Linear2d(0));
233+ }
234+
235+ //Grouping the point params in a convenient vector
236+ std::vector<Geom::Point *> handles(36);
237+
238+ handles[0] = &grid_point0;
239+ handles[1] = &grid_point1;
240+ handles[2] = &grid_point2;
241+ handles[3] = &grid_point3;
242+ handles[4] = &grid_point4;
243+ handles[5] = &grid_point5;
244+ handles[6] = &grid_point6;
245+ handles[7] = &grid_point7;
246+ handles[8] = &grid_point8x9;
247+ handles[9] = &grid_point8x9;
248+ handles[10] = &grid_point10x11;
249+ handles[11] = &grid_point10x11;
250+ handles[12] = &grid_point12;
251+ handles[13] = &grid_point13;
252+ handles[14] = &grid_point14;
253+ handles[15] = &grid_point15;
254+ handles[16] = &grid_point16;
255+ handles[17] = &grid_point17;
256+ handles[18] = &grid_point18;
257+ handles[19] = &grid_point19;
258+ handles[20] = &grid_point20x21;
259+ handles[21] = &grid_point20x21;
260+ handles[22] = &grid_point22x23;
261+ handles[23] = &grid_point22x23;
262+ handles[24] = &grid_point24x26;
263+ handles[25] = &grid_point25x27;
264+ handles[26] = &grid_point24x26;
265+ handles[27] = &grid_point25x27;
266+ handles[28] = &grid_point28x30;
267+ handles[29] = &grid_point29x31;
268+ handles[30] = &grid_point28x30;
269+ handles[31] = &grid_point29x31;
270+ handles[32] = &grid_point32x33x34x35;
271+ handles[33] = &grid_point32x33x34x35;
272+ handles[34] = &grid_point32x33x34x35;
273+ handles[35] = &grid_point32x33x34x35;
274+
275+ Geom::Point origin = Geom::Point(boundingbox_X.min(),boundingbox_Y.min());
276+
277+ double width = boundingbox_X.extent();
278+ double height = boundingbox_Y.extent();
279+
280+ //numbering is based on 4 rectangles.16
281+ for(unsigned dim = 0; dim < 2; dim++) {
282+ Geom::Point dir(0,0);
283+ dir[dim] = 1;
284+ for(unsigned vi = 0; vi < sb2[dim].vs; vi++) {
285+ for(unsigned ui = 0; ui < sb2[dim].us; ui++) {
286+ for(unsigned iv = 0; iv < 2; iv++) {
287+ for(unsigned iu = 0; iu < 2; iu++) {
288+ unsigned corner = iu + 2*iv;
289+ unsigned i = ui + vi*sb2[dim].us;
290+
291+ //This is the offset from the Upperleft point
292+ Geom::Point base( (ui + iu*(4-2*ui))*width/4.,
293+ (vi + iv*(4-2*vi))*height/4.);
294+
295+ //Special action for corners
296+ if(vi == 0 && ui == 0) {
297+ base = Geom::Point(0,0);
298+ }
299+
300+ // i = Upperleft corner of the considerated rectangle
301+ // corner = actual corner of the rectangle
302+ // origin = Upperleft point
303+ double dl = dot((*handles[corner+4*i] - (base + origin)), dir)/dot(dir,dir);
304+ sb2[dim][i][corner] = dl/( dim ? height : width )*pow(4.0,ui+vi);
305+ }
306+ }
307+ }
308+ }
309+ }
310+
311+ Piecewise<D2<SBasis> > output;
312+ output.push_cut(0.);
313+ for(unsigned i = 0; i < pwd2_in.size(); i++) {
314+ D2<SBasis> B = pwd2_in[i];
315+ B[Geom::X] -= origin[Geom::X];
316+ B[Geom::X]*= 1/width;
317+ B[Geom::Y] -= origin[Geom::Y];
318+ B[Geom::Y]*= 1/height;
319+ //Here comes the magic
320+ D2<SBasis> tB = compose_each(sb2,B);
321+ tB[Geom::X] = tB[Geom::X] * width + origin[Geom::X];
322+ tB[Geom::Y] = tB[Geom::Y] * height + origin[Geom::Y];
323+
324+ output.push(tB,i+1);
325+ }
326+ return output;
327+}
328+
329+Gtk::Widget *
330+LPELattice2::newWidget()
331+{
332+ // use manage here, because after deletion of Effect object, others might still be pointing to this widget.
333+ Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) );
334+
335+ vbox->set_border_width(5);
336+ Gtk::Button* resetButton = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset grid"))));
337+ resetButton->set_alignment(0.0, 0.5);
338+ resetButton->signal_clicked().connect(sigc::mem_fun (*this,&LPELattice2::resetGrid));
339+ Gtk::Widget* resetButtonWidget = dynamic_cast<Gtk::Widget *>(resetButton);
340+ resetButtonWidget->set_tooltip_text("Reset grid");
341+ vbox->pack_start(*resetButtonWidget, true, true,2);
342+ std::vector<Parameter *>::iterator it = param_vector.begin();
343+ while (it != param_vector.end()) {
344+ if ((*it)->widget_is_visible) {
345+ Parameter * param = *it;
346+ Gtk::Widget * widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
347+ if(param->param_key == "grid"){
348+ widg = NULL;
349+ }
350+ Glib::ustring * tip = param->param_getTooltip();
351+ if (widg) {
352+ vbox->pack_start(*widg, true, true, 2);
353+ if (tip) {
354+ widg->set_tooltip_text(*tip);
355+ } else {
356+ widg->set_tooltip_text("");
357+ widg->set_has_tooltip(false);
358+ }
359+ }
360+ }
361+
362+ ++it;
363+ }
364+ return dynamic_cast<Gtk::Widget *>(vbox);
365+}
366+
367+void
368+LPELattice2::doBeforeEffect (SPLPEItem const* lpeitem)
369+{
370+ original_bbox(lpeitem);
371+ setDefaults();
372+}
373+
374+void
375+LPELattice2::setDefaults()
376+{
377+ Geom::Point gp0((boundingbox_X.max()-boundingbox_X.min())/4*0+boundingbox_X.min(),
378+ (boundingbox_Y.max()-boundingbox_Y.min())/4*0+boundingbox_Y.min());
379+
380+ Geom::Point gp1((boundingbox_X.max()-boundingbox_X.min())/4*4+boundingbox_X.min(),
381+ (boundingbox_Y.max()-boundingbox_Y.min())/4*0+boundingbox_Y.min());
382+
383+ Geom::Point gp2((boundingbox_X.max()-boundingbox_X.min())/4*0+boundingbox_X.min(),
384+ (boundingbox_Y.max()-boundingbox_Y.min())/4*4+boundingbox_Y.min());
385+
386+ Geom::Point gp3((boundingbox_X.max()-boundingbox_X.min())/4*4+boundingbox_X.min(),
387+ (boundingbox_Y.max()-boundingbox_Y.min())/4*4+boundingbox_Y.min());
388+
389+ Geom::Point gp4((boundingbox_X.max()-boundingbox_X.min())/4*1+boundingbox_X.min(),
390+ (boundingbox_Y.max()-boundingbox_Y.min())/4*0+boundingbox_Y.min());
391+
392+ Geom::Point gp5((boundingbox_X.max()-boundingbox_X.min())/4*3+boundingbox_X.min(),
393+ (boundingbox_Y.max()-boundingbox_Y.min())/4*0+boundingbox_Y.min());
394+
395+ Geom::Point gp6((boundingbox_X.max()-boundingbox_X.min())/4*1+boundingbox_X.min(),
396+ (boundingbox_Y.max()-boundingbox_Y.min())/4*4+boundingbox_Y.min());
397+
398+ Geom::Point gp7((boundingbox_X.max()-boundingbox_X.min())/4*3+boundingbox_X.min(),
399+ (boundingbox_Y.max()-boundingbox_Y.min())/4*4+boundingbox_Y.min());
400+
401+ Geom::Point gp8x9((boundingbox_X.max()-boundingbox_X.min())/4*2+boundingbox_X.min(),
402+ (boundingbox_Y.max()-boundingbox_Y.min())/4*0+boundingbox_Y.min());
403+
404+ Geom::Point gp10x11((boundingbox_X.max()-boundingbox_X.min())/4*2+boundingbox_X.min(),
405+ (boundingbox_Y.max()-boundingbox_Y.min())/4*4+boundingbox_Y.min());
406+
407+ Geom::Point gp12((boundingbox_X.max()-boundingbox_X.min())/4*0+boundingbox_X.min(),
408+ (boundingbox_Y.max()-boundingbox_Y.min())/4*1+boundingbox_Y.min());
409+
410+ Geom::Point gp13((boundingbox_X.max()-boundingbox_X.min())/4*4+boundingbox_X.min(),
411+ (boundingbox_Y.max()-boundingbox_Y.min())/4*1+boundingbox_Y.min());
412+
413+ Geom::Point gp14((boundingbox_X.max()-boundingbox_X.min())/4*0+boundingbox_X.min(),
414+ (boundingbox_Y.max()-boundingbox_Y.min())/4*3+boundingbox_Y.min());
415+
416+ Geom::Point gp15((boundingbox_X.max()-boundingbox_X.min())/4*4+boundingbox_X.min(),
417+ (boundingbox_Y.max()-boundingbox_Y.min())/4*3+boundingbox_Y.min());
418+
419+ Geom::Point gp16((boundingbox_X.max()-boundingbox_X.min())/4*1+boundingbox_X.min(),
420+ (boundingbox_Y.max()-boundingbox_Y.min())/4*1+boundingbox_Y.min());
421+
422+ Geom::Point gp17((boundingbox_X.max()-boundingbox_X.min())/4*3+boundingbox_X.min(),
423+ (boundingbox_Y.max()-boundingbox_Y.min())/4*1+boundingbox_Y.min());
424+
425+ Geom::Point gp18((boundingbox_X.max()-boundingbox_X.min())/4*1+boundingbox_X.min(),
426+ (boundingbox_Y.max()-boundingbox_Y.min())/4*3+boundingbox_Y.min());
427+
428+ Geom::Point gp19((boundingbox_X.max()-boundingbox_X.min())/4*3+boundingbox_X.min(),
429+ (boundingbox_Y.max()-boundingbox_Y.min())/4*3+boundingbox_Y.min());
430+
431+ Geom::Point gp20x21((boundingbox_X.max()-boundingbox_X.min())/4*2+boundingbox_X.min(),
432+ (boundingbox_Y.max()-boundingbox_Y.min())/4*1+boundingbox_Y.min());
433+
434+ Geom::Point gp22x23((boundingbox_X.max()-boundingbox_X.min())/4*2+boundingbox_X.min(),
435+ (boundingbox_Y.max()-boundingbox_Y.min())/4*3+boundingbox_Y.min());
436+
437+ Geom::Point gp24x26((boundingbox_X.max()-boundingbox_X.min())/4*0+boundingbox_X.min(),
438+ (boundingbox_Y.max()-boundingbox_Y.min())/4*2+boundingbox_Y.min());
439+
440+ Geom::Point gp25x27((boundingbox_X.max()-boundingbox_X.min())/4*4+boundingbox_X.min(),
441+ (boundingbox_Y.max()-boundingbox_Y.min())/4*2+boundingbox_Y.min());
442+
443+ Geom::Point gp28x30((boundingbox_X.max()-boundingbox_X.min())/4*1+boundingbox_X.min(),
444+ (boundingbox_Y.max()-boundingbox_Y.min())/4*2+boundingbox_Y.min());
445+
446+ Geom::Point gp29x31((boundingbox_X.max()-boundingbox_X.min())/4*3+boundingbox_X.min(),
447+ (boundingbox_Y.max()-boundingbox_Y.min())/4*2+boundingbox_Y.min());
448+
449+ Geom::Point gp32x33x34x35((boundingbox_X.max()-boundingbox_X.min())/4*2+boundingbox_X.min(),
450+ (boundingbox_Y.max()-boundingbox_Y.min())/4*2+boundingbox_Y.min());
451+
452+ grid_point0.param_update_default(gp0);
453+ grid_point1.param_update_default(gp1);
454+ grid_point2.param_update_default(gp2);
455+ grid_point3.param_update_default(gp3);
456+ grid_point4.param_update_default(gp4);
457+ grid_point5.param_update_default(gp5);
458+ grid_point6.param_update_default(gp6);
459+ grid_point7.param_update_default(gp7);
460+ grid_point8x9.param_update_default(gp8x9);
461+ grid_point10x11.param_update_default(gp10x11);
462+ grid_point12.param_update_default(gp12);
463+ grid_point13.param_update_default(gp13);
464+ grid_point14.param_update_default(gp14);
465+ grid_point15.param_update_default(gp15);
466+ grid_point16.param_update_default(gp16);
467+ grid_point17.param_update_default(gp17);
468+ grid_point18.param_update_default(gp18);
469+ grid_point19.param_update_default(gp19);
470+ grid_point20x21.param_update_default(gp20x21);
471+ grid_point22x23.param_update_default(gp22x23);
472+ grid_point24x26.param_update_default(gp24x26);
473+ grid_point25x27.param_update_default(gp25x27);
474+ grid_point28x30.param_update_default(gp28x30);
475+ grid_point29x31.param_update_default(gp29x31);
476+ grid_point32x33x34x35.param_update_default(gp32x33x34x35);
477+}
478+
479+void
480+LPELattice2::resetGrid()
481+{
482+ grid_point0.param_set_and_write_default();
483+ grid_point1.param_set_and_write_default();
484+ grid_point2.param_set_and_write_default();
485+ grid_point3.param_set_and_write_default();
486+ grid_point4.param_set_and_write_default();
487+ grid_point5.param_set_and_write_default();
488+ grid_point6.param_set_and_write_default();
489+ grid_point7.param_set_and_write_default();
490+ grid_point8x9.param_set_and_write_default();
491+ grid_point10x11.param_set_and_write_default();
492+ grid_point12.param_set_and_write_default();
493+ grid_point13.param_set_and_write_default();
494+ grid_point14.param_set_and_write_default();
495+ grid_point15.param_set_and_write_default();
496+ grid_point16.param_set_and_write_default();
497+ grid_point17.param_set_and_write_default();
498+ grid_point18.param_set_and_write_default();
499+ grid_point19.param_set_and_write_default();
500+ grid_point20x21.param_set_and_write_default();
501+ grid_point22x23.param_set_and_write_default();
502+ grid_point24x26.param_set_and_write_default();
503+ grid_point25x27.param_set_and_write_default();
504+ grid_point28x30.param_set_and_write_default();
505+ grid_point29x31.param_set_and_write_default();
506+ grid_point32x33x34x35.param_set_and_write_default();
507+ //todo:this hack is only to reposition the knots on reser grid button
508+ //Better update path effect in LPEITEM
509+ SPDesktop * desktop = inkscape_active_desktop();
510+ tools_switch(desktop, TOOLS_SELECT);
511+ tools_switch(desktop, TOOLS_NODES);
512+}
513+
514+void
515+LPELattice2::resetDefaults(SPItem const* item)
516+{
517+ Effect::resetDefaults(item);
518+ original_bbox(SP_LPE_ITEM(item));
519+ setDefaults();
520+ resetGrid();
521+}
522+
523+void
524+LPELattice2::calculateCurve(Geom::Point a,Geom::Point b, SPCurve* c, bool horizontal, bool move)
525+{
526+ using Geom::X;
527+ using Geom::Y;
528+ if(move) c->moveto(a);
529+ Geom::Point cubic1 = a + (1./3)* (b - a);
530+ Geom::Point cubic2 = b + (1./3)* (a - b);
531+ if(horizontal) c->curveto(Geom::Point(cubic1[X],a[Y]),Geom::Point(cubic2[X],b[Y]),b);
532+ else c->curveto(Geom::Point(a[X],cubic1[Y]),Geom::Point(b[X],cubic2[Y]),b);
533+}
534+
535+void
536+LPELattice2::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
537+{
538+ hp_vec.clear();
539+
540+ SPCurve *c = new SPCurve();
541+ calculateCurve(grid_point0,grid_point4, c,true, true);
542+ calculateCurve(grid_point4,grid_point8x9, c,true, false);
543+ calculateCurve(grid_point8x9,grid_point5, c,true, false);
544+ calculateCurve(grid_point5,grid_point1, c,true, false);
545+
546+ calculateCurve(grid_point12,grid_point16, c,true, true);
547+ calculateCurve(grid_point16,grid_point20x21, c,true, false);
548+ calculateCurve(grid_point20x21,grid_point17, c,true, false);
549+ calculateCurve(grid_point17,grid_point13, c,true, false);
550+
551+ calculateCurve(grid_point24x26,grid_point28x30, c,true, true);
552+ calculateCurve(grid_point28x30,grid_point32x33x34x35, c,true, false);
553+ calculateCurve(grid_point32x33x34x35,grid_point29x31, c,true, false);
554+ calculateCurve(grid_point29x31,grid_point25x27, c,true, false);
555+
556+ calculateCurve(grid_point14,grid_point18, c,true, true);
557+ calculateCurve(grid_point18,grid_point22x23, c,true, false);
558+ calculateCurve(grid_point22x23,grid_point19, c,true, false);
559+ calculateCurve(grid_point19,grid_point15, c,true, false);
560+
561+ calculateCurve(grid_point2,grid_point6, c,true, true);
562+ calculateCurve(grid_point6,grid_point10x11, c,true, false);
563+ calculateCurve(grid_point10x11,grid_point7, c,true, false);
564+ calculateCurve(grid_point7,grid_point3, c,true, false);
565+
566+ calculateCurve(grid_point0,grid_point12, c,false, true);
567+ calculateCurve(grid_point12,grid_point24x26, c,false, false);
568+ calculateCurve(grid_point24x26,grid_point14, c,false, false);
569+ calculateCurve(grid_point14,grid_point2, c,false, false);
570+
571+ calculateCurve(grid_point4,grid_point16, c,false, true);
572+ calculateCurve(grid_point16,grid_point28x30, c,false, false);
573+ calculateCurve(grid_point28x30,grid_point18, c,false, false);
574+ calculateCurve(grid_point18,grid_point6, c,false, false);
575+
576+ calculateCurve(grid_point8x9,grid_point20x21, c,false, true);
577+ calculateCurve(grid_point20x21,grid_point32x33x34x35, c,false, false);
578+ calculateCurve(grid_point32x33x34x35,grid_point22x23, c,false, false);
579+ calculateCurve(grid_point22x23,grid_point10x11, c,false, false);
580+
581+ calculateCurve(grid_point5,grid_point17, c, false, true);
582+ calculateCurve(grid_point17,grid_point29x31, c,false, false);
583+ calculateCurve(grid_point29x31,grid_point19, c,false, false);
584+ calculateCurve(grid_point19,grid_point7, c,false, false);
585+
586+ calculateCurve(grid_point1,grid_point13, c, false, true);
587+ calculateCurve(grid_point13,grid_point25x27, c,false, false);
588+ calculateCurve(grid_point25x27,grid_point15, c,false, false);
589+ calculateCurve(grid_point15,grid_point3, c, false, false);
590+ hp_vec.push_back(c->get_pathvector());
591+}
592+
593+
594+/* ######################## */
595+
596+} //namespace LivePathEffect
597+} /* namespace Inkscape */
598+
599+
600+
601+
602+/*
603+ Local Variables:
604+ mode:c++
605+ c-file-style:"stroustrup"
606+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
607+ indent-tabs-mode:nil
608+ fill-column:99
609+ End:
610+*/
611+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
612
613=== added file 'src/live_effects/lpe-lattice2.h'
614--- src/live_effects/lpe-lattice2.h 1970-01-01 00:00:00 +0000
615+++ src/live_effects/lpe-lattice2.h 2014-05-13 06:54:02 +0000
616@@ -0,0 +1,92 @@
617+#ifndef INKSCAPE_LPE_LATTICE2_H
618+#define INKSCAPE_LPE_LATTICE2_H
619+
620+/** \file
621+ * LPE <lattice2> implementation, see lpe-lattice2.cpp.
622+ */
623+
624+/*
625+ * Authors:
626+ * Johan Engelen
627+ * Steren Giannini
628+ * Noé Falzon
629+ * Victor Navez
630+ * ~suv
631+ * Jabiertxo Arraiza
632+*
633+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
634+ *
635+ * Released under GNU GPL, read the file 'COPYING' for more information
636+ */
637+
638+#include "live_effects/parameter/enum.h"
639+#include "live_effects/effect.h"
640+#include "live_effects/parameter/pointreseteable.h"
641+#include "live_effects/lpegroupbbox.h"
642+
643+namespace Inkscape {
644+namespace LivePathEffect {
645+
646+class LPELattice2 : public Effect, GroupBBoxEffect {
647+public:
648+
649+ LPELattice2(LivePathEffectObject *lpeobject);
650+ virtual ~LPELattice2();
651+
652+ virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
653+
654+ virtual void resetDefaults(SPItem const* item);
655+
656+ virtual void doBeforeEffect(SPLPEItem const* lpeitem);
657+
658+ virtual Gtk::Widget * newWidget();
659+
660+ virtual void calculateCurve(Geom::Point a,Geom::Point b, SPCurve *c, bool horizontal, bool move);
661+
662+ virtual void setDefaults();
663+
664+ virtual void resetGrid();
665+
666+ //virtual void original_bbox(SPLPEItem const* lpeitem, bool absolute = false);
667+
668+ //virtual void addCanvasIndicators(SPLPEItem const*/*lpeitem*/, std::vector<Geom::PathVector> &/*hp_vec*/);
669+
670+ //virtual std::vector<Geom::PathVector> getHelperPaths(SPLPEItem const* lpeitem);
671+protected:
672+ void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec);
673+private:
674+
675+ PointReseteableParam grid_point0;
676+ PointReseteableParam grid_point1;
677+ PointReseteableParam grid_point2;
678+ PointReseteableParam grid_point3;
679+ PointReseteableParam grid_point4;
680+ PointReseteableParam grid_point5;
681+ PointReseteableParam grid_point6;
682+ PointReseteableParam grid_point7;
683+ PointReseteableParam grid_point8x9;
684+ PointReseteableParam grid_point10x11;
685+ PointReseteableParam grid_point12;
686+ PointReseteableParam grid_point13;
687+ PointReseteableParam grid_point14;
688+ PointReseteableParam grid_point15;
689+ PointReseteableParam grid_point16;
690+ PointReseteableParam grid_point17;
691+ PointReseteableParam grid_point18;
692+ PointReseteableParam grid_point19;
693+ PointReseteableParam grid_point20x21;
694+ PointReseteableParam grid_point22x23;
695+ PointReseteableParam grid_point24x26;
696+ PointReseteableParam grid_point25x27;
697+ PointReseteableParam grid_point28x30;
698+ PointReseteableParam grid_point29x31;
699+ PointReseteableParam grid_point32x33x34x35;
700+
701+ LPELattice2(const LPELattice2&);
702+ LPELattice2& operator=(const LPELattice2&);
703+};
704+
705+} //namespace LivePathEffect
706+} //namespace Inkscape
707+
708+#endif
709
710=== modified file 'src/live_effects/parameter/Makefile_insert'
711--- src/live_effects/parameter/Makefile_insert 2012-01-12 21:06:16 +0000
712+++ src/live_effects/parameter/Makefile_insert 2014-05-13 06:54:02 +0000
713@@ -11,6 +11,8 @@
714 live_effects/parameter/random.h \
715 live_effects/parameter/point.cpp \
716 live_effects/parameter/point.h \
717+ live_effects/parameter/pointreseteable.cpp \
718+ live_effects/parameter/pointreseteable.h \
719 live_effects/parameter/enum.h \
720 live_effects/parameter/path-reference.cpp \
721 live_effects/parameter/path-reference.h \
722
723=== added file 'src/live_effects/parameter/pointreseteable.cpp'
724--- src/live_effects/parameter/pointreseteable.cpp 1970-01-01 00:00:00 +0000
725+++ src/live_effects/parameter/pointreseteable.cpp 2014-05-13 06:54:02 +0000
726@@ -0,0 +1,210 @@
727+/*
728+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
729+ *
730+ * Released under GNU GPL, read the file 'COPYING' for more information
731+ */
732+
733+#include "ui/widget/registered-widget.h"
734+#include "live_effects/parameter/pointreseteable.h"
735+#include "live_effects/effect.h"
736+#include "svg/svg.h"
737+#include "svg/stringstream.h"
738+#include "ui/widget/point.h"
739+#include "widgets/icon.h"
740+#include "inkscape.h"
741+#include "verbs.h"
742+#include "knotholder.h"
743+#include <glibmm/i18n.h>
744+#include "tools-switch.h"
745+#include "ui/tools/node-tool.h"
746+
747+// needed for on-canvas editting:
748+#include "desktop.h"
749+
750+namespace Inkscape {
751+
752+namespace LivePathEffect {
753+
754+PointReseteableParam::PointReseteableParam( const Glib::ustring& label, const Glib::ustring& tip,
755+ const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
756+ Effect* effect, const gchar *htip, Geom::Point default_value)
757+ : Geom::Point(default_value), Parameter(label, tip, key, wr, effect), defvalue(default_value)
758+{
759+ knot_shape = SP_KNOT_SHAPE_DIAMOND;
760+ knot_mode = SP_KNOT_MODE_XOR;
761+ knot_color = 0xffffff00;
762+ handle_tip = g_strdup(htip);
763+}
764+
765+PointReseteableParam::~PointReseteableParam()
766+{
767+ if (handle_tip)
768+ g_free(handle_tip);
769+}
770+
771+void
772+PointReseteableParam::param_set_default()
773+{
774+ param_setValue(defvalue);
775+}
776+
777+void
778+PointReseteableParam::param_set_and_write_default()
779+{
780+ param_set_and_write_new_value(defvalue);
781+}
782+
783+void
784+PointReseteableParam::param_update_default(Geom::Point newpoint)
785+{
786+ this->defvalue = newpoint;
787+}
788+
789+bool
790+PointReseteableParam::param_readSVGValue(const gchar * strvalue)
791+{
792+ gchar ** strarray = g_strsplit(strvalue, ",", 2);
793+ double newx, newy;
794+ unsigned int success = sp_svg_number_read_d(strarray[0], &newx);
795+ success += sp_svg_number_read_d(strarray[1], &newy);
796+ g_strfreev (strarray);
797+ if (success == 2) {
798+ param_setValue( Geom::Point(newx, newy) );
799+ return true;
800+ }
801+ return false;
802+}
803+
804+gchar *
805+PointReseteableParam::param_getSVGValue() const
806+{
807+ Inkscape::SVGOStringStream os;
808+ os << *dynamic_cast<Geom::Point const *>( this );
809+ gchar * str = g_strdup(os.str().c_str());
810+ return str;
811+}
812+
813+Gtk::Widget *
814+PointReseteableParam::param_newWidget()
815+{
816+ Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = Gtk::manage(
817+ new Inkscape::UI::Widget::RegisteredTransformedPoint( param_label,
818+ param_tooltip,
819+ param_key,
820+ *param_wr,
821+ param_effect->getRepr(),
822+ param_effect->getSPDoc() ) );
823+ // TODO: fix to get correct desktop (don't use SP_ACTIVE_DESKTOP)
824+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
825+ Geom::Affine transf = desktop->doc2dt();
826+ pointwdg->setTransform(transf);
827+ pointwdg->setValue( *this );
828+ pointwdg->clearProgrammatically();
829+ pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter"));
830+
831+ Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() );
832+ static_cast<Gtk::HBox*>(hbox)->pack_start(*pointwdg, true, true);
833+ static_cast<Gtk::HBox*>(hbox)->show_all_children();
834+
835+ return dynamic_cast<Gtk::Widget *> (hbox);
836+}
837+
838+void
839+PointReseteableParam::param_setValue(Geom::Point newpoint)
840+{
841+ *dynamic_cast<Geom::Point *>( this ) = newpoint;
842+ if(SP_ACTIVE_DESKTOP){
843+ SPDesktop* desktop = SP_ACTIVE_DESKTOP;
844+ if (tools_isactive( desktop, TOOLS_NODES)) {
845+ Inkscape::UI::Tools::NodeTool *nt = static_cast<Inkscape::UI::Tools::NodeTool*>( desktop->event_context);
846+ nt->update_helperpath();
847+ }
848+ }
849+}
850+
851+void
852+PointReseteableParam::param_set_and_write_new_value (Geom::Point newpoint)
853+{
854+ Inkscape::SVGOStringStream os;
855+ os << newpoint;
856+ gchar * str = g_strdup(os.str().c_str());
857+ param_write_to_repr(str);
858+ g_free(str);
859+}
860+
861+void
862+PointReseteableParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/)
863+{
864+ param_set_and_write_new_value( (*this) * postmul );
865+}
866+
867+
868+void
869+PointReseteableParam::set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color)
870+{
871+ knot_shape = shape;
872+ knot_mode = mode;
873+ knot_color = color;
874+}
875+
876+class PointReseteableParamKnotHolderEntity : public KnotHolderEntity {
877+public:
878+ PointReseteableParamKnotHolderEntity(PointReseteableParam *p) { this->pparam = p; }
879+ virtual ~PointReseteableParamKnotHolderEntity() {}
880+
881+ virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
882+ virtual Geom::Point knot_get() const;
883+ virtual void knot_click(guint state);
884+
885+private:
886+ PointReseteableParam *pparam;
887+};
888+
889+void
890+PointReseteableParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
891+{
892+ Geom::Point const s = snap_knot_position(p, state);
893+ pparam->param_setValue(s);
894+ sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
895+}
896+
897+Geom::Point
898+PointReseteableParamKnotHolderEntity::knot_get() const
899+{
900+ return *pparam;
901+}
902+
903+void
904+PointReseteableParamKnotHolderEntity::knot_click(guint state)
905+{
906+ if (state & GDK_CONTROL_MASK) {
907+ if (state & GDK_MOD1_MASK) {
908+ this->pparam->param_set_default();
909+ sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
910+ }
911+ }
912+}
913+
914+void
915+PointReseteableParam::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item)
916+{
917+ PointReseteableParamKnotHolderEntity *e = new PointReseteableParamKnotHolderEntity(this);
918+ // TODO: can we ditch handleTip() etc. because we have access to handle_tip etc. itself???
919+ e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, handleTip(), knot_shape, knot_mode, knot_color);
920+ knotholder->add(e);
921+}
922+
923+} /* namespace LivePathEffect */
924+
925+} /* namespace Inkscape */
926+
927+/*
928+ Local Variables:
929+ mode:c++
930+ c-file-style:"stroustrup"
931+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
932+ indent-tabs-mode:nil
933+ fill-column:99
934+ End:
935+*/
936+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
937
938=== added file 'src/live_effects/parameter/pointreseteable.h'
939--- src/live_effects/parameter/pointreseteable.h 1970-01-01 00:00:00 +0000
940+++ src/live_effects/parameter/pointreseteable.h 2014-05-13 06:54:02 +0000
941@@ -0,0 +1,74 @@
942+#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_RESETEABLE_H
943+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_RESETEABLE_H
944+
945+/*
946+ * Inkscape::LivePathEffectParameters
947+ *
948+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
949+ *
950+ * Released under GNU GPL, read the file 'COPYING' for more information
951+ */
952+
953+#include <glib.h>
954+#include <2geom/point.h>
955+
956+#include "live_effects/parameter/parameter.h"
957+
958+#include "knot-holder-entity.h"
959+
960+namespace Inkscape {
961+
962+namespace LivePathEffect {
963+
964+class PointReseteableParamKnotHolderEntity;
965+
966+class PointReseteableParam : public Geom::Point, public Parameter {
967+public:
968+ PointReseteableParam( const Glib::ustring& label,
969+ const Glib::ustring& tip,
970+ const Glib::ustring& key,
971+ Inkscape::UI::Widget::Registry* wr,
972+ Effect* effect,
973+ const gchar *handle_tip = NULL,
974+ Geom::Point default_value = Geom::Point(0,0) ); // tip for automatically associated on-canvas handle
975+ virtual ~PointReseteableParam();
976+
977+ virtual Gtk::Widget * param_newWidget();
978+
979+ bool param_readSVGValue(const gchar * strvalue);
980+ gchar * param_getSVGValue() const;
981+ inline const gchar *handleTip() const { return handle_tip ? handle_tip : param_tooltip.c_str(); }
982+
983+ void param_setValue(Geom::Point newpoint);
984+ void param_set_default();
985+ void param_set_and_write_default();
986+ void param_update_default(Geom::Point newpoint);
987+
988+ void param_set_and_write_new_value(Geom::Point newpoint);
989+
990+ virtual void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/);
991+
992+ void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color);
993+
994+ virtual bool providesKnotHolderEntities() const { return true; }
995+ virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
996+
997+ friend class PointReseteableParamKnotHolderEntity;
998+private:
999+ PointReseteableParam(const PointReseteableParam&);
1000+ PointReseteableParam& operator=(const PointReseteableParam&);
1001+
1002+ Geom::Point defvalue;
1003+
1004+ SPKnotShapeType knot_shape;
1005+ SPKnotModeType knot_mode;
1006+ guint32 knot_color;
1007+ gchar *handle_tip;
1008+};
1009+
1010+
1011+} //namespace LivePathEffect
1012+
1013+} //namespace Inkscape
1014+
1015+#endif
1016
1017=== modified file 'src/ui/tools/node-tool.cpp'
1018--- src/ui/tools/node-tool.cpp 2014-03-27 01:33:44 +0000
1019+++ src/ui/tools/node-tool.cpp 2014-05-13 06:54:02 +0000
1020@@ -23,6 +23,8 @@
1021 #include "message-context.h"
1022 #include "selection.h"
1023 #include "shape-editor.h" // temporary!
1024+#include "live_effects/effect.h"
1025+#include "display/curve.h"
1026 #include "sp-clippath.h"
1027 #include "sp-item-group.h"
1028 #include "sp-mask.h"
1029@@ -167,6 +169,10 @@
1030 this->desktop->remove_temporary_canvasitem(this->flash_tempitem);
1031 }
1032
1033+ if (this->helperpath_tmpitem) {
1034+ this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem);
1035+ }
1036+
1037 this->_selection_changed_connection.disconnect();
1038 //this->_selection_modified_connection.disconnect();
1039 this->_mouseover_changed_connection.disconnect();
1040@@ -252,6 +258,7 @@
1041 this->flash_tempitem = NULL;
1042 this->flashed_item = NULL;
1043 this->_last_over = NULL;
1044+ this->helperpath_tmpitem = NULL;
1045
1046 // read prefs before adding items to selection to prevent momentarily showing the outline
1047 sp_event_context_read(this, "show_handles");
1048@@ -278,6 +285,41 @@
1049 }
1050
1051 this->desktop->emitToolSubselectionChanged(NULL); // sets the coord entry fields to inactive
1052+ this->update_helperpath();
1053+}
1054+
1055+void NodeTool::update_helperpath(){
1056+ Inkscape::Selection *selection = sp_desktop_selection (this->desktop);
1057+ if (this->helperpath_tmpitem) {
1058+ this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem);
1059+ this->helperpath_tmpitem = NULL;
1060+ }
1061+ if (SP_IS_LPE_ITEM(selection->singleItem())) {
1062+ Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE();
1063+ if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) {
1064+ if (lpe) {
1065+ SPCurve *c = new SPCurve();
1066+ SPCurve *cc = new SPCurve();
1067+ std::vector<Geom::PathVector> cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem()));
1068+ for (std::vector<Geom::PathVector>::iterator p = cs.begin(); p != cs.end(); ++p) {
1069+ cc->set_pathvector(*p);
1070+ c->append(cc, false);
1071+ cc->reset();
1072+ }
1073+ if (!c->is_empty()) {
1074+ c->transform(selection->singleItem()->i2dt_affine());
1075+ SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c);
1076+ sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath),
1077+ 0x0000ff9A, 1.0,
1078+ SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
1079+ sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO);
1080+ this->helperpath_tmpitem = this->desktop->add_temporary_canvasitem(helperpath,0);
1081+ }
1082+ c->unref();
1083+ cc->unref();
1084+ }
1085+ }
1086+ }
1087 }
1088
1089 void NodeTool::set(const Inkscape::Preferences::Entry& value) {
1090@@ -392,7 +434,7 @@
1091 for (std::set<ShapeRecord>::iterator i = shapes.begin(); i != shapes.end(); ++i) {
1092 ShapeRecord const &r = *i;
1093
1094- if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item)) &&
1095+ if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item) || SP_IS_GROUP(r.item) || SP_IS_OBJECTGROUP(r.item)) &&
1096 this->_shape_editors.find(r.item) == this->_shape_editors.end())
1097 {
1098 ShapeEditor *si = new ShapeEditor(this->desktop);
1099@@ -416,7 +458,7 @@
1100
1101 Inkscape::Selection *selection = desktop->selection;
1102 static Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1103-
1104+
1105 if (this->_multipath->event(this, event)) {
1106 return true;
1107 }
1108@@ -433,6 +475,7 @@
1109 {
1110 case GDK_MOTION_NOTIFY: {
1111 combine_motion_events(desktop->canvas, event->motion, 0);
1112+ this->update_helperpath();
1113 SPItem *over_item = sp_event_context_find_item (desktop, event_point(event->button),
1114 FALSE, TRUE);
1115
1116@@ -441,7 +484,6 @@
1117 //ink_node_tool_update_tip(nt, event);
1118 this->update_tip(event);
1119 }
1120-
1121 // create pathflash outline
1122 if (prefs->getBool("/tools/nodes/pathflash_enabled")) {
1123 if (over_item == this->flashed_item) {
1124
1125=== modified file 'src/ui/tools/node-tool.h'
1126--- src/ui/tools/node-tool.h 2014-03-27 01:33:44 +0000
1127+++ src/ui/tools/node-tool.h 2014-05-13 06:54:02 +0000
1128@@ -51,6 +51,7 @@
1129 static const std::string prefsPath;
1130
1131 virtual void setup();
1132+ virtual void update_helperpath();
1133 virtual void set(const Inkscape::Preferences::Entry& val);
1134 virtual bool root_handler(GdkEvent* event);
1135
1136@@ -63,6 +64,7 @@
1137
1138 SPItem *flashed_item;
1139 Inkscape::Display::TemporaryItem *flash_tempitem;
1140+ Inkscape::Display::TemporaryItem *helperpath_tmpitem;
1141 Inkscape::UI::Selector* _selector;
1142 Inkscape::UI::PathSharedData* _path_data;
1143 SPCanvasGroup *_transform_handle_group;