1 /* === S Y N F I G ========================================================= */
2 /*!	\file duckmatic.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) 2011 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_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++/sigc++.h>
43 #include <synfig/time.h>
44 #include <synfig/color.h>
45 #include <ETL/smart_ptr>
46 
47 #include "duck.h"
48 #include <synfig/color.h>
49 #include <synfig/guidset.h>
50 
51 /* === M A C R O S ========================================================= */
52 
53 #ifdef HASH_MAP_H
54 #include HASH_MAP_H
55 #include FUNCTIONAL_H
56 
57 #ifndef __STRING_HASH__
58 #define __STRING_HASH__
59 class StringHash
60 {
61 # ifdef FUNCTIONAL_HASH_ON_STRING
62 	HASH_MAP_NAMESPACE::hash<synfig::String> hasher_;
63 # else  // FUNCTIONAL_HASH_ON_STRING
64 	HASH_MAP_NAMESPACE::hash<const char*> hasher_;
65 # endif  // FUNCTIONAL_HASH_ON_STRING
66 public:
operator()67 	size_t operator()(const synfig::String& x)const
68 	{
69 # ifdef FUNCTIONAL_HASH_ON_STRING
70 		return hasher_(x);
71 # else  // FUNCTIONAL_HASH_ON_STRING
72 		return hasher_(x.c_str());
73 # endif  // FUNCTIONAL_HASH_ON_STRING
74 	}
75 };
76 #endif
77 #else
78 #include <map>
79 #endif
80 
81 /* === T Y P E D E F S ===================================================== */
82 
83 /* === C L A S S E S & S T R U C T S ======================================= */
84 
85 namespace synfigapp { class ValueDesc; class CanvasInterface; }
86 namespace synfig { class ParamDesc; }
87 
88 namespace studio
89 {
90 
91 class CanvasView;
92 class Duckmatic;
93 
94 class DuckDrag_Base : public etl::shared_object
95 {
96 public:
97 	virtual void begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& begin)=0;
98 	virtual bool end_duck_drag(Duckmatic* duckmatic)=0;
99 	virtual void duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector)=0;
100 };
101 
102 class DuckDrag_Translate : public DuckDrag_Base
103 {
104 	synfig::Vector last_translate_;
105 	synfig::Vector drag_offset_;
106 	synfig::Vector snap;
107 	std::vector<synfig::Vector> positions;
108 	bool is_moving;
109 
110 public:
111 	void begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& begin);
112 	bool end_duck_drag(Duckmatic* duckmatic);
113 	void duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector);
114 };
115 
116 class BezierDrag_Base : public etl::shared_object
117 {
118 public:
119 	virtual void begin_bezier_drag(Duckmatic* duckmatic, const synfig::Vector& begin, float bezier_click_pos)=0;
120 	virtual bool end_bezier_drag(Duckmatic* duckmatic)=0;
121 	virtual void bezier_drag(Duckmatic* duckmatic, const synfig::Vector& vector)=0;
122 };
123 
124 class BezierDrag_Default : public BezierDrag_Base
125 {
126 	synfig::Vector last_translate_;
127 	synfig::Vector drag_offset_;
128 	float click_pos_;
129 	synfig::Vector c1_initial;
130 	synfig::Vector c2_initial;
131 	float c1_ratio;
132 	float c2_ratio;
133 	//bool c1_selected;
134 	//bool c2_selected;
135 	//Warning: unused variables c1_selected c2_selected
136 	bool is_moving;
137 
138 public:
139 	void begin_bezier_drag(Duckmatic* duckmatic, const synfig::Vector& begin, float bezier_click_pos);
140 	bool end_bezier_drag(Duckmatic* duckmatic);
141 	void bezier_drag(Duckmatic* duckmatic, const synfig::Vector& vector);
142 };
143 
144 /*! \class Duckmatic
145 **
146 **	This class helps organize any of the devices displayed in
147 **	the work area that the user may want to interact with.
148 **	This includes ducks, beziers, and strokes
149 **
150 */
151 class Duckmatic
152 {
153 	friend class DuckDrag_Base;
154 	friend class DuckDrag_Translate;
155 
156 	/*
157  -- ** -- P U B L I C   T Y P E S ---------------------------------------------
158 	*/
159 
160 public:
161 
162 #ifdef HASH_MAP_H
163 typedef HASH_MAP_CLASS<synfig::GUID,etl::smart_ptr<synfig::Point>,synfig::GUIDHash> DuckDataMap;
164 #else
165 typedef std::map<synfig::GUID,etl::smart_ptr<synfig::Point> > DuckDataMap;
166 #endif
167 
168 	typedef studio::DuckMap DuckMap;
169 
170 	typedef studio::Duck Duck;
171 
172 	struct Stroke;
173 
174 	struct Bezier;
175 
176 	class Push;
177 
178 	friend class Push;
179 
180 	typedef Duck::Type Type;
181 
182 	typedef std::list<float> GuideList;
183 
184 	/*
185  -- ** -- P R I V A T E   D A T A ---------------------------------------------
186 	*/
187 
188 private:
189 
190 	etl::loose_handle<synfigapp::CanvasInterface> canvas_interface;
191 
192 	Type type_mask, type_mask_state;
193 
194 	DuckMap duck_map;
195 
196 	DuckDataMap duck_data_share_map;
197 
198 	std::list<etl::handle<Stroke> > stroke_list_;
199 
200 	std::list<etl::handle<Stroke> > persistent_stroke_list_;
201 
202 	synfig::GUIDSet selected_ducks;
203 
204 	synfig::GUID last_duck_guid;
205 
206 	std::list<etl::handle<Bezier> > bezier_list_;
207 
208 	//! I cannot recall what this is for
209 	//synfig::Vector snap;
210 
211 	etl::handle<DuckDrag_Base> duck_dragger_;
212 
213 	etl::handle<BezierDrag_Base> bezier_dragger_;
214 
215 	sigc::signal<void> signal_duck_selection_changed_;
216 	sigc::signal<void, const etl::handle<Duck>& > signal_duck_selection_single_;
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 
246 	//! This flag is set if operations should snap to the grid
247 	/*! \todo perhaps there should be two of these flags, one for each axis?
248 	**	\see show_grid, grid_size */
249 	bool grid_snap;
250 
251 	bool guide_snap;
252 
253 	//! This vector describes the grid size.
254 	/*! \see grid_snap, show_grid */
255 	synfig::Vector grid_size;
256 	//! Hold the grid color.
257 	synfig::Color grid_color;
258 	//! Hold the guides color.
259 	synfig::Color guides_color;
260 
261 	float zoom;					//!< Zoom factor
262 	float prev_zoom;			//!< Previous Zoom factor
263 
264 	bool show_persistent_strokes;
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 
set_alternative_mode(bool x)290 	void set_alternative_mode(bool x) { alternative_mode_=x; }
get_alternative_mode()291 	bool get_alternative_mode()const { return alternative_mode_; }
292 
set_lock_animation_mode(bool x)293 	void set_lock_animation_mode(bool x) { lock_animation_mode_=x; }
get_lock_animation_mode()294 	bool get_lock_animation_mode()const { return lock_animation_mode_; }
295 
signal_duck_selection_changed()296 	sigc::signal<void>& signal_duck_selection_changed() { return signal_duck_selection_changed_; }
signal_duck_selection_single()297 	sigc::signal<void, const etl::handle<Duck>& >& signal_duck_selection_single() { return signal_duck_selection_single_; }
signal_strokes_changed()298 	sigc::signal<void>& signal_strokes_changed() { return signal_strokes_changed_; }
signal_grid_changed()299 	sigc::signal<void>& signal_grid_changed() { return signal_grid_changed_; }
signal_sketch_saved()300 	sigc::signal<void>& signal_sketch_saved() { return signal_sketch_saved_; }
301 
get_guide_list_x()302 	GuideList& get_guide_list_x() { return guide_list_x_; }
get_guide_list_y()303 	GuideList& get_guide_list_y() { return guide_list_y_; }
get_guide_list_x()304 	const GuideList& get_guide_list_x()const { return guide_list_x_; }
get_guide_list_y()305 	const GuideList& get_guide_list_y()const { return guide_list_y_; }
306 
307 	void set_guide_snap(bool x=true);
get_guide_snap()308 	bool get_guide_snap()const { return guide_snap; }
toggle_guide_snap()309 	void toggle_guide_snap() { set_guide_snap(!get_guide_snap()); }
310 	//! Sets the color of the guides
311 	void set_guides_color(const synfig::Color &c);
312 	//! Returns the color of the guides
get_guides_color()313 	const synfig::Color &get_guides_color()const { return guides_color;}
314 
315 	//! Sets the state of the grid snap flag
316 	void set_grid_snap(bool x=true);
317 
318 	//! Gets the state of the grid snap flag
get_grid_snap()319 	bool get_grid_snap()const { return grid_snap; }
320 
enable_grid_snap()321 	void enable_grid_snap() { set_grid_snap(true); }
322 
disable_grid_snap()323 	void disable_grid_snap() { set_grid_snap(false); }
324 
toggle_grid_snap()325 	void toggle_grid_snap() { set_grid_snap(!grid_snap); }
326 
327 	synfig::Point snap_point_to_grid(const synfig::Point& x)const;
328 
get_show_persistent_strokes()329 	bool get_show_persistent_strokes()const { return show_persistent_strokes; }
330 	void set_show_persistent_strokes(bool x);
331 
332 	//! Sets the size of the grid
333 	void set_grid_size(const synfig::Vector &s);
334 	//! Sets the color of the grid
335 	void set_grid_color(const synfig::Color &c);
336 
337 	//! Returns the size of the grid
get_grid_size()338 	const synfig::Vector &get_grid_size()const { return grid_size; }
339 	//! Returns the color of the grid
get_grid_color()340 	const synfig::Color &get_grid_color()const { return grid_color;}
341 
get_time()342 	const synfig::Time &get_time()const { return cur_time; }
343 
get_axis_lock()344 	bool get_axis_lock()const { return axis_lock; }
set_axis_lock(bool x)345 	void set_axis_lock(bool x) { axis_lock=x; }
346 
set_time(synfig::Time x)347 	void set_time(synfig::Time x) { cur_time=x; }
348 
349 	bool is_duck_group_selectable(const etl::handle<Duck>& x)const;
350 
351 	//const DuckMap& duck_map()const { return duck_map; }
352 	DuckList get_duck_list()const;
353 
bezier_list()354 	const std::list<etl::handle<Bezier> >& bezier_list()const { return bezier_list_; }
355 
stroke_list()356 	const std::list<etl::handle<Stroke> >& stroke_list()const { return stroke_list_; }
357 
persistent_stroke_list()358 	const std::list<etl::handle<Stroke> >& persistent_stroke_list()const { return persistent_stroke_list_; }
359 
persistent_stroke_list()360 	std::list<etl::handle<Stroke> >& persistent_stroke_list() { return persistent_stroke_list_; }
361 
362     /*
363  -- ** -- D U C K  S E L E C T I O N  M E T H O D S----------------------------
364     */
365 
366     //! Return first selected duck (handle) has const Duck etl::handle
367 	etl::handle<Duck> get_selected_duck()const;
368 	//! Return list of selected ducks (handles)
369 	/*!
370      ** \return ducks (handles) has const DuckList
371      ** \sa get_selected_duck, clear_selected_ducks, count_selected_ducks
372     */
373 	DuckList get_selected_ducks()const;
374     //! Return list of box contained ducks (handles). The box is defined by a vector's pair
375     /*!
376      ** \param tl The top left canvas coordinate has const synfig::Vector
377      ** \param br The bottom right canvas coordinate has const synfig::Vector
378      ** \return ducks (handles) has const DuckList
379      ** \sa toggle_select_ducks_in_box, select_ducks_in_box, find_duck
380     */
381 	DuckList get_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br)const;
382 
383 	void refresh_selected_ducks();
384     //! Clear all selected ducks
385 	void clear_selected_ducks();
386 	//! Return the number of selected ducks
387     /*!
388      ** \return the number of selected ducks (handles) has int
389      */
390 	int count_selected_ducks()const;
391     //! Give the selection status of a duck
392     /*!
393      ** \return \a true if the given duck (handle) is currently selected
394      */
395     bool duck_is_selected(const etl::handle<Duck> &duck)const;
396 	//! Toggle the duck (handle)
397     /*!
398      ** \param duck The duck (handle) to toggle has etl::handle parameter
399      */
400 	void toggle_select_duck(const etl::handle<Duck> &duck);
401     //! Select the duck (handle)
402     /*!
403      ** \param duck The duck (handle) to select has etl::handle parameter
404      */
405 	void select_duck(const etl::handle<Duck> &duck);
406     //! Unselect the duck (handle)
407     /*!
408      ** \param duck The duck (handle) to unselect has etl::handle parameter
409      */
410 	void unselect_duck(const etl::handle<Duck> &duck);
411 
412     //! Toggle the ducks (handles) contained in the box defined by a pair of vectors
413     /*!
414      ** \param tl The top left canvas coordinate has const synfig::Vector
415      ** \param br The bottom right canvas coordinate has const synfig::Vector
416      ** \sa toggle_select_duck, select_ducks_in_box, get_ducks_in_box
417     */
418 	void toggle_select_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br);
419 	//! Select the ducks (handles) contained in the box defined by a pair of vectors
420     /*!
421      ** \param tl The top left canvas coordinate has const synfig::Vector
422      ** \param br The bottom right canvas coordinate has const synfig::Vector
423      ** \sa toggle_select_ducks_in_box, select_ducks_in_box, clear_selected_ducks
424     */
425 	void select_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br);
426 
427 
get_curr_transform_stack()428 	const synfig::TransformStack& get_curr_transform_stack()const { return curr_transform_stack; }
429 
clear_curr_transform_stack()430 	inline void clear_curr_transform_stack() { curr_transform_stack.clear(); curr_transform_stack_set=false; }
431 
432 
433 	etl::handle<Bezier> get_selected_bezier()const;
434 
435 	//! Begin dragging ducks
436 	/*!
437 	 ** \param offset Canvas coordinates of the mouse when the drag began
438 	*/
439 	void start_duck_drag(const synfig::Vector& offset);
440 
441 	//! Continue dragging the selected ducks
442 	/*! The overall vector of the drag is vector-offset
443 	 ** (where offset was given in start_duck_drag)
444 	 ** \param vector Canvas coordinates of the mouse at this moment
445 	*/
446 	void translate_selected_ducks(const synfig::Vector& vector);
447 
448 	//! Update the coordinates of tangents and linked-to-bline ducks
449 	void update_ducks();
450 
451 	//! Ends the duck drag
452 	bool end_duck_drag();
453 
454 	//! \todo writeme
455 	// bezier drags (similar to duck drags)
456 	void start_bezier_drag(const synfig::Vector& offset, float bezier_click_pos);
457 
458 	void translate_selected_bezier(const synfig::Vector& vector);
459 
460 	bool end_bezier_drag();
461 
462 
463 	//! Signals to each selected duck that it has been clicked
464 	void signal_user_click_selected_ducks(int button);
465 
466 	//! Calls a single duck's edited signal
467 	/*! Updates the corresponding valuenodes after a drag */
468 	void signal_edited_duck(const etl::handle<Duck> &duck, bool moving = false);
469 
470 	//! Calls all of the ducks' edited signals
471 	/*! Updates corresponding valuenodes after a drag */
472 	void signal_edited_selected_ducks(bool moving = false);
473 
474 	bool on_duck_changed(const studio::Duck &duck,const synfigapp::ValueDesc& value_desc);
475 
476 	etl::handle<Duck> find_similar_duck(etl::handle<Duck> duck);
477 	etl::handle<Duck> add_similar_duck(etl::handle<Duck> duck);
478 
479 	void add_stroke(etl::smart_ptr<std::list<synfig::Point> > stroke_point_list, const synfig::Color& color=synfig::Color(0,0,0));
480 
481 	void add_persistent_stroke(etl::smart_ptr<std::list<synfig::Point> > stroke_point_list, const synfig::Color& color=synfig::Color(0,0,0));
482 
483 	void clear_persistent_strokes();
484 
485 	void add_duck(const etl::handle<Duck> &duck);
486 
487 	void add_bezier(const etl::handle<Bezier> &bezier);
488 
489 	void erase_duck(const etl::handle<Duck> &duck);
490 
491 	void erase_bezier(const etl::handle<Bezier> &bezier);
492 
493 	//! Returns the last duck added
494 	etl::handle<Duck> last_duck()const;
495 
496 	etl::handle<Bezier> last_bezier()const;
497 
498 	//! \note parameter is in canvas coordinates
499 	/*!	A radius of "zero" will have an unlimited radius */
500 	etl::handle<Duck> find_duck(synfig::Point pos, synfig::Real radius=0, Duck::Type type=Duck::TYPE_DEFAULT);
501 
502 	GuideList::iterator find_guide_x(synfig::Point pos, float radius=0.1);
503 	GuideList::iterator find_guide_y(synfig::Point pos, float radius=0.1);
504 	GuideList::const_iterator find_guide_x(synfig::Point pos, float radius=0.1)const { return const_cast<Duckmatic*>(this)->find_guide_x(pos,radius); }
505 	GuideList::const_iterator find_guide_y(synfig::Point pos, float radius=0.1)const { return const_cast<Duckmatic*>(this)->find_guide_y(pos,radius); }
506 
507 	//! \note parameter is in canvas coordinates
508 	/*!	A radius of "zero" will have an unlimited radius */
509 	//etl::handle<Bezier> find_bezier(synfig::Point pos, synfig::Real radius=0);
510 
511 	//! \note parameter is in canvas coordinates
512 	/*!	A radius of "zero" will have an unlimited radius */
513 	etl::handle<Bezier> find_bezier(synfig::Point pos, synfig::Real radius=0, float* location=0);
514 
515 	etl::handle<Bezier> find_bezier(synfig::Point pos, synfig::Real scale, synfig::Real radius, float* location=0);
516 
517 	//! if transform_count is set function will not restore transporm stack
518 	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, int *transform_count = NULL);
519 
520 	bool add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<CanvasView> canvas_view, const synfig::TransformStack& transform_stack_, synfig::ParamDesc *param_desc=0);
521 
522 	//! Set the type mask, which determines what types of ducks are shown
523 	//! \Param[in]   x   Duck::Type set to backup when toggling handles
524 	//! \Sa              get_type_mask(), CanvasView::toggle_duck_all()
set_type_mask(Type x)525 	void set_type_mask(Type x) { type_mask=x; }
526 	//! Get the type mask, which determines what types of ducks are shown
527 	//! \Sa              set_type_mask(), CanvasView::toggle_duck_all()
get_type_mask()528 	Type get_type_mask()const { return type_mask; }
529 
530 	//! Set the type mask state, which determines what types of ducks are shown on toggle
531 	//! \Param[in]   x   Duck::Type set to backup when toggling handles
532 	//! \Sa              get_type_mask_state(), CanvasView::toggle_duck_mask_all()
set_type_mask_state(Type x)533 	void set_type_mask_state(Type x) { type_mask_state=x; }
534 	//! Get the type mask state, which determines what types of ducks are shown on toggle
535 	//! \Sa              set_type_mask_state(), CanvasView::toggle_duck_mask_all()
get_type_mask_state()536 	Type get_type_mask_state()const { return type_mask_state; }
537 
538 	void select_all_ducks();
539 	void unselect_all_ducks();
540 
541 	void clear_ducks();
542 
543 	bool save_sketch(const synfig::String& filename)const;
544 	bool load_sketch(const synfig::String& filename);
get_sketch_filename()545 	const synfig::String& get_sketch_filename()const { return sketch_filename_; }
546 
set_duck_dragger(etl::handle<DuckDrag_Base> x)547 	void set_duck_dragger(etl::handle<DuckDrag_Base> x) { duck_dragger_=x; }
get_duck_dragger()548 	etl::handle<DuckDrag_Base> get_duck_dragger()const { return duck_dragger_; }
clear_duck_dragger()549 	void clear_duck_dragger() { duck_dragger_=new DuckDrag_Translate(); }
550 
551 
set_bezier_dragger(etl::handle<BezierDrag_Base> x)552 	void set_bezier_dragger(etl::handle<BezierDrag_Base> x) { bezier_dragger_=x; }
get_bezier_dragger()553 	etl::handle<BezierDrag_Base> get_bezier_dragger()const { return bezier_dragger_; }
clear_bezier_dragger()554 	void clear_bezier_dragger() { bezier_dragger_=new BezierDrag_Default(); }
555 }; // END of class Duckmatic
556 
557 
558 /*! \class Duckmatic::Push
559 **	\writeme */
560 class Duckmatic::Push
561 {
562 	Duckmatic *duckmatic_;
563 	DuckMap duck_map;
564 	std::list<etl::handle<Bezier> > bezier_list_;
565 	std::list<etl::handle<Stroke> > stroke_list_;
566 	DuckDataMap duck_data_share_map;
567 	etl::handle<DuckDrag_Base> duck_dragger_;
568 
569 	bool needs_restore;
570 
571 public:
572 	Push(Duckmatic *duckmatic_);
573 	~Push();
574 	void restore();
575 }; // END of class Duckmatic::Push
576 
577 /*! \struct Duckmatic::Bezier
578 **	\writeme */
579 struct Duckmatic::Bezier : public etl::shared_object
580 {
581 private:
582 	sigc::signal<void,float> signal_user_click_[5];
583 public:
584 
585 	etl::handle<Duck> p1,p2,c1,c2;
is_validBezier586 	bool is_valid()const { return p1 && p2 && c1 && c2; }
587 
588 	sigc::signal<void,float> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
589 }; // END of struct Duckmatic::Bezier
590 
591 /*! \struct Duckmatic::Stroke
592 **	\writeme */
593 struct Duckmatic::Stroke : public etl::shared_object
594 {
595 private:
596 	sigc::signal<void,float> signal_user_click_[5];
597 public:
598 
599 	etl::smart_ptr<std::list<synfig::Point> > stroke_data;
600 
601 	synfig::Color color;
602 
is_validStroke603 	bool is_valid()const { return (bool)stroke_data; }
604 
605 	sigc::signal<void,float> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
606 }; // END of struct Duckmatic::Stroke
607 
608 }; // END of namespace studio
609 
610 /* === E N D =============================================================== */
611 
612 #endif
613