Code

* add RegisteredTransformedPoint widget, that transforms the point before displaying...
[inkscape.git] / src / live_effects / parameter / pointparam-knotholder.cpp
1 <<<<<<< .mine\r
2 #define INKSCAPE_LPE_POINTPARAM_KNOTHOLDER_C\r
3 \r
4 /*\r
5  * Container for PointParamKnotHolder visual handles\r
6  *\r
7  * Authors:\r
8  *   Johan Engelen <goejendaagh@zonnet.nl>\r
9  *\r
10  * Copyright (C) 2008 authors\r
11  *\r
12  * Released under GNU GPL, read the file 'COPYING' for more information\r
13  */\r
14 \r
15 #include "live_effects/parameter/pointparam-knotholder.h"\r
16 #include "live_effects/lpeobject.h"\r
17 #include "document.h"\r
18 #include "sp-shape.h"\r
19 #include "knot.h"\r
20 #include "knotholder.h"\r
21 #include "knot-holder-entity.h"\r
22 \r
23 #include <libnr/nr-matrix-div.h>\r
24 #include <glibmm/i18n.h>\r
25 #include <2geom/point.h>\r
26 #include <2geom/matrix.h>\r
27 #include "svg/stringstream.h"\r
28 #include "xml/repr.h"\r
29 \r
30 class SPDesktop;\r
31 \r
32 namespace Inkscape {\r
33 \r
34 static void pointparam_knot_clicked_handler (SPKnot *knot, guint state, PointParamKnotHolder *kh);\r
35 static void pointparam_knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, PointParamKnotHolder *kh);\r
36 static void pointparam_knot_ungrabbed_handler (SPKnot *knot, unsigned int state, PointParamKnotHolder *kh);\r
37 static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass);\r
38 \r
39 void pointparam_knot_holder_dispose(GObject *object);\r
40 \r
41 static SPKnotHolderClass *parent_class;\r
42 \r
43 /**\r
44  * Registers PointParamKnotHolder class and returns its type number.\r
45  */\r
46 GType pointparam_knot_holder_get_type()\r
47 {\r
48     static GType type = 0;\r
49     if (!type) {\r
50         GTypeInfo info = {\r
51             sizeof(PointParamKnotHolderClass),\r
52             NULL,       /* base_init */\r
53             NULL,       /* base_finalize */\r
54             (GClassInitFunc) pointparam_knot_holder_class_init,\r
55             NULL,       /* class_finalize */\r
56             NULL,       /* class_data */\r
57             sizeof (PointParamKnotHolder),\r
58             16, /* n_preallocs */\r
59             NULL,\r
60             NULL\r
61         };\r
62         type = g_type_register_static (G_TYPE_OBJECT, "InkscapePointParamKnotHolder", &info, (GTypeFlags) 0);\r
63     }\r
64     return type;\r
65 }\r
66 \r
67 /**\r
68  * PointParamKnotHolder vtable initialization.\r
69  */\r
70 static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass)\r
71 {\r
72     GObjectClass *gobject_class;\r
73     gobject_class = (GObjectClass *) klass;\r
74 \r
75     parent_class = (SPKnotHolderClass*) g_type_class_peek_parent(klass);\r
76     gobject_class->dispose = pointparam_knot_holder_dispose;\r
77 }\r
78 \r
79 PointParamKnotHolder *pointparam_knot_holder_new(SPDesktop *desktop, SPObject *lpeobject, const gchar * key, SPItem *item)\r
80 {\r
81     g_return_val_if_fail(desktop != NULL, NULL);\r
82     g_return_val_if_fail(item != NULL, NULL);\r
83     g_return_val_if_fail(SP_IS_ITEM(item), NULL);\r
84 \r
85     PointParamKnotHolder *knot_holder = (PointParamKnotHolder*)g_object_new (INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, 0);\r
86     knot_holder->desktop = desktop;\r
87     knot_holder->item = item;\r
88     knot_holder->lpeobject = LIVEPATHEFFECT(lpeobject);\r
89     g_object_ref(G_OBJECT(item));\r
90     g_object_ref(G_OBJECT(lpeobject));\r
91     knot_holder->entity = NULL;\r
92 \r
93     knot_holder->released = NULL;\r
94 \r
95     knot_holder->repr = lpeobject->repr;\r
96     knot_holder->repr_key = key;\r
97 \r
98     knot_holder->local_change = FALSE;\r
99 \r
100     return knot_holder;\r
101 }\r
102 \r
103 void pointparam_knot_holder_dispose(GObject *object) {\r
104     PointParamKnotHolder *kh = G_TYPE_CHECK_INSTANCE_CAST((object), INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, PointParamKnotHolder);\r
105 \r
106     g_object_unref(G_OBJECT(kh->item));\r
107     g_object_unref(G_OBJECT(kh->lpeobject));\r
108     while (kh->entity) {\r
109         SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data;\r
110         g_signal_handler_disconnect(e->knot, e->_click_handler_id);\r
111         g_signal_handler_disconnect(e->knot, e->_ungrab_handler_id);\r
112         /* unref should call destroy */\r
113         g_object_unref(e->knot);\r
114         g_free(e);\r
115         kh->entity = g_slist_remove(kh->entity, e);\r
116     }\r
117 }\r
118 \r
119 void\r
120 PointParamKnotHolder::add_knot (\r
121     Geom::Point         & p,\r
122     PointParamKnotHolderClickedFunc knot_click,\r
123     SPKnotShapeType     shape,\r
124     SPKnotModeType      mode,\r
125     guint32             color,\r
126     const gchar *tip )\r
127 {\r
128     /* create new SPKnotHolderEntry */\r
129     SPKnotHolderEntity *e = g_new(SPKnotHolderEntity, 1);\r
130     e->knot = sp_knot_new(desktop, tip);\r
131     e->knot_set = NULL;\r
132     e->knot_get = NULL;\r
133     if (knot_click) {\r
134         e->knot_click = knot_click;\r
135     } else {\r
136         e->knot_click = NULL;\r
137     }\r
138 \r
139     g_object_set(G_OBJECT (e->knot->item), "shape", shape, NULL);\r
140     g_object_set(G_OBJECT (e->knot->item), "mode", mode, NULL);\r
141 \r
142     e->knot->fill [SP_KNOT_STATE_NORMAL] = color;\r
143     g_object_set (G_OBJECT (e->knot->item), "fill_color", color, NULL);\r
144 \r
145     entity = g_slist_append(entity, e);\r
146 \r
147     /* Move to current point. */\r
148     NR::Point dp = p * sp_item_i2d_affine(item);\r
149     sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL);\r
150 \r
151     e->handler_id = g_signal_connect(e->knot, "moved", G_CALLBACK(pointparam_knot_moved_handler), this);\r
152     e->_click_handler_id = g_signal_connect(e->knot, "clicked", G_CALLBACK(pointparam_knot_clicked_handler), this);\r
153     e->_ungrab_handler_id = g_signal_connect(e->knot, "ungrabbed", G_CALLBACK(pointparam_knot_ungrabbed_handler), this);\r
154 \r
155     sp_knot_show(e->knot);\r
156 }\r
157 \r
158 static void pointparam_knot_clicked_handler(SPKnot */*knot*/, guint /*state*/, PointParamKnotHolder */*kh*/)\r
159 {\r
160 \r
161 }\r
162 \r
163 /**\r
164  * \param p In desktop coordinates.\r
165  *  This function does not write to XML, but tries to write directly to the PointParam to quickly live update the effect\r
166  */\r
167 static void pointparam_knot_moved_handler(SPKnot */*knot*/, NR::Point const *p, guint /*state*/, PointParamKnotHolder *kh)\r
168 {\r
169     NR::Matrix const i2d(sp_item_i2d_affine(kh->item));\r
170     NR::Point pos = (*p) / i2d;\r
171 \r
172     Inkscape::SVGOStringStream os;\r
173     os << pos.to_2geom();\r
174 \r
175     kh->lpeobject->lpe->setParameter(kh->repr_key, os.str().c_str());\r
176 }\r
177 \r
178 static void pointparam_knot_ungrabbed_handler(SPKnot *knot, unsigned int /*state*/, PointParamKnotHolder *kh)\r
179 {\r
180     NR::Matrix const i2d(sp_item_i2d_affine(kh->item));\r
181     NR::Point pos = sp_knot_position(knot) / i2d;\r
182 \r
183     Inkscape::SVGOStringStream os;\r
184     os << pos.to_2geom();\r
185 \r
186     kh->repr->setAttribute(kh->repr_key , os.str().c_str());\r
187 \r
188     sp_document_done(SP_OBJECT_DOCUMENT (kh->lpeobject), SP_VERB_CONTEXT_LPE, _("Change LPE point parameter"));\r
189 }\r
190 \r
191 } // namespace Inkscape\r
192 \r
193 /*\r
194   Local Variables:\r
195   mode:c++\r
196   c-file-style:"stroustrup"\r
197   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
198   indent-tabs-mode:nil\r
199   fill-column:99\r
200   End:\r
201 */\r
202 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
203 =======\r
204 #define INKSCAPE_LPE_POINTPARAM_KNOTHOLDER_C
206 /*
207  * Container for PointParamKnotHolder visual handles
208  *
209  * Authors:
210  *   Johan Engelen <goejendaagh@zonnet.nl>
211  *
212  * Copyright (C) 2008 authors
213  *
214  * Released under GNU GPL, read the file 'COPYING' for more information
215  */
217 #include "live_effects/parameter/pointparam-knotholder.h"
218 #include "live_effects/lpeobject.h"
219 #include "document.h"
220 #include "sp-shape.h"
221 #include "knot.h"
222 #include "knotholder.h"
223 #include "knot-holder-entity.h"
225 #include <libnr/nr-matrix-div.h>
226 #include <glibmm/i18n.h>
227 #include <2geom/point.h>
228 #include <2geom/matrix.h>
229 #include "svg/stringstream.h"
230 #include "xml/repr.h"
232 class SPDesktop;
234 namespace Inkscape {
236 static void pointparam_knot_clicked_handler (SPKnot *knot, guint state, PointParamKnotHolder *kh);
237 static void pointparam_knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, PointParamKnotHolder *kh);
238 static void pointparam_knot_ungrabbed_handler (SPKnot *knot, unsigned int state, PointParamKnotHolder *kh);
239 static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass);
241 void pointparam_knot_holder_dispose(GObject *object);
243 static SPKnotHolderClass *parent_class;
245 /**
246  * Registers PointParamKnotHolder class and returns its type number.
247  */
248 GType pointparam_knot_holder_get_type()
250     static GType type = 0;
251     if (!type) {
252         GTypeInfo info = {
253             sizeof(PointParamKnotHolderClass),
254             NULL,       /* base_init */
255             NULL,       /* base_finalize */
256             (GClassInitFunc) pointparam_knot_holder_class_init,
257             NULL,       /* class_finalize */
258             NULL,       /* class_data */
259             sizeof (PointParamKnotHolder),
260             16, /* n_preallocs */
261             NULL,
262             NULL
263         };
264         type = g_type_register_static (G_TYPE_OBJECT, "InkscapePointParamKnotHolder", &info, (GTypeFlags) 0);
265     }
266     return type;
269 /**
270  * PointParamKnotHolder vtable initialization.
271  */
272 static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass)
274     GObjectClass *gobject_class;
275     gobject_class = (GObjectClass *) klass;
277     parent_class = (SPKnotHolderClass*) g_type_class_peek_parent(klass);
278     gobject_class->dispose = pointparam_knot_holder_dispose;
281 PointParamKnotHolder *pointparam_knot_holder_new(SPDesktop *desktop, SPObject *lpeobject, const gchar * key, SPItem *item)
283     g_return_val_if_fail(desktop != NULL, NULL);
284     g_return_val_if_fail(item != NULL, NULL);
285     g_return_val_if_fail(SP_IS_ITEM(item), NULL);
287     PointParamKnotHolder *knot_holder = (PointParamKnotHolder*)g_object_new (INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, 0);
288     knot_holder->desktop = desktop;
289     knot_holder->item = item;
290     knot_holder->lpeobject = LIVEPATHEFFECT(lpeobject);
291     g_object_ref(G_OBJECT(item));
292     g_object_ref(G_OBJECT(lpeobject));
293     knot_holder->entity = NULL;
295     knot_holder->released = NULL;
297     knot_holder->repr = lpeobject->repr;
298     knot_holder->repr_key = key;
300     knot_holder->local_change = FALSE;
302     return knot_holder;
305 void pointparam_knot_holder_dispose(GObject *object) {
306     PointParamKnotHolder *kh = G_TYPE_CHECK_INSTANCE_CAST((object), INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, PointParamKnotHolder);
308     g_object_unref(G_OBJECT(kh->item));
309     g_object_unref(G_OBJECT(kh->lpeobject));
310     while (kh->entity) {
311         SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data;
312         g_signal_handler_disconnect(e->knot, e->_click_handler_id);
313         g_signal_handler_disconnect(e->knot, e->_ungrab_handler_id);
314         /* unref should call destroy */
315         g_object_unref(e->knot);
316         g_free(e);
317         kh->entity = g_slist_remove(kh->entity, e);
318     }
321 void
322 PointParamKnotHolder::add_knot (
323     Geom::Point         & p,
324     PointParamKnotHolderClickedFunc knot_click,
325     SPKnotShapeType     shape,
326     SPKnotModeType      mode,
327     guint32             color,
328     const gchar *tip )
330     /* create new SPKnotHolderEntry */
331     SPKnotHolderEntity *e = g_new(SPKnotHolderEntity, 1);
332     e->knot = sp_knot_new(desktop, tip);
333     e->knot_set = NULL;
334     e->knot_get = NULL;
335     if (knot_click) {
336         e->knot_click = knot_click;
337     } else {
338         e->knot_click = NULL;
339     }
341     g_object_set(G_OBJECT (e->knot->item), "shape", shape, NULL);
342     g_object_set(G_OBJECT (e->knot->item), "mode", mode, NULL);
344     e->knot->fill [SP_KNOT_STATE_NORMAL] = color;
345     g_object_set (G_OBJECT (e->knot->item), "fill_color", color, NULL);
347     entity = g_slist_append(entity, e);
349     /* Move to current point. */
350     NR::Point dp = p * sp_item_i2d_affine(item);
351     sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL);
353     e->handler_id = g_signal_connect(e->knot, "moved", G_CALLBACK(pointparam_knot_moved_handler), this);
354     e->_click_handler_id = g_signal_connect(e->knot, "clicked", G_CALLBACK(pointparam_knot_clicked_handler), this);
355     e->_ungrab_handler_id = g_signal_connect(e->knot, "ungrabbed", G_CALLBACK(pointparam_knot_ungrabbed_handler), this);
357     sp_knot_show(e->knot);
360 static void pointparam_knot_clicked_handler(SPKnot */*knot*/, guint /*state*/, PointParamKnotHolder */*kh*/)
365 /**
366  * \param p In desktop coordinates.
367  *  This function does not write to XML, but tries to write directly to the PointParam to quickly live update the effect
368  */
369 static void pointparam_knot_moved_handler(SPKnot */*knot*/, NR::Point const *p, guint /*state*/, PointParamKnotHolder *kh)
371     NR::Matrix const i2d(sp_item_i2d_affine(kh->item));
372     NR::Point pos = (*p) / i2d;
374     Inkscape::SVGOStringStream os;
375     os << pos[0] << "," << pos[1];
377     kh->lpeobject->lpe->setParameter(kh->repr_key, os.str().c_str());
380 static void pointparam_knot_ungrabbed_handler(SPKnot *knot, unsigned int /*state*/, PointParamKnotHolder *kh)
382     NR::Matrix const i2d(sp_item_i2d_affine(kh->item));
383     NR::Point pos = sp_knot_position(knot) / i2d;
385     Inkscape::SVGOStringStream os;
386     os << pos[0] << "," << pos[1];
388     kh->repr->setAttribute(kh->repr_key , os.str().c_str());
390     sp_document_done(SP_OBJECT_DOCUMENT (kh->lpeobject), SP_VERB_CONTEXT_NODE, _("Change LPE point parameter"));
393 } // namespace Inkscape
395 /*
396   Local Variables:
397   mode:c++
398   c-file-style:"stroustrup"
399   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
400   indent-tabs-mode:nil
401   fill-column:99
402   End:
403 */
404 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
405 >>>>>>> .r17984\r