1 #define INKSCAPE_LIVEPATHEFFECT_POWERSTROKE_POINT_ARRAY_CPP
3 /*
4 * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
5 *
6 * Released under GNU GPL, read the file 'COPYING' for more information
7 */
9 #include "live_effects/parameter/powerstrokepointarray.h"
11 #include "live_effects/effect.h"
12 #include "svg/svg.h"
13 #include "svg/stringstream.h"
14 #include "knotholder.h"
15 #include "sp-lpe-item.h"
17 #include <2geom/piecewise.h>
18 #include <2geom/sbasis-geometric.h>
20 // needed for on-canvas editting:
21 #include "desktop.h"
23 namespace Inkscape {
25 namespace LivePathEffect {
27 PowerStrokePointArrayParam::PowerStrokePointArrayParam( const Glib::ustring& label, const Glib::ustring& tip,
28 const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
29 Effect* effect, const gchar *htip)
30 : ArrayParam<Geom::Point>(label, tip, key, wr, effect, 0)
31 {
32 knot_shape = SP_KNOT_SHAPE_DIAMOND;
33 knot_mode = SP_KNOT_MODE_XOR;
34 knot_color = 0xff00ff00;
35 handle_tip = g_strdup(htip);
36 }
38 PowerStrokePointArrayParam::~PowerStrokePointArrayParam()
39 {
40 if (handle_tip)
41 g_free(handle_tip);
42 }
44 Gtk::Widget *
45 PowerStrokePointArrayParam::param_newWidget(Gtk::Tooltips * /*tooltips*/)
46 {
47 return NULL;
48 /*
49 Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = Gtk::manage(
50 new Inkscape::UI::Widget::RegisteredTransformedPoint( param_label,
51 param_tooltip,
52 param_key,
53 *param_wr,
54 param_effect->getRepr(),
55 param_effect->getSPDoc() ) );
56 // TODO: fix to get correct desktop (don't use SP_ACTIVE_DESKTOP)
57 SPDesktop *desktop = SP_ACTIVE_DESKTOP;
58 Geom::Matrix transf = desktop->doc2dt();
59 pointwdg->setTransform(transf);
60 pointwdg->setValue( *this );
61 pointwdg->clearProgrammatically();
62 pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter"));
64 Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() );
65 static_cast<Gtk::HBox*>(hbox)->pack_start(*pointwdg, true, true);
66 static_cast<Gtk::HBox*>(hbox)->show_all_children();
68 return dynamic_cast<Gtk::Widget *> (hbox);
69 */
70 }
73 void
74 PowerStrokePointArrayParam::param_transform_multiply(Geom::Matrix const& postmul, bool /*set*/)
75 {
76 // param_set_and_write_new_value( (*this) * postmul );
77 }
80 void
81 PowerStrokePointArrayParam::set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color)
82 {
83 knot_shape = shape;
84 knot_mode = mode;
85 knot_color = color;
86 }
88 class PowerStrokePointArrayParamKnotHolderEntity : public LPEKnotHolderEntity {
89 public:
90 PowerStrokePointArrayParamKnotHolderEntity(PowerStrokePointArrayParam *p, unsigned int index);
91 virtual ~PowerStrokePointArrayParamKnotHolderEntity() {}
93 virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
94 virtual Geom::Point knot_get();
95 virtual void knot_click(guint state);
97 private:
98 PowerStrokePointArrayParam *_pparam;
99 unsigned int _index;
100 };
102 PowerStrokePointArrayParamKnotHolderEntity::PowerStrokePointArrayParamKnotHolderEntity(PowerStrokePointArrayParam *p, unsigned int index)
103 : _pparam(p),
104 _index(index)
105 {
106 }
108 void
109 PowerStrokePointArrayParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/)
110 {
111 /// @todo how about item transforms???
112 using namespace Geom;
113 Piecewise<D2<SBasis> > const & pwd2 = _pparam->get_pwd2();
114 Piecewise<D2<SBasis> > const & n = _pparam->get_pwd2_normal();
116 Geom::Point const s = snap_knot_position(p);
117 double t = nearest_point(s, pwd2);
118 double offset = dot(s - pwd2.valueAt(t), n.valueAt(t));
119 _pparam->_vector.at(_index) = Geom::Point(t, offset);
120 sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
121 }
123 Geom::Point
124 PowerStrokePointArrayParamKnotHolderEntity::knot_get()
125 {
126 using namespace Geom;
127 Piecewise<D2<SBasis> > const & pwd2 = _pparam->get_pwd2();
128 Piecewise<D2<SBasis> > const & n = _pparam->get_pwd2_normal();
130 Point offset_point = _pparam->_vector.at(_index);
132 Point canvas_point = pwd2.valueAt(offset_point[X]) + offset_point[Y] * n.valueAt(offset_point[X]);
133 return canvas_point;
134 }
136 void
137 PowerStrokePointArrayParamKnotHolderEntity::knot_click(guint state)
138 {
139 g_print ("This is the %d handle associated to parameter '%s'\n", _index, _pparam->param_key.c_str());
141 if (state & GDK_CONTROL_MASK) {
142 std::vector<Geom::Point> & vec = _pparam->_vector;
143 vec.insert(vec.begin() + _index, 1, vec.at(_index));
144 _pparam->param_set_and_write_new_value(vec);
145 g_print ("Added handle %d associated to parameter '%s'\n", _index, _pparam->param_key.c_str());
146 /// @todo this BUGS ! the knot stuff should be reloaded when adding a new node!
147 }
148 }
150 void
151 PowerStrokePointArrayParam::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item)
152 {
153 for (unsigned int i = 0; i < _vector.size(); ++i) {
154 PowerStrokePointArrayParamKnotHolderEntity *e = new PowerStrokePointArrayParamKnotHolderEntity(this, i);
155 e->create(desktop, item, knotholder, handle_tip, knot_shape, knot_mode, knot_color);
156 knotholder->add(e);
157 }
158 }
160 } /* namespace LivePathEffect */
162 } /* namespace Inkscape */
164 /*
165 Local Variables:
166 mode:c++
167 c-file-style:"stroustrup"
168 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
169 indent-tabs-mode:nil
170 fill-column:99
171 End:
172 */
173 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :