source: synfigstudio/trunk/fuentes/src/gui/duck.h @ 481

Last change on this file since 481 was 481, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 14.3 KB
Line 
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++/sigc++.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__
54class 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
61public:
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
82namespace studio {
83class Duckmatic;
84
85/*! \class Duck
86**      \writeme */
87class Duck : public etl::shared_object
88{
89        friend class Duckmatic;
90
91public:
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                TYPE_BONE_RECURSIVE                     =       (1 <<  6),      //   64
102                TYPE_WIDTHPOINT_POSITION        =       (1 <<  7),      //  128
103                TYPE_SCALE                                      =       (1 <<  8),      //  256
104                TYPE_SCALE_X                            =       (1 <<  9),      //  512
105                TYPE_SCALE_Y                            =       (1 << 10),      // 1024
106                TYPE_SKEW                                       =       (1 << 11),      // 2048
107
108                TYPE_ALL                =       (~0),
109
110                TYPE_DEFAULT    =       0xdefadefa
111        };
112
113        typedef etl::handle<Duck> Handle;
114        typedef etl::loose_handle<Duck> LooseHandle;
115
116private:
117
118        sigc::signal<bool,const Duck &> signal_edited_;
119        sigc::signal<void> signal_user_click_[5];
120
121
122        // information about represented value
123
124        synfig::GUID guid_;
125        synfig::String name;
126        Type type_;
127        synfigapp::ValueDesc value_desc_;
128        synfigapp::ValueDesc alternative_value_desc_;
129
130
131        // Flags
132
133        bool editable_;
134        bool alternative_editable_;
135        bool edit_immediatelly_;
136        bool radius_;
137        bool tangent_;
138        bool hover_;
139        bool ignore_;
140        bool exponential_;
141        bool track_axes_;
142        bool lock_aspect_;
143
144        // positioning
145
146        synfig::TransformStack transform_stack_;
147
148        synfig::Real scalar_;
149
150        synfig::Point origin_;
151        Handle origin_duck_;
152
153        Handle axis_x_angle_duck_;
154        synfig::Angle axis_x_angle_;
155
156        Handle axis_x_mag_duck_;
157        synfig::Real axis_x_mag_;
158
159        Handle axis_y_angle_duck_;
160        synfig::Angle axis_y_angle_;
161
162        Handle axis_y_mag_duck_;
163        synfig::Real axis_y_mag_;
164
165        Handle connect_duck_;
166        Handle box_duck_;
167
168        // value
169
170        synfig::Point point_;
171        etl::smart_ptr<synfig::Point> shared_point_;
172        etl::smart_ptr<synfig::Angle> shared_angle_;
173        etl::smart_ptr<synfig::Real> shared_mag_;
174        synfig::Angle rotations_;
175        synfig::Point aspect_point_;
176
177        static int duck_count;
178public:
179
180        // constructors
181
182        Duck();
183        explicit Duck(const synfig::Point &point);
184        Duck(const synfig::Point &point,const synfig::Point &origin);
185        ~Duck();
186
187
188        // signals
189
190        sigc::signal<bool,const Duck &> &signal_edited()
191                { return signal_edited_; }
192        sigc::signal<void> &signal_user_click(int i=0)
193                { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
194
195
196        // information about represented value
197
198        void set_guid(const synfig::GUID& x) { guid_=x; }
199        const synfig::GUID& get_guid()const { return guid_; }
200        synfig::GUID get_data_guid()const;
201
202        //! Sets the name of the duck
203        void set_name(const synfig::String &x);
204        //! Retrieves the name of the duck
205        synfig::String get_name()const { return name; }
206
207        void set_type(Type x) { type_=x; }
208        Type get_type()const { return type_; }
209
210#ifdef _DEBUG
211        //!     Returns a string containing the name of the given Type
212        static synfig::String type_name(Type id);
213        //!     Returns a string containing the name of the type
214        synfig::String type_name()const { return type_name(get_type()); }
215#endif  // _DEBUG
216
217        void set_value_desc(const synfigapp::ValueDesc &x)
218                { value_desc_=x; }
219        const synfigapp::ValueDesc& get_value_desc() const
220                { return value_desc_; }
221        void set_alternative_value_desc(const synfigapp::ValueDesc &x)
222                { alternative_value_desc_=x; }
223        const synfigapp::ValueDesc& get_alternative_value_desc() const
224                { return alternative_value_desc_; }
225
226
227        // flags
228
229        bool get_editable(bool is_alternative_mode)const
230        {
231                if (alternative_value_desc_.is_valid())
232                        return is_alternative_mode ? alternative_editable_ : editable_;
233                return editable_;
234        }
235        //! Changes the editable flag.
236        void set_editable(bool x)
237                { editable_=x; }
238        //! Retrieves the status of the editable flag
239        bool get_editable()const
240                { return editable_; }
241        //! Changes the editable_alternative flag.
242        void set_alternative_editable(bool x)
243                { alternative_editable_=x; }
244        //! Retrieves the status of the editable_alternative flag
245        bool get_alternative_editable()const
246                { return alternative_editable_; }
247
248        bool is_radius()const
249                { return radius_; }
250        void set_radius(bool r)
251                { radius_=r; }
252
253        //! If set, the duck will send signal_edited while moving.
254        //! If not set, the duck will send signal_edited when button released.
255        void set_edit_immediatelly(bool x)
256                { edit_immediatelly_=x; }
257        bool get_edit_immediatelly()const
258                { return edit_immediatelly_; }
259
260        void set_tangent(bool x)
261                { tangent_=x; if (x) type_=TYPE_TANGENT; }
262        bool get_tangent()const
263                { return tangent_; }
264
265        //! Sets whether to show the duck as if it is being hovered over
266        void set_hover(bool h)
267                { hover_=h; }
268        //! Retrieves whether to show the duck as if it is being hovered over
269        bool get_hover()const
270                { return hover_; }
271
272        //! Sets whether to ignore the duck when checking for user interaction
273        void set_ignore(bool i)
274                { ignore_=i; }
275        //! Retrieves whether to ignore the duck when checking for user interaction
276        bool get_ignore()const
277                { return ignore_; }
278       
279        //! Sets if the duck is using the exponential function
280        /*!     Such representation allows to set the Real values in the range from \c -inf to \c inf . */
281        void set_exponential(bool n)
282                { exponential_=n; }
283        //! Retrieves the exponential value
284        bool get_exponential()const
285                { return exponential_; }
286
287        //! draw projection lines onto axes
288        bool is_axes_tracks()const
289                { return track_axes_; }
290        void set_track_axes(bool r)
291                { track_axes_=r; }
292
293        bool is_aspect_locked()const
294                { return lock_aspect_; }
295        void set_lock_aspect(bool r)
296                { if (!lock_aspect_ && r) aspect_point_=point_.norm(); lock_aspect_=r; }
297
298        // positioning
299
300        void set_transform_stack(const synfig::TransformStack& x)
301                { transform_stack_=x; }
302        const synfig::TransformStack& get_transform_stack()const
303                { return transform_stack_; }
304
305        //! Sets the scalar multiplier for the duck with respect to the origin
306        void set_scalar(synfig::Vector::value_type n)
307                { scalar_=n; }
308        //! Retrieves the scalar value
309        synfig::Vector::value_type get_scalar()const
310                { return scalar_; }
311
312        //! Sets the origin point.
313        void set_origin(const synfig::Point &x)
314                { origin_=x; origin_duck_=NULL; }
315        //! Sets the origin point as another duck
316        void set_origin(const Handle &x)
317                { origin_duck_=x; }
318        //! Retrieves the origin location
319        synfig::Point get_origin()const
320                { return origin_duck_?origin_duck_->get_point():origin_; }
321        //! Retrieves the origin duck
322        const Handle& get_origin_duck() const
323                { return origin_duck_; }
324
325        void set_axis_x_angle(const synfig::Angle &a)
326                { axis_x_angle_=a; axis_x_angle_duck_=NULL; }
327        void set_axis_x_angle(const Handle &duck, const synfig::Angle angle = synfig::Angle::zero())
328                { axis_x_angle_duck_=duck; axis_x_angle_=angle; }
329        synfig::Angle get_axis_x_angle()const
330                { return axis_x_angle_duck_?get_sub_trans_point(axis_x_angle_duck_,false).angle()+axis_x_angle_:axis_x_angle_; }
331        const Handle& get_axis_x_angle_duck()const
332                { return axis_x_angle_duck_; }
333
334        void set_axis_x_mag(const synfig::Real &m)
335                { axis_x_mag_=m; axis_x_mag_duck_=NULL; }
336        void set_axis_x_mag(const Handle &duck)
337                { axis_x_mag_duck_=duck; }
338        synfig::Real get_axis_x_mag()const
339                { return axis_x_mag_duck_?get_sub_trans_point(axis_x_mag_duck_,false).mag():axis_x_mag_; }
340        const Handle& get_axis_x_mag_duck()const
341                { return axis_x_mag_duck_; }
342
343        synfig::Point get_axis_x()const
344                { return synfig::Point(get_axis_x_mag(), get_axis_x_angle()); }
345
346        void set_axis_y_angle(const synfig::Angle &a)
347                { axis_y_angle_=a; axis_y_angle_duck_=NULL; }
348        void set_axis_y_angle(const Handle &duck, const synfig::Angle angle = synfig::Angle::zero())
349                { axis_y_angle_duck_=duck; axis_y_angle_=angle; }
350        synfig::Angle get_axis_y_angle()const
351                { return axis_y_angle_duck_?get_sub_trans_point(axis_y_angle_duck_,false).angle()+axis_y_angle_:axis_y_angle_; }
352        const Handle& get_axis_y_angle_duck()const
353                { return axis_y_angle_duck_; }
354
355        void set_axis_y_mag(const synfig::Real &m)
356                { axis_y_mag_=m; axis_y_mag_duck_=NULL; }
357        void set_axis_y_mag(const Handle &duck)
358                { axis_y_mag_duck_=duck; }
359        synfig::Real get_axis_y_mag()const
360                { return axis_y_mag_duck_?get_sub_trans_point(axis_y_mag_duck_,false).mag():axis_y_mag_; }
361        const Handle& get_axis_y_mag_duck()const
362                { return axis_y_mag_duck_; }
363
364        synfig::Point get_axis_y()const
365                { return synfig::Point(get_axis_y_mag(), get_axis_y_angle()); }
366
367        //! linear ducks moves along specified axis only (angle locked)
368        bool is_linear()const
369                { return !get_axis_y_mag_duck() && get_axis_y_mag() == 0; }
370        void set_linear(bool r)
371                { if (is_linear() != r) set_axis_y_mag(r?0:1); }
372        void set_linear(bool r, const synfig::Angle &a)
373                { set_linear(r); set_axis_x_angle(a); }
374        void set_linear(bool r, const Handle &duck)
375                { set_linear(r); set_axis_x_angle(duck); }
376        synfig::Angle get_linear_angle()const
377                { return get_axis_x_angle(); }
378        const Handle& get_linear_duck()const
379                { return get_axis_x_angle_duck(); }
380
381
382        // guidelines to other ducks
383
384        //! draw line from specified duck to this duck
385        void set_connect_duck(const Handle& x)
386                { connect_duck_=x; }
387        const Handle& get_connect_duck()const
388                { return connect_duck_; }
389
390        //! draw rectangle by two points - from this duck and from specified duck
391        void set_box_duck(const Handle& x)
392                { box_duck_=x; }
393        const Handle& get_box_duck()const
394                { return box_duck_; }
395
396
397        // value
398
399        //! Sets the location of the duck with respect to the origin
400        void set_point(const synfig::Point &x);
401        //! Returns the location of the duck
402        synfig::Point get_point()const;
403
404        void set_shared_point(const etl::smart_ptr<synfig::Point>&x)
405                { shared_point_=x; }
406        const etl::smart_ptr<synfig::Point>& get_shared_point()const
407                { return shared_point_; }
408
409        void set_shared_angle(const etl::smart_ptr<synfig::Angle>&x)
410                { shared_angle_=x; }
411        const etl::smart_ptr<synfig::Angle>& get_shared_angle()const
412                { return shared_angle_; }
413
414        void set_shared_mag(const etl::smart_ptr<synfig::Real>&x)
415                { shared_mag_=x; }
416        const etl::smart_ptr<synfig::Real>& get_shared_mag()const
417                { return shared_mag_; }
418
419        //! Returns the rotations of the duck
420        //! For angle and tangent ducks, rotations are used instead of the location
421        //! so that the duck can me rotated more than 180 degrees
422        synfig::Angle get_rotations()const
423                { return rotations_; };
424        //! Sets the rotations of the duck
425        void set_rotations(const synfig::Angle &x)
426                { rotations_=x; };
427
428
429        // calculation of position of duck at workarea
430
431        synfig::Point get_trans_point()const;
432
433        void set_trans_point(const synfig::Point &x);
434        void set_trans_point(const synfig::Point &x, const synfig::Time &time);
435
436        synfig::Point get_sub_trans_point(const synfig::Point &x)const;
437        synfig::Point get_sub_trans_point()const;
438        synfig::Point get_sub_trans_point_without_offset(const synfig::Point &x)const;
439        synfig::Point get_sub_trans_point_without_offset()const;
440        void set_sub_trans_point(const synfig::Point &x);
441        void set_sub_trans_point(const synfig::Point &x, const synfig::Time &time);
442        synfig::Point get_sub_trans_point(const Handle &duck, const synfig::Point &def, bool translate = true)const;
443        synfig::Point get_sub_trans_point(const Handle &duck, bool translate = true)const
444                { return get_sub_trans_point(duck, synfig::Point(0,0), translate); }
445        synfig::Point get_sub_trans_origin()const;
446
447        //! Retrieves the origin location
448        synfig::Point get_trans_origin()const;
449
450
451        // operators
452
453        bool operator==(const Duck &rhs)const;
454}; // END of class Duck
455
456//! Combine Flags
457inline Duck::Type
458operator|(Duck::Type lhs, const Duck::Type rhs)
459{ return static_cast<Duck::Type>(int(lhs)|int(rhs)); }
460
461//! Exclude Flags
462inline Duck::Type
463operator-(Duck::Type lhs, const Duck::Type rhs)
464{ return static_cast<Duck::Type>(int(lhs)&~int(rhs)); }
465
466inline Duck::Type&
467operator|=(Duck::Type& lhs, const Duck::Type rhs)
468{ *reinterpret_cast<int*>(&lhs)|=int(rhs); return lhs; }
469
470inline Duck::Type
471operator&(const Duck::Type lhs, const Duck::Type rhs)
472{ return static_cast<Duck::Type>(int(lhs)&int(rhs)); }
473
474class DuckMap : public
475#ifdef HASH_MAP_H
476HASH_MAP_CLASS<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash>
477{
478        typedef HASH_MAP_CLASS<synfig::GUID,etl::handle<studio::Duck>,synfig::GUIDHash> PARENT_TYPE;
479#else
480std::map<synfig::GUID,etl::handle<studio::Duck> >
481{
482        typedef std::map<synfig::GUID,etl::handle<studio::Duck> > PARENT_TYPE;
483#endif
484public:
485        void insert(const Duck::Handle& x) { operator[](x->get_guid())=x;  }
486}; // END of class DuckMap
487
488typedef std::list<Duck::Handle> DuckList;
489
490}; // END of namespace studio
491
492/* === E N D =============================================================== */
493
494#endif
Note: See TracBrowser for help on using the repository browser.