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 #ifndef SYNFIG_NO_ANGLE
50 /* === M A C R O S ========================================================= */
52 // This is a hack for GCC 3.0.4... which has a broken dynamic_cast<>
53 // It is deprecated, and will be removed soon.
54 #if ( __GNUC__ == 3 ) && ( __GNUC__MINOR__ == 0 )
55 # define DCAST_HACK_BASECLASS() int cast__
56 # define DCAST_HACK_ID(x) static const int my_cast__(void) { return x; }
57 # define DCAST_HACK_ENABLE() cast__=my_cast__()
59 # define DCAST_HACK_BASECLASS()
60 # define DCAST_HACK_ID(x)
61 # define DCAST_HACK_ENABLE()
64 #define CHECK_TYPE_AND_SET_VALUE(variable, type) \
65 /* I don't think this ever happens - maybe remove this code? */ \
66 if (get_type() == ValueBase::TYPE_NIL) { \
67 warning("%s:%d get_type() IS nil sometimes!", \
68 __FILE__, __LINE__); \
71 if (get_type() != ValueBase::TYPE_NIL && \
72 !(ValueBase::same_type_as(value->get_type(), type)) && \
73 !PlaceholderValueNode::Handle::cast_dynamic(value)) { \
74 error(_("%s:%d wrong type for %s: need %s but got %s"), \
76 link_local_name(i).c_str(), \
77 ValueBase::type_local_name(type).c_str(), \
78 ValueBase::type_local_name(value->get_type()).c_str()); \
82 signal_child_changed()(i); \
83 signal_value_changed()(); \
86 /* === T Y P E D E F S ===================================================== */
88 /* === C L A S S E S & S T R U C T S ======================================= */
93 class LinkableValueNode;
99 class ValueNode : public synfig::Node
102 friend class LinkableValueNode;
105 -- ** -- T Y P E S -----------------------------------------------------------
110 typedef etl::handle<ValueNode> Handle;
112 typedef etl::loose_handle<ValueNode> LooseHandle;
114 typedef etl::handle<const ValueNode> ConstHandle;
116 typedef etl::rhandle<ValueNode> RHandle;
119 static bool subsys_init();
121 static bool subsys_stop();
124 -- ** -- D A T A -------------------------------------------------------------
128 ValueBase::Type type;
130 etl::loose_handle<Canvas> canvas_;
131 etl::loose_handle<Canvas> root_canvas_;
134 -- ** -- S I G N A L S -------------------------------------------------------
139 //! ValueBase Changed
140 sigc::signal<void> signal_value_changed_;
142 //! Children Reordered
143 sigc::signal<void,int*> signal_children_reordered_;
146 sigc::signal<void,int> signal_child_changed_;
149 sigc::signal<void,int> signal_child_removed_;
152 sigc::signal<void,int> signal_child_inserted_;
155 sigc::signal<void> signal_id_changed_;
158 -- ** -- S I G N A L I N T E R F A C E -------------------------------------
163 //! ValueBase Changed
164 sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
166 //! Children Reordered
167 sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
170 sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
173 sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
176 sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
179 sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
182 -- ** -- C O N S T R U C T O R S ---------------------------------------------
187 ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
191 virtual ~ValueNode();
194 -- ** -- M E M B E R F U N C T I O N S -------------------------------------
199 //! Returns the value of the ValueNode at time \a t
200 virtual ValueBase operator()(Time /*t*/)const
201 { return ValueBase(); }
203 //! \internal Sets the id of the ValueNode
204 void set_id(const String &x);
206 //! Returns the id of the ValueNode
207 /*! The ID is used for keeping track of a
208 ** specific instance of a ValueNode. */
209 const String &get_id()const { return name; }
211 //! Returns the name of the ValueNode type
212 virtual String get_name()const=0;
214 //! Returns the localized name of the ValueNode type
215 virtual String get_local_name()const=0;
217 //! Return a full description of the ValueNode and its parentage
218 virtual String get_description(bool show_exported_name = true)const;
222 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
225 bool is_exported()const { return !get_id().empty(); }
227 //! Returns the type of the ValueNode
228 ValueBase::Type get_type()const { return type; }
230 //! Returns a handle to the parent canvas, if it has one.
231 etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
233 //! Returns a handle to the parent canvas, if it has one.
234 etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
237 void set_parent_canvas(etl::loose_handle<Canvas> x);
240 void set_root_canvas(etl::loose_handle<Canvas> x);
243 String get_relative_id(etl::loose_handle<const Canvas> x)const;
245 int replace(etl::handle<ValueNode> x);
248 //! Sets the type of the ValueNode
249 void set_type(ValueBase::Type t) { type=t; }
251 virtual void on_changed();
254 DCAST_HACK_BASECLASS();
256 }; // END of class ValueNode
258 /*! \class PlaceholderValueNode
261 class PlaceholderValueNode : public ValueNode
264 typedef etl::handle<PlaceholderValueNode> Handle;
265 typedef etl::loose_handle<PlaceholderValueNode> LooseHandle;
266 typedef etl::handle<const PlaceholderValueNode> ConstHandle;
267 typedef etl::rhandle<PlaceholderValueNode> RHandle;
271 PlaceholderValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
275 virtual ValueBase operator()(Time t)const;
277 virtual String get_name()const;
279 virtual String get_local_name()const;
281 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
283 static Handle create(ValueBase::Type type=ValueBase::TYPE_NIL);
286 virtual void get_times_vfunc(Node::time_set &/*set*/) const {}
287 }; // END of class PlaceholderValueNode
290 /*! \class LinkableValueNode
293 class LinkableValueNode : public ValueNode
295 friend class ValueNode;
298 typedef etl::handle<LinkableValueNode> Handle;
300 typedef etl::loose_handle<LinkableValueNode> LooseHandle;
302 typedef etl::handle<const LinkableValueNode> ConstHandle;
304 typedef etl::rhandle<LinkableValueNode> RHandle;
307 //! Type that represents a pointer to a ValueNode's constructor
308 typedef LinkableValueNode* (*Factory)(const ValueBase&);
310 typedef bool (*CheckType)(ValueBase::Type);
316 CheckType check_type;
317 ReleaseVersion release_version; // which version of synfig introduced this valuenode type
320 typedef std::map<String,BookEntry> Book;
324 static Handle create(const String &name, const ValueBase& x);
326 static bool check_type(const String &name, ValueBase::Type x);
329 LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
333 virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
339 virtual int link_count()const=0;
341 virtual String link_local_name(int i)const=0;
343 virtual String link_name(int i)const=0;
345 virtual int get_link_index_from_name(const String &name)const=0;
347 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
349 bool set_link(int i,ValueNode::Handle x);
350 bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x); }
352 ValueNode::LooseHandle get_link(int i)const;
353 ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
356 get_description(int index = -1, bool show_exported_name = true)const;
359 //! Sets the type of the ValueNode
360 void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
362 virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
364 // Wrapper for new operator, used by clone()
365 virtual LinkableValueNode* create_new()const=0;
367 virtual void get_times_vfunc(Node::time_set &set) const;
368 }; // END of class LinkableValueNode
370 /*! \class ValueNodeList
371 ** \brief A searchable value_node list container
372 ** \warning Do not confuse with ValueNode_DynamicList!
375 class ValueNodeList : public std::list<ValueNode::RHandle>
377 int placeholder_count_;
381 //! Finds the ValueNode in the list with the given \a name
382 /*! \return If found, returns a handle to the ValueNode.
383 ** Otherwise, returns an empty handle.
385 ValueNode::Handle find(const String &name);
387 //! Finds the ValueNode in the list with the given \a name
388 /*! \return If found, returns a handle to the ValueNode.
389 ** Otherwise, returns an empty handle.
391 ValueNode::ConstHandle find(const String &name)const;
393 //! Removes the \a value_node from the list
394 bool erase(ValueNode::Handle value_node);
397 bool add(ValueNode::Handle value_node);
400 bool count(const String &id)const;
402 //! Similar to find, but will create a placeholder value_node if it cannot be found.
403 ValueNode::Handle surefind(const String &name);
405 //! Removes any value_nodes with reference counts of 1.
408 //! Placeholder Count
409 int placeholder_count()const { return placeholder_count_; }
412 ValueNode::LooseHandle find_value_node(const GUID& guid);
414 }; // END of namespace synfig
416 /* === E N D =============================================================== */