Fix a crash when running single-threaded and dragging the time slider.
[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<void> signal_user_click_[5];
106
107         Type type_;
108
109         synfig::Point point;
110
111         etl::smart_ptr<synfig::Point> shared_point;
112
113         synfig::Point origin;
114         synfig::String name;
115         synfig::Real scalar;
116
117         etl::handle<Duck> origin_duck;
118
119         etl::handle<Duck> connect_duck;
120         etl::handle<Duck> box_duck;
121
122         synfig::GUID guid_;
123
124         // Flags
125         bool editable;
126         bool radius_;
127         bool tangent_;
128
129         synfig::TransformStack transform_stack_;
130
131         synfigapp::ValueDesc value_desc_;
132
133         static int duck_count;
134 public:
135         Duck();
136         Duck(const synfig::Point &point);
137         Duck(const synfig::Point &point,const synfig::Point &origin);
138         ~Duck();
139
140         sigc::signal<bool,const synfig::Point &> &signal_edited() { return signal_edited_; }
141         sigc::signal<void> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
142
143         void set_guid(const synfig::GUID& x) { guid_=x; }
144         const synfig::GUID& get_guid()const { return guid_; }
145
146         synfig::GUID get_data_guid()const;
147
148         //! Changes the editable flag. If set, the duck will not be able to be moved.
149         void set_editable(bool x) { editable=x; }
150
151         //! Retrieves the status of the editable flag
152         bool get_editable()const { return editable; }
153
154         //! \writeme
155         void set_tangent(bool x) { tangent_=x; type_=TYPE_TANGENT; }
156
157         //! \writeme
158         bool get_tangent()const { return tangent_; }
159
160         void set_connect_duck(const etl::handle<Duck>& x) { connect_duck=x; }
161         void set_box_duck(const etl::handle<Duck>& x) { box_duck=x; }
162
163         const etl::handle<Duck>& get_connect_duck()const { return connect_duck; }
164         const etl::handle<Duck>& get_box_duck()const { return box_duck; }
165
166         void set_value_desc(synfigapp::ValueDesc x) { value_desc_=x; }
167
168         synfigapp::ValueDesc& get_value_desc() { return value_desc_; }
169
170         void set_transform_stack(const synfig::TransformStack& x) { transform_stack_=x; }
171
172         const synfig::TransformStack& get_transform_stack()const { return transform_stack_; }
173
174         //! \writeme
175         void set_type(Type x) { type_=x; }
176
177         //! \writeme
178         Type get_type()const { return type_; }
179
180         //! Sets the scalar multiplier for the duck with respect to the origin
181         void set_scalar(synfig::Vector::value_type n) { scalar=n; }
182
183         //! Retrieves the scalar value
184         synfig::Vector::value_type get_scalar()const { return scalar; }
185
186         void set_shared_point(const etl::smart_ptr<synfig::Point>&x) { shared_point=x; }
187
188         //! Sets the location of the duck with respect to the origin
189         void set_point(const synfig::Point &x) { (shared_point?*shared_point:point)=x; }
190
191         //! Returns the location of the duck
192         synfig::Point get_point()const { return shared_point?*shared_point:point; }
193
194         synfig::Point get_trans_point()const;
195
196         void set_trans_point(const synfig::Point &x);
197
198         synfig::Point get_sub_trans_point()const;
199         void set_sub_trans_point(const synfig::Point &x);
200         synfig::Point get_sub_trans_origin()const;
201
202         //! Sets the origin point.
203         void set_origin(const synfig::Point &x);
204
205         //! Sets the origin point as another duck
206         void set_origin(const etl::handle<Duck> &x);
207
208         //! Retrieves the origin location
209         synfig::Point get_origin()const;
210
211         //! Retrieves the origin duck
212         const etl::handle<Duck> & get_origin_duck() const;
213
214         //! Retrieves the origin location
215         synfig::Point get_trans_origin()const;
216
217         void set_radius(bool r) { radius_=r; }
218         bool is_radius()const { return radius_; }
219
220         //! Sets the name of the duck
221         void set_name(const synfig::String &x);
222
223         //! Retrieves the name of the duck
224         synfig::String get_name()const { return name; }
225
226         bool operator==(const Duck &rhs)const;
227 }; // END of class Duck
228
229 //! Combine Flags
230 inline Duck::Type
231 operator|(Duck::Type lhs, const Duck::Type rhs)
232 { return static_cast<Duck::Type>(int(lhs)|int(rhs)); }
233
234 //! Exclude 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 inline Duck::Type&
240 operator|=(Duck::Type& lhs, const Duck::Type rhs)
241 { *reinterpret_cast<int*>(&lhs)|=int(rhs); return lhs; }
242
243 inline Duck::Type
244 operator&(const Duck::Type lhs, const Duck::Type rhs)
245 { return static_cast<Duck::Type>(int(lhs)&int(rhs)); }
246
247 class DuckMap : public
248 #ifdef HASH_MAP_H
249 __gnu_cxx::hash_map<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash>
250 {
251         typedef __gnu_cxx::hash_map<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash> PARENT_TYPE;
252 #else
253 std::map<synfig::GUID,etl::handle<studio::Duck> >
254 {
255         typedef std::map<synfig::GUID,etl::handle<studio::Duck> > PARENT_TYPE;
256 #endif
257 public:
258         void insert(const Duck::Handle& x) { operator[](x->get_guid())=x;  }
259 }; // END of class DuckMap
260
261 typedef std::list<Duck::Handle> DuckList;
262
263 }; // END of namespace studio
264
265 /* === E N D =============================================================== */
266
267 #endif