Working on 1827966: Angles are recalculated to 360 mod. New signal for class Duck...
[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 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === S T A R T =========================================================== */
24
25 #ifndef __SYNFIG_DUCKMATIC_DUCK_H
26 #define __SYNFIG_DUCKMATIC_DUCK_H
27
28 /* === H E A D E R S ======================================================= */
29
30 #include <list>
31
32 #include <ETL/smart_ptr>
33 #include <ETL/handle>
34
35 #include <synfig/vector.h>
36 #include <synfig/string.h>
37 #include <synfig/real.h>
38 #include <sigc++/signal.h>
39 #include <sigc++/object.h>
40 #include <synfig/time.h>
41 #include <ETL/smart_ptr>
42 #include <synfigapp/value_desc.h>
43 #include <synfig/transform.h>
44
45 /* === M A C R O S ========================================================= */
46
47 #define HASH_MAP_H <ext/hash_map>
48 #define HASH_SET_H <ext/hash_set>
49
50 #ifdef HASH_MAP_H
51 #include HASH_MAP_H
52 #ifndef __STRING_HASH__
53 #define __STRING_HASH__
54 class StringHash
55 {
56         __gnu_cxx::hash<const char*> hasher_;
57 public:
58         size_t operator()(const synfig::String& x)const
59         {
60                 return hasher_(x.c_str());
61         }
62 };
63 #endif
64 #else
65 #include <map>
66 #endif
67
68 #include <set>
69
70 /* === T Y P E D E F S ===================================================== */
71
72 /* === C L A S S E S & S T R U C T S ======================================= */
73
74 namespace studio {
75 class Duckmatic;
76
77 /*! \class Duck
78 **      \writeme */
79 class Duck : public etl::shared_object
80 {
81         friend class Duckmatic;
82
83 public:
84         enum Type
85         {
86                 TYPE_NONE               =       (0),
87                 TYPE_POSITION   =       (1<<0),
88                 TYPE_TANGENT    =       (1<<1),
89                 TYPE_RADIUS             =       (1<<2),
90                 TYPE_WIDTH              =       (1<<3),
91                 TYPE_ANGLE              =       (1<<4),
92                 TYPE_VERTEX             =       (1<<5),
93
94                 TYPE_ALL                =       (~0),
95
96                 TYPE_DEFAULT    =       0xdefadefa
97         };
98
99         typedef etl::handle<Duck> Handle;
100         typedef etl::loose_handle<Duck> LooseHandle;
101
102 private:
103
104         sigc::signal<bool,const synfig::Point &> signal_edited_;
105         sigc::signal<bool,const synfig::Angle &> signal_edited_angle_;
106         sigc::signal<void> signal_user_click_[5];
107
108         Type type_;
109
110         synfig::Point point;
111         synfig::Angle rotations;
112
113         etl::smart_ptr<synfig::Point> shared_point;
114
115         synfig::Point origin;
116         synfig::String name;
117         synfig::Real scalar;
118
119         etl::handle<Duck> origin_duck;
120
121         etl::handle<Duck> connect_duck;
122         etl::handle<Duck> box_duck;
123
124         synfig::GUID guid_;
125
126         // Flags
127         bool editable;
128         bool radius_;
129         bool tangent_;
130
131         synfig::TransformStack transform_stack_;
132
133         synfigapp::ValueDesc value_desc_;
134
135         static int duck_count;
136 public:
137         Duck();
138         Duck(const synfig::Point &point);
139         Duck(const synfig::Point &point,const synfig::Point &origin);
140         ~Duck();
141
142         sigc::signal<bool,const synfig::Point &> &signal_edited() { return signal_edited_; }
143         sigc::signal<bool,const synfig::Angle &> &signal_edited_angle() { return signal_edited_angle_; }
144         sigc::signal<void> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
145
146         void set_guid(const synfig::GUID& x) { guid_=x; }
147         const synfig::GUID& get_guid()const { return guid_; }
148
149         synfig::GUID get_data_guid()const;
150
151         //! Changes the editable flag. If set, the duck will not be able to be moved.
152         void set_editable(bool x) { editable=x; }
153
154         //! Retrieves the status of the editable flag
155         bool get_editable()const { return editable; }
156
157         //! \writeme
158         void set_tangent(bool x) { tangent_=x; type_=TYPE_TANGENT; }
159
160         //! \writeme
161         bool get_tangent()const { return tangent_; }
162
163         void set_connect_duck(const etl::handle<Duck>& x) { connect_duck=x; }
164         void set_box_duck(const etl::handle<Duck>& x) { box_duck=x; }
165
166         const etl::handle<Duck>& get_connect_duck()const { return connect_duck; }
167         const etl::handle<Duck>& get_box_duck()const { return box_duck; }
168
169         void set_value_desc(synfigapp::ValueDesc x) { value_desc_=x; }
170
171         synfigapp::ValueDesc& get_value_desc() { return value_desc_; }
172
173         void set_transform_stack(const synfig::TransformStack& x) { transform_stack_=x; }
174
175         const synfig::TransformStack& get_transform_stack()const { return transform_stack_; }
176
177         //! \writeme
178         void set_type(Type x) { type_=x; }
179
180         //! \writeme
181         Type get_type()const { return type_; }
182
183         //! Sets the scalar multiplier for the duck with respect to the origin
184         void set_scalar(synfig::Vector::value_type n) { scalar=n; }
185
186         //! Retrieves the scalar value
187         synfig::Vector::value_type get_scalar()const { return scalar; }
188
189         void set_shared_point(const etl::smart_ptr<synfig::Point>&x) { shared_point=x; }
190
191         //! Sets the location of the duck with respect to the origin
192         void set_point(const synfig::Point &x) { (shared_point?*shared_point:point)=x; }
193
194         //! Returns the location of the duck
195         synfig::Point get_point()const { return shared_point?*shared_point:point; }
196
197         synfig::Angle get_rotations()const { return rotations; };
198
199         synfig::Point get_trans_point()const;
200
201         void set_trans_point(const synfig::Point &x);
202
203         synfig::Point get_sub_trans_point()const;
204         void set_sub_trans_point(const synfig::Point &x);
205         synfig::Point get_sub_trans_origin()const;
206
207         //! Sets the origin point.
208         void set_origin(const synfig::Point &x);
209
210         //! Sets the origin point as another duck
211         void set_origin(const etl::handle<Duck> &x);
212
213         //! Retrieves the origin location
214         synfig::Point get_origin()const;
215
216         //! Retrieves the origin duck
217         const etl::handle<Duck> & get_origin_duck() const;
218
219         //! Retrieves the origin location
220         synfig::Point get_trans_origin()const;
221
222         void set_radius(bool r) { radius_=r; }
223         bool is_radius()const { return radius_; }
224
225         //! Sets the name of the duck
226         void set_name(const synfig::String &x);
227
228         //! Retrieves the name of the duck
229         synfig::String get_name()const { return name; }
230
231         bool operator==(const Duck &rhs)const;
232 }; // END of class Duck
233
234 //! Combine Flags
235 inline Duck::Type
236 operator|(Duck::Type lhs, const Duck::Type rhs)
237 { return static_cast<Duck::Type>(int(lhs)|int(rhs)); }
238
239 //! Exclude Flags
240 inline Duck::Type
241 operator-(Duck::Type lhs, const Duck::Type rhs)
242 { return static_cast<Duck::Type>(int(lhs)&~int(rhs)); }
243
244 inline Duck::Type&
245 operator|=(Duck::Type& lhs, const Duck::Type rhs)
246 { *reinterpret_cast<int*>(&lhs)|=int(rhs); return lhs; }
247
248 inline Duck::Type
249 operator&(const Duck::Type lhs, const Duck::Type rhs)
250 { return static_cast<Duck::Type>(int(lhs)&int(rhs)); }
251
252 class DuckMap : public
253 #ifdef HASH_MAP_H
254 __gnu_cxx::hash_map<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash>
255 {
256         typedef __gnu_cxx::hash_map<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash> PARENT_TYPE;
257 #else
258 std::map<synfig::GUID,etl::handle<studio::Duck> >
259 {
260         typedef std::map<synfig::GUID,etl::handle<studio::Duck> > PARENT_TYPE;
261 #endif
262 public:
263         void insert(const Duck::Handle& x) { operator[](x->get_guid())=x;  }
264 }; // END of class DuckMap
265
266 typedef std::list<Duck::Handle> DuckList;
267
268 }; // END of namespace studio
269
270 /* === E N D =============================================================== */
271
272 #endif