9ba7b00c503379f627ab9ba1c7afa635a260e29c
[synfig.git] / 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 **
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.
15 **
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
21 */
22 /* ========================================================================= */
23
24 /* === S T A R T =========================================================== */
25
26 #ifndef __SYNFIG_DUCKMATIC_DUCK_H
27 #define __SYNFIG_DUCKMATIC_DUCK_H
28
29 /* === H E A D E R S ======================================================= */
30
31 #include <list>
32
33 #include <ETL/smart_ptr>
34 #include <ETL/handle>
35
36 #include <synfig/vector.h>
37 #include <synfig/string.h>
38 #include <synfig/real.h>
39 #include <sigc++/signal.h>
40 #include <sigc++/object.h>
41 #include <synfig/time.h>
42 #include <ETL/smart_ptr>
43 #include <synfigapp/value_desc.h>
44 #include <synfig/transform.h>
45
46 /* === M A C R O S ========================================================= */
47
48 #ifdef HASH_MAP_H
49 #include HASH_MAP_H
50 #include FUNCTIONAL_H
51
52 #ifndef __STRING_HASH__
53 #define __STRING_HASH__
54 class StringHash
55 {
56 # ifdef FUNCTIONAL_HASH_ON_STRING
57         HASH_MAP_NAMESPACE::hash<synfig::String> hasher_;
58 # else  // FUNCTIONAL_HASH_ON_STRING
59         HASH_MAP_NAMESPACE::hash<const char*> hasher_;
60 # endif  // FUNCTIONAL_HASH_ON_STRING
61 public:
62         size_t operator()(const synfig::String& x)const
63         {
64 # ifdef FUNCTIONAL_HASH_ON_STRING
65                 return hasher_(x);
66 # else  // FUNCTIONAL_HASH_ON_STRING
67                 return hasher_(x.c_str());
68 # endif  // FUNCTIONAL_HASH_ON_STRING
69         }
70 };
71 #endif
72 #else
73 #include <map>
74 #endif
75
76 #include <set>
77
78 /* === T Y P E D E F S ===================================================== */
79
80 /* === C L A S S E S & S T R U C T S ======================================= */
81
82 namespace studio {
83 class Duckmatic;
84
85 /*! \class Duck
86 **      \writeme */
87 class Duck : public etl::shared_object
88 {
89         friend class Duckmatic;
90
91 public:
92         enum Type
93         {
94                 TYPE_NONE               =       (0),    //  0
95                 TYPE_POSITION   =       (1<<0), //  1
96                 TYPE_TANGENT    =       (1<<1), //  2
97                 TYPE_RADIUS             =       (1<<2), //  4
98                 TYPE_WIDTH              =       (1<<3), //  8
99                 TYPE_ANGLE              =       (1<<4), // 16
100                 TYPE_VERTEX             =       (1<<5), // 32
101
102                 TYPE_ALL                =       (~0),
103
104                 TYPE_DEFAULT    =       0xdefadefa
105         };
106
107         typedef etl::handle<Duck> Handle;
108         typedef etl::loose_handle<Duck> LooseHandle;
109
110 private:
111
112         sigc::signal<bool,const synfig::Point &> signal_edited_;
113         sigc::signal<bool,const synfig::Angle &> signal_edited_angle_;
114         sigc::signal<void> signal_user_click_[5];
115
116         Type type_;
117
118         synfig::Point point;
119         synfig::Angle rotations;
120
121         etl::smart_ptr<synfig::Point> shared_point;
122
123         synfig::Point origin;
124         synfig::String name;
125         synfig::Real scalar;
126
127         etl::handle<Duck> origin_duck;
128
129         etl::handle<Duck> connect_duck;
130         etl::handle<Duck> box_duck;
131
132         synfig::GUID guid_;
133
134         // Flags
135         bool editable;
136         bool radius_;
137         bool tangent_;
138         bool hover_;
139         bool ignore_;
140
141         synfig::TransformStack transform_stack_;
142
143         synfigapp::ValueDesc value_desc_;
144
145         static int duck_count;
146 public:
147         Duck();
148         Duck(const synfig::Point &point);
149         Duck(const synfig::Point &point,const synfig::Point &origin);
150         ~Duck();
151
152         sigc::signal<bool,const synfig::Point &> &signal_edited() { return signal_edited_; }
153         sigc::signal<bool,const synfig::Angle &> &signal_edited_angle() { return signal_edited_angle_; }
154         sigc::signal<void> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
155
156         void set_guid(const synfig::GUID& x) { guid_=x; }
157         const synfig::GUID& get_guid()const { return guid_; }
158
159         synfig::GUID get_data_guid()const;
160
161         //! Changes the editable flag. If set, the duck will not be able to be moved.
162         void set_editable(bool x) { editable=x; }
163
164         //! Retrieves the status of the editable flag
165         bool get_editable()const { return editable; }
166
167         //! \writeme
168         void set_tangent(bool x) { tangent_=x; type_=TYPE_TANGENT; }
169
170         //! \writeme
171         bool get_tangent()const { return tangent_; }
172
173         //! Sets whether to show the duck as if it is being hovered over
174         void set_hover(bool h) { hover_=h; }
175
176         //! Retrieves whether to show the duck as if it is being hovered over
177         bool get_hover()const { return hover_; }
178
179         //! Sets whether to ignore the duck when checking for user interaction
180         void set_ignore(bool i) { ignore_=i; }
181
182         //! Retrieves whether to ignore the duck when checking for user interaction
183         bool get_ignore()const { return ignore_; }
184
185         void set_connect_duck(const etl::handle<Duck>& x) { connect_duck=x; }
186         void set_box_duck(const etl::handle<Duck>& x) { box_duck=x; }
187
188         const etl::handle<Duck>& get_connect_duck()const { return connect_duck; }
189         const etl::handle<Duck>& get_box_duck()const { return box_duck; }
190
191         void set_value_desc(synfigapp::ValueDesc x) { value_desc_=x; }
192
193         synfigapp::ValueDesc& get_value_desc() { return value_desc_; }
194
195         void set_transform_stack(const synfig::TransformStack& x) { transform_stack_=x; }
196
197         const synfig::TransformStack& get_transform_stack()const { return transform_stack_; }
198
199         //! \writeme
200         void set_type(Type x) { type_=x; }
201
202         //! \writeme
203         Type get_type()const { return type_; }
204
205         //! Sets the scalar multiplier for the duck with respect to the origin
206         void set_scalar(synfig::Vector::value_type n) { scalar=n; }
207
208         //! Retrieves the scalar value
209         synfig::Vector::value_type get_scalar()const { return scalar; }
210
211         void set_shared_point(const etl::smart_ptr<synfig::Point>&x) { shared_point=x; }
212
213         //! Sets the location of the duck with respect to the origin
214         void set_point(const synfig::Point &x) { (shared_point?*shared_point:point)=x; }
215
216         //! Returns the location of the duck
217         synfig::Point get_point()const { return shared_point?*shared_point:point; }
218
219         synfig::Angle get_rotations()const { return rotations; };
220
221         synfig::Point get_trans_point()const;
222
223         void set_trans_point(const synfig::Point &x);
224
225         synfig::Point get_sub_trans_point()const;
226         void set_sub_trans_point(const synfig::Point &x);
227         synfig::Point get_sub_trans_origin()const;
228
229         //! Sets the origin point.
230         void set_origin(const synfig::Point &x);
231
232         //! Sets the origin point as another duck
233         void set_origin(const etl::handle<Duck> &x);
234
235         //! Retrieves the origin location
236         synfig::Point get_origin()const;
237
238         //! Retrieves the origin duck
239         const etl::handle<Duck> & get_origin_duck() const;
240
241         //! Retrieves the origin location
242         synfig::Point get_trans_origin()const;
243
244         void set_radius(bool r) { radius_=r; }
245         bool is_radius()const { return radius_; }
246
247         //! Sets the name of the duck
248         void set_name(const synfig::String &x);
249
250         //! Retrieves the name of the duck
251         synfig::String get_name()const { return name; }
252
253         bool operator==(const Duck &rhs)const;
254
255 #ifdef _DEBUG
256         //!     Returns a string containing the name of the given Type
257         static synfig::String type_name(Type id);
258
259         //!     Returns a string containing the name of the type
260         synfig::String type_name()const { return type_name(get_type()); }
261 #endif  // _DEBUG
262
263 }; // END of class Duck
264
265 //! Combine Flags
266 inline Duck::Type
267 operator|(Duck::Type lhs, const Duck::Type rhs)
268 { return static_cast<Duck::Type>(int(lhs)|int(rhs)); }
269
270 //! Exclude Flags
271 inline Duck::Type
272 operator-(Duck::Type lhs, const Duck::Type rhs)
273 { return static_cast<Duck::Type>(int(lhs)&~int(rhs)); }
274
275 inline Duck::Type&
276 operator|=(Duck::Type& lhs, const Duck::Type rhs)
277 { *reinterpret_cast<int*>(&lhs)|=int(rhs); return lhs; }
278
279 inline Duck::Type
280 operator&(const Duck::Type lhs, const Duck::Type rhs)
281 { return static_cast<Duck::Type>(int(lhs)&int(rhs)); }
282
283 class DuckMap : public
284 #ifdef HASH_MAP_H
285 HASH_MAP_CLASS<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash>
286 {
287         typedef HASH_MAP_CLASS<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash> PARENT_TYPE;
288 #else
289 std::map<synfig::GUID,etl::handle<studio::Duck> >
290 {
291         typedef std::map<synfig::GUID,etl::handle<studio::Duck> > PARENT_TYPE;
292 #endif
293 public:
294         void insert(const Duck::Handle& x) { operator[](x->get_guid())=x;  }
295 }; // END of class DuckMap
296
297 typedef std::list<Duck::Handle> DuckList;
298
299 }; // END of namespace studio
300
301 /* === E N D =============================================================== */
302
303 #endif