synfig-studio  1.0.3
duck.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
23 /* ========================================================================= */
24 
25 /* === S T A R T =========================================================== */
26 
27 #ifndef __SYNFIG_DUCKMATIC_DUCK_H
28 #define __SYNFIG_DUCKMATIC_DUCK_H
29 
30 /* === H E A D E R S ======================================================= */
31 
32 #include <list>
33 
34 #include <ETL/smart_ptr>
35 #include <ETL/handle>
36 
37 #include <synfig/vector.h>
38 #include <synfig/string.h>
39 #include <synfig/real.h>
40 #include <sigc++/signal.h>
41 #include <sigc++/object.h>
42 #include <synfig/time.h>
43 #include <ETL/smart_ptr>
44 #include <synfigapp/value_desc.h>
45 #include <synfig/transform.h>
46 
47 /* === M A C R O S ========================================================= */
48 
49 #ifdef HASH_MAP_H
50 #include HASH_MAP_H
51 #include FUNCTIONAL_H
52 
53 #ifndef __STRING_HASH__
54 #define __STRING_HASH__
55 class StringHash
56 {
57 # ifdef FUNCTIONAL_HASH_ON_STRING
58  HASH_MAP_NAMESPACE::hash<synfig::String> hasher_;
59 # else // FUNCTIONAL_HASH_ON_STRING
60  HASH_MAP_NAMESPACE::hash<const char*> hasher_;
61 # endif // FUNCTIONAL_HASH_ON_STRING
62 public:
63  size_t operator()(const synfig::String& x)const
64  {
65 # ifdef FUNCTIONAL_HASH_ON_STRING
66  return hasher_(x);
67 # else // FUNCTIONAL_HASH_ON_STRING
68  return hasher_(x.c_str());
69 # endif // FUNCTIONAL_HASH_ON_STRING
70  }
71 };
72 #endif
73 #else
74 #include <map>
75 #endif
76 
77 #include <set>
78 
79 /* === T Y P E D E F S ===================================================== */
80 
81 /* === C L A S S E S & S T R U C T S ======================================= */
82 
83 namespace studio {
84 class Duckmatic;
85 
88 class Duck : public etl::shared_object
89 {
90  friend class Duckmatic;
91 
92 public:
93  enum Type
94  {
95  TYPE_NONE = (0), // 0
96  TYPE_POSITION = (1 << 0), // 1
97  TYPE_TANGENT = (1 << 1), // 2
98  TYPE_RADIUS = (1 << 2), // 4
99  TYPE_WIDTH = (1 << 3), // 8
100  TYPE_ANGLE = (1 << 4), // 16
101  TYPE_VERTEX = (1 << 5), // 32
102  TYPE_BONE_RECURSIVE = (1 << 6), // 64
103  TYPE_WIDTHPOINT_POSITION = (1 << 7), // 128
104  TYPE_SCALE = (1 << 8), // 256
105  TYPE_SCALE_X = (1 << 9), // 512
106  TYPE_SCALE_Y = (1 << 10), // 1024
107  TYPE_SKEW = (1 << 11), // 2048
108 
109  TYPE_ALL = (~0),
110 
111  TYPE_DEFAULT = 0xdefadefa
112  };
113 
114  typedef etl::handle<Duck> Handle;
115  typedef etl::loose_handle<Duck> LooseHandle;
116 
117 private:
118 
119  sigc::signal<bool,const Duck &> signal_edited_;
120  sigc::signal<void> signal_user_click_[5];
121 
122 
123  // information about represented value
124 
125  synfig::GUID guid_;
126  synfig::String name;
127  Type type_;
128  synfigapp::ValueDesc value_desc_;
129  synfigapp::ValueDesc alternative_value_desc_;
130 
131 
132  // Flags
133 
134  bool editable_;
135  bool alternative_editable_;
136  bool edit_immediatelly_;
137  bool radius_;
138  bool tangent_;
139  bool hover_;
140  bool ignore_;
141  bool exponential_;
142  bool track_axes_;
143  bool lock_aspect_;
144 
145  // positioning
146 
147  synfig::TransformStack transform_stack_;
148 
149  synfig::Real scalar_;
150 
151  synfig::Point origin_;
152  Handle origin_duck_;
153 
154  Handle axis_x_angle_duck_;
155  synfig::Angle axis_x_angle_;
156 
157  Handle axis_x_mag_duck_;
158  synfig::Real axis_x_mag_;
159 
160  Handle axis_y_angle_duck_;
161  synfig::Angle axis_y_angle_;
162 
163  Handle axis_y_mag_duck_;
164  synfig::Real axis_y_mag_;
165 
166  Handle connect_duck_;
167  Handle box_duck_;
168 
169  // value
170 
171  synfig::Point point_;
172  etl::smart_ptr<synfig::Point> shared_point_;
173  etl::smart_ptr<synfig::Angle> shared_angle_;
174  etl::smart_ptr<synfig::Real> shared_mag_;
175  synfig::Angle rotations_;
176  synfig::Point aspect_point_;
177 
178  static int duck_count;
179 public:
180 
181  // constructors
182 
183  Duck();
184  explicit Duck(const synfig::Point &point);
185  Duck(const synfig::Point &point,const synfig::Point &origin);
186  ~Duck();
187 
188 
189  // signals
190 
191  sigc::signal<bool,const Duck &> &signal_edited()
192  { return signal_edited_; }
193  sigc::signal<void> &signal_user_click(int i=0)
194  { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
195 
196 
197  // information about represented value
198 
199  void set_guid(const synfig::GUID& x) { guid_=x; }
200  const synfig::GUID& get_guid()const { return guid_; }
201  synfig::GUID get_data_guid()const;
202 
204  void set_name(const synfig::String &x);
206  synfig::String get_name()const { return name; }
207 
208  void set_type(Type x) { type_=x; }
209  Type get_type()const { return type_; }
210 
211 #ifdef _DEBUG
212 
213  static synfig::String type_name(Type id);
215  synfig::String type_name()const { return type_name(get_type()); }
216 #endif // _DEBUG
217 
219  { value_desc_=x; }
221  { return value_desc_; }
223  { alternative_value_desc_=x; }
225  { return alternative_value_desc_; }
226 
227 
228  // flags
229 
230  bool get_editable(bool is_alternative_mode)const
231  {
232  if (alternative_value_desc_.is_valid())
233  return is_alternative_mode ? alternative_editable_ : editable_;
234  return editable_;
235  }
237  void set_editable(bool x)
238  { editable_=x; }
240  bool get_editable()const
241  { return editable_; }
244  { alternative_editable_=x; }
247  { return alternative_editable_; }
248 
249  bool is_radius()const
250  { return radius_; }
251  void set_radius(bool r)
252  { radius_=r; }
253 
257  { edit_immediatelly_=x; }
259  { return edit_immediatelly_; }
260 
261  void set_tangent(bool x)
262  { tangent_=x; if (x) type_=TYPE_TANGENT; }
263  bool get_tangent()const
264  { return tangent_; }
265 
267  void set_hover(bool h)
268  { hover_=h; }
270  bool get_hover()const
271  { return hover_; }
272 
274  void set_ignore(bool i)
275  { ignore_=i; }
277  bool get_ignore()const
278  { return ignore_; }
279 
281 
282  void set_exponential(bool n)
283  { exponential_=n; }
285  bool get_exponential()const
286  { return exponential_; }
287 
289  bool is_axes_tracks()const
290  { return track_axes_; }
291  void set_track_axes(bool r)
292  { track_axes_=r; }
293 
294  bool is_aspect_locked()const
295  { return lock_aspect_; }
296  void set_lock_aspect(bool r)
297  { if (!lock_aspect_ && r) aspect_point_=point_.norm(); lock_aspect_=r; }
298 
299  // positioning
300 
301  void set_transform_stack(const synfig::TransformStack& x)
302  { transform_stack_=x; }
303  const synfig::TransformStack& get_transform_stack()const
304  { return transform_stack_; }
305 
307  void set_scalar(synfig::Vector::value_type n)
308  { scalar_=n; }
310  synfig::Vector::value_type get_scalar()const
311  { return scalar_; }
312 
314  void set_origin(const synfig::Point &x)
315  { origin_=x; origin_duck_=NULL; }
317  void set_origin(const Handle &x)
318  { origin_duck_=x; }
320  synfig::Point get_origin()const
321  { return origin_duck_?origin_duck_->get_point():origin_; }
323  const Handle& get_origin_duck() const
324  { return origin_duck_; }
325 
326  void set_axis_x_angle(const synfig::Angle &a)
327  { axis_x_angle_=a; axis_x_angle_duck_=NULL; }
328  void set_axis_x_angle(const Handle &duck, const synfig::Angle angle = synfig::Angle::zero())
329  { axis_x_angle_duck_=duck; axis_x_angle_=angle; }
330  synfig::Angle get_axis_x_angle()const
331  { return axis_x_angle_duck_?get_sub_trans_point(axis_x_angle_duck_,false).angle()+axis_x_angle_:axis_x_angle_; }
333  { return axis_x_angle_duck_; }
334 
335  void set_axis_x_mag(const synfig::Real &m)
336  { axis_x_mag_=m; axis_x_mag_duck_=NULL; }
337  void set_axis_x_mag(const Handle &duck)
338  { axis_x_mag_duck_=duck; }
339  synfig::Real get_axis_x_mag()const
340  { return axis_x_mag_duck_?get_sub_trans_point(axis_x_mag_duck_,false).mag():axis_x_mag_; }
342  { return axis_x_mag_duck_; }
343 
344  synfig::Point get_axis_x()const
345  { return synfig::Point(get_axis_x_mag(), get_axis_x_angle()); }
346 
347  void set_axis_y_angle(const synfig::Angle &a)
348  { axis_y_angle_=a; axis_y_angle_duck_=NULL; }
349  void set_axis_y_angle(const Handle &duck, const synfig::Angle angle = synfig::Angle::zero())
350  { axis_y_angle_duck_=duck; axis_y_angle_=angle; }
351  synfig::Angle get_axis_y_angle()const
352  { return axis_y_angle_duck_?get_sub_trans_point(axis_y_angle_duck_,false).angle()+axis_y_angle_:axis_y_angle_; }
354  { return axis_y_angle_duck_; }
355 
356  void set_axis_y_mag(const synfig::Real &m)
357  { axis_y_mag_=m; axis_y_mag_duck_=NULL; }
358  void set_axis_y_mag(const Handle &duck)
359  { axis_y_mag_duck_=duck; }
360  synfig::Real get_axis_y_mag()const
361  { return axis_y_mag_duck_?get_sub_trans_point(axis_y_mag_duck_,false).mag():axis_y_mag_; }
363  { return axis_y_mag_duck_; }
364 
365  synfig::Point get_axis_y()const
366  { return synfig::Point(get_axis_y_mag(), get_axis_y_angle()); }
367 
369  bool is_linear()const
370  { return !get_axis_y_mag_duck() && get_axis_y_mag() == 0; }
371  void set_linear(bool r)
372  { if (is_linear() != r) set_axis_y_mag(r?0:1); }
373  void set_linear(bool r, const synfig::Angle &a)
374  { set_linear(r); set_axis_x_angle(a); }
375  void set_linear(bool r, const Handle &duck)
376  { set_linear(r); set_axis_x_angle(duck); }
377  synfig::Angle get_linear_angle()const
378  { return get_axis_x_angle(); }
379  const Handle& get_linear_duck()const
380  { return get_axis_x_angle_duck(); }
381 
382 
383  // guidelines to other ducks
384 
386  void set_connect_duck(const Handle& x)
387  { connect_duck_=x; }
388  const Handle& get_connect_duck()const
389  { return connect_duck_; }
390 
392  void set_box_duck(const Handle& x)
393  { box_duck_=x; }
394  const Handle& get_box_duck()const
395  { return box_duck_; }
396 
397 
398  // value
399 
401  void set_point(const synfig::Point &x);
403  synfig::Point get_point()const;
404 
405  void set_shared_point(const etl::smart_ptr<synfig::Point>&x)
406  { shared_point_=x; }
407  const etl::smart_ptr<synfig::Point>& get_shared_point()const
408  { return shared_point_; }
409 
410  void set_shared_angle(const etl::smart_ptr<synfig::Angle>&x)
411  { shared_angle_=x; }
412  const etl::smart_ptr<synfig::Angle>& get_shared_angle()const
413  { return shared_angle_; }
414 
415  void set_shared_mag(const etl::smart_ptr<synfig::Real>&x)
416  { shared_mag_=x; }
417  const etl::smart_ptr<synfig::Real>& get_shared_mag()const
418  { return shared_mag_; }
419 
423  synfig::Angle get_rotations()const
424  { return rotations_; };
426  void set_rotations(const synfig::Angle &x)
427  { rotations_=x; };
428 
429 
430  // calculation of position of duck at workarea
431 
432  synfig::Point get_trans_point()const;
433 
434  void set_trans_point(const synfig::Point &x);
435  void set_trans_point(const synfig::Point &x, const synfig::Time &time);
436 
437  synfig::Point get_sub_trans_point(const synfig::Point &x)const;
438  synfig::Point get_sub_trans_point()const;
439  synfig::Point get_sub_trans_point_without_offset(const synfig::Point &x)const;
440  synfig::Point get_sub_trans_point_without_offset()const;
441  void set_sub_trans_point(const synfig::Point &x);
442  void set_sub_trans_point(const synfig::Point &x, const synfig::Time &time);
443  synfig::Point get_sub_trans_point(const Handle &duck, const synfig::Point &def, bool translate = true)const;
444  synfig::Point get_sub_trans_point(const Handle &duck, bool translate = true)const
445  { return get_sub_trans_point(duck, synfig::Point(0,0), translate); }
446  synfig::Point get_sub_trans_origin()const;
447 
449  synfig::Point get_trans_origin()const;
450 
451 
452  // operators
453 
454  bool operator==(const Duck &rhs)const;
455 }; // END of class Duck
456 
458 inline Duck::Type
460 { return static_cast<Duck::Type>(int(lhs)|int(rhs)); }
461 
463 inline Duck::Type
465 { return static_cast<Duck::Type>(int(lhs)&~int(rhs)); }
466 
467 inline Duck::Type&
469 { *reinterpret_cast<int*>(&lhs)|=int(rhs); return lhs; }
470 
471 inline Duck::Type
472 operator&(const Duck::Type lhs, const Duck::Type rhs)
473 { return static_cast<Duck::Type>(int(lhs)&int(rhs)); }
474 
475 class DuckMap : public
476 #ifdef HASH_MAP_H
477 HASH_MAP_CLASS<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash>
478 {
479  typedef HASH_MAP_CLASS<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash> PARENT_TYPE;
480 #else
481 std::map<synfig::GUID,etl::handle<studio::Duck> >
482 {
483  typedef std::map<synfig::GUID,etl::handle<studio::Duck> > PARENT_TYPE;
484 #endif
485 public:
486  void insert(const Duck::Handle& x) { operator[](x->get_guid())=x; }
487 }; // END of class DuckMap
488 
489 typedef std::list<Duck::Handle> DuckList;
490 
491 }; // END of namespace studio
492 
493 /* === E N D =============================================================== */
494 
495 #endif