1 /* === S Y N F I G ========================================================= */
3 ** \brief Template File
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
10 ** Copyright (c) 2009 Nikita Kitaev
12 ** This package is free software; you can redistribute it and/or
13 ** modify it under the terms of the GNU General Public License as
14 ** published by the Free Software Foundation; either version 2 of
15 ** the License, or (at your option) any later version.
17 ** This package is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ** General Public License for more details.
23 /* ========================================================================= */
25 /* === H E A D E R S ======================================================= */
37 #include <synfig/valuenode_bline.h>
38 #include <synfig/valuenode_blinecalctangent.h>
39 #include <synfig/valuenode_blinecalcvertex.h>
40 #include <synfig/valuenode_blinecalcwidth.h>
41 #include <synfig/valuenode_composite.h>
46 /* === U S I N G =========================================================== */
50 using namespace synfig;
51 using namespace studio;
53 /* === M A C R O S ========================================================= */
55 /* === G L O B A L S ======================================================= */
57 int studio::Duck::duck_count(0);
65 synfig::error("%d ducks not yet deleted!",counter);
69 int _DuckCounter::counter(0);
72 /* === P R O C E D U R E S ================================================= */
74 /* === M E T H O D S ======================================================= */
77 rotations(synfig::Angle::deg(0)),
85 { duck_count++; _DuckCounter::counter++; }
87 Duck::Duck(const synfig::Point &point):
90 rotations(synfig::Angle::deg(0)),
99 { duck_count++; _DuckCounter::counter++;}
101 Duck::Duck(const synfig::Point &point,const synfig::Point &origin):
103 rotations(synfig::Angle::deg(0)),
112 { duck_count++; _DuckCounter::counter++;}
114 Duck::~Duck() { duck_count--; _DuckCounter::counter--;}
117 Duck::get_data_guid()const
119 if(value_desc_.is_value_node())
120 return value_desc_.get_value_node()->get_guid();
121 return synfig::GUID::hasher(get_name());
125 Duck::set_name(const synfig::String &x)
128 if(guid_==synfig::GUID::zero())
130 guid_=synfig::GUID::hasher(name);
136 Duck::operator==(const Duck &rhs)const
142 scalar==rhs.scalar &&
144 transform_stack_.size()==rhs.transform_stack_.size();
146 //(origin_duck?*origin_duck==*rhs.origin_duck:origin==rhs.origin) &&
147 //(shared_point?*shared_point==*rhs.shared_point:point==rhs.point) ;
151 Duck::get_trans_point()const
153 return transform_stack_.perform(get_sub_trans_point());
157 Duck::set_trans_point(const synfig::Point &x)
159 set_sub_trans_point(transform_stack_.unperform(x));
163 Duck::set_trans_point(const synfig::Point &x, const synfig::Time &time)
165 set_sub_trans_point(transform_stack_.unperform(x), time);
168 //! Sets the origin point.
170 Duck::set_origin(const synfig::Point &x)
172 origin=x; origin_duck=0;
175 //! Sets the origin point as another duck
177 Duck::set_origin(const etl::handle<Duck> &x)
182 //! Retrieves the origin location
184 Duck::get_origin()const
186 return origin_duck?origin_duck->get_point():origin;
189 //! Retrieves the origin duck
190 const etl::handle<Duck> &
191 Duck::get_origin_duck() const
196 //! Retrieves the origin location
198 Duck::get_trans_origin()const
200 return transform_stack_.perform(get_sub_trans_origin());
204 Duck::get_sub_trans_point()const
206 return get_point()*get_scalar()+get_sub_trans_origin();
210 Duck::set_sub_trans_point(const synfig::Point &x, const synfig::Time &time)
212 if (get_type() == Duck::TYPE_TANGENT ||
213 get_type() == Duck::TYPE_ANGLE)
215 Angle old_angle = get_point().angle();
216 set_point((x-get_sub_trans_origin())/get_scalar());
217 Angle change = get_point().angle() - old_angle;
218 while (change < Angle::deg(-180)) change += Angle::deg(360);
219 while (change > Angle::deg(180)) change -= Angle::deg(360);
220 int old_halves = round_to_int(Angle::deg(rotations).get()/180);
222 int new_halves = round_to_int(Angle::deg(rotations).get()/180);
223 if (old_halves != new_halves &&
224 (new_halves > 1 || new_halves < -1 ||
225 old_halves > 1 || old_halves < -1))
226 synfig::info("rotation: %.2f turns", new_halves/2.0);
227 } else if(get_type() == Duck::TYPE_VERTEX || get_type() == Duck::TYPE_POSITION)
229 set_point((x-get_sub_trans_origin())/get_scalar());
231 ValueNode_BLineCalcVertex::Handle bline_vertex;
232 ValueNode_Composite::Handle composite;
234 if ((bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(get_value_desc().get_value_node())) ||
235 ((composite = ValueNode_Composite::Handle::cast_dynamic(get_value_desc().get_value_node())) &&
236 composite->get_type() == ValueBase::TYPE_BLINEPOINT &&
237 (bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(composite->get_link("point")))))
239 synfig::Point closest_point = get_point();
240 synfig::Real radius = 0.0;
241 ValueNode_BLine::Handle bline = ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link(bline_vertex->get_link_index_from_name("bline")));
242 synfig::find_closest_point(
248 set_point(closest_point);
251 else set_point((x-get_sub_trans_origin())/get_scalar());
255 Duck::set_sub_trans_point(const synfig::Point &x)
257 if (get_type() == Duck::TYPE_TANGENT ||
258 get_type() == Duck::TYPE_ANGLE)
260 Angle old_angle = get_point().angle();
261 set_point((x-get_sub_trans_origin())/get_scalar());
262 Angle change = get_point().angle() - old_angle;
263 while (change < Angle::deg(-180)) change += Angle::deg(360);
264 while (change > Angle::deg(180)) change -= Angle::deg(360);
265 int old_halves = round_to_int(Angle::deg(rotations).get()/180);
267 int new_halves = round_to_int(Angle::deg(rotations).get()/180);
268 if (old_halves != new_halves &&
269 (new_halves > 1 || new_halves < -1 ||
270 old_halves > 1 || old_halves < -1))
271 synfig::info("rotation: %.2f turns", new_halves/2.0);
273 else set_point((x-get_sub_trans_origin())/get_scalar());
277 Duck::get_sub_trans_origin()const
279 return origin_duck?origin_duck->get_sub_trans_point():origin;
284 Duck::type_name(Type id)
288 if (id & TYPE_POSITION) { if (!ret.empty()) ret += ", "; ret += "position"; }
289 if (id & TYPE_TANGENT ) { if (!ret.empty()) ret += ", "; ret += "tangent" ; }
290 if (id & TYPE_RADIUS ) { if (!ret.empty()) ret += ", "; ret += "radius" ; }
291 if (id & TYPE_WIDTH ) { if (!ret.empty()) ret += ", "; ret += "width" ; }
292 if (id & TYPE_ANGLE ) { if (!ret.empty()) ret += ", "; ret += "angle" ; }
293 if (id & TYPE_VERTEX ) { if (!ret.empty()) ret += ", "; ret += "vertex" ; }