Documentation
[synfig.git] / synfig-studio / src / gui / duck.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file duck.h
3 **      \brief Template Header
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **      Copyright (c) 2007, 2008 Chris Moore
10 **      Copyright (c) 2009 Nikita Kitaev
11 **
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.
16 **
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.
21 **      \endlegal
22 */
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
86 /*! \class Duck
87 **      \writeme */
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
103                 TYPE_ALL                =       (~0),
104
105                 TYPE_DEFAULT    =       0xdefadefa
106         };
107
108         typedef etl::handle<Duck> Handle;
109         typedef etl::loose_handle<Duck> LooseHandle;
110
111 private:
112
113         sigc::signal<bool,const synfig::Point &> signal_edited_;
114         sigc::signal<bool,const synfig::Angle &> signal_edited_angle_;
115         sigc::signal<void> signal_user_click_[5];
116
117         Type type_;
118
119         synfig::Point point;
120         synfig::Angle rotations;
121
122         etl::smart_ptr<synfig::Point> shared_point;
123
124         synfig::Point origin;
125         synfig::String name;
126         synfig::Real scalar;
127
128         etl::handle<Duck> origin_duck;
129
130         etl::handle<Duck> connect_duck;
131         etl::handle<Duck> box_duck;
132
133         synfig::GUID guid_;
134
135         // Flags
136         bool editable;
137         bool radius_;
138         bool tangent_;
139         bool hover_;
140         bool ignore_;
141
142         synfig::TransformStack transform_stack_;
143
144         synfigapp::ValueDesc value_desc_;
145
146         static int duck_count;
147 public:
148         Duck();
149         Duck(const synfig::Point &point);
150         Duck(const synfig::Point &point,const synfig::Point &origin);
151         ~Duck();
152
153         sigc::signal<bool,const synfig::Point &> &signal_edited() { return signal_edited_; }
154         sigc::signal<bool,const synfig::Angle &> &signal_edited_angle() { return signal_edited_angle_; }
155         sigc::signal<void> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
156
157         void set_guid(const synfig::GUID& x) { guid_=x; }
158         const synfig::GUID& get_guid()const { return guid_; }
159
160         synfig::GUID get_data_guid()const;
161
162         //! Changes the editable flag. If set, the duck will not be able to be moved.
163         void set_editable(bool x) { editable=x; }
164
165         //! Retrieves the status of the editable flag
166         bool get_editable()const { return editable; }
167
168         //! \writeme
169         void set_tangent(bool x) { tangent_=x; type_=TYPE_TANGENT; }
170
171         //! \writeme
172         bool get_tangent()const { return tangent_; }
173
174         //! Sets whether to show the duck as if it is being hovered over
175         void set_hover(bool h) { hover_=h; }
176
177         //! Retrieves whether to show the duck as if it is being hovered over
178         bool get_hover()const { return hover_; }
179
180         //! Sets whether to ignore the duck when checking for user interaction
181         void set_ignore(bool i) { ignore_=i; }
182
183         //! Retrieves whether to ignore the duck when checking for user interaction
184         bool get_ignore()const { return ignore_; }
185
186         void set_connect_duck(const etl::handle<Duck>& x) { connect_duck=x; }
187         void set_box_duck(const etl::handle<Duck>& x) { box_duck=x; }
188
189         const etl::handle<Duck>& get_connect_duck()const { return connect_duck; }
190         const etl::handle<Duck>& get_box_duck()const { return box_duck; }
191
192         void set_value_desc(synfigapp::ValueDesc x) { value_desc_=x; }
193
194         synfigapp::ValueDesc& get_value_desc() { return value_desc_; }
195
196         void set_transform_stack(const synfig::TransformStack& x) { transform_stack_=x; }
197
198         const synfig::TransformStack& get_transform_stack()const { return transform_stack_; }
199
200         //! Sets the type of duck
201         void set_type(Type x) { type_=x; }
202
203         //! Gets the type of duck
204         Type get_type()const { return type_; }
205
206         //! Sets the scalar multiplier for the duck with respect to the origin
207         void set_scalar(synfig::Vector::value_type n) { scalar=n; }
208
209         //! Retrieves the scalar value
210         synfig::Vector::value_type get_scalar()const { return scalar; }
211
212         void set_shared_point(const etl::smart_ptr<synfig::Point>&x) { shared_point=x; }
213
214         //! Sets the location of the duck with respect to the origin
215         void set_point(const synfig::Point &x) { (shared_point?*shared_point:point)=x; }
216
217         //! Returns the location of the duck
218         synfig::Point get_point()const { return shared_point?*shared_point:point; }
219
220         //! Returns the rotations of the duck
221         /*! For angle and tangent ducks, rotations are used instead of the location
222          *  so that the duck can me rotated more than 180 degrees
223          */
224         synfig::Angle get_rotations()const { return rotations; };
225         
226         //! Sets the rotations of the duck
227         void set_rotations(const synfig::Angle &x) { rotations=x; };
228
229         synfig::Point get_trans_point()const;
230
231         void set_trans_point(const synfig::Point &x);
232         void set_trans_point(const synfig::Point &x, const synfig::Time &time);
233
234         synfig::Point get_sub_trans_point()const;
235         void set_sub_trans_point(const synfig::Point &x);
236         void set_sub_trans_point(const synfig::Point &x, const synfig::Time &time);
237         synfig::Point get_sub_trans_origin()const;
238
239         //! Sets the origin point.
240         void set_origin(const synfig::Point &x);
241
242         //! Sets the origin point as another duck
243         void set_origin(const etl::handle<Duck> &x);
244
245         //! Retrieves the origin location
246         synfig::Point get_origin()const;
247
248         //! Retrieves the origin duck
249         const etl::handle<Duck> & get_origin_duck() const;
250
251         //! Retrieves the origin location
252         synfig::Point get_trans_origin()const;
253
254         void set_radius(bool r) { radius_=r; }
255         bool is_radius()const { return radius_; }
256
257         //! Sets the name of the duck
258         void set_name(const synfig::String &x);
259
260         //! Retrieves the name of the duck
261         synfig::String get_name()const { return name; }
262
263         bool operator==(const Duck &rhs)const;
264
265 #ifdef _DEBUG
266         //!     Returns a string containing the name of the given Type
267         static synfig::String type_name(Type id);
268
269         //!     Returns a string containing the name of the type
270         synfig::String type_name()const { return type_name(get_type()); }
271 #endif  // _DEBUG
272
273 }; // END of class Duck
274
275 //! Combine Flags
276 inline Duck::Type
277 operator|(Duck::Type lhs, const Duck::Type rhs)
278 { return static_cast<Duck::Type>(int(lhs)|int(rhs)); }
279
280 //! Exclude Flags
281 inline Duck::Type
282 operator-(Duck::Type lhs, const Duck::Type rhs)
283 { return static_cast<Duck::Type>(int(lhs)&~int(rhs)); }
284
285 inline Duck::Type&
286 operator|=(Duck::Type& lhs, const Duck::Type rhs)
287 { *reinterpret_cast<int*>(&lhs)|=int(rhs); return lhs; }
288
289 inline Duck::Type
290 operator&(const Duck::Type lhs, const Duck::Type rhs)
291 { return static_cast<Duck::Type>(int(lhs)&int(rhs)); }
292
293 class DuckMap : public
294 #ifdef HASH_MAP_H
295 HASH_MAP_CLASS<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash>
296 {
297         typedef HASH_MAP_CLASS<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash> PARENT_TYPE;
298 #else
299 std::map<synfig::GUID,etl::handle<studio::Duck> >
300 {
301         typedef std::map<synfig::GUID,etl::handle<studio::Duck> > PARENT_TYPE;
302 #endif
303 public:
304         void insert(const Duck::Handle& x) { operator[](x->get_guid())=x;  }
305 }; // END of class DuckMap
306
307 typedef std::list<Duck::Handle> DuckList;
308
309 }; // END of namespace studio
310
311 /* === E N D =============================================================== */
312
313 #endif