1 /* === S Y N F I G ========================================================= */
3 ** \brief Canvas Class Implementation
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
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.
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.
22 /* ========================================================================= */
24 /* === S T A R T =========================================================== */
26 #ifndef __SYNFIG_CANVAS_H
27 #define __SYNFIG_CANVAS_H
29 /* === H E A D E R S ======================================================= */
34 #include <sigc++/signal.h>
35 #include <sigc++/connection.h>
39 #include "canvasbase.h"
40 #include "valuenode.h"
46 /* === M A C R O S ========================================================= */
48 /* version change history:
50 * 0.1: the original version
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
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
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)
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
83 * Tangent lengths calculated by the "Segment Tangent" and "BLine
84 * Tangent" ValueNodes were scaled by a factor of 0.5.
88 * Stop scaling tangents by 0.5.
92 * Added "offset", "scale", and "fixed_length" links to the
93 * "BLine Tangent" ValueNode.
97 * Added "scale" link to the "BLine Width" ValueNode in svn r1872.
99 * Added "loop" link to the "Gradient Color" ValueNode in svn r1901.
103 * Added "loop" link to the "Random" ValueNode in svn r2315.
106 #define CURRENT_CANVAS_VERSION "0.7"
108 /* === T Y P E D E F S ===================================================== */
110 /* === C L A S S E S & S T R U C T S ======================================= */
120 class Canvas : public CanvasBase, public Node
123 -- ** -- T Y P E S -----------------------------------------------------------
127 typedef etl::handle<Canvas> Handle;
128 typedef etl::loose_handle<Canvas> LooseHandle;
129 typedef etl::handle<const Canvas> ConstHandle;
131 typedef std::list<Handle> Children;
133 friend void synfig::optimize_layers(Time, Context, Canvas::Handle, bool seen_motion_blur);
136 -- ** -- D A T A -------------------------------------------------------------
141 //! Contains the ID string for the Canvas
142 /*! \see get_id(), set_id() */
145 //! Contains the name of the Canvas
146 /*! \see set_name(), get_name() */
149 //! Contains a description of the Canvas
150 /*! \see set_description(), get_description() */
153 //! Contains the canvas' version string
154 /*! \see set_version(), get_version() */
157 //! Contains the author's name
158 /*! \see set_author(), get_author() */
161 //! Contains the author's email address
162 /*! \todo This private parameter has no binding, so it's unusable at the moment */
165 //! File name of Canvas
166 /*! \see get_file_name(), set_file_name() */
169 //! Metadata map for Canvas.
170 /*! \see get_meta_data(), set_meta_data(), erase_meta_data() */
171 std::map<String, String> meta_data_;
173 //! Contains a list of ValueNodes that are in this Canvas
174 /*! \see value_node_list(), find_value_node() */
175 ValueNodeList value_node_list_;
178 KeyframeList keyframe_list_;
180 //! A handle to the parent canvas of this canvas.
181 /*! If canvas is a root canvas, then this handle is empty
186 //! List containing any child Canvases
187 /*! \see children() */
190 //! Render Description for Canvas
191 /*! \see rend_desc() */
194 //! Contains the value of the last call to set_time()
198 mutable std::map<String,Handle> externals_;
200 //! This flag is set if this canvas is "inline"
203 mutable bool is_dirty_;
207 //! Layer Group database
208 std::map<String,std::set<etl::handle<Layer> > > group_db_;
210 //! Layer Connection database
211 std::map<etl::loose_handle<Layer>,std::vector<sigc::connection> > connections_;
214 -- ** -- S I G N A L S -------------------------------------------------------
220 sigc::signal<void,String> signal_group_added_;
223 sigc::signal<void,String> signal_group_removed_;
226 sigc::signal<void,String> signal_group_changed_;
228 sigc::signal<void,String,etl::handle<synfig::Layer> > signal_group_pair_added_;
229 sigc::signal<void,String,etl::handle<synfig::Layer> > signal_group_pair_removed_;
232 sigc::signal<void,int*> signal_layers_reordered_;
235 sigc::signal<void> signal_rend_desc_changed_;
238 sigc::signal<void> signal_id_changed_;
241 //sigc::signal<void> signal_dirty_;
244 sigc::signal<void> signal_file_name_changed_;
247 sigc::signal<void, String> signal_meta_data_changed_;
249 //! Key-Specific meta data changed signals
250 std::map<String, sigc::signal<void> > signal_map_meta_data_changed_;
253 //! ValueBasenode Changed
254 sigc::signal<void, etl::handle<ValueNode> > signal_value_node_changed_;
256 sigc::signal<void, etl::handle<ValueNode> > signal_value_node_renamed_;
258 sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> > signal_value_node_child_added_;
260 sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> > signal_value_node_child_removed_;
263 -- ** -- S I G N A L I N T E R F A C E -------------------------------------
268 sigc::signal<void,String,etl::handle<synfig::Layer> >& signal_group_pair_added() { return signal_group_pair_added_; }
269 sigc::signal<void,String,etl::handle<synfig::Layer> >& signal_group_pair_removed() { return signal_group_pair_removed_; }
272 sigc::signal<void,String>& signal_group_added() { return signal_group_added_; }
275 sigc::signal<void,String>& signal_group_removed() { return signal_group_removed_; }
278 sigc::signal<void,String>& signal_group_changed() { return signal_group_changed_; }
281 sigc::signal<void,int*>& signal_layers_reordered() { return signal_layers_reordered_; }
284 sigc::signal<void>& signal_rend_desc_changed() { return signal_rend_desc_changed_; }
287 sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
289 //! File name Changed
290 sigc::signal<void>& signal_file_name_changed();
293 sigc::signal<void, String>& signal_meta_data_changed() { return signal_meta_data_changed_; }
296 sigc::signal<void>& signal_meta_data_changed(const String& key) { return signal_map_meta_data_changed_[key]; }
299 sigc::signal<void, etl::handle<ValueNode> >& signal_value_node_changed() { return signal_value_node_changed_; }
301 sigc::signal<void, etl::handle<ValueNode> >& signal_value_node_renamed() { return signal_value_node_renamed_; }
304 sigc::signal<void>& signal_dirty() { return signal_changed(); }
307 sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> >& signal_value_node_child_added() { return signal_value_node_child_added_; }
310 sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> >& signal_value_node_child_removed() { return signal_value_node_child_removed_; }
313 -- ** -- C O N S T R U C T O R S ---------------------------------------------
318 Canvas(const String &name);
325 -- ** -- M E M B E R F U N C T I O N S -------------------------------------
330 //! Returns the set of layers in group
331 std::set<etl::handle<Layer> > get_layers_in_group(const String&group);
333 //! Gets all the groups
334 std::set<String> get_groups()const;
336 //! Gets the number of groups in this canvas
337 int get_group_count()const;
339 //! Renames the given group
340 void rename_group(const String&old_name,const String&new_name);
343 bool is_inline()const { return is_inline_; }
345 //! Returns a handle to the RendDesc for this Canvas
346 RendDesc &rend_desc() { return desc_; }
348 //! Returns a handle to the RendDesc for this Canvas
349 const RendDesc &rend_desc()const { return desc_; }
351 //! Gets the name of the canvas
352 const String & get_name()const { return name_; }
354 //! Sets the name of the canvas
355 void set_name(const String &x);
357 //! Gets the version string of the canvas
358 const String get_version()const { return version_; }
360 //! Sets the version string of the canvas
361 void set_version(const String &x) { version_ = x; }
363 //! Gets the author of the canvas
364 const String & get_author()const { return author_; }
366 //! Sets the author of the canvas
367 void set_author(const String &x);
369 //! Gets the description of the canvas
370 const String & get_description()const { return description_; }
372 //! Sets the name of the canvas
373 void set_description(const String &x);
375 //! Gets the ID of the canvas
376 const String & get_id()const { return id_; }
378 //! Sets the ID of the canvas
379 void set_id(const String &x);
381 //! Returns the data string for the given meta data key
382 String get_meta_data(const String& key)const;
384 //! Returns a list of meta data keys
385 std::list<String> get_meta_data_keys()const;
387 //! Sets a meta data key to a specific string
388 void set_meta_data(const String& key, const String& data);
390 //! Removes a meta data key
391 void erase_meta_data(const String& key);
394 String get_relative_id(etl::loose_handle<const Canvas> x)const;
396 //! \internal \writeme
397 String _get_relative_id(etl::loose_handle<const Canvas> x)const;
399 //! Returns \c true if the Canvas is a root Canvas. \c false otherwise
400 bool is_root()const { return !parent_; }
402 //! Returns a handle to the parent Canvas.
403 /*! The returned handle will be empty if this is a root canvas */
404 LooseHandle parent()const { return parent_; }
406 LooseHandle get_root()const;
408 //! Returns a list of all child canvases in this canvas
409 std::list<Handle> &children() { return children_; }
411 //! Returns a list of all child canvases in this canvas
412 const std::list<Handle> &children()const { return children_; }
414 //! Gets the color at the specified point
415 //Color get_color(const Point &pos)const;
417 //! Sets the time for all the layers in the canvas
418 void set_time(Time t)const;
421 Time get_time()const { return cur_time_; }
423 //! Returns the number of layers in the canvas
426 //! Removes all the layers from the canvas
429 //! Returns true if the canvas has no layers
432 //! Returns a reference to the ValueNodeList for this Canvas
433 // ValueNodeList &value_node_list() { return value_node_list_; }
435 //! Returns a reference to the ValueNodeList for this Canvas
436 const ValueNodeList &value_node_list()const;
438 //! Returns a reference to the KeyframeList for this Canvas
439 KeyframeList &keyframe_list();
441 //! Returns a reference to the KeyframeList for this Canvas
442 const KeyframeList &keyframe_list()const;
444 //! Finds the ValueNode in the Canvas with the given \a id
445 /*! \return If found, returns a handle to the ValueNode.
446 ** Otherwise, returns an empty handle.
448 ValueNode::Handle find_value_node(const String &id);
450 //! \internal \writeme
451 ValueNode::Handle surefind_value_node(const String &id);
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.
457 ValueNode::ConstHandle find_value_node(const String &id)const;
460 void add_value_node(ValueNode::Handle x, const String &id);
463 //void rename_value_node(ValueNode::Handle x, const String &id);
466 void remove_value_node(ValueNode::Handle x);
469 void remove_value_node(const String &id) { remove_value_node(find_value_node(id)); }
471 //! Finds a child Canvas in the Canvas with the given \a name
472 /*! \return If found, returns a handle to the child Canvas.
473 ** If not found, it creates a new Canvas and returns it
474 ** If an error occurs, it returns an empty handle
476 Handle surefind_canvas(const String &id,String &warnings);
478 //! Finds a child Canvas in the Canvas with the given \a id
479 /*! \return If found, returns a handle to the child Canvas.
480 ** Otherwise, returns an empty handle.
482 Handle find_canvas(const String &id, String &warnings);
484 //! Finds a child Canvas in the Canvas with the given \a id
485 /*! \return If found, returns a handle to the child Canvas.
486 ** Otherwise, returns an empty handle.
488 ConstHandle find_canvas(const String &id, String &warnings)const;
490 //! Sets the file path for the Canvas
491 //void set_file_path(const String &);
493 //! Returns the file path from the file name
494 String get_file_path()const;
496 //! Sets the filename (with path)
497 void set_file_name(const String &);
499 //! Gets the filename (with path)
500 String get_file_name()const;
502 //! Creates a new child canvas, and returns its handle
503 Handle new_child_canvas();
505 //! Creates a new child canvas with an ID of \a id, and returns its handle
506 Handle new_child_canvas(const String &id);
508 //! Adds the given canvas as a child
509 Handle add_child_canvas(Handle child_canvas, const String &id);
511 void remove_child_canvas(Handle child_canvas);
513 etl::handle<Layer> find_layer(const Point &pos);
515 int get_depth(etl::handle<Layer>)const;
517 Context get_context()const;
521 const_iterator end()const;
523 reverse_iterator rbegin();
525 const_reverse_iterator rbegin()const;
527 etl::handle<Layer> &back();
529 void push_back(etl::handle<Layer> x);
531 void push_front(etl::handle<Layer> x);
533 void push_back_simple(etl::handle<Layer> x);
535 void insert(iterator iter,etl::handle<Layer> x);
536 void erase(iterator iter);
538 const etl::handle<Layer> &back()const;
540 void set_inline(LooseHandle parent);
542 static Handle create();
544 static Handle create_inline(Handle parent);
546 Handle clone(const GUID& deriv_guid=GUID())const;
548 void register_external_canvas(String file, Handle canvas);
551 void show_externals(String file, int line, String text) const;
555 void add_group_pair(String group, etl::handle<Layer> layer);
556 void remove_group_pair(String group, etl::handle<Layer> layer);
557 void add_connection(etl::loose_handle<Layer> layer, sigc::connection connection);
558 void disconnect_connections(etl::loose_handle<Layer> layer);
561 virtual void on_changed();
562 virtual void get_times_vfunc(Node::time_set &set) const;
563 }; // END of class Canvas
565 void optimize_layers(Time time, Context context, Canvas::Handle op_canvas, bool seen_motion_blur=false);
568 }; // END of namespace synfig
570 /* === E N D =============================================================== */