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
10 ** This package is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU General Public License as
12 ** published by the Free Software Foundation; either version 2 of
13 ** the License, or (at your option) any later version.
15 ** This package is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ** General Public License for more details.
21 /* ========================================================================= */
23 /* === S T A R T =========================================================== */
25 #ifndef __SYNFIG_VALUENODE_H
26 #define __SYNFIG_VALUENODE_H
28 /* === H E A D E R S ======================================================= */
35 #include <ETL/stringf>
36 #include "exception.h"
38 #include <sigc++/signal.h>
41 #ifndef SYNFIG_NO_ANGLE
49 /* === M A C R O S ========================================================= */
51 // This is a hack for GCC 3.0.4... which has a broken dynamic_cast<>
52 // It is deprecated, and will be removed soon.
53 #if ( __GNUC__ == 3 ) && ( __GNUC__MINOR__ == 0 )
54 # define DCAST_HACK_BASECLASS() int cast__
55 # define DCAST_HACK_ID(x) static const int my_cast__(void) { return x; }
56 # define DCAST_HACK_ENABLE() cast__=my_cast__()
58 # define DCAST_HACK_BASECLASS()
59 # define DCAST_HACK_ID(x)
60 # define DCAST_HACK_ENABLE()
63 #define CHECK_TYPE_AND_SET_VALUE(variable, type) \
64 /* I don't think this ever happens - maybe remove this code? */ \
65 if (get_type() == ValueBase::TYPE_NIL) { \
66 warning("%s:%d get_type() IS nil sometimes!", \
67 __FILE__, __LINE__); \
70 if (get_type() != ValueBase::TYPE_NIL && \
71 !(ValueBase::same_type_as(value->get_type(), type)) && \
72 !PlaceholderValueNode::Handle::cast_dynamic(value)) { \
73 error(_("%s:%d wrong type for %s: need %s but got %s"), \
75 link_local_name(i).c_str(), \
76 ValueBase::type_local_name(type).c_str(), \
77 ValueBase::type_local_name(value->get_type()).c_str()); \
81 signal_child_changed()(i); \
82 signal_value_changed()(); \
85 /* === T Y P E D E F S ===================================================== */
87 /* === C L A S S E S & S T R U C T S ======================================= */
92 class LinkableValueNode;
98 class ValueNode : public synfig::Node
101 friend class LinkableValueNode;
104 -- ** -- T Y P E S -----------------------------------------------------------
109 typedef etl::handle<ValueNode> Handle;
111 typedef etl::loose_handle<ValueNode> LooseHandle;
113 typedef etl::handle<const ValueNode> ConstHandle;
115 typedef etl::rhandle<ValueNode> RHandle;
118 static bool subsys_init();
120 static bool subsys_stop();
123 -- ** -- D A T A -------------------------------------------------------------
127 ValueBase::Type type;
129 etl::loose_handle<Canvas> canvas_;
130 etl::loose_handle<Canvas> root_canvas_;
133 -- ** -- S I G N A L S -------------------------------------------------------
138 //! ValueBase Changed
139 sigc::signal<void> signal_value_changed_;
141 //! Children Reordered
142 sigc::signal<void,int*> signal_children_reordered_;
145 sigc::signal<void,int> signal_child_changed_;
148 sigc::signal<void,int> signal_child_removed_;
151 sigc::signal<void,int> signal_child_inserted_;
154 sigc::signal<void> signal_id_changed_;
157 -- ** -- S I G N A L I N T E R F A C E -------------------------------------
162 //! ValueBase Changed
163 sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
165 //! Children Reordered
166 sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
169 sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
172 sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
175 sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
178 sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
181 -- ** -- C O N S T R U C T O R S ---------------------------------------------
186 ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
190 virtual ~ValueNode();
193 -- ** -- M E M B E R F U N C T I O N S -------------------------------------
198 //! Returns the value of the ValueNode at time \a t
199 virtual ValueBase operator()(Time /*t*/)const
200 { return ValueBase(); }
202 //! \internal Sets the id of the ValueNode
203 void set_id(const String &x);
205 //! Returns the id of the ValueNode
206 /*! The ID is used for keeping track of a
207 ** specific instance of a ValueNode. */
208 const String &get_id()const { return name; }
210 //! Returns the name of the ValueNode type
211 virtual String get_name()const=0;
213 //! Returns the localized name of the ValueNode type
214 virtual String get_local_name()const=0;
216 //! Return a full description of the ValueNode and its parentage
217 virtual String get_description(bool show_exported_name = true)const;
221 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
224 bool is_exported()const { return !get_id().empty(); }
226 //! Returns the type of the ValueNode
227 ValueBase::Type get_type()const { return type; }
229 //! Returns a handle to the parent canvas, if it has one.
230 etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
232 //! Returns a handle to the parent canvas, if it has one.
233 etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
236 void set_parent_canvas(etl::loose_handle<Canvas> x);
239 void set_root_canvas(etl::loose_handle<Canvas> x);
242 String get_relative_id(etl::loose_handle<const Canvas> x)const;
244 int replace(etl::handle<ValueNode> x);
247 //! Sets the type of the ValueNode
248 void set_type(ValueBase::Type t) { type=t; }
250 virtual void on_changed();
253 DCAST_HACK_BASECLASS();
255 }; // END of class ValueNode
257 /*! \class PlaceholderValueNode
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
292 class LinkableValueNode : public ValueNode
294 friend class ValueNode;
297 typedef etl::handle<LinkableValueNode> Handle;
299 typedef etl::loose_handle<LinkableValueNode> LooseHandle;
301 typedef etl::handle<const LinkableValueNode> ConstHandle;
303 typedef etl::rhandle<LinkableValueNode> RHandle;
306 //! Type that represents a pointer to a ValueNode's constructor
307 typedef LinkableValueNode* (*Factory)(const ValueBase&);
309 typedef bool (*CheckType)(ValueBase::Type);
315 CheckType check_type;
316 ReleaseVersion release_version; // which version of synfig introduced this valuenode type
319 typedef std::map<String,BookEntry> Book;
323 static Handle create(const String &name, const ValueBase& x);
325 static bool check_type(const String &name, ValueBase::Type x);
328 LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
332 virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
338 virtual int link_count()const=0;
340 virtual String link_local_name(int i)const=0;
342 virtual String link_name(int i)const=0;
344 virtual int get_link_index_from_name(const String &name)const=0;
346 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
348 bool set_link(int i,ValueNode::Handle x);
349 bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x); }
351 ValueNode::LooseHandle get_link(int i)const;
352 ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
355 get_description(int index, bool show_exported_name = true)const;
358 //! Sets the type of the ValueNode
359 void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
361 virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
363 // Wrapper for new operator, used by clone()
364 virtual LinkableValueNode* create_new()const=0;
366 virtual void get_times_vfunc(Node::time_set &set) const;
367 }; // END of class LinkableValueNode
369 /*! \class ValueNodeList
370 ** \brief A searchable value_node list container
371 ** \warning Do not confuse with ValueNode_DynamicList!
374 class ValueNodeList : public std::list<ValueNode::RHandle>
376 int placeholder_count_;
380 //! Finds the ValueNode in the list with the given \a name
381 /*! \return If found, returns a handle to the ValueNode.
382 ** Otherwise, returns an empty handle.
384 ValueNode::Handle find(const String &name);
386 //! Finds the ValueNode in the list with the given \a name
387 /*! \return If found, returns a handle to the ValueNode.
388 ** Otherwise, returns an empty handle.
390 ValueNode::ConstHandle find(const String &name)const;
392 //! Removes the \a value_node from the list
393 bool erase(ValueNode::Handle value_node);
396 bool add(ValueNode::Handle value_node);
399 bool count(const String &id)const;
401 //! Similar to find, but will create a placeholder value_node if it cannot be found.
402 ValueNode::Handle surefind(const String &name);
404 //! Removes any value_nodes with reference counts of 1.
407 //! Placeholder Count
408 int placeholder_count()const { return placeholder_count_; }
411 ValueNode::LooseHandle find_value_node(const GUID& guid);
413 }; // END of namespace synfig
415 /* === E N D =============================================================== */