Merge lp:~inkscape.dev/inkscape/show_handles into lp:~inkscape.dev/inkscape/trunk
- show_handles
- Merge into trunk
Proposed by
Jabiertxof
Status: | Merged | ||||
---|---|---|---|---|---|
Merge reported by: | su_v | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~inkscape.dev/inkscape/show_handles | ||||
Merge into: | lp:~inkscape.dev/inkscape/trunk | ||||
Diff against target: |
368 lines (+283/-0) 7 files modified
po/POTFILES.in (+1/-0) src/live_effects/CMakeLists.txt (+2/-0) src/live_effects/Makefile_insert (+2/-0) src/live_effects/effect-enum.h (+1/-0) src/live_effects/effect.cpp (+5/-0) src/live_effects/lpe-show_handles.cpp (+211/-0) src/live_effects/lpe-show_handles.h (+61/-0) |
||||
To merge this branch: | bzr merge lp:~inkscape.dev/inkscape/show_handles | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Liam P. White (community) | Approve | ||
Jabiertxof | Needs Resubmitting | ||
Review via email: mp+230243@code.launchpad.net |
Commit message
Description of the change
Show Handles extension in a LPE.
To post a comment you must log in.
Revision history for this message
Jabiertxof (jabiertxof) wrote : | # |
Fixes all. Thanks Liam for the review!
review:
Needs Resubmitting
- 13510. By Jabiertxof <email address hidden>
-
Code refactor: now lines draw ok when handle is degenerate or cirle handle is biger then the distance to node. also remove code duplication at loop
Revision history for this message
Liam P. White (liampwhite) wrote : | # |
Looks all good now.
review:
Approve
Revision history for this message
su_v (suv-lp) wrote : | # |
show_handles was added to experimental in r13480
http://
experimental was merged into trunk in r13641
http://
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.in' |
2 | --- po/POTFILES.in 2014-06-07 00:42:14 +0000 |
3 | +++ po/POTFILES.in 2014-08-19 17:31:23 +0000 |
4 | @@ -142,6 +142,7 @@ |
5 | src/live_effects/lpe-powerstroke.cpp |
6 | src/live_effects/lpe-rough-hatches.cpp |
7 | src/live_effects/lpe-ruler.cpp |
8 | +src/live_effects/lpe-show_handles.cpp |
9 | src/live_effects/lpe-sketch.cpp |
10 | src/live_effects/lpe-vonkoch.cpp |
11 | src/live_effects/parameter/bool.cpp |
12 | |
13 | === modified file 'src/live_effects/CMakeLists.txt' |
14 | --- src/live_effects/CMakeLists.txt 2012-03-23 21:02:03 +0000 |
15 | +++ src/live_effects/CMakeLists.txt 2014-08-19 17:31:23 +0000 |
16 | @@ -29,6 +29,7 @@ |
17 | lpe-recursiveskeleton.cpp |
18 | lpe-rough-hatches.cpp |
19 | lpe-ruler.cpp |
20 | + lpe-show_handles.cpp |
21 | # lpe-skeleton.cpp |
22 | lpe-sketch.cpp |
23 | lpe-spiro.cpp |
24 | @@ -89,6 +90,7 @@ |
25 | lpe-recursiveskeleton.h |
26 | lpe-rough-hatches.h |
27 | lpe-ruler.h |
28 | + lpe-show_handles.h |
29 | lpe-skeleton.h |
30 | lpe-sketch.h |
31 | lpe-spiro.h |
32 | |
33 | === modified file 'src/live_effects/Makefile_insert' |
34 | --- src/live_effects/Makefile_insert 2012-03-23 21:02:03 +0000 |
35 | +++ src/live_effects/Makefile_insert 2014-08-19 17:31:23 +0000 |
36 | @@ -40,6 +40,8 @@ |
37 | live_effects/lpe-test-doEffect-stack.h \ |
38 | live_effects/lpe-lattice.cpp \ |
39 | live_effects/lpe-lattice.h \ |
40 | + live_effects/lpe-show_handles.cpp \ |
41 | + live_effects/lpe-show_handles.h \ |
42 | live_effects/lpe-envelope.cpp \ |
43 | live_effects/lpe-envelope.h \ |
44 | live_effects/lpe-spiro.cpp \ |
45 | |
46 | === modified file 'src/live_effects/effect-enum.h' |
47 | --- src/live_effects/effect-enum.h 2012-01-12 21:06:16 +0000 |
48 | +++ src/live_effects/effect-enum.h 2014-08-19 17:31:23 +0000 |
49 | @@ -28,6 +28,7 @@ |
50 | PERSPECTIVE_PATH, |
51 | SPIRO, |
52 | LATTICE, |
53 | + SHOW_HANDLES, |
54 | ENVELOPE, |
55 | CONSTRUCT_GRID, |
56 | PERP_BISECTOR, |
57 | |
58 | === modified file 'src/live_effects/effect.cpp' |
59 | --- src/live_effects/effect.cpp 2014-05-05 08:40:12 +0000 |
60 | +++ src/live_effects/effect.cpp 2014-08-19 17:31:23 +0000 |
61 | @@ -25,6 +25,7 @@ |
62 | #include "live_effects/lpe-perspective_path.h" |
63 | #include "live_effects/lpe-spiro.h" |
64 | #include "live_effects/lpe-lattice.h" |
65 | +#include "live_effects/lpe-show_handles.h" |
66 | #include "live_effects/lpe-envelope.h" |
67 | #include "live_effects/lpe-constructgrid.h" |
68 | #include "live_effects/lpe-perp_bisector.h" |
69 | @@ -120,6 +121,7 @@ |
70 | /* 0.49 */ |
71 | {POWERSTROKE, N_("Power stroke"), "powerstroke"}, |
72 | {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, |
73 | + {SHOW_HANDLES, N_("Show handles"), "show_handles"}, |
74 | }; |
75 | const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); |
76 | |
77 | @@ -243,6 +245,9 @@ |
78 | case CLONE_ORIGINAL: |
79 | neweffect = static_cast<Effect*> ( new LPECloneOriginal(lpeobj) ); |
80 | break; |
81 | + case SHOW_HANDLES: |
82 | + neweffect = static_cast<Effect*> ( new LPEShowHandles(lpeobj) ); |
83 | + break; |
84 | default: |
85 | g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); |
86 | neweffect = NULL; |
87 | |
88 | === added file 'src/live_effects/lpe-show_handles.cpp' |
89 | --- src/live_effects/lpe-show_handles.cpp 1970-01-01 00:00:00 +0000 |
90 | +++ src/live_effects/lpe-show_handles.cpp 2014-08-19 17:31:23 +0000 |
91 | @@ -0,0 +1,211 @@ |
92 | +/* |
93 | + * Authors: |
94 | + * Jabier Arraiza Cenoz |
95 | +* |
96 | +* Copyright (C) Jabier Arraiza Cenoz 2014 <jabier.arraiza@marker.es> |
97 | + * Released under GNU GPL, read the file 'COPYING' for more information |
98 | + */ |
99 | + |
100 | +#include <gtkmm.h> |
101 | +#include <glibmm/i18n.h> |
102 | +#include "live_effects/lpe-show_handles.h" |
103 | +#include "live_effects/parameter/parameter.h" |
104 | +#include <2geom/sbasis-to-bezier.h> |
105 | +#include <2geom/svg-path-parser.h> |
106 | +#include "helper/geom.h" |
107 | +#include "desktop-style.h" |
108 | +#include "style.h" |
109 | +#include "svg/svg.h" |
110 | + |
111 | +namespace Inkscape { |
112 | +namespace LivePathEffect { |
113 | + |
114 | +LPEShowHandles::LPEShowHandles(LivePathEffectObject *lpeobject) |
115 | + : Effect(lpeobject), |
116 | + nodes(_("Show nodes"), _("Show nodes"), "nodes", &wr, this, true), |
117 | + handles(_("Show handles"), _("Show handles"), "handles", &wr, this, true), |
118 | + originalPath(_("Show path"), _("Show path"), "originalPath", &wr, this, true), |
119 | + scaleNodesAndHandles(_("Scale nodes and handles"), _("Scale nodes and handles"), "scaleNodesAndHandles", &wr, this, 10) |
120 | +{ |
121 | + registerParameter(dynamic_cast<Parameter *>(&nodes)); |
122 | + registerParameter(dynamic_cast<Parameter *>(&handles)); |
123 | + registerParameter(dynamic_cast<Parameter *>(&originalPath)); |
124 | + registerParameter(dynamic_cast<Parameter *>(&scaleNodesAndHandles)); |
125 | + scaleNodesAndHandles.param_set_range(0, 500.); |
126 | + scaleNodesAndHandles.param_set_increments(1, 1); |
127 | + scaleNodesAndHandles.param_set_digits(2); |
128 | + strokeWidth = 1.0; |
129 | +} |
130 | + |
131 | +bool LPEShowHandles::alertsOff = false; |
132 | + |
133 | +/** |
134 | + * Sets default styles to element |
135 | + * this permanently remove.some styles of the element |
136 | + */ |
137 | + |
138 | +void LPEShowHandles::doOnApply(SPLPEItem const* lpeitem) |
139 | +{ |
140 | + if(!alertsOff) { |
141 | + char *msg = _("The \"show handles\" path effect will remove any custom style on the object you are applying it to. If this is not what you want, click Cancel."); |
142 | + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL, true); |
143 | + gint response = dialog.run(); |
144 | + alertsOff = true; |
145 | + if(response == GTK_RESPONSE_CANCEL) { |
146 | + SPLPEItem* item = const_cast<SPLPEItem*>(lpeitem); |
147 | + item->removeCurrentPathEffect(false); |
148 | + return; |
149 | + } |
150 | + } |
151 | + SPLPEItem* item = const_cast<SPLPEItem*>(lpeitem); |
152 | + SPCSSAttr *css = sp_repr_css_attr_new (); |
153 | + sp_repr_css_set_property (css, "stroke", "black"); |
154 | + sp_repr_css_set_property (css, "stroke-width", "1"); |
155 | + sp_repr_css_set_property (css, "stroke-linecap", "butt"); |
156 | + sp_repr_css_set_property(css, "fill", "none"); |
157 | + |
158 | + sp_desktop_apply_css_recursive(item, css, true); |
159 | + sp_repr_css_attr_unref (css); |
160 | +} |
161 | + |
162 | +void LPEShowHandles::doBeforeEffect (SPLPEItem const* lpeitem) |
163 | +{ |
164 | + SPItem const* item = SP_ITEM(lpeitem); |
165 | + strokeWidth = item->style->stroke_width.computed; |
166 | +} |
167 | + |
168 | +std::vector<Geom::Path> LPEShowHandles::doEffect_path (std::vector<Geom::Path> const & path_in) |
169 | +{ |
170 | + std::vector<Geom::Path> path_out; |
171 | + Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); |
172 | + if(originalPath) { |
173 | + for (unsigned int i=0; i < path_in.size(); i++) { |
174 | + path_out.push_back(path_in[i]); |
175 | + } |
176 | + } |
177 | + if(!outlinepath.empty()) { |
178 | + outlinepath.clear(); |
179 | + } |
180 | + generateHelperPath(original_pathv); |
181 | + for (unsigned int i=0; i < outlinepath.size(); i++) { |
182 | + path_out.push_back(outlinepath[i]); |
183 | + } |
184 | + return path_out; |
185 | +} |
186 | + |
187 | +void |
188 | +LPEShowHandles::generateHelperPath(Geom::PathVector result) |
189 | +{ |
190 | + if(!handles && !nodes) { |
191 | + return; |
192 | + } |
193 | + |
194 | + Geom::CubicBezier const *cubic = NULL; |
195 | + for (Geom::PathVector::iterator path_it = result.begin(); path_it != result.end(); ++path_it) { |
196 | + //Si está vacío... |
197 | + if (path_it->empty()) { |
198 | + continue; |
199 | + } |
200 | + //Itreadores |
201 | + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve |
202 | + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve |
203 | + Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop |
204 | + |
205 | + if (path_it->closed()) { |
206 | + // if the path is closed, maybe we have to stop a bit earlier because the |
207 | + // closing line segment has zerolength. |
208 | + const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type |
209 | + // Geom::LineSegment. |
210 | + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { |
211 | + // closingline.isDegenerate() did not work, because it only checks for |
212 | + // *exact* zero length, which goes wrong for relative coordinates and |
213 | + // rounding errors... |
214 | + // the closing line segment has zero-length. So stop before that one! |
215 | + curve_endit = path_it->end_open(); |
216 | + } |
217 | + } |
218 | + if(nodes) { |
219 | + drawNode(curve_it1->initialPoint()); |
220 | + } |
221 | + while (curve_it1 != curve_endit) { |
222 | + cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1); |
223 | + if (cubic) { |
224 | + if(handles) { |
225 | + if(!are_near((*cubic)[0],(*cubic)[1])){ |
226 | + drawHandle((*cubic)[1]); |
227 | + drawHandleLine((*cubic)[0],(*cubic)[1]); |
228 | + } |
229 | + if(!are_near((*cubic)[3],(*cubic)[2])){ |
230 | + drawHandle((*cubic)[2]); |
231 | + drawHandleLine((*cubic)[3],(*cubic)[2]); |
232 | + } |
233 | + } |
234 | + } |
235 | + if(nodes) { |
236 | + drawNode(curve_it1->finalPoint()); |
237 | + } |
238 | + ++curve_it1; |
239 | + if(curve_it2 != curve_endit){ |
240 | + ++curve_it2; |
241 | + } |
242 | + } |
243 | + } |
244 | +} |
245 | + |
246 | +void |
247 | +LPEShowHandles::drawNode(Geom::Point p) |
248 | +{ |
249 | + if(strokeWidth * scaleNodesAndHandles > 0.0) { |
250 | + double diameter = strokeWidth * scaleNodesAndHandles; |
251 | + char const * svgd; |
252 | + svgd = "M 0.55,0.5 A 0.05,0.05 0 0 1 0.5,0.55 0.05,0.05 0 0 1 0.45,0.5 0.05,0.05 0 0 1 0.5,0.45 0.05,0.05 0 0 1 0.55,0.5 Z M 0,0 1,0 1,1 0,1 Z"; |
253 | + Geom::PathVector pathv = sp_svg_read_pathv(svgd); |
254 | + pathv *= Geom::Affine(diameter,0,0,diameter,0,0); |
255 | + pathv += p - Geom::Point(diameter/2,diameter/2); |
256 | + outlinepath.push_back(pathv[0]); |
257 | + outlinepath.push_back(pathv[1]); |
258 | + } |
259 | +} |
260 | + |
261 | +void |
262 | +LPEShowHandles::drawHandle(Geom::Point p) |
263 | +{ |
264 | + if(strokeWidth * scaleNodesAndHandles > 0.0) { |
265 | + double diameter = strokeWidth * scaleNodesAndHandles; |
266 | + char const * svgd; |
267 | + svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z"; |
268 | + Geom::PathVector pathv = sp_svg_read_pathv(svgd); |
269 | + pathv *= Geom::Affine(diameter,0,0,diameter,0,0); |
270 | + pathv += p - Geom::Point(diameter * 0.35,diameter * 0.35); |
271 | + outlinepath.push_back(pathv[0]); |
272 | + } |
273 | +} |
274 | + |
275 | + |
276 | +void |
277 | +LPEShowHandles::drawHandleLine(Geom::Point p,Geom::Point p2) |
278 | +{ |
279 | + Geom::Path path; |
280 | + double diameter = strokeWidth * scaleNodesAndHandles; |
281 | + if(diameter > 0.0 && Geom::distance(p,p2) > (diameter * 0.35)){ |
282 | + Geom::Ray ray2(p, p2); |
283 | + p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35)); |
284 | + } |
285 | + path.start( p ); |
286 | + path.appendNew<Geom::LineSegment>( p2 ); |
287 | + outlinepath.push_back(path); |
288 | +} |
289 | + |
290 | +}; //namespace LivePathEffect |
291 | +}; /* namespace Inkscape */ |
292 | + |
293 | +/* |
294 | + Local Variables: |
295 | + mode:c++ |
296 | + c-file-style:"stroustrup" |
297 | + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) |
298 | + indent-tabs-mode:nil |
299 | + fill-column:99 |
300 | + End: |
301 | +*/ |
302 | +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : |
303 | |
304 | === added file 'src/live_effects/lpe-show_handles.h' |
305 | --- src/live_effects/lpe-show_handles.h 1970-01-01 00:00:00 +0000 |
306 | +++ src/live_effects/lpe-show_handles.h 2014-08-19 17:31:23 +0000 |
307 | @@ -0,0 +1,61 @@ |
308 | +#ifndef INKSCAPE_LPE_SHOW_HANDLES_H |
309 | +#define INKSCAPE_LPE_SHOW_HANDLES_H |
310 | + |
311 | +/* |
312 | + * Authors: |
313 | + * Jabier Arraiza Cenoz |
314 | +* |
315 | +* Copyright (C) Jabier Arraiza Cenoz 2014 <jabier.arraiza@marker.es> |
316 | + * Released under GNU GPL, read the file 'COPYING' for more information |
317 | + */ |
318 | + |
319 | +#include "live_effects/effect.h" |
320 | +#include "live_effects/lpegroupbbox.h" |
321 | +#include "live_effects/parameter/bool.h" |
322 | + |
323 | +namespace Inkscape { |
324 | +namespace LivePathEffect { |
325 | + |
326 | +class LPEShowHandles : public Effect , GroupBBoxEffect { |
327 | + |
328 | +public: |
329 | + LPEShowHandles(LivePathEffectObject *lpeobject); |
330 | + virtual ~LPEShowHandles(){} |
331 | + |
332 | + virtual void doOnApply(SPLPEItem const* lpeitem); |
333 | + |
334 | + virtual void doBeforeEffect (SPLPEItem const* lpeitem); |
335 | + |
336 | + virtual void generateHelperPath(Geom::PathVector result); |
337 | + |
338 | + virtual void drawNode(Geom::Point p); |
339 | + |
340 | + virtual void drawHandle(Geom::Point p); |
341 | + |
342 | + virtual void drawHandleLine(Geom::Point p,Geom::Point p2); |
343 | + |
344 | +protected: |
345 | + |
346 | + virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & path_in); |
347 | + |
348 | +private: |
349 | + |
350 | + BoolParam nodes; |
351 | + BoolParam handles; |
352 | + BoolParam originalPath; |
353 | + ScalarParam scaleNodesAndHandles; |
354 | + double strokeWidth; |
355 | + static bool alertsOff; |
356 | + |
357 | + Geom::PathVector outlinepath; |
358 | + |
359 | + LPEShowHandles(const LPEShowHandles &); |
360 | + LPEShowHandles &operator=(const LPEShowHandles &); |
361 | + |
362 | +}; |
363 | + |
364 | +}; //namespace LivePathEffect |
365 | +}; //namespace Inkscape |
366 | +#endif |
367 | + |
368 | +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : |
Looks good for the most part. Things that need fixing are placed in diff comments.
lpe-show_handles.h needs to comply with our coding style a little bit more. Use four spaces instead of two, and don't forget the "tail."
( // vim: filetype= cpp:expandtab: shiftwidth= 4:tabstop= 8:softtabstop= 4 : )