SVN r1677 partially broke the bline tool by making non-editable ducks selectable...
[synfig.git] / synfig-studio / trunk / src / gtkmm / duck.cpp
blobeca6112d99d45131f9b59f320335e9bc3a017b58
1 /* === S Y N F I G ========================================================= */
2 /*! \file duck.cpp
3 ** \brief Template File
4 **
5 ** $Id$
6 **
7 ** \legal
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
11 ** This package is free software; you can redistribute it and/or
12 ** modify it under the terms of the GNU General Public License as
13 ** published by the Free Software Foundation; either version 2 of
14 ** the License, or (at your option) any later version.
16 ** This package is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ** General Public License for more details.
20 ** \endlegal
22 /* ========================================================================= */
24 /* === H E A D E R S ======================================================= */
26 #ifdef USING_PCH
27 # include "pch.h"
28 #else
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
33 #include "duck.h"
34 #include <ETL/misc>
36 #include "general.h"
38 #endif
40 /* === U S I N G =========================================================== */
42 using namespace std;
43 using namespace etl;
44 using namespace synfig;
45 using namespace studio;
47 /* === M A C R O S ========================================================= */
49 /* === G L O B A L S ======================================================= */
51 int studio::Duck::duck_count(0);
53 struct _DuckCounter
55 static int counter;
56 ~_DuckCounter()
58 if(counter)
59 synfig::error("%d ducks not yet deleted!",counter);
61 } _duck_counter;
63 int _DuckCounter::counter(0);
66 /* === P R O C E D U R E S ================================================= */
68 /* === M E T H O D S ======================================================= */
70 Duck::Duck():
71 rotations(synfig::Angle::deg(0)),
72 origin(0,0),
73 scalar(1),
74 editable(false),
75 radius_(false),
76 tangent_(false),
77 hover_(false),
78 ignore_(false)
79 { duck_count++; _DuckCounter::counter++; }
81 Duck::Duck(const synfig::Point &point):
82 type_(TYPE_NONE),
83 point(point),
84 rotations(synfig::Angle::deg(0)),
85 origin(0,0),
86 scalar(1),
87 guid_(0),
88 editable(false),
89 radius_(false),
90 tangent_(false),
91 hover_(false),
92 ignore_(false)
93 { duck_count++; _DuckCounter::counter++;}
95 Duck::Duck(const synfig::Point &point,const synfig::Point &origin):
96 point(point),
97 rotations(synfig::Angle::deg(0)),
98 origin(origin),
99 scalar(1),
100 guid_(0),
101 editable(false),
102 radius_(true),
103 tangent_(false),
104 hover_(false),
105 ignore_(false)
106 { duck_count++; _DuckCounter::counter++;}
108 Duck::~Duck() { duck_count--; _DuckCounter::counter--;}
110 synfig::GUID
111 Duck::get_data_guid()const
113 if(value_desc_.is_value_node())
114 return value_desc_.get_value_node()->get_guid();
115 return GUID::hasher(get_name());
118 void
119 Duck::set_name(const synfig::String &x)
121 name=x;
122 if(guid_==GUID::zero())
124 guid_=GUID::hasher(name);
129 bool
130 Duck::operator==(const Duck &rhs)const
132 if(this==&rhs)
133 return true;
134 return
135 name==rhs.name &&
136 scalar==rhs.scalar &&
137 type_==rhs.type_ &&
138 transform_stack_.size()==rhs.transform_stack_.size();
139 //true;
140 //(origin_duck?*origin_duck==*rhs.origin_duck:origin==rhs.origin) &&
141 //(shared_point?*shared_point==*rhs.shared_point:point==rhs.point) ;
144 synfig::Point
145 Duck::get_trans_point()const
147 return transform_stack_.perform(get_sub_trans_point());
150 void
151 Duck::set_trans_point(const synfig::Point &x)
153 set_sub_trans_point(transform_stack_.unperform(x));
156 //! Sets the origin point.
157 void
158 Duck::set_origin(const synfig::Point &x)
160 origin=x; origin_duck=0;
163 //! Sets the origin point as another duck
164 void
165 Duck::set_origin(const etl::handle<Duck> &x)
167 origin_duck=x;
170 //! Retrieves the origin location
171 synfig::Point
172 Duck::get_origin()const
174 return origin_duck?origin_duck->get_point():origin;
177 //! Retrieves the origin duck
178 const etl::handle<Duck> &
179 Duck::get_origin_duck() const
181 return origin_duck;
184 //! Retrieves the origin location
185 synfig::Point
186 Duck::get_trans_origin()const
188 return transform_stack_.perform(get_sub_trans_origin());
191 synfig::Point
192 Duck::get_sub_trans_point()const
194 return get_point()*get_scalar()+get_sub_trans_origin();
197 void
198 Duck::set_sub_trans_point(const synfig::Point &x)
200 if (get_type() == Duck::TYPE_TANGENT ||
201 get_type() == Duck::TYPE_ANGLE)
203 Angle old_angle = get_point().angle();
204 set_point((x-get_sub_trans_origin())/get_scalar());
205 Angle change = get_point().angle() - old_angle;
206 while (change < Angle::deg(-180)) change += Angle::deg(360);
207 while (change > Angle::deg(180)) change -= Angle::deg(360);
208 int old_quarters = round_to_int(Angle::deg(rotations).get()/90);
209 rotations += change;
210 int new_quarters = round_to_int(Angle::deg(rotations).get()/90);
211 if (old_quarters != new_quarters)
212 synfig::info("rotation: %.2f turns", new_quarters/4.0);
214 else
215 set_point((x-get_sub_trans_origin())/get_scalar());
218 synfig::Point
219 Duck::get_sub_trans_origin()const
221 return origin_duck?origin_duck->get_sub_trans_point():origin;