Fix the tangents output by "Segment Tangent" and "BLine Tangent". They were scaled...
[synfig.git] / synfig-core / trunk / src / synfig / canvas.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file canvas.h
3 **      \brief Canvas Class Implementation
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 **
11 **      This package is free software; you can redistribute it and/or
12 **      modify it under the terms of the GNU General Public License as
13 **      published by the Free Software Foundation; either version 2 of
14 **      the License, or (at your option) any later version.
15 **
16 **      This package is distributed in the hope that it will be useful,
17 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 **      General Public License for more details.
20 **      \endlegal
21 */
22 /* ========================================================================= */
23
24 /* === S T A R T =========================================================== */
25
26 #ifndef __SYNFIG_CANVAS_H
27 #define __SYNFIG_CANVAS_H
28
29 /* === H E A D E R S ======================================================= */
30
31 #include <map>
32 #include <list>
33 #include <ETL/handle>
34 #include <sigc++/signal.h>
35 #include <sigc++/connection.h>
36
37 #include "vector.h"
38 #include "string.h"
39 #include "canvasbase.h"
40 #include "valuenode.h"
41 #include "keyframe.h"
42 #include "renddesc.h"
43 #include "node.h"
44 #include "guid.h"
45
46 /* === M A C R O S ========================================================= */
47
48 /* version change history:
49  *
50  * 0.1: the original version
51  *
52  *      if a waypoint goes from -179 to 179 degrees, that is a 2
53  *      degree change.  there's no way to express a 720 degree
54  *      rotation with a single pair of waypoints
55  *
56  * 0.2: svn r1227
57  *
58  *      angles no longer wrap at -180 degrees back to 180 degrees; if
59  *      a waypoint goes from -179 to 179 degrees, that is a rotation
60  *      of 358 degrees.  loading a version 0.1 canvas will modify
61  *      constant angle waypoints to that they are within 180 degrees
62  *      of the previous waypoint's value
63  *
64  *      the 'straight' blend method didn't used to work properly.  it
65  *      didn't work at all on transparent pixels in layers other than
66  *      the PasteCanvas layer.  for example, the examples/japan.sifz
67  *      file has a red circle (straight, amount=1.0) on top of a
68  *      striped conical gradient.  if 'straight' was working, the
69  *      conical gradient would be entirely obscured by the circle
70  *      layer (even by its transparent pixels)
71  *
72  * 0.3: svn r1422
73  *
74  *      the 'straight' blend method was fixed.  loading a version 0.2
75  *      or older canvas will replace the 'straight' blend method in
76  *      non-pastecanvas layers with 'composite', unless they're
77  *      completely transparent, in which case it will replace them
78  *      with an  'alpha over' blend instead.  Images like
79  *      examples/logo.sifz use transparent straight blends to do
80  *      masking, which no longer works now that 'straight' blending is
81  *      fixed.
82  *
83  *      Tangent lengths calculated by the "Segment Tangent" and "BLine
84  *      Tangent" ValueNodes were scaled by a factor of 0.5.
85  *
86  * 0.4: svn r1856
87  *
88  *      Stop scaling tangents by 0.5.
89  */
90
91 #define CURRENT_CANVAS_VERSION "0.4"
92
93 /* === T Y P E D E F S ===================================================== */
94
95 /* === C L A S S E S & S T R U C T S ======================================= */
96
97 namespace synfig {
98
99 class Context;
100 class GUID;
101
102 /*!     \class Canvas
103 **      \todo writeme
104 */
105 class Canvas : public CanvasBase, public Node
106 {
107         /*
108  --     ** -- T Y P E S -----------------------------------------------------------
109         */
110
111 public:
112         typedef etl::handle<Canvas> Handle;
113         typedef etl::loose_handle<Canvas> LooseHandle;
114         typedef etl::handle<const Canvas> ConstHandle;
115
116         typedef std::list<Handle> Children;
117
118         friend void synfig::optimize_layers(Time, Context, Canvas::Handle, bool seen_motion_blur);
119
120         /*
121  --     ** -- D A T A -------------------------------------------------------------
122         */
123
124 private:
125
126         //! Contains the ID string for the Canvas
127         /*!     \see get_id(), set_id() */
128         String id_;
129
130         //! Contains the name of the Canvas
131         /*!     \see set_name(), get_name() */
132         String name_;
133
134         //! Contains a description of the Canvas
135         /*!     \see set_description(), get_description() */
136         String description_;
137
138         //! Contains the canvas' version string
139         /*!     \see set_version(), get_version() */
140         String version_;
141
142         //! Contains the author's name
143         /*!     \see set_author(), get_author() */
144         String author_;
145
146         //! Contains the author's email address
147         /*!     \todo This private parameter has no binding, so it's unusable at the moment */
148         String email_;
149
150         //! File name of Canvas
151         /*! \see get_file_name(), set_file_name() */
152         String file_name_;
153
154         //! Metadata map for Canvas.
155         /*! \see get_meta_data(), set_meta_data(), erase_meta_data() */
156         std::map<String, String> meta_data_;
157
158         //! Contains a list of ValueNodes that are in this Canvas
159         /*!     \see value_node_list(), find_value_node() */
160         ValueNodeList value_node_list_;
161
162         //! \writeme
163         KeyframeList keyframe_list_;
164
165         //! A handle to the parent canvas of this canvas.
166         /*!     If canvas is a root canvas, then this handle is empty
167         **      \see parent()
168         */
169         LooseHandle parent_;
170
171         //! List containing any child Canvases
172         /*!     \see children() */
173         Children children_;
174
175         //! Render Description for Canvas
176         /*!     \see rend_desc() */
177     RendDesc desc_;
178
179         //! Contains the value of the last call to set_time()
180         Time cur_time_;
181
182         //! \writeme
183         mutable std::map<String,Handle> externals_;
184
185         //! This flag is set if this canvas is "inline"
186         bool is_inline_;
187
188         mutable bool is_dirty_;
189
190         bool op_flag_;
191
192         //! Layer Group database
193         std::map<String,std::set<etl::handle<Layer> > > group_db_;
194
195         //! Layer Connection database
196         std::map<etl::loose_handle<Layer>,std::vector<sigc::connection> > connections_;
197
198         /*
199  -- ** -- S I G N A L S -------------------------------------------------------
200         */
201
202 private:
203
204         //!     Group Added
205         sigc::signal<void,String> signal_group_added_;
206
207         //!     Group Removed
208         sigc::signal<void,String> signal_group_removed_;
209
210         //! Group Changed
211         sigc::signal<void,String> signal_group_changed_;
212
213         sigc::signal<void,String,etl::handle<synfig::Layer> > signal_group_pair_added_;
214         sigc::signal<void,String,etl::handle<synfig::Layer> > signal_group_pair_removed_;
215
216         //!     Layers Reordered
217         sigc::signal<void,int*> signal_layers_reordered_;
218
219         //!     RendDesc Changed
220         sigc::signal<void> signal_rend_desc_changed_;
221
222         //!     ID Changed
223         sigc::signal<void> signal_id_changed_;
224
225         //!     Dirty
226         //sigc::signal<void> signal_dirty_;
227
228         //!     FileName Changed
229         sigc::signal<void> signal_file_name_changed_;
230
231         //!     Metadata Changed
232         sigc::signal<void, String> signal_meta_data_changed_;
233
234         //! Key-Specific meta data changed signals
235         std::map<String, sigc::signal<void> > signal_map_meta_data_changed_;
236
237
238         //!     ValueBasenode Changed
239         sigc::signal<void, etl::handle<ValueNode> > signal_value_node_changed_;
240
241         sigc::signal<void, etl::handle<ValueNode> > signal_value_node_renamed_;
242
243         sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> > signal_value_node_child_added_;
244
245         sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> > signal_value_node_child_removed_;
246
247         /*
248  -- ** -- S I G N A L   I N T E R F A C E -------------------------------------
249         */
250
251 public:
252
253         sigc::signal<void,String,etl::handle<synfig::Layer> >& signal_group_pair_added() { return signal_group_pair_added_; }
254         sigc::signal<void,String,etl::handle<synfig::Layer> >& signal_group_pair_removed() { return signal_group_pair_removed_; }
255
256         //!     Group Added
257         sigc::signal<void,String>& signal_group_added() { return signal_group_added_; }
258
259         //!     Group Removed
260         sigc::signal<void,String>& signal_group_removed() { return signal_group_removed_; }
261
262         //! Group Changed
263         sigc::signal<void,String>& signal_group_changed() { return signal_group_changed_; }
264
265         //!     Layers Reordered
266         sigc::signal<void,int*>& signal_layers_reordered() { return signal_layers_reordered_; }
267
268         //!     RendDesc Changed
269         sigc::signal<void>& signal_rend_desc_changed() { return signal_rend_desc_changed_; }
270
271         //!     ID Changed
272         sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
273
274         //!     File name Changed
275         sigc::signal<void>& signal_file_name_changed();
276
277         //!     Metadata Changed
278         sigc::signal<void, String>& signal_meta_data_changed() { return signal_meta_data_changed_; }
279
280         //!     Metadata Changed
281         sigc::signal<void>& signal_meta_data_changed(const String& key) { return signal_map_meta_data_changed_[key]; }
282
283
284         sigc::signal<void, etl::handle<ValueNode> >& signal_value_node_changed() { return signal_value_node_changed_; }
285
286         sigc::signal<void, etl::handle<ValueNode> >& signal_value_node_renamed() { return signal_value_node_renamed_; }
287
288         //!     Dirty
289         sigc::signal<void>& signal_dirty() { return signal_changed();   }
290
291         //! \writeme
292         sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> >& signal_value_node_child_added() { return signal_value_node_child_added_; }
293
294         //! \writeme
295         sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> >& signal_value_node_child_removed() { return signal_value_node_child_removed_; }
296
297         /*
298  --     ** -- C O N S T R U C T O R S ---------------------------------------------
299         */
300
301 protected:
302
303         Canvas(const String &name);
304
305 public:
306
307         ~Canvas();
308
309         /*
310  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
311         */
312
313 public:
314
315         //! Returns the set of layers in group
316         std::set<etl::handle<Layer> > get_layers_in_group(const String&group);
317
318         //! Gets all the groups
319         std::set<String> get_groups()const;
320
321         //! Gets the number of groups in this canvas
322         int get_group_count()const;
323
324         //! Renames the given group
325         void rename_group(const String&old_name,const String&new_name);
326
327         //! \writeme
328         bool is_inline()const { return is_inline_; }
329
330         //! Returns a handle to the RendDesc for this Canvas
331         RendDesc &rend_desc() { return desc_; }
332
333         //! Returns a handle to the RendDesc for this Canvas
334         const RendDesc &rend_desc()const { return desc_; }
335
336         //! Gets the name of the canvas
337         const String & get_name()const { return name_; }
338
339         //! Sets the name of the canvas
340         void set_name(const String &x);
341
342         //! Gets the version string of the canvas
343         const String get_version()const { return version_; }
344
345         //! Sets the version string of the canvas
346         void set_version(const String &x) { version_ = x; }
347
348         //! Gets the author of the canvas
349         const String & get_author()const { return author_; }
350
351         //! Sets the author of the canvas
352         void set_author(const String &x);
353
354         //! Gets the description of the canvas
355         const String & get_description()const { return description_; }
356
357         //! Sets the name of the canvas
358         void set_description(const String &x);
359
360         //! Gets the ID of the canvas
361         const String & get_id()const { return id_; }
362
363         //! Sets the ID of the canvas
364         void set_id(const String &x);
365
366         //!     Returns the data string for the given meta data key
367         String get_meta_data(const String& key)const;
368
369         //!     Returns a list of meta data keys
370         std::list<String> get_meta_data_keys()const;
371
372         //! Sets a meta data key to a specific string
373         void set_meta_data(const String& key, const String& data);
374
375         //! Removes a meta data key
376         void erase_meta_data(const String& key);
377
378         //! \writeme
379         String get_relative_id(etl::loose_handle<const Canvas> x)const;
380
381         //! \internal \writeme
382         String _get_relative_id(etl::loose_handle<const Canvas> x)const;
383
384         //! Returns \c true if the Canvas is a root Canvas. \c false otherwise
385         bool is_root()const { return !parent_; }
386
387         //! Returns a handle to the parent Canvas.
388         /*! The returned handle will be empty if this is a root canvas */
389         LooseHandle parent()const { return parent_; }
390
391         LooseHandle get_root()const;
392
393         //! Returns a list of all child canvases in this canvas
394         std::list<Handle> &children() { return children_; }
395
396         //! Returns a list of all child canvases in this canvas
397         const std::list<Handle> &children()const { return children_; }
398
399         //! Gets the color at the specified point
400         //Color get_color(const Point &pos)const;
401
402         //! Sets the time for all the layers in the canvas
403         void set_time(Time t)const;
404
405         //! \writeme
406         Time get_time()const { return cur_time_; }
407
408         //! Returns the number of layers in the canvas
409         int size()const;
410
411         //! Removes all the layers from the canvas
412         void clear();
413
414         //! Returns true if the canvas has no layers
415         bool empty()const;
416
417         //! Returns a reference to the ValueNodeList for this Canvas
418         // ValueNodeList &value_node_list() { return value_node_list_; }
419
420         //! Returns a reference to the ValueNodeList for this Canvas
421         const ValueNodeList &value_node_list()const;
422
423         //! Returns a reference to the KeyframeList for this Canvas
424         KeyframeList &keyframe_list();
425
426         //! Returns a reference to the KeyframeList for this Canvas
427         const KeyframeList &keyframe_list()const;
428
429         //! Finds the ValueNode in the Canvas with the given \a id
430         /*!     \return If found, returns a handle to the ValueNode.
431         **              Otherwise, returns an empty handle.
432         */
433         ValueNode::Handle find_value_node(const String &id);
434
435         //! \internal \writeme
436         ValueNode::Handle surefind_value_node(const String &id);
437
438         //! Finds the ValueNode in the Canvas with the given \a id
439         /*!     \return If found, returns a handle to the ValueNode.
440         **              Otherwise, returns an empty handle.
441         */
442         ValueNode::ConstHandle find_value_node(const String &id)const;
443
444         //! \writeme
445         void add_value_node(ValueNode::Handle x, const String &id);
446
447         //! writeme
448         //void rename_value_node(ValueNode::Handle x, const String &id);
449
450         //! \writeme
451         void remove_value_node(ValueNode::Handle x);
452
453         //! \writeme
454         void remove_value_node(const String &id) { remove_value_node(find_value_node(id)); }
455
456         //! Finds a child Canvas in the Canvas with the given \a name
457         /*!     \return If found, returns a handle to the child Canvas.
458         **              If not found, it creates a new Canvas and returns it
459         **              If an error occurs, it returns an empty handle
460         */
461         Handle surefind_canvas(const String &id);
462
463         //! Finds a child Canvas in the Canvas with the given \a id
464         /*!     \return If found, returns a handle to the child Canvas.
465         **              Otherwise, returns an empty handle.
466         */
467         Handle find_canvas(const String &id);
468
469         //! Finds a child Canvas in the Canvas with the given \a id
470         /*!     \return If found, returns a handle to the child Canvas.
471         **              Otherwise, returns an empty handle.
472         */
473         ConstHandle find_canvas(const String &id)const;
474
475         //! Sets the file path for the Canvas
476         //void set_file_path(const String &);
477
478         //! Returns the file path from the file name
479         String get_file_path()const;
480
481         //! Sets the filename (with path)
482         void set_file_name(const String &);
483
484         //! Gets the filename (with path)
485         String get_file_name()const;
486
487         //! Creates a new child canvas, and returns its handle
488         Handle new_child_canvas();
489
490         //! Creates a new child canvas with an ID of \a id, and returns its handle
491         Handle new_child_canvas(const String &id);
492
493         //! Adds the given canvas as a child
494         Handle add_child_canvas(Handle child_canvas, const String &id);
495
496         void remove_child_canvas(Handle child_canvas);
497
498         etl::handle<Layer> find_layer(const Point &pos);
499
500         int get_depth(etl::handle<Layer>)const;
501
502         Context get_context()const;
503
504         iterator end();
505
506         const_iterator end()const;
507
508         reverse_iterator rbegin();
509
510         const_reverse_iterator rbegin()const;
511
512         etl::handle<Layer> &back();
513
514         void push_back(etl::handle<Layer> x);
515
516         void push_front(etl::handle<Layer> x);
517
518         void push_back_simple(etl::handle<Layer> x);
519
520         void insert(iterator iter,etl::handle<Layer> x);
521         void erase(iterator iter);
522
523         const etl::handle<Layer> &back()const;
524
525         void set_inline(LooseHandle parent);
526
527         static Handle create();
528
529         static Handle create_inline(Handle parent);
530
531         Handle clone(const GUID& deriv_guid=GUID())const;
532
533 private:
534         void add_group_pair(String group, etl::handle<Layer> layer);
535         void remove_group_pair(String group, etl::handle<Layer> layer);
536         void add_connection(etl::loose_handle<Layer> layer, sigc::connection connection);
537         void disconnect_connections(etl::loose_handle<Layer> layer);
538
539 protected:
540         virtual void on_changed();
541         virtual void get_times_vfunc(Node::time_set &set) const;
542 }; // END of class Canvas
543
544 void optimize_layers(Time time, Context context, Canvas::Handle op_canvas, bool seen_motion_blur=false);
545
546
547 }; // END of namespace synfig
548
549 /* === E N D =============================================================== */
550
551 #endif