Revision 1150 changed the way angles work so that 0 degrees and 360 degrees are treat...
[synfig.git] / synfig-core / trunk / src / synfig / valuenode.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file valuenode.h
3 **      \brief Header file for implementation of the "Placeholder" valuenode conversion.
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
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.
14 **
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.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === S T A R T =========================================================== */
24
25 #ifndef __SYNFIG_VALUENODE_H
26 #define __SYNFIG_VALUENODE_H
27
28 /* === H E A D E R S ======================================================= */
29
30 #include "vector.h"
31 #include "value.h"
32 #include "string.h"
33 #include <ETL/handle>
34 #include <ETL/stringf>
35 #include "exception.h"
36 #include <map>
37 #include <sigc++/signal.h>
38 #include "guid.h"
39
40 #ifndef SYNFIG_NO_ANGLE
41 #include <ETL/angle>
42 #endif
43
44 #include "node.h"
45
46 #include <set>
47
48 /* === M A C R O S ========================================================= */
49
50 // This is a hack for GCC 3.0.4... which has a broken dynamic_cast<>
51 // It is deprecated, and will be removed soon.
52 #if ( __GNUC__ == 3 ) && ( __GNUC__MINOR__ == 0 )
53 # define DCAST_HACK_BASECLASS() int cast__
54 # define DCAST_HACK_ID(x)               static const int my_cast__(void) { return x; }
55 # define DCAST_HACK_ENABLE()    cast__=my_cast__()
56 #else
57 # define DCAST_HACK_BASECLASS()
58 # define DCAST_HACK_ID(x)
59 # define DCAST_HACK_ENABLE()
60 #endif
61
62 /* === T Y P E D E F S ===================================================== */
63
64 /* === C L A S S E S & S T R U C T S ======================================= */
65
66 namespace synfig {
67
68 class Canvas;
69 class LinkableValueNode;
70 class Layer;
71
72 /*!     \class ValueNode
73 **      \todo writeme
74 */
75 class ValueNode : public synfig::Node
76 {
77         friend class Layer;
78         friend class LinkableValueNode;
79
80         /*
81  --     ** -- T Y P E S -----------------------------------------------------------
82         */
83
84 public:
85
86         typedef etl::handle<ValueNode> Handle;
87
88         typedef etl::loose_handle<ValueNode> LooseHandle;
89
90         typedef etl::handle<const ValueNode> ConstHandle;
91
92         typedef etl::rhandle<ValueNode> RHandle;
93
94
95         static bool subsys_init();
96
97         static bool subsys_stop();
98
99         /*
100  --     ** -- D A T A -------------------------------------------------------------
101         */
102
103 private:
104         ValueBase::Type type;
105         String name;
106         etl::loose_handle<Canvas> canvas_;
107         etl::loose_handle<Canvas> root_canvas_;
108
109         /*
110  -- ** -- S I G N A L S -------------------------------------------------------
111         */
112
113 private:
114
115         //!     ValueBase Changed
116         sigc::signal<void> signal_value_changed_;
117
118         //!     Children Reordered
119         sigc::signal<void,int*> signal_children_reordered_;
120
121         //!     Child Changed
122         sigc::signal<void,int> signal_child_changed_;
123
124         //!     Child Removed
125         sigc::signal<void,int> signal_child_removed_;
126
127         //!     Child Inserted
128         sigc::signal<void,int> signal_child_inserted_;
129
130         //!     ID Changed
131         sigc::signal<void> signal_id_changed_;
132
133         /*
134  -- ** -- S I G N A L   I N T E R F A C E -------------------------------------
135         */
136
137 public:
138
139         //!     ValueBase Changed
140         sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
141
142         //!     Children Reordered
143         sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
144
145         //!     Child Changed
146         sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
147
148         //!     Child Removed
149         sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
150
151         //!     Child Inserted
152         sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
153
154         //!     ID Changed
155         sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
156
157         /*
158  --     ** -- C O N S T R U C T O R S ---------------------------------------------
159         */
160
161 protected:
162
163         ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
164
165 public:
166
167         virtual ~ValueNode();
168
169         /*
170  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
171         */
172
173 public:
174
175         //! Returns the value of the ValueNode at time \a t
176         virtual ValueBase operator()(Time /*t*/)const
177                 { return ValueBase(); }
178
179         //! \internal Sets the id of the ValueNode
180         void set_id(const String &x);
181
182         //! Returns the id of the ValueNode
183         /*!     The ID is used for keeping track of a
184         **      specific instance of a ValueNode. */
185         const String &get_id()const { return name; }
186
187         //! Returns the name of the ValueNode type
188         virtual String get_name()const=0;
189
190         //! Returns the localized name of the ValueNode type
191         virtual String get_local_name()const=0;
192
193
194         //! \writeme
195         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
196
197         //! \writeme
198         bool is_exported()const { return !get_id().empty(); }
199
200         //! Returns the type of the ValueNode
201         ValueBase::Type get_type()const { return type; }
202
203         //! Returns a handle to the parent canvas, if it has one.
204         etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
205
206         //! Returns a handle to the parent canvas, if it has one.
207         etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
208
209         //! \writeme
210         void set_parent_canvas(etl::loose_handle<Canvas> x);
211
212         //! \writeme
213         void set_root_canvas(etl::loose_handle<Canvas> x);
214
215         //! \writeme
216         String get_relative_id(etl::loose_handle<const Canvas> x)const;
217
218         int replace(etl::handle<ValueNode> x);
219
220 protected:
221         //! Sets the type of the ValueNode
222         void set_type(ValueBase::Type t) { type=t; }
223
224         virtual void on_changed();
225
226 public:
227         DCAST_HACK_BASECLASS();
228         DCAST_HACK_ID(0);
229 }; // END of class ValueNode
230
231 /*!     \class PlaceholderValueNode
232 **      \todo writeme
233 */
234 class PlaceholderValueNode : public ValueNode
235 {
236 public:
237         typedef etl::handle<PlaceholderValueNode> Handle;
238         typedef etl::loose_handle<PlaceholderValueNode> LooseHandle;
239         typedef etl::handle<const PlaceholderValueNode> ConstHandle;
240         typedef etl::rhandle<PlaceholderValueNode> RHandle;
241
242 private:
243
244         PlaceholderValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
245
246 public:
247
248         virtual ValueBase operator()(Time t)const;
249
250         virtual String get_name()const;
251
252         virtual String get_local_name()const;
253
254         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
255
256         static Handle create(ValueBase::Type type=ValueBase::TYPE_NIL);
257
258 protected:
259         virtual void get_times_vfunc(Node::time_set &/*set*/) const {}
260 }; // END of class PlaceholderValueNode
261
262
263 /*!     \class LinkableValueNode
264 **      \todo writeme
265 */
266 class LinkableValueNode : public ValueNode
267 {
268         friend class ValueNode;
269 public:
270
271         typedef etl::handle<LinkableValueNode> Handle;
272
273         typedef etl::loose_handle<LinkableValueNode> LooseHandle;
274
275         typedef etl::handle<const LinkableValueNode> ConstHandle;
276
277         typedef etl::rhandle<LinkableValueNode> RHandle;
278
279
280         //! Type that represents a pointer to a ValueNode's constructor
281         typedef LinkableValueNode* (*Factory)(const ValueBase&);
282
283         typedef bool (*CheckType)(ValueBase::Type);
284
285         struct BookEntry
286         {
287                 String local_name;
288                 Factory factory;
289                 CheckType check_type;
290         };
291
292         typedef std::map<String,BookEntry> Book;
293
294         static Book& book();
295
296         static Handle create(const String &name, const ValueBase& x);
297
298         static bool check_type(const String &name, ValueBase::Type x);
299
300 public:
301         LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
302                 ValueNode(type) { }
303
304 protected:
305         virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
306
307         void unlink_all();
308
309 public:
310
311         virtual int link_count()const=0;
312
313         virtual String link_local_name(int i)const=0;
314
315         virtual String link_name(int i)const=0;
316
317         virtual int get_link_index_from_name(const String &name)const=0;
318
319         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
320
321         bool set_link(int i,ValueNode::Handle x);
322         bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x);      }
323
324         ValueNode::LooseHandle get_link(int i)const;
325         ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
326
327 protected:
328         //! Sets the type of the ValueNode
329         void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
330
331         virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
332
333         // Wrapper for new operator, used by clone()
334         virtual LinkableValueNode* create_new()const=0;
335
336         virtual void get_times_vfunc(Node::time_set &set) const;
337 }; // END of class LinkableValueNode
338
339 /*!     \class ValueNodeList
340 **      \brief A searchable value_node list container
341 **      \warning Do not confuse with ValueNode_DynamicList!
342 **      \todo writeme
343 */
344 class ValueNodeList : public std::list<ValueNode::RHandle>
345 {
346         int placeholder_count_;
347 public:
348         ValueNodeList();
349
350         //! Finds the ValueNode in the list with the given \a name
351         /*!     \return If found, returns a handle to the ValueNode.
352         **              Otherwise, returns an empty handle.
353         */
354         ValueNode::Handle find(const String &name);
355
356         //! Finds the ValueNode in the list with the given \a name
357         /*!     \return If found, returns a handle to the ValueNode.
358         **              Otherwise, returns an empty handle.
359         */
360         ValueNode::ConstHandle find(const String &name)const;
361
362         //! Removes the \a value_node from the list
363         bool erase(ValueNode::Handle value_node);
364
365         //! \writeme
366         bool add(ValueNode::Handle value_node);
367
368         //! \writeme
369         bool count(const String &id)const;
370
371         //! Similar to find, but will create a placeholder value_node if it cannot be found.
372         ValueNode::Handle surefind(const String &name);
373
374         //! Removes any value_nodes with reference counts of 1.
375         void audit();
376
377         //! Placeholder Count
378         int placeholder_count()const { return placeholder_count_; }
379 };
380
381 ValueNode::LooseHandle find_value_node(const GUID& guid);
382
383 }; // END of namespace synfig
384
385 /* === E N D =============================================================== */
386
387 #endif