Code

Make knotholders for LPE items finally work; each effect can now overload the addKnot...
authorcilix42 <cilix42@users.sourceforge.net>
Sun, 8 Jun 2008 17:33:58 +0000 (17:33 +0000)
committercilix42 <cilix42@users.sourceforge.net>
Sun, 8 Jun 2008 17:33:58 +0000 (17:33 +0000)
There is now also a virtual onKnotUngrabbed() method for each knotholder entity which can be used to do cleanup tasks (for LPE parameters it currently writes the value to SVG, although this should probably happen automatically)

14 files changed:
src/knot-holder-entity.h
src/knot.cpp
src/knot.h
src/knotholder.cpp
src/knotholder.h
src/live_effects/effect.cpp
src/live_effects/effect.h
src/live_effects/lpe-tangent_to_curve.cpp
src/live_effects/lpe-tangent_to_curve.h
src/live_effects/parameter/parameter.h
src/live_effects/parameter/point.cpp
src/live_effects/parameter/point.h
src/object-edit.cpp
src/shape-editor.cpp

index 5c273fe29a5a2918b644b62e533dac0838a0aef3..f0862c87483ccf44958ddc8b068f71ff4165013f 100644 (file)
@@ -43,11 +43,17 @@ public:
                         SPKnotModeType mode = SP_KNOT_MODE_XOR,
                         guint32 color = 0xffffff00);
 
+    /* derived classes like PointParam for LPEs use this, e.g., to indicate that we must not call
+       delete on their pointer when a knotholder is destroyed */
+    virtual bool isLPEParam() { return false; }
+
     /* the get/set/click handlers are virtual functions; each handler class for a knot
        should be derived from KnotHolderEntity and override these functions */
     virtual void knot_set(NR::Point const &p, NR::Point const &origin, guint state) = 0;
     virtual NR::Point knot_get() = 0;
     virtual void knot_click(guint /*state*/) {}
+    virtual void onKnotUngrabbed() {} // this is called 'manually' from KnotHolder; would it be
+                                      // more efficient to establish another signal connection?
 
     void update_knot();
 
index 4e4cf567806513622b584ccaa56bd144c9e9b286..2348f4aeac61beca37e22212df4ea2b349f8838a 100644 (file)
@@ -335,7 +335,7 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot
                         g_signal_emit(knot,
                                       knot_signals[UNGRABBED], 0,
                                       event->button.state);
-                        knot->_ungrabbed_signal.emit();
+                        knot->_ungrabbed_signal.emit(knot);
                     } else {
                         g_signal_emit(knot,
                                       knot_signals[CLICKED], 0,
index 07f5040fac30087c2a921605377332ebf0a7a1c3..b1505daacbec3b7a31447d6e4cfa378c52d12833 100644 (file)
@@ -74,7 +74,7 @@ struct SPKnot : GObject {
     **/
     sigc::signal<void, SPKnot *, NR::Point const *, guint> _moved_signal;
     sigc::signal<void, SPKnot *, guint> _click_signal;
-    sigc::signal<void> _ungrabbed_signal;
+    sigc::signal<void, SPKnot *> _ungrabbed_signal;
 
     //TODO: all the members above should eventualle become private, accessible via setters/getters
     inline void setSize (guint i) {size = i;}
index 0a3cb295769138d99112eba3a52f891570c20c60..1ca280d48c0b85db91f0cc52b1909264d3082dc3 100644 (file)
@@ -58,7 +58,16 @@ KnotHolder::KnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFun
 KnotHolder::~KnotHolder() {
     g_object_unref(G_OBJECT(item));
     for(std::list<KnotHolderEntity *>::iterator i = entity.begin(); i != entity.end(); ++i) {
-        delete *i;
+        KnotHolderEntity* e = (*i);
+        if (!e->isLPEParam()) {
+            // knotholder entity may be deleted
+            delete (*i);
+        } else {
+            // we must not delete the entity since it's an LPE parameter,
+            // but the handle should be destroyed
+            g_object_unref(e->knot);
+        }
+        (*i) = NULL;
     }
     entity.clear(); // this shouldn't be necessary, though
 }
@@ -145,7 +154,7 @@ KnotHolder::knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state)
 }
 
 void
-KnotHolder::knot_ungrabbed_handler()
+KnotHolder::knot_ungrabbed_handler(SPKnot *knot)
 {
     if (this->released) {
         this->released(this->item);
@@ -153,6 +162,16 @@ KnotHolder::knot_ungrabbed_handler()
         SPObject *object = (SPObject *) this->item;
         object->updateRepr(object->repr, SP_OBJECT_WRITE_EXT);
 
+        /* do cleanup tasks (e.g., for LPE items write the parameter values
+         * that were changed by dragging the handle to SVG)
+         */
+        for(std::list<KnotHolderEntity *>::iterator i = this->entity.begin(); i != this->entity.end(); ++i) {
+            KnotHolderEntity *e = *i;
+            if (e->knot == knot) {
+                e->onKnotUngrabbed(); // for most KnotHolderEntitys this does nothing
+            }
+        }
+
         unsigned int object_verb = SP_VERB_NONE;
 
         if (SP_IS_RECT(object))
@@ -177,6 +196,12 @@ KnotHolder::knot_ungrabbed_handler()
     }
 }
 
+void
+KnotHolder::add(KnotHolderEntity *e)
+{
+    entity.push_back(e);
+}
+
 void
 KnotHolder::add_pattern_knotholder()
 {
index 316db208217e74317b56227b9c304966b860848c..14a1397689f5fc23a1f53c6b3476266468977e4c 100644 (file)
@@ -46,7 +46,9 @@ public:
 
     void knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state);
     void knot_clicked_handler(SPKnot *knot, guint state);
-    void knot_ungrabbed_handler();
+    void knot_ungrabbed_handler(SPKnot *knot);
+
+    void add(KnotHolderEntity *e);
 
     void add_pattern_knotholder();
 
index 0749e4e93b250117d6dfe9c1ff757807408c7cb6..db395c81b51c6b7684f49d965cffa99d21f13396 100644 (file)
@@ -321,21 +321,39 @@ Effect::registerParameter(Parameter * param)
     param_vector.push_back(param);
 }
 
+// TODO: Does it still make sense to use this? E.g., should we keep a list of knotholder entities
+//       in the effect itself and add them here in a semi-automatic manner (similarly to how it is
+//       done with parameters) instead of adding each one separately in the overloaded function
+//       addKnotHolderHandles()?
 void
 Effect::registerKnotHolderHandle(SPKnotHolderSetFunc set_func, SPKnotHolderGetFunc get_func)
 {
-    knotholder_func_vector.push_back(std::make_pair(set_func, get_func));
+    //knotholder_func_vector.push_back(std::make_pair(set_func, get_func));
 }
 
-// TODO: allow for adding click_functions and description strings, too
 void
-Effect::addHandles(KnotHolder *knotholder) {
-    std::vector<std::pair<SPKnotHolderSetFunc, SPKnotHolderGetFunc> >::iterator i;
-    for (i = knotholder_func_vector.begin(); i != knotholder_func_vector.end(); ++i) {
-        //knotholder->add(i->first, i->second, NULL, (""));
+Effect::addPointParamHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
+    using namespace std;
+    for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) {
+        if ((*p)->paramType() == Inkscape::LivePathEffect::POINT_PARAM) {
+            g_print ("Parameter is of type PointParam\n");
+            KnotHolderEntity *e = dynamic_cast<KnotHolderEntity *>(*p);
+            e->create(desktop, item, knotholder);
+            knotholder->add(e);
+        } else {
+            g_print ("Parameter is *not* of type PointParam\n");
+        }
     }
 }
 
+/**
+ * Virtual method to add knotholder handles for LPE items
+ */
+void
+Effect::addKnotHolderHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item)
+{
+}
+
 /**
  * This *creates* a new widget, management of deletion should be done by the caller
  */
index a8cb525b8f500b915fa73f1d3ab05826bbac2d8f..c46c145b58afcf8c6455104f2f0c1f10f09c13c0 100644 (file)
@@ -101,8 +101,9 @@ public:
 
     virtual void transform_multiply(Geom::Matrix const& postmul, bool set);
 
-    bool providesKnotholder() { return knotholder_func_vector.size() > 0; }
-    void addHandles(KnotHolder *knotholder);
+    virtual bool providesKnotholder() { return false; }
+    void addPointParamHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
+    virtual void addKnotHolderHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
 
     Glib::ustring          getName();
     Inkscape::XML::Node *  getRepr();
@@ -135,7 +136,6 @@ protected:
     Parameter * getNextOncanvasEditableParam();
 
     std::vector<Parameter *> param_vector;
-    std::vector<std::pair<SPKnotHolderSetFunc, SPKnotHolderGetFunc> > knotholder_func_vector;
     int oncanvasedit_it;
     BoolParam is_visible;
 
index 80158e2f4c81f165f33344c2031ed12ae73b274e..b61a078a4562cc4e24e60847b99fe7b34cb191b7 100644 (file)
 namespace Inkscape {
 namespace LivePathEffect {
 
-/* FIXME: We should make these member functions of LPETangentToCurve.
-          Is there an easy way to register member functions with knotholder?
-    KNOWN BUG: Because of the above, this effect does not work well when in an LPE stack
-*/
-NR::Point attach_pt_get(SPItem *item) {
-    Inkscape::LivePathEffect::LPETangentToCurve *lpe =
-        dynamic_cast<Inkscape::LivePathEffect::LPETangentToCurve *> (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)));
-
-    if (lpe)
-        return lpe->ptA;
-    else
-        return NR::Point(0,0);
+LPETangentToCurve::LPETangentToCurve(LivePathEffectObject *lpeobject) :
+    Effect(lpeobject),
+    angle(_("Angle"), _("Additional angle between tangent and curve"), "angle", &wr, this, 0.0),
+    t_attach(_("Location along curve"), _("Location of the point of attachment along the curve (between 0.0 and number-of-segments)"), "t_attach", &wr, this, 0.5),
+    length_left(_("Length left"), _("Specifies the left end of the tangent"), "length-left", &wr, this, 150),
+    length_right(_("Length right"), _("Specifies the right end of the tangent"), "length-right", &wr, this, 150)
+{
+    registerParameter( dynamic_cast<Parameter *>(&angle) );
+    registerParameter( dynamic_cast<Parameter *>(&t_attach) );
+    registerParameter( dynamic_cast<Parameter *>(&length_left) );
+    registerParameter( dynamic_cast<Parameter *>(&length_right) );
 }
 
-void attach_pt_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) {
-    Inkscape::LivePathEffect::LPETangentToCurve *lpe =
-        dynamic_cast<Inkscape::LivePathEffect::LPETangentToCurve *> (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)));
-
-    if (!lpe)
-        return;
+LPETangentToCurve::~LPETangentToCurve()
+{
+}
 
+Geom::Piecewise<Geom::D2<Geom::SBasis> >
+LPETangentToCurve::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
+{
     using namespace Geom;
+    Piecewise<D2<SBasis> > output;
+
+    ptA = pwd2_in.valueAt(t_attach);
+    derivA = unit_vector(derivative(pwd2_in).valueAt(t_attach));
+
+    // TODO: Why are positive angles measured clockwise, not counterclockwise?
+    Geom::Rotate rot(Geom::Rotate::from_degrees(-angle));
+    derivA = derivA * rot;
+
+    C = ptA - derivA * length_left;
+    D = ptA + derivA * length_right;
+
+    output = Piecewise<D2<SBasis> >(D2<SBasis>(Linear(C[X], D[X]), Linear(C[Y], D[Y])));
+
+    return output;
+}
+
+class KnotHolderEntityAttachPt : public KnotHolderEntity
+{
+public:
+    virtual bool isLPEParam() { return true; }
+
+    virtual void knot_set(NR::Point const &p, NR::Point const &origin, guint state);
+    virtual NR::Point knot_get();
+    virtual void onKnotUngrabbed();
+};
+
+class KnotHolderEntityLeftEnd : public KnotHolderEntity
+{
+public:
+    virtual bool isLPEParam() { return true; }
+
+    virtual void knot_set(NR::Point const &p, NR::Point const &origin, guint state);
+    virtual NR::Point knot_get();
+    virtual void onKnotUngrabbed();
+};
+
+class KnotHolderEntityRightEnd : public KnotHolderEntity
+{
+public:
+    virtual bool isLPEParam() { return true; }
+
+    virtual void knot_set(NR::Point const &p, NR::Point const &origin, guint state);
+    virtual NR::Point knot_get();
+    virtual void onKnotUngrabbed();
+};
+
+void
+LPETangentToCurve::addKnotHolderHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item)
+{
+    KnotHolderEntityLeftEnd *entity_left_end = new KnotHolderEntityLeftEnd();
+    KnotHolderEntityRightEnd *entity_right_end = new KnotHolderEntityRightEnd();
+    KnotHolderEntityAttachPt *entity_attach_pt = new KnotHolderEntityAttachPt();
+
+    entity_left_end->create(desktop, item, knotholder,
+                            _("Adjust the \"left\" end of the tangent"));
+    entity_right_end->create(desktop, item, knotholder,
+                            _("Adjust the \"right\" end of the tangent"));
+    entity_attach_pt->create(desktop, item, knotholder,
+                            _("Adjust the point of attachment of the tangent"));
+
+    knotholder->add(entity_left_end);
+    knotholder->add(entity_right_end);
+    knotholder->add(entity_attach_pt);
+}
+
+static LPETangentToCurve *
+get_effect(SPItem *item)
+{
+    Effect *effect = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item));
+    if (effect->effectType() != TANGENT_TO_CURVE) {
+        g_print ("Warning: Effect is not of type LPETangentToCurve!\n");
+        return NULL;
+    }
+    return static_cast<LPETangentToCurve *>(effect);
+}
+
+void
+KnotHolderEntityAttachPt::knot_set(NR::Point const &p, NR::Point const &origin, guint state)
+{
+     using namespace Geom;
+     LPETangentToCurve* lpe = get_effect(item);
 
     // FIXME: There must be a better way of converting the path's SPCurve* to pwd2.
     SPCurve *curve = sp_path_get_curve_for_edit (SP_PATH(item));
@@ -66,94 +148,73 @@ void attach_pt_set(SPItem *item, NR::Point const &p, NR::Point const &origin, gu
     sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), true, true);
 }
 
-NR::Point left_end_get(SPItem *item) {
-    Inkscape::LivePathEffect::LPETangentToCurve *lpe =
-        dynamic_cast<Inkscape::LivePathEffect::LPETangentToCurve *> (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)));
-
-    if (lpe)
-        return lpe->C;
-    else
-        return NR::Point(0,0);
-}
-
-NR::Point right_end_get(SPItem *item) {
-    Inkscape::LivePathEffect::LPETangentToCurve *lpe =
-        dynamic_cast<Inkscape::LivePathEffect::LPETangentToCurve *> (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)));
-
-    if (lpe)
-        return lpe->D;
-    else
-        return NR::Point(0,0);
-}
-
-void left_end_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) {
-    Inkscape::LivePathEffect::LPETangentToCurve *lpe =
-        dynamic_cast<Inkscape::LivePathEffect::LPETangentToCurve *> (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)));
-
-    if (!lpe)
-        return;
-
+void
+KnotHolderEntityLeftEnd::knot_set(NR::Point const &p, NR::Point const &origin, guint state)
+{
+    LPETangentToCurve *lpe = get_effect(item);
+    
     double lambda = Geom::nearest_point(p.to_2geom(), lpe->ptA, lpe->derivA);
     lpe->length_left.param_set_value(-lambda);
 
-    // 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), true, true);
+    sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);    
 }
 
-void right_end_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) {
-    Inkscape::LivePathEffect::LPETangentToCurve *lpe =
-        dynamic_cast<Inkscape::LivePathEffect::LPETangentToCurve *> (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)));
-
-    if (!lpe)
-        return;
-
+void
+KnotHolderEntityRightEnd::knot_set(NR::Point const &p, NR::Point const &origin, guint state)
+{
+    LPETangentToCurve *lpe = get_effect(item);
+    
     double lambda = Geom::nearest_point(p.to_2geom(), lpe->ptA, lpe->derivA);
     lpe->length_right.param_set_value(lambda);
 
-    // 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), true, true);
+    sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);    
 }
 
-LPETangentToCurve::LPETangentToCurve(LivePathEffectObject *lpeobject) :
-    Effect(lpeobject),
-    t_attach(_("Location along curve"), _("Location of the point of attachment along the curve (between 0.0 and number-of-segments)"), "t_attach", &wr, this, 0.5),
-    length_left(_("Length left"), _("Specifies the left end of the tangent"), "length-left", &wr, this, 150),
-    length_right(_("Length right"), _("Specifies the right end of the tangent"), "length-right", &wr, this, 150),
-    angle(_("Angle"), _("Additional angle between tangent and curve"), "angle", &wr, this, 0.0)
+NR::Point
+KnotHolderEntityAttachPt::knot_get()
 {
-    registerParameter( dynamic_cast<Parameter *>(&t_attach) );
-    registerParameter( dynamic_cast<Parameter *>(&length_left) );
-    registerParameter( dynamic_cast<Parameter *>(&length_right) );
-    registerParameter( dynamic_cast<Parameter *>(&angle) );
-    registerKnotHolderHandle(attach_pt_set, attach_pt_get);
-    registerKnotHolderHandle(left_end_set, left_end_get);
-    registerKnotHolderHandle(right_end_set, right_end_get);
+    LPETangentToCurve* lpe = get_effect(item);
+    return lpe->ptA;
 }
 
-LPETangentToCurve::~LPETangentToCurve()
+NR::Point
+KnotHolderEntityLeftEnd::knot_get()
 {
+    LPETangentToCurve *lpe = get_effect(item);
+    return lpe->C;
 }
 
-Geom::Piecewise<Geom::D2<Geom::SBasis> >
-LPETangentToCurve::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
+NR::Point
+KnotHolderEntityRightEnd::knot_get()
 {
-    using namespace Geom;
-    Piecewise<D2<SBasis> > output;
+    LPETangentToCurve *lpe = get_effect(item);
+    return lpe->D;
+}
 
-    ptA = pwd2_in.valueAt(t_attach);
-    derivA = unit_vector(derivative(pwd2_in).valueAt(t_attach));
+void
+KnotHolderEntityAttachPt::onKnotUngrabbed()
+{
+    LPETangentToCurve *lpe = get_effect(item);
+    lpe->t_attach.write_to_SVG();
+}
 
-    // TODO: Why are positive angles measured clockwise, not counterclockwise?
-    Geom::Rotate rot(Geom::Rotate::from_degrees(-angle));
-    derivA = derivA * rot;
+void
+KnotHolderEntityLeftEnd::onKnotUngrabbed()
+{
+    LPETangentToCurve *lpe = get_effect(item);
+    lpe->length_left.write_to_SVG();
+}
 
-    C = ptA - derivA * length_left;
-    D = ptA + derivA * length_right;
+void
+KnotHolderEntityRightEnd::onKnotUngrabbed()
+{
+    LPETangentToCurve *lpe = get_effect(item);
+    lpe->length_right.write_to_SVG();
+}
 
-    output = Piecewise<D2<SBasis> >(D2<SBasis>(Linear(C[X], D[X]), Linear(C[Y], D[Y])));
 
-    return output;
-}
 
 } //namespace LivePathEffect
 } /* namespace Inkscape */
index 3bddc11fb6014cf399f3318c860c14cb2cf94d38..0de2baf5624834b11fa5e717bbb5b56fcfcfee46 100644 (file)
@@ -28,25 +28,24 @@ public:
     LPETangentToCurve(LivePathEffectObject *lpeobject);
     virtual ~LPETangentToCurve();
 
+    bool providesKnotholder() { return true; }
+    virtual void addKnotHolderHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
+
     virtual Geom::Piecewise<Geom::D2<Geom::SBasis> >
       doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
 
-    /* the knotholder functions must be declared friends */
-    friend NR::Point attach_pt_get(SPItem *item);
-    friend NR::Point left_end_get(SPItem *item);
-    friend NR::Point right_end_get(SPItem *item);
-    friend void attach_pt_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state);
-    friend void left_end_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state);
-    friend void right_end_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state);
+    /* the knotholder entity classes must be declared friends */
+    friend class KnotHolderEntityLeftEnd;
+    friend class KnotHolderEntityRightEnd;
+    friend class KnotHolderEntityAttachPt;
 
 private:
-    ScalarParam t_attach;
+    ScalarParam angle;
 
+    ScalarParam t_attach;
     ScalarParam length_left;
     ScalarParam length_right;
 
-    ScalarParam angle;
-
     Geom::Point ptA; // point of attachment to the curve
     Geom::Point derivA;
 
index 511ce46a23edfd8fa8f17764c9cc978973f10ea7..c4e58c8d5d21ae3d5d3cb82ef055a9dfca7f483d 100644 (file)
@@ -58,7 +58,8 @@ public:
 
     virtual bool param_readSVGValue(const gchar * strvalue) = 0;   // returns true if new value is valid / accepted.
     virtual gchar * param_getSVGValue() const = 0;
-
+    void write_to_SVG() { param_write_to_repr(param_getSVGValue()); }
     virtual void param_set_default() = 0;
 
     void printTypeName();
index 49a47660f3dac67df6ddaeabfe8933f3e627194c..502af1f231cfd4cf806d4c13c69f37a0556548d0 100644 (file)
@@ -162,12 +162,33 @@ PointParam::set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint
     knot_color = color;
 }
 
+void
+PointParam::knot_set(NR::Point const &p, NR::Point const &origin, guint state)
+{
+    g_print ("PointParam::knot_set() was called!\n");
+    param_setValue(p.to_2geom());
+}
+
+NR::Point
+PointParam::knot_get()
+{
+    g_print ("PointParam::knot_get() was called.\n");
+    g_print ("We return (%f, %f)\n", (*this)[0], (*this)[1]);
+    return *this;
+}
+
+void
+PointParam::knot_click(guint state)
+{
+    g_print ("PointParam::knot_click() was called!\n");
+}
 
 // CALLBACKS:
 
 void
 PointParam::on_button_click()
 {
+    g_print ("PointParam::on_button_click()\n");
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
     SPItem * item = sp_desktop_selection(desktop)->singleItem();
     if (item != NULL) {
index d963d835ad0d23262d26377602667c726a4a44d9..3e8dc843ab9a7f3b95995e3d459d4abe0d4601bd 100644 (file)
 
 #include "live_effects/parameter/parameter.h"
 
-#include "knot-enums.h"
+#include "knot-holder-entity.h"
 
 namespace Inkscape {
 
 namespace LivePathEffect {
 
 
-class PointParam : public Geom::Point, public Parameter {
+class PointParam : public Geom::Point, public Parameter, public KnotHolderEntity {
 public:
     PointParam( const Glib::ustring& label,
                 const Glib::ustring& tip,
@@ -51,6 +51,13 @@ public:
 
     void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color);
 
+    /* these are overloaded from KnotHolderEntity */
+    virtual void knot_set(NR::Point const &p, NR::Point const &origin, guint state);
+    virtual NR::Point knot_get();
+    virtual void knot_click(guint state);
+
+    virtual bool isLPEParam() { return true; }
+
 private:
     PointParam(const PointParam&);
     PointParam& operator=(const PointParam&);
index 281b5e89dc3bf3355d289b42449208f45fb3a65a..8d8be4b85752a073d3fa0107f6d871d8d19881d1 100644 (file)
@@ -56,11 +56,8 @@ static KnotHolder *sp_lpe_knot_holder(SPItem *item, SPDesktop *desktop)
     KnotHolder *knot_holder = new KnotHolder(desktop, item, NULL);
 
     Inkscape::LivePathEffect::Effect *effect = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item));
-    if (!effect) {
-        g_error("sp_lpe_knot_holder: logical error, this method cannot be called with item having an LPE");
-    } else {
-        effect->addHandles(knot_holder);
-    }
+//    effect->addPointParamHandles(knot_holder, desktop, item);
+    effect->addKnotHolderHandles(knot_holder, desktop, item);
 
     return knot_holder;
 }
index 3b892db038273d5cf503f249a42969608b3c25d0..9cfa83af1f864da5d53cfad5ad45d5f180838e68 100644 (file)
@@ -192,19 +192,14 @@ void ShapeEditor::set_item(SPItem *item) {
     if (item) {
         if (SP_IS_LPE_ITEM(item)) {
             SPLPEItem *lpeitem = SP_LPE_ITEM(item);
-            if ( !sp_lpe_item_get_current_lpe(lpeitem) ||   // if returns NULL, the whole expression evaluates to true and C++ will not call the otherwise crashing 2 functions below
-                 !sp_lpe_item_get_current_lpe(lpeitem)->isVisible() ||
-                 !sp_lpe_item_get_current_lpe(lpeitem)->providesKnotholder() )
-                // only create nodepath if the item either doesn't have an LPE
-                // or the LPE is invisible or it doesn't provide a knotholder itself
-            {
-                this->nodepath =
-                    sp_nodepath_new(desktop, item, (prefs_get_int_attribute("tools.nodes", "show_handles", 1) != 0));
+            if (!sp_lpe_item_get_current_lpe(lpeitem) ||   // if returns NULL, the whole expression evaluates to true and C++ will not call the otherwise crashing 2 functions below
+                !sp_lpe_item_get_current_lpe(lpeitem)->isVisible() ||
+                !sp_lpe_item_get_current_lpe(lpeitem)->providesKnotholder()) {
+                    // only create nodepath if the item either doesn't have an LPE
+                    // or the LPE is invisible or it doesn't provide a knotholder itself
+                    this->nodepath =
+                        sp_nodepath_new(desktop, item, (prefs_get_int_attribute("tools.nodes", "show_handles", 1) != 0));
             }
-        } else {
-            // only create nodepath if the item either doesn't have an LPE: no fear the item cannot have an LPE
-            this->nodepath =
-                sp_nodepath_new(desktop, item, (prefs_get_int_attribute("tools.nodes", "show_handles", 1) != 0));
         }
 
         if (this->nodepath) {