From 6d4d113f18776c07a193beeab77046b475858945 Mon Sep 17 00:00:00 2001 From: johanengelen Date: Sat, 22 Mar 2008 19:11:02 +0000 Subject: [PATCH] * add RegisteredTransformedPoint widget, that transforms the point before displaying/writing. This in order to keep them in SVG coordinate system in XML, but in canvas coord system in the spinbox * move Geom::Point XML writing to central place in ostringstream * add verb for LPE context --- src/live_effects/parameter/point.cpp | 4 +- .../parameter/pointparam-knotholder.cpp | 204 ++++++++++++++++++ src/svg/stringstream-test.h | 2 + src/svg/stringstream.cpp | 7 + src/svg/stringstream.h | 4 + src/ui/widget/point.cpp | 5 + src/ui/widget/point.h | 3 +- src/ui/widget/registered-widget.cpp | 47 ++++ src/ui/widget/registered-widget.h | 21 +- src/verbs.cpp | 3 +- src/verbs.h | 2 +- 11 files changed, 296 insertions(+), 6 deletions(-) diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index 35d0fcdba..9b48327f6 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -70,7 +70,7 @@ gchar * PointParam::param_writeSVGValue() const { Inkscape::SVGOStringStream os; - os << (*this)[0] << "," << (*this)[1]; + os << *dynamic_cast( this ); gchar * str = g_strdup(os.str().c_str()); return str; } @@ -117,7 +117,7 @@ void PointParam::param_set_and_write_new_value (Geom::Point newpoint) { Inkscape::SVGOStringStream os; - os << newpoint[0] << "," << newpoint[1]; + os << newpoint; gchar * str = g_strdup(os.str().c_str()); param_write_to_repr(str); g_free(str); diff --git a/src/live_effects/parameter/pointparam-knotholder.cpp b/src/live_effects/parameter/pointparam-knotholder.cpp index 12d081703..fa042be5a 100644 --- a/src/live_effects/parameter/pointparam-knotholder.cpp +++ b/src/live_effects/parameter/pointparam-knotholder.cpp @@ -1,3 +1,206 @@ +<<<<<<< .mine +#define INKSCAPE_LPE_POINTPARAM_KNOTHOLDER_C + +/* + * Container for PointParamKnotHolder visual handles + * + * Authors: + * Johan Engelen + * + * Copyright (C) 2008 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/parameter/pointparam-knotholder.h" +#include "live_effects/lpeobject.h" +#include "document.h" +#include "sp-shape.h" +#include "knot.h" +#include "knotholder.h" +#include "knot-holder-entity.h" + +#include +#include +#include <2geom/point.h> +#include <2geom/matrix.h> +#include "svg/stringstream.h" +#include "xml/repr.h" + +class SPDesktop; + +namespace Inkscape { + +static void pointparam_knot_clicked_handler (SPKnot *knot, guint state, PointParamKnotHolder *kh); +static void pointparam_knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, PointParamKnotHolder *kh); +static void pointparam_knot_ungrabbed_handler (SPKnot *knot, unsigned int state, PointParamKnotHolder *kh); +static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass); + +void pointparam_knot_holder_dispose(GObject *object); + +static SPKnotHolderClass *parent_class; + +/** + * Registers PointParamKnotHolder class and returns its type number. + */ +GType pointparam_knot_holder_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(PointParamKnotHolderClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pointparam_knot_holder_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PointParamKnotHolder), + 16, /* n_preallocs */ + NULL, + NULL + }; + type = g_type_register_static (G_TYPE_OBJECT, "InkscapePointParamKnotHolder", &info, (GTypeFlags) 0); + } + return type; +} + +/** + * PointParamKnotHolder vtable initialization. + */ +static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass) +{ + GObjectClass *gobject_class; + gobject_class = (GObjectClass *) klass; + + parent_class = (SPKnotHolderClass*) g_type_class_peek_parent(klass); + gobject_class->dispose = pointparam_knot_holder_dispose; +} + +PointParamKnotHolder *pointparam_knot_holder_new(SPDesktop *desktop, SPObject *lpeobject, const gchar * key, SPItem *item) +{ + g_return_val_if_fail(desktop != NULL, NULL); + g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(SP_IS_ITEM(item), NULL); + + PointParamKnotHolder *knot_holder = (PointParamKnotHolder*)g_object_new (INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, 0); + knot_holder->desktop = desktop; + knot_holder->item = item; + knot_holder->lpeobject = LIVEPATHEFFECT(lpeobject); + g_object_ref(G_OBJECT(item)); + g_object_ref(G_OBJECT(lpeobject)); + knot_holder->entity = NULL; + + knot_holder->released = NULL; + + knot_holder->repr = lpeobject->repr; + knot_holder->repr_key = key; + + knot_holder->local_change = FALSE; + + return knot_holder; +} + +void pointparam_knot_holder_dispose(GObject *object) { + PointParamKnotHolder *kh = G_TYPE_CHECK_INSTANCE_CAST((object), INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, PointParamKnotHolder); + + g_object_unref(G_OBJECT(kh->item)); + g_object_unref(G_OBJECT(kh->lpeobject)); + while (kh->entity) { + SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data; + g_signal_handler_disconnect(e->knot, e->_click_handler_id); + g_signal_handler_disconnect(e->knot, e->_ungrab_handler_id); + /* unref should call destroy */ + g_object_unref(e->knot); + g_free(e); + kh->entity = g_slist_remove(kh->entity, e); + } +} + +void +PointParamKnotHolder::add_knot ( + Geom::Point & p, + PointParamKnotHolderClickedFunc knot_click, + SPKnotShapeType shape, + SPKnotModeType mode, + guint32 color, + const gchar *tip ) +{ + /* create new SPKnotHolderEntry */ + SPKnotHolderEntity *e = g_new(SPKnotHolderEntity, 1); + e->knot = sp_knot_new(desktop, tip); + e->knot_set = NULL; + e->knot_get = NULL; + if (knot_click) { + e->knot_click = knot_click; + } else { + e->knot_click = NULL; + } + + g_object_set(G_OBJECT (e->knot->item), "shape", shape, NULL); + g_object_set(G_OBJECT (e->knot->item), "mode", mode, NULL); + + e->knot->fill [SP_KNOT_STATE_NORMAL] = color; + g_object_set (G_OBJECT (e->knot->item), "fill_color", color, NULL); + + entity = g_slist_append(entity, e); + + /* Move to current point. */ + NR::Point dp = p * sp_item_i2d_affine(item); + sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL); + + e->handler_id = g_signal_connect(e->knot, "moved", G_CALLBACK(pointparam_knot_moved_handler), this); + e->_click_handler_id = g_signal_connect(e->knot, "clicked", G_CALLBACK(pointparam_knot_clicked_handler), this); + e->_ungrab_handler_id = g_signal_connect(e->knot, "ungrabbed", G_CALLBACK(pointparam_knot_ungrabbed_handler), this); + + sp_knot_show(e->knot); +} + +static void pointparam_knot_clicked_handler(SPKnot */*knot*/, guint /*state*/, PointParamKnotHolder */*kh*/) +{ + +} + +/** + * \param p In desktop coordinates. + * This function does not write to XML, but tries to write directly to the PointParam to quickly live update the effect + */ +static void pointparam_knot_moved_handler(SPKnot */*knot*/, NR::Point const *p, guint /*state*/, PointParamKnotHolder *kh) +{ + NR::Matrix const i2d(sp_item_i2d_affine(kh->item)); + NR::Point pos = (*p) / i2d; + + Inkscape::SVGOStringStream os; + os << pos.to_2geom(); + + kh->lpeobject->lpe->setParameter(kh->repr_key, os.str().c_str()); +} + +static void pointparam_knot_ungrabbed_handler(SPKnot *knot, unsigned int /*state*/, PointParamKnotHolder *kh) +{ + NR::Matrix const i2d(sp_item_i2d_affine(kh->item)); + NR::Point pos = sp_knot_position(knot) / i2d; + + Inkscape::SVGOStringStream os; + os << pos.to_2geom(); + + kh->repr->setAttribute(kh->repr_key , os.str().c_str()); + + sp_document_done(SP_OBJECT_DOCUMENT (kh->lpeobject), SP_VERB_CONTEXT_LPE, _("Change LPE point parameter")); +} + +} // 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:encoding=utf-8:textwidth=99 : +======= #define INKSCAPE_LPE_POINTPARAM_KNOTHOLDER_C /* @@ -199,3 +402,4 @@ static void pointparam_knot_ungrabbed_handler(SPKnot *knot, unsigned int /*state End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +>>>>>>> .r17984 diff --git a/src/svg/stringstream-test.h b/src/svg/stringstream-test.h index 6612f3fd2..a8da13150 100644 --- a/src/svg/stringstream-test.h +++ b/src/svg/stringstream-test.h @@ -1,5 +1,6 @@ #include #include "svg/stringstream.h" +#include <2geom/point.h> template static void @@ -45,6 +46,7 @@ public: svg_test_datum(" my string ", " my string "); svg_test_datum((signed char const *) "023", "023"); svg_test_datum((unsigned char const *) "023", "023"); + svg_test_datum(Geom::Point(1.23, 3.45), "1.23,3.45"); } void testConcat() diff --git a/src/svg/stringstream.cpp b/src/svg/stringstream.cpp index 65c01e7b6..62e20961a 100644 --- a/src/svg/stringstream.cpp +++ b/src/svg/stringstream.cpp @@ -1,6 +1,7 @@ #include "svg/stringstream.h" #include "svg/strip-trailing-zeros.h" #include "prefs-utils.h" +#include <2geom/point.h> Inkscape::SVGOStringStream::SVGOStringStream() { @@ -57,6 +58,12 @@ operator<<(Inkscape::SVGOStringStream &os, double d) return os; } +Inkscape::SVGOStringStream & +operator<<(Inkscape::SVGOStringStream &os, Geom::Point const & p) +{ + os << p[0] << ',' << p[1]; + return os; +} /* Local Variables: diff --git a/src/svg/stringstream.h b/src/svg/stringstream.h index 8ef5ece52..4e19125b4 100644 --- a/src/svg/stringstream.h +++ b/src/svg/stringstream.h @@ -5,6 +5,9 @@ #include #include +namespace Geom { + class Point; +} namespace Inkscape { typedef std::ios_base &(*std_oct_type)(std::ios_base &); @@ -78,6 +81,7 @@ Inkscape::SVGOStringStream &operator<<(Inkscape::SVGOStringStream &os, float d); Inkscape::SVGOStringStream &operator<<(Inkscape::SVGOStringStream &os, double d); +Inkscape::SVGOStringStream &operator<<(Inkscape::SVGOStringStream &os, Geom::Point const & p); #endif diff --git a/src/ui/widget/point.cpp b/src/ui/widget/point.cpp index 634329ddc..1efb26a78 100644 --- a/src/ui/widget/point.cpp +++ b/src/ui/widget/point.cpp @@ -149,6 +149,11 @@ Point::getYValue() const { return ywidget.getValue(); } +Geom::Point +Point::getValue() const +{ + return Geom::Point( getXValue() , getYValue() ); +} /** Get the value spin_button represented as an integer. */ int diff --git a/src/ui/widget/point.h b/src/ui/widget/point.h index b65a13e20..a9be05afc 100644 --- a/src/ui/widget/point.h +++ b/src/ui/widget/point.h @@ -19,7 +19,7 @@ #include #include - +#include <2geom/point.h> #include "ui/widget/labelled.h" #include "ui/widget/scalar.h" @@ -57,6 +57,7 @@ public: bool getSnapToTicks() const; double getXValue() const; double getYValue() const; + Geom::Point getValue() const; int getXValueAsInt() const; int getYValueAsInt() const; diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 3b36ea6bc..1de084f5d 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -467,6 +467,53 @@ RegisteredPoint::on_value_changed() _wr->setUpdating (false); } +/*######################################### + * Registered TRANSFORMEDPOINT + */ + +RegisteredTransformedPoint::~RegisteredTransformedPoint() +{ + _value_x_changed_connection.disconnect(); + _value_y_changed_connection.disconnect(); +} + +RegisteredTransformedPoint::RegisteredTransformedPoint ( const Glib::ustring& label, const Glib::ustring& tip, + const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, + SPDocument* doc_in ) + : RegisteredWidget (label, tip), + transform(Geom::identity()) +{ + init_parent(key, wr, repr_in, doc_in); + + setRange (-1e6, 1e6); + setDigits (2); + setIncrements(0.1, 1.0); + _value_x_changed_connection = signal_x_value_changed().connect (sigc::mem_fun (*this, &RegisteredTransformedPoint::on_value_changed)); + _value_y_changed_connection = signal_y_value_changed().connect (sigc::mem_fun (*this, &RegisteredTransformedPoint::on_value_changed)); +} + +void +RegisteredTransformedPoint::on_value_changed() +{ + if (setProgrammatically()) { + clearProgrammatically(); + return; + } + + if (_wr->isUpdating()) + return; + + _wr->setUpdating (true); + + Geom::Point pos = getValue() * transform; + + Inkscape::SVGOStringStream os; + os << pos; + + write_to_xml(os.str().c_str()); + + _wr->setUpdating (false); +} /*######################################### * Registered RANDOM diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index a3b04575e..f34895620 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -17,7 +17,7 @@ #include #include #include - +#include <2geom/matrix.h> #include "xml/node.h" #include "registry.h" @@ -294,6 +294,25 @@ protected: }; +class RegisteredTransformedPoint : public RegisteredWidget { +public: + virtual ~RegisteredTransformedPoint(); + RegisteredTransformedPoint ( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Registry& wr, + Inkscape::XML::Node* repr_in = NULL, + SPDocument *doc_in = NULL ); + +protected: + sigc::connection _value_x_changed_connection; + sigc::connection _value_y_changed_connection; + void on_value_changed(); + + Geom::Matrix transform; +}; + + class RegisteredRandom : public RegisteredWidget { public: virtual ~RegisteredRandom(); diff --git a/src/verbs.cpp b/src/verbs.cpp index b9dfec271..b32d0041b 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2429,7 +2429,8 @@ Verb *Verb::_base_verbs[] = { N_("Create diagram connectors"), "draw_connector"), new ContextVerb(SP_VERB_CONTEXT_PAINTBUCKET, "ToolPaintBucket", N_("Paint Bucket"), N_("Fill bounded areas"), "draw_paintbucket"), - + new ContextVerb(SP_VERB_CONTEXT_LPE, "ToolLPE", N_("LPE Edit"), + N_("Edit Live Path Effect parameters"), "draw_lpe"), /* Tool prefs */ new ContextVerb(SP_VERB_CONTEXT_SELECT_PREFS, "SelectPrefs", N_("Selector Preferences"), N_("Open Preferences for the Selector tool"), NULL), diff --git a/src/verbs.h b/src/verbs.h index 471beaa48..89e677ead 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -162,7 +162,7 @@ enum { SP_VERB_CONTEXT_DROPPER, SP_VERB_CONTEXT_CONNECTOR, SP_VERB_CONTEXT_PAINTBUCKET, -// SP_VERB_CONTEXT_LPE, /*not really a tool but for editing LPE parameters on-canvas for example */ + SP_VERB_CONTEXT_LPE, /* not really a tool but used for editing LPE parameters on-canvas for example */ /* Tool preferences */ SP_VERB_CONTEXT_SELECT_PREFS, SP_VERB_CONTEXT_NODE_PREFS, -- 2.30.2