1 /* === S Y N F I G ========================================================= */
3 ** \brief Header file for implementation of the "Placeholder" valuenode conversion.
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 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_VALUENODE_H
27 #define __SYNFIG_VALUENODE_H
29 /* === H E A D E R S ======================================================= */
36 #include <ETL/stringf>
37 #include "exception.h"
39 #include <sigc++/signal.h>
42 #include "paramdesc.h"
48 /* === M A C R O S ========================================================= */
50 #define CHECK_TYPE_AND_SET_VALUE(variable, type) \
51 /* I don't think this ever happens - maybe remove this code? */ \
52 if (get_type() == ValueBase::TYPE_NIL) { \
53 warning("%s:%d get_type() IS nil sometimes!", \
54 __FILE__, __LINE__); \
57 if (get_type() != ValueBase::TYPE_NIL && \
58 !(ValueBase::same_type_as(value->get_type(), type)) && \
59 !PlaceholderValueNode::Handle::cast_dynamic(value)) { \
60 error(_("%s:%d wrong type for %s: need %s but got %s"), \
62 link_local_name(i).c_str(), \
63 ValueBase::type_local_name(type).c_str(), \
64 ValueBase::type_local_name(value->get_type()).c_str()); \
68 signal_child_changed()(i); \
69 signal_value_changed()(); \
72 /* === T Y P E D E F S ===================================================== */
74 /* === C L A S S E S & S T R U C T S ======================================= */
79 class LinkableValueNode;
84 ** \brief Base class for all Value Nodes
86 class ValueNode : public synfig::Node
89 friend class LinkableValueNode;
92 -- ** -- T Y P E S -----------------------------------------------------------
97 typedef etl::handle<ValueNode> Handle;
99 typedef etl::loose_handle<ValueNode> LooseHandle;
101 typedef etl::handle<const ValueNode> ConstHandle;
103 typedef etl::rhandle<ValueNode> RHandle;
105 //!Instantiates the book of ValaueNodes and register all the valid valuenodes on it
106 static bool subsys_init();
107 //!Deletes the book of ValueNodes
108 static bool subsys_stop();
111 -- ** -- D A T A -------------------------------------------------------------
115 //! The type of the Value Node
117 ValueBase::Type type;
118 //! The name of the Value Node. This is the string that is used in the
119 //! sif file to define the value type: i.e. <param name="amount">
121 //! The canvas this Value Node belongs to
122 etl::loose_handle<Canvas> canvas_;
123 //! The root canvas this Value Node belongs to
124 etl::loose_handle<Canvas> root_canvas_;
127 -- ** -- S I G N A L S -------------------------------------------------------
132 //! ValueBase Changed
133 sigc::signal<void> signal_value_changed_;
135 //! Children Reordered
136 sigc::signal<void,int*> signal_children_reordered_;
139 sigc::signal<void,int> signal_child_changed_;
142 sigc::signal<void,int> signal_child_removed_;
145 sigc::signal<void,int> signal_child_inserted_;
148 sigc::signal<void> signal_id_changed_;
151 -- ** -- S I G N A L I N T E R F A C E -------------------------------------
156 //! ValueBase Changed
157 sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
159 //! Children Reordered
160 sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
163 sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
166 sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
169 sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
172 sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
175 -- ** -- C O N S T R U C T O R S ---------------------------------------------
180 ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
184 virtual ~ValueNode();
187 -- ** -- M E M B E R F U N C T I O N S -------------------------------------
192 //! Returns the value of the ValueNode at time \a t
193 virtual ValueBase operator()(Time /*t*/)const
194 { return ValueBase(); }
196 //! \internal Sets the id of the ValueNode
197 void set_id(const String &x);
199 //! Returns the id of the ValueNode
200 /*! The ID is used for keeping track of a
201 ** specific instance of a ValueNode. */
202 const String &get_id()const { return name; }
204 //! Returns the name of the ValueNode type
205 virtual String get_name()const=0;
207 //! Returns the localized name of the ValueNode type
208 virtual String get_local_name()const=0;
210 //! Return a full description of the ValueNode and its parentage
211 virtual String get_description(bool show_exported_name = true)const;
214 //! Clones a Value Node
215 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
217 //! Returns \true if the Value Node has an ID (has been exported)
218 bool is_exported()const { return !get_id().empty(); }
220 //! Returns the type of the ValueNode
221 ValueBase::Type get_type()const { return type; }
223 //! Returns a handle to the parent canvas, if it has one.
224 etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
226 //! Returns a handle to the parent canvas, if it has one.
227 etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
229 //! Sets the parent canvas for the Value Node
230 void set_parent_canvas(etl::loose_handle<Canvas> x);
232 //! Sets the root canvas parent for the Value Node
233 void set_root_canvas(etl::loose_handle<Canvas> x);
235 //! Returns the relative ID of a Node when accessed form the \x Canvas
236 String get_relative_id(etl::loose_handle<const Canvas> x)const;
238 //! Replaces the Value Node with a given one. It look up all its parents
239 //! remove it self from them and adds the given Value Node
240 //! Notice that it is called twice and the second time it uses
241 //! a replaceable handle to the Node
242 //! \see etl::rhandle
243 int replace(etl::handle<ValueNode> x);
246 //! Sets the type of the ValueNode
247 void set_type(ValueBase::Type t) { type=t; }
249 virtual void on_changed();
250 }; // END of class ValueNode
252 /*! \class PlaceholderValueNode
253 ** Seems to be a Place to hold a Value Node temporarly.
255 * Doesn't seem to implement any functionality. Seems to be used when the
256 * value node cannot be created using the Const, Animated or Linkable
260 class PlaceholderValueNode : public ValueNode
263 typedef etl::handle<PlaceholderValueNode> Handle;
264 typedef etl::loose_handle<PlaceholderValueNode> LooseHandle;
265 typedef etl::handle<const PlaceholderValueNode> ConstHandle;
266 typedef etl::rhandle<PlaceholderValueNode> RHandle;
270 PlaceholderValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
274 virtual ValueBase operator()(Time t)const;
276 virtual String get_name()const;
278 virtual String get_local_name()const;
280 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
282 static Handle create(ValueBase::Type type=ValueBase::TYPE_NIL);
285 virtual void get_times_vfunc(Node::time_set &/*set*/) const {}
286 }; // END of class PlaceholderValueNode
289 /*! \class LinkableValueNode
290 ** \brief Specialized Class of Value Nodes that has links to other
293 * This Value Node is calculated based on a math calculation or a time
294 * evaluation of the linked Value Nodes. It is commonly known as
295 * Converted Value Nodes. The derived clases defines the behavior.
297 class LinkableValueNode : public ValueNode
299 friend class ValueNode;
302 typedef etl::handle<LinkableValueNode> Handle;
304 typedef etl::loose_handle<LinkableValueNode> LooseHandle;
306 typedef etl::handle<const LinkableValueNode> ConstHandle;
308 typedef etl::rhandle<LinkableValueNode> RHandle;
311 //! Type that represents a pointer to a ValueNode's constructor
312 /*! As a pointer to the constructor, it represents a "factory" of
313 ** objects of this class.
315 typedef LinkableValueNode* (*Factory)(const ValueBase&);
317 //! This represents a pointer to a Type check member fucntion
318 /*! As a pointer to the member, it represents a fucntion that checks
319 ** the type of the provided ValueBase
321 typedef bool (*CheckType)(ValueBase::Type);
327 CheckType check_type;
328 ReleaseVersion release_version; // which version of synfig introduced this valuenode type
331 //! Book of types of linkable value nodes indexed by type name.
332 /*! While the sifz file is read, each time a new LinkableValueNode entry
333 ** is found, the factory constructor that the "factory" pointer member
334 ** of the "BookEntry" struct points to, is called, and a new object of
335 ** that type is created.
336 ** \sa LinkableValueNode::Factory
338 typedef std::map<String,BookEntry> Book;
340 //! The vocabulary of the children
341 /*! \see synfig::Paramdesc
343 typedef ParamVocab Vocab;
347 //! Creates a Linkable Value Node based on the name and the returned
348 //! value type. Returns a valid Handle if both (name and type) match
349 static Handle create(const String &name, const ValueBase& x);
351 //! Each derived Linkable Value Node has to implement this fucntion and
352 //! should return true only if the type matches. \name is the name of
353 //! the linked value node and \x is the returned value type
354 static bool check_type(const String &name, ValueBase::Type x);
357 LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
361 //! Stores the Value Node \x in the sub parameter i after check if the
362 //! type is the same.
363 //! It has to be defined by the derived class.
364 virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
366 //! Frees all the subparameters of the Linkable Value Node.
367 //! Used by the derived classed destructors.
372 //! Returns the number of linked Value Nodes
373 virtual int link_count()const;
375 //! Returns the local name of the 'i' linked Value Node
376 virtual String link_local_name(int i)const;
378 //! Returns the name of the 'i' linked Value Node
379 virtual String link_name(int i)const;
381 //! Returns the child index Value Node based on the name
382 virtual int get_link_index_from_name(const String &name)const;
384 //! Clones a Value Node
385 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
387 //! Sets a new Value Node link by its index
388 bool set_link(int i,ValueNode::Handle x);
389 //! Sets a new Value Node link by its name
390 bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x); }
392 //! Returns a Loose Handle to the Value Node based on the link's index
393 ValueNode::LooseHandle get_link(int i)const;
394 //! Returns a Loose Handle to the Value Node based on the link's name
395 ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
396 //! Return a full description of the linked ValueNode given by the index
397 String get_description(int index = -1, bool show_exported_name = true)const;
399 //! Gets the children vocabulary for linkable value nodes
400 virtual Vocab get_children_vocab()const;
403 //! Member to store the children vocabulary
404 Vocab children_vocab;
405 //! Sets the type of the ValueNode
406 void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
408 //! Virtual member to get the linked Value Node Handle
409 virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
411 //! Wrapper for new operator, used by clone()
412 virtual LinkableValueNode* create_new()const=0;
414 //! Returns the cached times values for all the children (linked Value Nodes)
415 virtual void get_times_vfunc(Node::time_set &set) const;
417 //! Pure Virtual member to get the children vocabulary
418 virtual Vocab get_children_vocab_vfunc()const=0;
420 //! Virtual memebr to set the children vocabulary to a given value
421 virtual void set_children_vocab(const Vocab& rvocab);
422 }; // END of class LinkableValueNode
424 /*! \class ValueNodeList
425 ** \brief A searchable value_node list container
426 ** \warning Do not confuse with ValueNode_DynamicList!
428 * Used by Canvas class to access to the exported value nodes.
430 class ValueNodeList : public std::list<ValueNode::RHandle>
432 int placeholder_count_;
436 //! Finds the ValueNode in the list with the given \a name
437 /*! \return If found, returns a handle to the ValueNode.
438 ** Otherwise, returns an empty handle.
440 ValueNode::Handle find(const String &name);
442 //! Finds the ValueNode in the list with the given \a name
443 /*! \return If found, returns a handle to the ValueNode.
444 ** Otherwise, returns an empty handle.
446 ValueNode::ConstHandle find(const String &name)const;
448 //! Removes the \a value_node from the list
449 bool erase(ValueNode::Handle value_node);
452 bool add(ValueNode::Handle value_node);
455 bool count(const String &id)const;
457 //! Similar to find, but will create a placeholder value_node if it cannot be found.
458 ValueNode::Handle surefind(const String &name);
460 //! Removes any value_nodes with reference counts of 1.
463 //! Placeholder Count
464 int placeholder_count()const { return placeholder_count_; }
467 ValueNode::LooseHandle find_value_node(const GUID& guid);
469 }; // END of namespace synfig
471 /* === E N D =============================================================== */