summaryrefslogtreecommitdiffstats
path: root/src/live_effects
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2014-08-12 22:30:34 +0000
committerJabiertxof <jtx@jtx.marker.es>2014-08-12 22:30:34 +0000
commit96126a3b2946c788d4701e35becfb22a4c38012e (patch)
tree244d0c95e0c04116f9f9c8916c7ff5ad0f40dff1 /src/live_effects
parentupdating pot files (diff)
downloadinkscape-96126a3b2946c788d4701e35becfb22a4c38012e.tar.gz
inkscape-96126a3b2946c788d4701e35becfb22a4c38012e.zip
Add 'Show handles' LPE
(bzr r13341.1.139)
Diffstat (limited to 'src/live_effects')
-rw-r--r--src/live_effects/CMakeLists.txt2
-rw-r--r--src/live_effects/Makefile_insert2
-rw-r--r--src/live_effects/effect-enum.h1
-rw-r--r--src/live_effects/effect.cpp7
-rw-r--r--src/live_effects/lpe-show_handles.cpp211
-rw-r--r--src/live_effects/lpe-show_handles.h61
6 files changed, 283 insertions, 1 deletions
diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt
index 3c64e5c8e..d126aca9f 100644
--- a/src/live_effects/CMakeLists.txt
+++ b/src/live_effects/CMakeLists.txt
@@ -31,6 +31,7 @@ set(live_effects_SRC
lpe-recursiveskeleton.cpp
lpe-rough-hatches.cpp
lpe-ruler.cpp
+ lpe-show_handles.cpp
lpe-simplify.cpp
# lpe-skeleton.cpp
lpe-sketch.cpp
@@ -99,6 +100,7 @@ set(live_effects_SRC
lpe-rough-hatches.h
lpe-ruler.h
lpe-simplify.h
+ lpe-show_handles.h
lpe-skeleton.h
lpe-sketch.h
lpe-spiro.h
diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert
index 91651a7c8..e9609a4aa 100644
--- a/src/live_effects/Makefile_insert
+++ b/src/live_effects/Makefile_insert
@@ -48,6 +48,8 @@ ink_common_sources += \
live_effects/lpe-lattice2.h \
live_effects/lpe-roughen.cpp \
live_effects/lpe-roughen.h \
+ live_effects/lpe-show_handles.cpp \
+ live_effects/lpe-show_handles.h \
live_effects/lpe-simplify.cpp \
live_effects/lpe-simplify.h \
live_effects/lpe-envelope.cpp \
diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h
index dac44981c..bc77d65c3 100644
--- a/src/live_effects/effect-enum.h
+++ b/src/live_effects/effect-enum.h
@@ -30,6 +30,7 @@ enum EffectType {
LATTICE,
LATTICE2,
ROUGHEN,
+ SHOW_HANDLES,
SIMPLIFY,
ENVELOPE,
CONSTRUCT_GRID,
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp
index 387dd7b8d..dc61701df 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -28,6 +28,7 @@
#include "live_effects/lpe-lattice.h"
#include "live_effects/lpe-lattice2.h"
#include "live_effects/lpe-roughen.h"
+#include "live_effects/lpe-show_handles.h"
#include "live_effects/lpe-simplify.h"
#include "live_effects/lpe-envelope.h"
#include "live_effects/lpe-constructgrid.h"
@@ -126,7 +127,8 @@ const Util::EnumData<EffectType> LPETypeData[] = {
/* 0.91 */
{POWERSTROKE, N_("Power stroke"), "powerstroke"},
{CLONE_ORIGINAL, N_("Clone original path"), "clone_original"},
- {ROUGHEN, N_("Roughen"), "roughen"},
+ {SHOW_HANDLES, N_("Show handles"), "show_handles"},
+ {ROUGHEN, N_("Roughen"), "roughen"},
{BSPLINE, N_("BSpline"), "bspline"},
{SIMPLIFY, N_("Simplify"), "simplify"},
{LATTICE2, N_("Lattice Deformation 2"), "lattice2"},
@@ -274,6 +276,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
case ROUGHEN:
neweffect = static_cast<Effect*> ( new LPERoughen(lpeobj) );
break;
+ case SHOW_HANDLES:
+ neweffect = static_cast<Effect*> ( new LPEShowHandles(lpeobj) );
+ break;
default:
g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr);
neweffect = NULL;
diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp
new file mode 100644
index 000000000..7b2b445b7
--- /dev/null
+++ b/src/live_effects/lpe-show_handles.cpp
@@ -0,0 +1,211 @@
+/*
+ * Authors:
+ * Jabier Arraiza Cenoz
+*
+* Copyright (C) Jabier Arraiza Cenoz 2014 <jabier.arraiza@marker.es>
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm.h>
+#include <glibmm/i18n.h>
+#include "live_effects/lpe-show_handles.h"
+#include "live_effects/parameter/parameter.h"
+#include <2geom/sbasis-to-bezier.h>
+#include <2geom/svg-path-parser.h>
+#include "helper/geom.h"
+#include "desktop-style.h"
+#include "style.h"
+#include "svg/svg.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+LPEShowHandles::LPEShowHandles(LivePathEffectObject *lpeobject)
+ : Effect(lpeobject),
+ nodes(_("Show nodes"), _("Show nodes"), "nodes", &wr, this, true),
+ handles(_("Show handles"), _("Show handles"), "handles", &wr, this, true),
+ originalPath(_("Show path"), _("Show path"), "originalPath", &wr, this, true),
+ scaleNodesAndHandles(_("Scale nodes and handles"), _("Scale nodes and handles"), "scaleNodesAndHandles", &wr, this, 10)
+{
+ registerParameter(dynamic_cast<Parameter *>(&nodes));
+ registerParameter(dynamic_cast<Parameter *>(&handles));
+ registerParameter(dynamic_cast<Parameter *>(&originalPath));
+ registerParameter(dynamic_cast<Parameter *>(&scaleNodesAndHandles));
+ scaleNodesAndHandles.param_set_range(0, 500.);
+ scaleNodesAndHandles.param_set_increments(1, 1);
+ scaleNodesAndHandles.param_set_digits(2);
+ strokeWidth = 1.0;
+}
+
+bool LPEShowHandles::alertsOff = false;
+
+/**
+ * Sets default styles to element
+ * this permanently remove.some styles of the element
+ */
+
+void LPEShowHandles::doOnApply(SPLPEItem const* lpeitem)
+{
+ if(!alertsOff) {
+ 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.");
+ Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL, true);
+ gint response = dialog.run();
+ alertsOff = true;
+ if(response == GTK_RESPONSE_CANCEL) {
+ SPLPEItem* item = const_cast<SPLPEItem*>(lpeitem);
+ item->removeCurrentPathEffect(false);
+ return;
+ }
+ }
+ SPLPEItem* item = const_cast<SPLPEItem*>(lpeitem);
+ SPCSSAttr *css = sp_repr_css_attr_new ();
+ sp_repr_css_set_property (css, "stroke", "black");
+ sp_repr_css_set_property (css, "stroke-width", "1");
+ sp_repr_css_set_property (css, "stroke-linecap", "butt");
+ sp_repr_css_set_property(css, "fill", "none");
+
+ sp_desktop_apply_css_recursive(item, css, true);
+ sp_repr_css_attr_unref (css);
+}
+
+void LPEShowHandles::doBeforeEffect (SPLPEItem const* lpeitem)
+{
+ SPItem const* item = SP_ITEM(lpeitem);
+ strokeWidth = item->style->stroke_width.computed;
+}
+
+std::vector<Geom::Path> LPEShowHandles::doEffect_path (std::vector<Geom::Path> const & path_in)
+{
+ std::vector<Geom::Path> path_out;
+ Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in);
+ if(originalPath) {
+ for (unsigned int i=0; i < path_in.size(); i++) {
+ path_out.push_back(path_in[i]);
+ }
+ }
+ if(!outlinepath.empty()) {
+ outlinepath.clear();
+ }
+ generateHelperPath(original_pathv);
+ for (unsigned int i=0; i < outlinepath.size(); i++) {
+ path_out.push_back(outlinepath[i]);
+ }
+ return path_out;
+}
+
+void
+LPEShowHandles::generateHelperPath(Geom::PathVector result)
+{
+ if(!handles && !nodes) {
+ return;
+ }
+
+ Geom::CubicBezier const *cubic = NULL;
+ for (Geom::PathVector::iterator path_it = result.begin(); path_it != result.end(); ++path_it) {
+ //Si está vacío...
+ if (path_it->empty()) {
+ continue;
+ }
+ //Itreadores
+ Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve
+ Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve
+ Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop
+
+ if (path_it->closed()) {
+ // if the path is closed, maybe we have to stop a bit earlier because the
+ // closing line segment has zerolength.
+ const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type
+ // Geom::LineSegment.
+ if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
+ // closingline.isDegenerate() did not work, because it only checks for
+ // *exact* zero length, which goes wrong for relative coordinates and
+ // rounding errors...
+ // the closing line segment has zero-length. So stop before that one!
+ curve_endit = path_it->end_open();
+ }
+ }
+ if(nodes) {
+ drawNode(curve_it1->initialPoint());
+ }
+ while (curve_it1 != curve_endit) {
+ cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
+ if (cubic) {
+ if(handles) {
+ if(!are_near((*cubic)[0],(*cubic)[1])){
+ drawHandle((*cubic)[1]);
+ drawHandleLine((*cubic)[0],(*cubic)[1]);
+ }
+ if(!are_near((*cubic)[3],(*cubic)[2])){
+ drawHandle((*cubic)[2]);
+ drawHandleLine((*cubic)[3],(*cubic)[2]);
+ }
+ }
+ }
+ if(nodes) {
+ drawNode(curve_it1->finalPoint());
+ }
+ ++curve_it1;
+ if(curve_it2 != curve_endit){
+ ++curve_it2;
+ }
+ }
+ }
+}
+
+void
+LPEShowHandles::drawNode(Geom::Point p)
+{
+ if(strokeWidth * scaleNodesAndHandles > 0.0) {
+ double diameter = strokeWidth * scaleNodesAndHandles;
+ char const * svgd;
+ 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";
+ Geom::PathVector pathv = sp_svg_read_pathv(svgd);
+ pathv *= Geom::Affine(diameter,0,0,diameter,0,0);
+ pathv += p - Geom::Point(diameter/2,diameter/2);
+ outlinepath.push_back(pathv[0]);
+ outlinepath.push_back(pathv[1]);
+ }
+}
+
+void
+LPEShowHandles::drawHandle(Geom::Point p)
+{
+ if(strokeWidth * scaleNodesAndHandles > 0.0) {
+ double diameter = strokeWidth * scaleNodesAndHandles;
+ char const * svgd;
+ 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";
+ Geom::PathVector pathv = sp_svg_read_pathv(svgd);
+ pathv *= Geom::Affine(diameter,0,0,diameter,0,0);
+ pathv += p - Geom::Point(diameter * 0.35,diameter * 0.35);
+ outlinepath.push_back(pathv[0]);
+ }
+}
+
+
+void
+LPEShowHandles::drawHandleLine(Geom::Point p,Geom::Point p2)
+{
+ Geom::Path path;
+ double diameter = strokeWidth * scaleNodesAndHandles;
+ if(diameter > 0.0 && Geom::distance(p,p2) > (diameter * 0.35)){
+ Geom::Ray ray2(p, p2);
+ p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35));
+ }
+ path.start( p );
+ path.appendNew<Geom::LineSegment>( p2 );
+ outlinepath.push_back(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/lpe-show_handles.h b/src/live_effects/lpe-show_handles.h
new file mode 100644
index 000000000..278908bb5
--- /dev/null
+++ b/src/live_effects/lpe-show_handles.h
@@ -0,0 +1,61 @@
+#ifndef INKSCAPE_LPE_SHOW_HANDLES_H
+#define INKSCAPE_LPE_SHOW_HANDLES_H
+
+/*
+ * Authors:
+ * Jabier Arraiza Cenoz
+*
+* Copyright (C) Jabier Arraiza Cenoz 2014 <jabier.arraiza@marker.es>
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/effect.h"
+#include "live_effects/lpegroupbbox.h"
+#include "live_effects/parameter/bool.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+class LPEShowHandles : public Effect , GroupBBoxEffect {
+
+public:
+ LPEShowHandles(LivePathEffectObject *lpeobject);
+ virtual ~LPEShowHandles(){}
+
+ virtual void doOnApply(SPLPEItem const* lpeitem);
+
+ virtual void doBeforeEffect (SPLPEItem const* lpeitem);
+
+ virtual void generateHelperPath(Geom::PathVector result);
+
+ virtual void drawNode(Geom::Point p);
+
+ virtual void drawHandle(Geom::Point p);
+
+ virtual void drawHandleLine(Geom::Point p,Geom::Point p2);
+
+protected:
+
+ virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & path_in);
+
+private:
+
+ BoolParam nodes;
+ BoolParam handles;
+ BoolParam originalPath;
+ ScalarParam scaleNodesAndHandles;
+ double strokeWidth;
+ static bool alertsOff;
+
+ Geom::PathVector outlinepath;
+
+ LPEShowHandles(const LPEShowHandles &);
+ LPEShowHandles &operator=(const LPEShowHandles &);
+
+};
+
+}; //namespace LivePathEffect
+}; //namespace Inkscape
+#endif
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :