167e0c87977a3463ccf897651690c9f6fe6c58ae
[synfig.git] / synfig-studio / trunk / src / gtkmm / 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 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),
95                 TYPE_POSITION   =       (1<<0),
96                 TYPE_TANGENT    =       (1<<1),
97                 TYPE_RADIUS             =       (1<<2),
98                 TYPE_WIDTH              =       (1<<3),
99                 TYPE_ANGLE              =       (1<<4),
100                 TYPE_VERTEX             =       (1<<5),
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
140         synfig::TransformStack transform_stack_;
141
142         synfigapp::ValueDesc value_desc_;
143
144         static int duck_count;
145 public:
146         Duck();
147         Duck(const synfig::Point &point);
148         Duck(const synfig::Point &point,const synfig::Point &origin);
149         ~Duck();
150
151         sigc::signal<bool,const synfig::Point &> &signal_edited() { return signal_edited_; }
152         sigc::signal<bool,const synfig::Angle &> &signal_edited_angle() { return signal_edited_angle_; }
153         sigc::signal<void> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
154
155         void set_guid(const synfig::GUID& x) { guid_=x; }
156         const synfig::GUID& get_guid()const { return guid_; }
157
158         synfig::GUID get_data_guid()const;
159
160         //! Changes the editable flag. If set, the duck will not be able to be moved.
161         void set_editable(bool x) { editable=x; }
162
163         //! Retrieves the status of the editable flag
164         bool get_editable()const { return editable; }
165
166         //! \writeme
167         void set_tangent(bool x) { tangent_=x; type_=TYPE_TANGENT; }
168
169         //! \writeme
170         bool get_tangent()const { return tangent_; }
171
172         //! Sets whether to show the duck as if it is being hovered over
173         void set_hover(bool h) { hover_=h; }
174
175         //! Retrieves whether to show the duck as if it is being hovered over
176         bool get_hover()const { return hover_; }
177
178         void set_connect_duck(const etl::handle<Duck>& x) { connect_duck=x; }
179         void set_box_duck(const etl::handle<Duck>& x) { box_duck=x; }
180
181         const etl::handle<Duck>& get_connect_duck()const { return connect_duck; }
182         const etl::handle<Duck>& get_box_duck()const { return box_duck; }
183
184         void set_value_desc(synfigapp::ValueDesc x) { value_desc_=x; }
185
186         synfigapp::ValueDesc& get_value_desc() { return value_desc_; }
187
188         void set_transform_stack(const synfig::TransformStack& x) { transform_stack_=x; }
189
190         const synfig::TransformStack& get_transform_stack()const { return transform_stack_; }
191
192         //! \writeme
193         void set_type(Type x) { type_=x; }
194
195         //! \writeme
196         Type get_type()const { return type_; }
197
198         //! Sets the scalar multiplier for the duck with respect to the origin
199         void set_scalar(synfig::Vector::value_type n) { scalar=n; }
200
201         //! Retrieves the scalar value
202         synfig::Vector::value_type get_scalar()const { return scalar; }
203
204         void set_shared_point(const etl::smart_ptr<synfig::Point>&x) { shared_point=x; }
205
206         //! Sets the location of the duck with respect to the origin
207         void set_point(const synfig::Point &x) { (shared_point?*shared_point:point)=x; }
208
209         //! Returns the location of the duck
210         synfig::Point get_point()const { return shared_point?*shared_point:point; }
211
212         synfig::Angle get_rotations()const { return rotations; };
213
214         synfig::Point get_trans_point()const;
215
216         void set_trans_point(const synfig::Point &x);
217
218         synfig::Point get_sub_trans_point()const;
219         void set_sub_trans_point(const synfig::Point &x);
220         synfig::Point get_sub_trans_origin()const;
221
222         //! Sets the origin point.
223         void set_origin(const synfig::Point &x);
224
225         //! Sets the origin point as another duck
226         void set_origin(const etl::handle<Duck> &x);
227
228         //! Retrieves the origin location
229         synfig::Point get_origin()const;
230
231         //! Retrieves the origin duck
232         const etl::handle<Duck> & get_origin_duck() const;
233
234         //! Retrieves the origin location
235         synfig::Point get_trans_origin()const;
236
237         void set_radius(bool r) { radius_=r; }
238         bool is_radius()const { return radius_; }
239
240         //! Sets the name of the duck
241         void set_name(const synfig::String &x);
242
243         //! Retrieves the name of the duck
244         synfig::String get_name()const { return name; }
245
246         bool operator==(const Duck &rhs)const;
247 }; // END of class Duck
248
249 //! Combine Flags
250 inline Duck::Type
251 operator|(Duck::Type lhs, const Duck::Type rhs)
252 { return static_cast<Duck::Type>(int(lhs)|int(rhs)); }
253
254 //! Exclude Flags
255 inline Duck::Type
256 operator-(Duck::Type lhs, const Duck::Type rhs)
257 { return static_cast<Duck::Type>(int(lhs)&~int(rhs)); }
258
259 inline Duck::Type&
260 operator|=(Duck::Type& lhs, const Duck::Type rhs)
261 { *reinterpret_cast<int*>(&lhs)|=int(rhs); return lhs; }
262
263 inline Duck::Type
264 operator&(const Duck::Type lhs, const Duck::Type rhs)
265 { return static_cast<Duck::Type>(int(lhs)&int(rhs)); }
266
267 class DuckMap : public
268 #ifdef HASH_MAP_H
269 HASH_MAP_CLASS<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash>
270 {
271         typedef HASH_MAP_CLASS<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash> PARENT_TYPE;
272 #else
273 std::map<synfig::GUID,etl::handle<studio::Duck> >
274 {
275         typedef std::map<synfig::GUID,etl::handle<studio::Duck> > PARENT_TYPE;
276 #endif
277 public:
278         void insert(const Duck::Handle& x) { operator[](x->get_guid())=x;  }
279 }; // END of class DuckMap
280
281 typedef std::list<Duck::Handle> DuckList;
282
283 }; // END of namespace studio
284
285 /* === E N D =============================================================== */
286
287 #endif