More documentation for canvas.h
[synfig.git] / synfig-core / 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  * 0.5: svn r1863
91  *
92  *      Added "offset", "scale", and "fixed_length" links to the
93  *      "BLine Tangent" ValueNode.
94  *
95  * 0.6: svn r2067
96  *
97  *      Added "scale" link to the "BLine Width" ValueNode in svn r1872.
98  *
99  *      Added "loop" link to the "Gradient Color" ValueNode in svn r1901.
100  *
101  * 0.7: svn r2315
102  *
103  *      Added "loop" link to the "Random" ValueNode in svn r2315.
104  */
105
106 #define CURRENT_CANVAS_VERSION "0.7"
107
108 /* === T Y P E D E F S ===================================================== */
109
110 /* === C L A S S E S & S T R U C T S ======================================= */
111
112 namespace synfig {
113
114 class Context;
115 class GUID;
116
117 /*!     \class Canvas
118 **      \brief Canvas is a double ended queue of Layers. It is the base class
119 * for a Synfig document.
120 *
121 * As a node it inherits all the parent child relationship and the GUID
122 * methods. As a double queue it allows insertion and deletion of Layers
123 * and can access to the layers on the queue easily.
124 */
125 class Canvas : public CanvasBase, public Node
126 {
127         /*
128  --     ** -- T Y P E S -----------------------------------------------------------
129         */
130
131 public:
132         typedef etl::handle<Canvas> Handle;
133         typedef etl::loose_handle<Canvas> LooseHandle;
134         typedef etl::handle<const Canvas> ConstHandle;
135
136         typedef std::list<Handle> Children;
137
138         friend void synfig::optimize_layers(Time, Context, Canvas::Handle, bool seen_motion_blur);
139
140         /*
141  --     ** -- D A T A -------------------------------------------------------------
142         */
143
144 private:
145
146         //! Contains the ID string for the Canvas
147         /*!     \see get_id(), set_id() */
148         String id_;
149
150         //! Contains the name of the Canvas
151         /*!     \see set_name(), get_name() */
152         String name_;
153
154         //! Contains a description of the Canvas
155         /*!     \see set_description(), get_description() */
156         String description_;
157
158         //! Contains the canvas' version string
159         /*!     \see set_version(), get_version() */
160         String version_;
161
162         //! Contains the author's name
163         /*!     \see set_author(), get_author() */
164         String author_;
165
166         //! Contains the author's email address
167         /*!     \todo This private parameter has no binding, so it's unusable at the moment */
168         String email_;
169
170         //! File name of Canvas
171         /*! \see get_file_name(), set_file_name() */
172         String file_name_;
173
174         //! Metadata map for Canvas.
175         /*! \see get_meta_data(), set_meta_data(), erase_meta_data() */
176         std::map<String, String> meta_data_;
177
178         //! Contains a list of ValueNodes that are in this Canvas
179         /*!     \see value_node_list(), find_value_node() */
180         ValueNodeList value_node_list_;
181
182         //! Contains a list of Keyframes that are in the Canvas
183         /*! \see keyframe_list()*/
184         KeyframeList keyframe_list_;
185
186         //! A handle to the parent canvas of this canvas.
187         /*!     If canvas is a root canvas, then this handle is empty
188         **      \see parent()
189         */
190         LooseHandle parent_;
191
192         //! List containing any child Canvases
193         /*!     \see children() */
194         Children children_;
195
196         //! Render Description for Canvas
197         /*!     \see rend_desc() */
198     RendDesc desc_;
199
200         //! Contains the value of the last call to set_time()
201         Time cur_time_;
202
203         //! Map of external Canvases used in this Canvas
204         mutable std::map<String,Handle> externals_;
205
206         //! This flag is set if this canvas is "inline"
207         bool is_inline_;
208
209         //! True if the Canvas properties has changed
210         mutable bool is_dirty_;
211
212         //! It is set to true when synfig::optimize_layers is called
213         bool op_flag_;
214
215         //! Layer Group database
216         std::map<String,std::set<etl::handle<Layer> > > group_db_;
217
218         //! Layer Signal Connection database. Seems to be unused.
219         std::map<etl::loose_handle<Layer>,std::vector<sigc::connection> > connections_;
220
221         /*
222  -- ** -- S I G N A L S -------------------------------------------------------
223         */
224
225 private:
226
227         //!     Group Added
228         sigc::signal<void,String> signal_group_added_;
229
230         //!     Group Removed
231         sigc::signal<void,String> signal_group_removed_;
232
233         //! Group Changed
234         sigc::signal<void,String> signal_group_changed_;
235
236         sigc::signal<void,String,etl::handle<synfig::Layer> > signal_group_pair_added_;
237         sigc::signal<void,String,etl::handle<synfig::Layer> > signal_group_pair_removed_;
238
239         //!     Layers Reordered
240         sigc::signal<void,int*> signal_layers_reordered_;
241
242         //!     RendDesc Changed
243         sigc::signal<void> signal_rend_desc_changed_;
244
245         //!     ID Changed
246         sigc::signal<void> signal_id_changed_;
247
248         //!     Dirty
249         //sigc::signal<void> signal_dirty_;
250
251         //!     FileName Changed
252         sigc::signal<void> signal_file_name_changed_;
253
254         //!     Metadata Changed
255         sigc::signal<void, String> signal_meta_data_changed_;
256
257         //! Key-Specific meta data changed signals
258         std::map<String, sigc::signal<void> > signal_map_meta_data_changed_;
259
260
261         //!     ValueBasenode Changed
262         sigc::signal<void, etl::handle<ValueNode> > signal_value_node_changed_;
263         //!     ValueBasenode Renamed
264         sigc::signal<void, etl::handle<ValueNode> > signal_value_node_renamed_;
265         //!     Child Value Node Added. Used in Dynamic List Value Nodes
266         sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> > signal_value_node_child_added_;
267         //!     Child Value Node Removed. Used in Dynamic List Value Nodes
268         sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> > signal_value_node_child_removed_;
269
270         /*
271  -- ** -- S I G N A L   I N T E R F A C E -------------------------------------
272         */
273
274 public:
275
276         sigc::signal<void,String,etl::handle<synfig::Layer> >& signal_group_pair_added() { return signal_group_pair_added_; }
277         sigc::signal<void,String,etl::handle<synfig::Layer> >& signal_group_pair_removed() { return signal_group_pair_removed_; }
278
279         //!     Group Added
280         sigc::signal<void,String>& signal_group_added() { return signal_group_added_; }
281
282         //!     Group Removed
283         sigc::signal<void,String>& signal_group_removed() { return signal_group_removed_; }
284
285         //! Group Changed
286         sigc::signal<void,String>& signal_group_changed() { return signal_group_changed_; }
287
288         //!     Layers Reordered
289         sigc::signal<void,int*>& signal_layers_reordered() { return signal_layers_reordered_; }
290
291         //!     RendDesc Changed
292         sigc::signal<void>& signal_rend_desc_changed() { return signal_rend_desc_changed_; }
293
294         //!     ID Changed
295         sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
296
297         //!     File name Changed
298         sigc::signal<void>& signal_file_name_changed();
299
300         //!     Metadata Changed
301         sigc::signal<void, String>& signal_meta_data_changed() { return signal_meta_data_changed_; }
302
303         //!     Metadata Changed
304         sigc::signal<void>& signal_meta_data_changed(const String& key) { return signal_map_meta_data_changed_[key]; }
305
306         //! Value Node Changed
307         sigc::signal<void, etl::handle<ValueNode> >& signal_value_node_changed() { return signal_value_node_changed_; }
308         //! Value Node Renamed
309         sigc::signal<void, etl::handle<ValueNode> >& signal_value_node_renamed() { return signal_value_node_renamed_; }
310
311         //! Dirty
312         sigc::signal<void>& signal_dirty() { return signal_changed();   }
313
314         //! Child Value Node Added
315         sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> >& signal_value_node_child_added() { return signal_value_node_child_added_; }
316
317         //! Child Value Node Removed
318         sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> >& signal_value_node_child_removed() { return signal_value_node_child_removed_; }
319
320         /*
321  --     ** -- C O N S T R U C T O R S ---------------------------------------------
322         */
323
324 protected:
325         //! Canvas constructor by Canvas name
326         Canvas(const String &name);
327
328 public:
329
330         ~Canvas();
331
332         /*
333  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
334         */
335
336 public:
337
338         //! Returns the set of layers in group
339         std::set<etl::handle<Layer> > get_layers_in_group(const String&group);
340
341         //! Gets all the groups
342         std::set<String> get_groups()const;
343
344         //! Gets the number of groups in this canvas
345         int get_group_count()const;
346
347         //! Renames the given group
348         void rename_group(const String&old_name,const String&new_name);
349
350         //! Returns true if the Canvas is in line
351         bool is_inline()const { return is_inline_; }
352
353         //! Returns a handle to the RendDesc for this Canvas
354         RendDesc &rend_desc() { return desc_; }
355
356         //! Returns a handle to the RendDesc for this Canvas
357         const RendDesc &rend_desc()const { return desc_; }
358
359         //! Gets the name of the canvas
360         const String & get_name()const { return name_; }
361
362         //! Sets the name of the canvas
363         void set_name(const String &x);
364
365         //! Gets the version string of the canvas
366         const String get_version()const { return version_; }
367
368         //! Sets the version string of the canvas
369         void set_version(const String &x) { version_ = x; }
370
371         //! Gets the author of the canvas
372         const String & get_author()const { return author_; }
373
374         //! Sets the author of the canvas
375         void set_author(const String &x);
376
377         //! Gets the description of the canvas
378         const String & get_description()const { return description_; }
379
380         //! Sets the name of the canvas
381         void set_description(const String &x);
382
383         //! Gets the ID of the canvas
384         const String & get_id()const { return id_; }
385
386         //! Sets the ID of the canvas
387         void set_id(const String &x);
388
389         //!     Returns the data string for the given meta data key
390         String get_meta_data(const String& key)const;
391
392         //!     Returns a list of meta data keys
393         std::list<String> get_meta_data_keys()const;
394
395         //! Sets a meta data key to a specific string
396         void set_meta_data(const String& key, const String& data);
397
398         //! Removes a meta data key
399         void erase_meta_data(const String& key);
400
401         //! Gets the relative ID string for an ancestor Canvas
402         String get_relative_id(etl::loose_handle<const Canvas> x)const;
403
404         //! Gets the relative ID string for an ancestor Canvas. Don't call it directly
405         String _get_relative_id(etl::loose_handle<const Canvas> x)const;
406
407         //! Returns \c true if the Canvas is a root Canvas. \c false otherwise
408         bool is_root()const { return !parent_; }
409
410         //! Returns a handle to the parent Canvas.
411         /*! The returned handle will be empty if this is a root canvas */
412         LooseHandle parent()const { return parent_; }
413
414         //! Returns a handle to the root Canvas
415         LooseHandle get_root()const;
416
417         //! Returns a list of all child canvases in this canvas
418         std::list<Handle> &children() { return children_; }
419
420         //! Returns a list of all child canvases in this canvas
421         const std::list<Handle> &children()const { return children_; }
422
423         //! Gets the color at the specified point
424         //Color get_color(const Point &pos)const;
425
426         //! Sets the time for all the layers in the canvas
427         void set_time(Time t)const;
428
429         //! Returns the current time of the Canvas
430         Time get_time()const { return cur_time_; }
431
432         //! Returns the number of layers in the canvas
433         int size()const;
434
435         //! Removes all the layers from the canvas
436         void clear();
437
438         //! Returns true if the canvas has no layers
439         bool empty()const;
440
441         //! Returns a reference to the ValueNodeList for this Canvas
442         // ValueNodeList &value_node_list() { return value_node_list_; }
443
444         //! Returns a reference to the ValueNodeList for this Canvas
445         const ValueNodeList &value_node_list()const;
446
447         //! Returns a reference to the KeyframeList for this Canvas
448         KeyframeList &keyframe_list();
449
450         //! Returns a reference to the KeyframeList for this Canvas
451         const KeyframeList &keyframe_list()const;
452
453         //! Finds the ValueNode in the Canvas with the given \a id
454         /*!     \return If found, returns a handle to the ValueNode.
455         **              Otherwise, returns an empty handle.
456         */
457         ValueNode::Handle find_value_node(const String &id);
458
459         //! \internal \writeme
460         ValueNode::Handle surefind_value_node(const String &id);
461
462         //! Finds the ValueNode in the Canvas with the given \a id
463         /*!     \return If found, returns a handle to the ValueNode.
464         **              Otherwise, returns an empty handle.
465         */
466         ValueNode::ConstHandle find_value_node(const String &id)const;
467
468         //! Adds a Value node by its Id.
469         /*! Throws an error if the Id is not
470         //! correct or the Value node is already exported
471         **/
472         void add_value_node(ValueNode::Handle x, const String &id);
473
474         //! writeme
475         //void rename_value_node(ValueNode::Handle x, const String &id);
476
477         //! Removes a Value Node from the Canvas by its Handle
478         void remove_value_node(ValueNode::Handle x);
479
480         //! Removes a Value Node from the Canvas by its Id
481         void remove_value_node(const String &id) { remove_value_node(find_value_node(id)); }
482
483         //! Finds a child Canvas in the Canvas with the given \a name
484         /*!     \return If found, returns a handle to the child Canvas.
485         **              If not found, it creates a new Canvas and returns it
486         **              If an error occurs, it returns an empty handle
487         */
488         Handle surefind_canvas(const String &id,String &warnings);
489
490         //! Finds a child Canvas in the Canvas with the given \a id
491         /*!     \return If found, returns a handle to the child Canvas.
492         **              Otherwise, returns an empty handle.
493         */
494         Handle find_canvas(const String &id, String &warnings);
495
496         //! Finds a child Canvas in the Canvas with the given \a id
497         /*!     \return If found, returns a handle to the child Canvas.
498         **              Otherwise, returns an empty handle.
499         */
500         ConstHandle find_canvas(const String &id, String &warnings)const;
501
502         //! Sets the file path for the Canvas
503         //void set_file_path(const String &);
504
505         //! Returns the file path from the file name
506         String get_file_path()const;
507
508         //! Sets the filename (with path)
509         void set_file_name(const String &);
510
511         //! Gets the filename (with path)
512         String get_file_name()const;
513
514         //! Creates a new child canvas, and returns its handle
515         Handle new_child_canvas();
516
517         //! Creates a new child canvas with an ID of \a id, and returns its handle
518         Handle new_child_canvas(const String &id);
519
520         //! Adds the given canvas as a child
521         Handle add_child_canvas(Handle child_canvas, const String &id);
522
523         //! Remove Child Canvas by its handle. If Current canvas is a child of a parent
524         //! it ask to the parent to remove the Child canvas.
525         void remove_child_canvas(Handle child_canvas);
526
527         //! Finds a Layer by its position.
528         //! \see get_context()
529         etl::handle<Layer> find_layer(const Point &pos);
530
531         //! Gets the depth of a particular Layer by its handle
532         int get_depth(etl::handle<Layer>)const;
533
534         //! Retireves the first layer of the double queue of Layers
535         Context get_context()const;
536         //! Returns the last Canvas layer queue iterator. Notice that it
537         /*! overrides the std::end() member that would return an interator
538          * just past the last element of the queue.*/
539         iterator end();
540         //! Returns the last Canvas layer queue const_iterator. Notice that it
541         /*! overrides the std::end() member that would return an interator
542          * just past the last element of the queue.*/
543         const_iterator end()const;
544         //! Returns the last Canvas layer queue reverse iterator. Notice that it
545         /*! overrides the std::rbegin() member that would return an interator
546          * just past the last element of the queue.*/
547         reverse_iterator rbegin();
548         //! Returns the last Canvas layer queue reverse const iterator. Notice that it
549         /*! overrides the std::rbegin() member that would return an interator
550          * just past the last element of the queue.*/
551         const_reverse_iterator rbegin()const;
552         //! Returns last layer in Canvas layer stack
553         etl::handle<Layer> &back();
554         //! Returns last layer in Canvas layer stack
555         const etl::handle<Layer> &back()const;
556         //! Inserts a layer just before the last layer.
557         //! \see end(), insert(iterator iter,etl::handle<Layer> x)
558         void push_back(etl::handle<Layer> x);
559         //! Inserts a layer just at the beggining of the Canvas layer dqueue
560         void push_front(etl::handle<Layer> x);
561         //! Inserts a layer in the last position of the Canvas layer dqueue
562         //! Uses the standard methods and doesn't perform any parentship
563         //! or signal update
564         void push_back_simple(etl::handle<Layer> x);
565         //! Inserts a layer before the given position by \iter and performs
566         //! the proper child parent relationships and signals update
567         void insert(iterator iter,etl::handle<Layer> x);
568         //! Removes a layer from the Canvas layer dqueue and its group and parent
569         //! relatioship. Although it is not already used, it clears the connections
570         //! see connections_
571         void erase(iterator iter);
572         //! Sets to be a inline canvas of a given Canvas \parent. The inline
573         //! Canvas inherits the groups and the render description.
574         //! \see rend_desc()
575         void set_inline(LooseHandle parent);
576         //! Returns a Canvas handle with "Untitled" as ID
577         static Handle create();
578         //! Creates an inline Canvas for a given Canvas \parent
579         static Handle create_inline(Handle parent);
580         //! Clones (copies) the Canvas if it is inline.
581         Handle clone(const GUID& deriv_guid=GUID())const;
582         //! Stores the external canvas by its file name and the Canvas handle
583         void register_external_canvas(String file, Handle canvas);
584
585 #ifdef _DEBUG
586         void show_externals(String file, int line, String text) const;
587 #endif  // _DEBUG
588
589 private:
590         //! Adds a \layer to a group given by its \group string to the group
591         //! database
592         void add_group_pair(String group, etl::handle<Layer> layer);
593         //! Removes a \layer from a group given by its \group string to the group
594         //! database
595         void remove_group_pair(String group, etl::handle<Layer> layer);
596         //! Seems to be used to add the stored signals connections of the layers.
597         //! \see connections_
598         void add_connection(etl::loose_handle<Layer> layer, sigc::connection connection);
599         //! Seems to be used to disconnect the stored signals connections of the layers.
600         //! \see connections_
601         void disconnect_connections(etl::loose_handle<Layer> layer);
602
603 protected:
604         //! Sets the Canvas to dirty and calls Node::on_changed()
605         virtual void on_changed();
606         //! Collects the times (TimePoints) of the Layers of the Canvas and
607         //! stores it in the passed Time Set \set
608         //! \see Node::get_times()
609         virtual void get_times_vfunc(Node::time_set &set) const;
610 }; // END of class Canvas
611
612         //! Optimize layers based on its calculated Z depth to perform a quick
613         //! render of the layers to the output.
614 void optimize_layers(Time time, Context context, Canvas::Handle op_canvas, bool seen_motion_blur=false);
615
616
617 }; // END of namespace synfig
618
619 /* === E N D =============================================================== */
620
621 #endif