synfig-studio  1.0.3
duckmatic.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
23 /* ========================================================================= */
24 
25 /* === S T A R T =========================================================== */
26 
27 #ifndef __SYNFIG_STUDIO_DUCKMATIC_H
28 #define __SYNFIG_STUDIO_DUCKMATIC_H
29 
30 /* === H E A D E R S ======================================================= */
31 
32 #include <list>
33 #include <map>
34 #include <set>
35 
36 #include <ETL/smart_ptr>
37 #include <ETL/handle>
38 
39 #include <synfig/vector.h>
40 #include <synfig/string.h>
41 #include <synfig/real.h>
42 #include <sigc++/signal.h>
43 #include <sigc++/object.h>
44 #include <synfig/time.h>
45 #include <synfig/color.h>
46 #include <ETL/smart_ptr>
47 
48 #include "duck.h"
49 #include <synfig/color.h>
50 #include <synfig/guidset.h>
51 
52 /* === M A C R O S ========================================================= */
53 
54 #ifdef HASH_MAP_H
55 #include HASH_MAP_H
56 #include FUNCTIONAL_H
57 
58 #ifndef __STRING_HASH__
59 #define __STRING_HASH__
60 class StringHash
61 {
62 # ifdef FUNCTIONAL_HASH_ON_STRING
63  HASH_MAP_NAMESPACE::hash<synfig::String> hasher_;
64 # else // FUNCTIONAL_HASH_ON_STRING
65  HASH_MAP_NAMESPACE::hash<const char*> hasher_;
66 # endif // FUNCTIONAL_HASH_ON_STRING
67 public:
68  size_t operator()(const synfig::String& x)const
69  {
70 # ifdef FUNCTIONAL_HASH_ON_STRING
71  return hasher_(x);
72 # else // FUNCTIONAL_HASH_ON_STRING
73  return hasher_(x.c_str());
74 # endif // FUNCTIONAL_HASH_ON_STRING
75  }
76 };
77 #endif
78 #else
79 #include <map>
80 #endif
81 
82 /* === T Y P E D E F S ===================================================== */
83 
84 /* === C L A S S E S & S T R U C T S ======================================= */
85 
86 namespace synfigapp { class ValueDesc; class CanvasInterface; }
87 namespace synfig { class ParamDesc; }
88 
89 namespace studio
90 {
91 
92 class CanvasView;
93 class Duckmatic;
94 
95 class DuckDrag_Base : public etl::shared_object
96 {
97 public:
98  virtual void begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& begin)=0;
99  virtual bool end_duck_drag(Duckmatic* duckmatic)=0;
100  virtual void duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector)=0;
101 };
102 
104 {
105  synfig::Vector last_translate_;
106  synfig::Vector drag_offset_;
107  synfig::Vector snap;
108  std::vector<synfig::Vector> positions;
109  bool is_moving;
110 
111 public:
112  void begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& begin);
113  bool end_duck_drag(Duckmatic* duckmatic);
114  void duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector);
115 };
116 
117 class BezierDrag_Base : public etl::shared_object
118 {
119 public:
120  virtual void begin_bezier_drag(Duckmatic* duckmatic, const synfig::Vector& begin, float bezier_click_pos)=0;
121  virtual bool end_bezier_drag(Duckmatic* duckmatic)=0;
122  virtual void bezier_drag(Duckmatic* duckmatic, const synfig::Vector& vector)=0;
123 };
124 
126 {
127  synfig::Vector last_translate_;
128  synfig::Vector drag_offset_;
129  float click_pos_;
130  synfig::Vector c1_initial;
131  synfig::Vector c2_initial;
132  float c1_ratio;
133  float c2_ratio;
134  //bool c1_selected;
135  //bool c2_selected;
136  //Warning: unused variables c1_selected c2_selected
137  bool is_moving;
138 
139 public:
140  void begin_bezier_drag(Duckmatic* duckmatic, const synfig::Vector& begin, float bezier_click_pos);
141  bool end_bezier_drag(Duckmatic* duckmatic);
142  void bezier_drag(Duckmatic* duckmatic, const synfig::Vector& vector);
143 };
144 
153 {
154  friend class DuckDrag_Base;
155  friend class DuckDrag_Translate;
156 
157  /*
158  -- ** -- P U B L I C T Y P E S ---------------------------------------------
159  */
160 
161 public:
162 
163 #ifdef HASH_MAP_H
164 typedef HASH_MAP_CLASS<synfig::GUID,etl::smart_ptr<synfig::Point>,synfig::GUIDHash> DuckDataMap;
165 #else
166 typedef std::map<synfig::GUID,etl::smart_ptr<synfig::Point> > DuckDataMap;
167 #endif
168 
170 
172 
173  struct Stroke;
174 
175  struct Bezier;
176 
177  class Push;
178 
179  friend class Push;
180 
181  typedef Duck::Type Type;
182 
183  typedef std::list<float> GuideList;
184 
185  /*
186  -- ** -- P R I V A T E D A T A ---------------------------------------------
187  */
188 
189 private:
190 
191  etl::loose_handle<synfigapp::CanvasInterface> canvas_interface;
192 
193  Type type_mask;
194 
195  DuckMap duck_map;
196 
197  DuckDataMap duck_data_share_map;
198 
199  std::list<etl::handle<Stroke> > stroke_list_;
200 
201  std::list<etl::handle<Stroke> > persistent_stroke_list_;
202 
203  synfig::GUIDSet selected_ducks;
204 
205  synfig::GUID last_duck_guid;
206 
207  std::list<etl::handle<Bezier> > bezier_list_;
208 
210  //synfig::Vector snap;
211 
212  etl::handle<DuckDrag_Base> duck_dragger_;
213 
214  etl::handle<BezierDrag_Base> bezier_dragger_;
215 
216  sigc::signal<void> signal_duck_selection_changed_;
217 
218  sigc::signal<void> signal_strokes_changed_;
219 
220  sigc::signal<void> signal_grid_changed_;
221 
222  mutable sigc::signal<void> signal_sketch_saved_;
223 
224  GuideList guide_list_x_;
225  GuideList guide_list_y_;
226 
227  mutable synfig::String sketch_filename_;
228 
229  synfig::TransformStack curr_transform_stack;
230  bool curr_transform_stack_set;
231  std::list<sigc::connection> duck_changed_connections;
232 
233  bool alternative_mode_;
234  bool lock_animation_mode_;
235 
236  /*
237  -- ** -- P R O T E C T E D D A T A -----------------------------------------
238  */
239 
240 protected:
241 
242  etl::handle<Bezier> selected_bezier;
243 
244  synfig::Time cur_time;
245 
247 
249  bool grid_snap;
250 
252 
254 
255  synfig::Vector grid_size;
257  synfig::Color grid_color;
259  synfig::Color guides_color;
260 
261  float zoom;
262  float prev_zoom;
263 
265 
266  bool axis_lock;
267 
268  /*
269  -- ** -- P R I V A T E M E T H O D S ---------------------------------------
270  */
271 
272 private:
273 
274  synfig::Vector last_translate_;
275  synfig::Vector drag_offset_;
276 
277  //etl::handle<Duck> selected_duck;
278 
279  void connect_signals(const Duck::Handle &duck, const synfigapp::ValueDesc& value_desc, CanvasView &canvas_view);
280 
281  /*
282  -- ** -- P U B L I C M E T H O D S -----------------------------------------
283  */
284 
285 public:
286 
287  Duckmatic(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface);
288  virtual ~Duckmatic();
289 
290  void set_alternative_mode(bool x) { alternative_mode_=x; }
291  bool get_alternative_mode()const { return alternative_mode_; }
292 
293  void set_lock_animation_mode(bool x) { lock_animation_mode_=x; }
294  bool get_lock_animation_mode()const { return lock_animation_mode_; }
295 
296  sigc::signal<void>& signal_duck_selection_changed() { return signal_duck_selection_changed_; }
297  sigc::signal<void>& signal_strokes_changed() { return signal_strokes_changed_; }
298  sigc::signal<void>& signal_grid_changed() { return signal_grid_changed_; }
299  sigc::signal<void>& signal_sketch_saved() { return signal_sketch_saved_; }
300 
301  GuideList& get_guide_list_x() { return guide_list_x_; }
302  GuideList& get_guide_list_y() { return guide_list_y_; }
303  const GuideList& get_guide_list_x()const { return guide_list_x_; }
304  const GuideList& get_guide_list_y()const { return guide_list_y_; }
305 
306  void set_guide_snap(bool x=true);
307  bool get_guide_snap()const { return guide_snap; }
310  void set_guides_color(const synfig::Color &c);
312  const synfig::Color &get_guides_color()const { return guides_color;}
313 
315  void set_grid_snap(bool x=true);
316 
318  bool get_grid_snap()const { return grid_snap; }
319 
320  void enable_grid_snap() { set_grid_snap(true); }
321 
322  void disable_grid_snap() { set_grid_snap(false); }
323 
325 
326  synfig::Point snap_point_to_grid(const synfig::Point& x)const;
327 
329  void set_show_persistent_strokes(bool x);
330 
332  void set_grid_size(const synfig::Vector &s);
334  void set_grid_color(const synfig::Color &c);
335 
337  const synfig::Vector &get_grid_size()const { return grid_size; }
339  const synfig::Color &get_grid_color()const { return grid_color;}
340 
341  const synfig::Time &get_time()const { return cur_time; }
342 
343  bool get_axis_lock()const { return axis_lock; }
344  void set_axis_lock(bool x) { axis_lock=x; }
345 
346  void set_time(synfig::Time x) { cur_time=x; }
347 
348  bool is_duck_group_selectable(const etl::handle<Duck>& x)const;
349 
350  //const DuckMap& duck_map()const { return duck_map; }
351  DuckList get_duck_list()const;
352 
353  const std::list<etl::handle<Bezier> >& bezier_list()const { return bezier_list_; }
354 
355  const std::list<etl::handle<Stroke> >& stroke_list()const { return stroke_list_; }
356 
357  const std::list<etl::handle<Stroke> >& persistent_stroke_list()const { return persistent_stroke_list_; }
358 
359  std::list<etl::handle<Stroke> >& persistent_stroke_list() { return persistent_stroke_list_; }
360 
361  /*
362  -- ** -- D U C K S E L E C T I O N M E T H O D S----------------------------
363  */
364 
366  etl::handle<Duck> get_selected_duck()const;
368 
374 
380  DuckList get_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br)const;
381 
382  void refresh_selected_ducks();
384  void clear_selected_ducks();
386 
389  int count_selected_ducks()const;
391 
394  bool duck_is_selected(const etl::handle<Duck> &duck)const;
396 
399  void toggle_select_duck(const etl::handle<Duck> &duck);
401 
404  void select_duck(const etl::handle<Duck> &duck);
406 
409  void unselect_duck(const etl::handle<Duck> &duck);
410 
412 
417  void toggle_select_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br);
419 
424  void select_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br);
425 
426 
427  const synfig::TransformStack& get_curr_transform_stack()const { return curr_transform_stack; }
428 
429  inline void clear_curr_transform_stack() { curr_transform_stack.clear(); curr_transform_stack_set=false; }
430 
431 
432  etl::handle<Bezier> get_selected_bezier()const;
433 
435 
438  void start_duck_drag(const synfig::Vector& offset);
439 
441 
445  void translate_selected_ducks(const synfig::Vector& vector);
446 
448  void update_ducks();
449 
451  bool end_duck_drag();
452 
454  // bezier drags (similar to duck drags)
455  void start_bezier_drag(const synfig::Vector& offset, float bezier_click_pos);
456 
457  void translate_selected_bezier(const synfig::Vector& vector);
458 
459  bool end_bezier_drag();
460 
461 
463  void signal_user_click_selected_ducks(int button);
464 
466 
467  void signal_edited_duck(const etl::handle<Duck> &duck, bool moving = false);
468 
470 
471  void signal_edited_selected_ducks(bool moving = false);
472 
473  bool on_duck_changed(const studio::Duck &duck,const synfigapp::ValueDesc& value_desc);
474 
475  etl::handle<Duck> find_similar_duck(etl::handle<Duck> duck);
476  etl::handle<Duck> add_similar_duck(etl::handle<Duck> duck);
477 
478  void add_stroke(etl::smart_ptr<std::list<synfig::Point> > stroke_point_list, const synfig::Color& color=synfig::Color(0,0,0));
479 
480  void add_persistent_stroke(etl::smart_ptr<std::list<synfig::Point> > stroke_point_list, const synfig::Color& color=synfig::Color(0,0,0));
481 
483 
484  void add_duck(const etl::handle<Duck> &duck);
485 
486  void add_bezier(const etl::handle<Bezier> &bezier);
487 
488  void erase_duck(const etl::handle<Duck> &duck);
489 
490  void erase_bezier(const etl::handle<Bezier> &bezier);
491 
493  etl::handle<Duck> last_duck()const;
494 
495  etl::handle<Bezier> last_bezier()const;
496 
498 
499  etl::handle<Duck> find_duck(synfig::Point pos, synfig::Real radius=0, Duck::Type type=Duck::TYPE_DEFAULT);
500 
501  GuideList::iterator find_guide_x(synfig::Point pos, float radius=0.1);
502  GuideList::iterator find_guide_y(synfig::Point pos, float radius=0.1);
503  GuideList::const_iterator find_guide_x(synfig::Point pos, float radius=0.1)const { return const_cast<Duckmatic*>(this)->find_guide_x(pos,radius); }
504  GuideList::const_iterator find_guide_y(synfig::Point pos, float radius=0.1)const { return const_cast<Duckmatic*>(this)->find_guide_y(pos,radius); }
505 
507 
508  //etl::handle<Bezier> find_bezier(synfig::Point pos, synfig::Real radius=0);
509 
511 
512  etl::handle<Bezier> find_bezier(synfig::Point pos, synfig::Real radius=0, float* location=0);
513 
514  etl::handle<Bezier> find_bezier(synfig::Point pos, synfig::Real scale, synfig::Real radius, float* location=0);
515 
516  void add_ducks_layers(synfig::Canvas::Handle canvas, std::set<synfig::Layer::Handle>& selected_layer_set, etl::handle<CanvasView> canvas_view, synfig::TransformStack& transform_stack);
517 
518  bool add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<CanvasView> canvas_view, const synfig::TransformStack& transform_stack_, synfig::ParamDesc *param_desc=0);
519 
521  void set_type_mask(Type x) { type_mask=x; }
522 
524  Type get_type_mask()const { return type_mask; }
525 
526  void select_all_ducks();
527  void unselect_all_ducks();
528 
529  void clear_ducks();
530 
531  bool save_sketch(const synfig::String& filename)const;
532  bool load_sketch(const synfig::String& filename);
533  const synfig::String& get_sketch_filename()const { return sketch_filename_; }
534 
535  void set_duck_dragger(etl::handle<DuckDrag_Base> x) { duck_dragger_=x; }
536  etl::handle<DuckDrag_Base> get_duck_dragger()const { return duck_dragger_; }
537  void clear_duck_dragger() { duck_dragger_=new DuckDrag_Translate(); }
538 
539 
540  void set_bezier_dragger(etl::handle<BezierDrag_Base> x) { bezier_dragger_=x; }
541  etl::handle<BezierDrag_Base> get_bezier_dragger()const { return bezier_dragger_; }
542  void clear_bezier_dragger() { bezier_dragger_=new BezierDrag_Default(); }
543 }; // END of class Duckmatic
544 
545 
549 {
550  Duckmatic *duckmatic_;
551  DuckMap duck_map;
552  std::list<etl::handle<Bezier> > bezier_list_;
553  std::list<etl::handle<Stroke> > stroke_list_;
554  DuckDataMap duck_data_share_map;
555  etl::handle<DuckDrag_Base> duck_dragger_;
556 
557  bool needs_restore;
558 
559 public:
560  Push(Duckmatic *duckmatic_);
561  ~Push();
562  void restore();
563 }; // END of class Duckmatic::Push
564 
567 struct Duckmatic::Bezier : public etl::shared_object
568 {
569 private:
570  sigc::signal<void,float> signal_user_click_[5];
571 public:
572 
573  etl::handle<Duck> p1,p2,c1,c2;
574  bool is_valid()const { return p1 && p2 && c1 && c2; }
575 
576  sigc::signal<void,float> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
577 }; // END of struct Duckmatic::Bezier
578 
581 struct Duckmatic::Stroke : public etl::shared_object
582 {
583 private:
584  sigc::signal<void,float> signal_user_click_[5];
585 public:
586 
587  etl::smart_ptr<std::list<synfig::Point> > stroke_data;
588 
589  synfig::Color color;
590 
591  bool is_valid()const { return (bool)stroke_data; }
592 
593  sigc::signal<void,float> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
594 }; // END of struct Duckmatic::Stroke
595 
596 }; // END of namespace studio
597 
598 /* === E N D =============================================================== */
599 
600 #endif