Code

svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging...
[inkscape.git] / src / live_effects / parameter / pointparam-knotholder.cpp
1 #define INKSCAPE_LPE_POINTPARAM_KNOTHOLDER_C
3 /*
4  * Container for PointParamKnotHolder visual handles
5  *
6  * Authors:
7  *   Johan Engelen <goejendaagh@zonnet.nl>
8  *
9  * Copyright (C) 2008 authors
10  *
11  * Released under GNU GPL, read the file 'COPYING' for more information
12  */
14 #include "live_effects/parameter/pointparam-knotholder.h"
15 #include "live_effects/lpeobject.h"
16 #include "document.h"
17 #include "sp-shape.h"
18 #include "knot.h"
19 #include "knotholder.h"
20 #include "knot-holder-entity.h"
22 #include <libnr/nr-matrix-div.h>
23 #include <glibmm/i18n.h>
24 #include <2geom/point.h>
25 #include <2geom/matrix.h>
26 #include "svg/stringstream.h"
27 #include "xml/repr.h"
29 class SPDesktop;
31 namespace Inkscape {
33 static void pointparam_knot_clicked_handler (SPKnot *knot, guint state, PointParamKnotHolder *kh);
34 static void pointparam_knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, PointParamKnotHolder *kh);
35 static void pointparam_knot_ungrabbed_handler (SPKnot *knot, unsigned int state, PointParamKnotHolder *kh);
36 static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass);
38 void pointparam_knot_holder_dispose(GObject *object);
40 static SPKnotHolderClass *parent_class;
42 /**
43  * Registers PointParamKnotHolder class and returns its type number.
44  */
45 GType pointparam_knot_holder_get_type()
46 {
47     static GType type = 0;
48     if (!type) {
49         GTypeInfo info = {
50             sizeof(PointParamKnotHolderClass),
51             NULL,       /* base_init */
52             NULL,       /* base_finalize */
53             (GClassInitFunc) pointparam_knot_holder_class_init,
54             NULL,       /* class_finalize */
55             NULL,       /* class_data */
56             sizeof (PointParamKnotHolder),
57             16, /* n_preallocs */
58             NULL,
59             NULL
60         };
61         type = g_type_register_static (G_TYPE_OBJECT, "InkscapePointParamKnotHolder", &info, (GTypeFlags) 0);
62     }
63     return type;
64 }
66 /**
67  * PointParamKnotHolder vtable initialization.
68  */
69 static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass)
70 {
71     GObjectClass *gobject_class;
72     gobject_class = (GObjectClass *) klass;
74     parent_class = (SPKnotHolderClass*) g_type_class_peek_parent(klass);
75     gobject_class->dispose = pointparam_knot_holder_dispose;
76 }
78 PointParamKnotHolder *pointparam_knot_holder_new(SPDesktop *desktop, SPObject *lpeobject, const gchar * key, SPItem *item)
79 {
80     g_return_val_if_fail(desktop != NULL, NULL);
81     g_return_val_if_fail(item != NULL, NULL);
82     g_return_val_if_fail(SP_IS_ITEM(item), NULL);
84     PointParamKnotHolder *knot_holder = (PointParamKnotHolder*)g_object_new (INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, 0);
85     knot_holder->desktop = desktop;
86     knot_holder->item = item;
87     knot_holder->lpeobject = LIVEPATHEFFECT(lpeobject);
88     g_object_ref(G_OBJECT(item));
89     g_object_ref(G_OBJECT(lpeobject));
90     knot_holder->entity = NULL;
92     knot_holder->released = NULL;
94     knot_holder->repr = lpeobject->repr;
95     knot_holder->repr_key = key;
97     knot_holder->local_change = FALSE;
99     return knot_holder;
102 void pointparam_knot_holder_dispose(GObject *object) {
103     PointParamKnotHolder *kh = G_TYPE_CHECK_INSTANCE_CAST((object), INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, PointParamKnotHolder);
105     g_object_unref(G_OBJECT(kh->item));
106     g_object_unref(G_OBJECT(kh->lpeobject));
107     while (kh->entity) {
108         SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data;
109         g_signal_handler_disconnect(e->knot, e->_click_handler_id);
110         g_signal_handler_disconnect(e->knot, e->_ungrab_handler_id);
111         /* unref should call destroy */
112         g_object_unref(e->knot);
113         g_free(e);
114         kh->entity = g_slist_remove(kh->entity, e);
115     }
118 void
119 PointParamKnotHolder::add_knot (
120     Geom::Point         & p,
121     PointParamKnotHolderClickedFunc knot_click,
122     SPKnotShapeType     shape,
123     SPKnotModeType      mode,
124     guint32             color,
125     const gchar *tip )
127     /* create new SPKnotHolderEntry */
128     SPKnotHolderEntity *e = g_new(SPKnotHolderEntity, 1);
129     e->knot = sp_knot_new(desktop, tip);
130     e->knot_set = NULL;
131     e->knot_get = NULL;
132     if (knot_click) {
133         e->knot_click = knot_click;
134     } else {
135         e->knot_click = NULL;
136     }
138     g_object_set(G_OBJECT (e->knot->item), "shape", shape, NULL);
139     g_object_set(G_OBJECT (e->knot->item), "mode", mode, NULL);
141     e->knot->fill [SP_KNOT_STATE_NORMAL] = color;
142     g_object_set (G_OBJECT (e->knot->item), "fill_color", color, NULL);
144     entity = g_slist_append(entity, e);
146     /* Move to current point. */
147     NR::Point dp = p * sp_item_i2d_affine(item);
148     sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL);
150     e->handler_id = g_signal_connect(e->knot, "moved", G_CALLBACK(pointparam_knot_moved_handler), this);
151     e->_click_handler_id = g_signal_connect(e->knot, "clicked", G_CALLBACK(pointparam_knot_clicked_handler), this);
152     e->_ungrab_handler_id = g_signal_connect(e->knot, "ungrabbed", G_CALLBACK(pointparam_knot_ungrabbed_handler), this);
154     sp_knot_show(e->knot);
157 static void pointparam_knot_clicked_handler(SPKnot */*knot*/, guint /*state*/, PointParamKnotHolder */*kh*/)
162 /**
163  * \param p In desktop coordinates.
164  *  This function does not write to XML, but tries to write directly to the PointParam to quickly live update the effect
165  */
166 static void pointparam_knot_moved_handler(SPKnot */*knot*/, NR::Point const *p, guint /*state*/, PointParamKnotHolder *kh)
168     NR::Matrix const i2d(sp_item_i2d_affine(kh->item));
169     NR::Point pos = (*p) / i2d;
171     Inkscape::SVGOStringStream os;
172     os << pos.to_2geom();
174     kh->lpeobject->lpe->setParameter(kh->repr_key, os.str().c_str());
177 static void pointparam_knot_ungrabbed_handler(SPKnot *knot, unsigned int /*state*/, PointParamKnotHolder *kh)
179     NR::Matrix const i2d(sp_item_i2d_affine(kh->item));
180     NR::Point pos = sp_knot_position(knot) / i2d;
182     Inkscape::SVGOStringStream os;
183     os << pos.to_2geom();
185     kh->repr->setAttribute(kh->repr_key , os.str().c_str());
187     sp_document_done(SP_OBJECT_DOCUMENT (kh->lpeobject), SP_VERB_CONTEXT_LPE, _("Change LPE point parameter"));
190 } // namespace Inkscape
192 /*
193   Local Variables:
194   mode:c++
195   c-file-style:"stroustrup"
196   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
197   indent-tabs-mode:nil
198   fill-column:99
199   End:
200 */
201 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :