Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_06 / src / synfig / valuenode_dynamiclist.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file valuenode_dynamiclist.h
3 **      \brief Template Header
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_DYNAMICLIST_H
26 #define __SYNFIG_VALUENODE_DYNAMICLIST_H
27
28 /* === H E A D E R S ======================================================= */
29
30 #include <vector>
31 #include <list>
32
33 #include "valuenode.h"
34 #include "time.h"
35 #include "uniqueid.h"
36 #include "activepoint.h"
37
38 /* === M A C R O S ========================================================= */
39
40 /* === C L A S S E S & S T R U C T S ======================================= */
41
42 namespace synfig {
43 class ValueNode_BLine;
44
45 /*! \class ValueNode_DynamicList
46 **      \brief Animated List ValueNode
47 **
48 **      This ValueNode was originally set up to have a list
49 **      of ValueNodes and their associated "on" and "off" points.
50 **      ie: Any time that was directly after an "on" point,
51 **      the item would be "on", and any time that was directly
52 **      after an "off" point would be "off". This is pretty intuitive.
53 **      However, it does have its problems.
54 **
55 **      The problems arise when we introduce the concept of a
56 **      Keyframe. Keyframes can be manipulated via the Synfig
57 **      Application Library. They allow the user to quickly
58 **      and "automagickly" rearange an animation by moving
59 **      the associated keyframes. With the old way that the
60 **      "on" and "off" points were handled, this task became
61 **      overly complicated.
62 **
63 **      What is required is a "symmetric" system of describing
64 **      "on" and "off" points. Instead of the point representing
65 **      the state of the item after that point in time, we have
66 **      the point represent <i>only that frame</i>. The state
67 **      of the item is calculated by looking at the points
68 **      around it: If either (or both) points are "on", then the
69 **      current state is "on". Otherwise, the point is "off"
70 **
71 **      This may be a bit confusing at first, but it is required
72 **      if we want the keyframe mechanism to "just work".
73 */
74 class ValueNode_DynamicList : public LinkableValueNode
75 {
76 public:
77
78         /*! \class ListEntry
79         **      \brief Contains a potential list item, and associated timing information
80         **
81         **      This structure contains a RHandle to a ValueNode,
82         **      as well as the associated on/off timing information
83         **      which determines when this item is included in the list.
84         **
85         **      The timing information is stored in the member <tt>timing_info</tt>.
86         */
87         struct ListEntry : public UniqueID
88         {
89                 friend class ValueNode_DynamicList;
90                 friend class ValueNode_BLine;
91         public:
92                 typedef synfig::Activepoint Activepoint;
93
94                 typedef std::list<Activepoint> ActivepointList;
95
96                 typedef std::pair<ActivepointList::iterator,bool>               findresult;
97                 typedef std::pair<ActivepointList::const_iterator,bool> const_findresult;
98
99
100         private:
101                 mutable Node::time_set  times;
102         public:
103                 ValueNode::RHandle value_node;
104
105                 ActivepointList timing_info;
106
107         private:
108                 int index;
109                 etl::loose_handle<ValueNode> parent_;
110                 void set_parent_value_node(const etl::loose_handle<ValueNode> &x) { parent_=x; }
111
112         public:
113
114                 int get_index()const { return index; }
115
116
117                 bool status_at_time(const Time &x)const;
118
119                 float amount_at_time(const Time &x, bool *rising=0)const;
120
121                 ActivepointList::iterator add(Time time, bool status, int priority=0);
122                 ActivepointList::iterator add(const Activepoint &x);
123
124                 findresult find_uid(const UniqueID& x);
125                 const_findresult find_uid(const UniqueID& x)const;
126
127                 findresult find_time(const Time& x);
128                 const_findresult find_time(const Time& x)const;
129
130                 ActivepointList::iterator find(const UniqueID& x);
131                 ActivepointList::const_iterator find(const UniqueID& x)const;
132                 ActivepointList::iterator find(const Time& x);
133                 ActivepointList::const_iterator find(const Time& x)const;
134                 ActivepointList::iterator find_prev(const Time& x);
135                 ActivepointList::const_iterator find_prev(const Time& x)const;
136                 ActivepointList::iterator find_next(const Time& x);
137                 ActivepointList::const_iterator find_next(const Time& x)const;
138
139                 Activepoint new_activepoint_at_time(const Time& x)const;
140
141                 ActivepointList::iterator add(Time time)
142                         { return add(time, status_at_time(time)); }
143
144                 void erase(const UniqueID& x);
145
146                 int find(const Time& begin,const Time& end,std::vector<Activepoint*>& list);
147
148                 const synfig::Node::time_set    &get_times() const;
149
150                 const etl::loose_handle<ValueNode> &get_parent_value_node()const { return parent_; }
151
152                 ListEntry();
153                 ListEntry(const ValueNode::Handle &value_node);
154                 ListEntry(const ValueNode::Handle &value_node,Time begin, Time end);
155         }; // END of struct ValueNode_DynamicList::ListEntry
156
157         typedef etl::handle<ValueNode_DynamicList> Handle;
158         typedef etl::handle<const ValueNode_DynamicList> ConstHandle;
159
160 protected:
161         ValueNode_DynamicList(ValueBase::Type container_type=ValueBase::TYPE_NIL);
162
163         ValueBase::Type container_type;
164
165         bool loop_;
166
167
168 public:
169         std::vector<ListEntry> list;
170
171 public:
172
173         void add(const ValueNode::Handle &value_node, int index=-1);
174         void add(const ListEntry &value_node, int index=-1);
175         void erase(const ValueNode::Handle &value_node);
176         void reindex();
177
178         int find_next_valid_entry(int x, Time t)const;
179         int find_prev_valid_entry(int x, Time t)const;
180
181         virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
182
183         virtual int link_count()const;
184
185         virtual String link_name(int i)const;
186
187         virtual ValueBase operator()(Time t)const;
188
189         virtual ~ValueNode_DynamicList();
190
191         virtual String link_local_name(int i)const;
192         virtual int get_link_index_from_name(const String &name)const;
193
194         virtual String get_name()const;
195         virtual String get_local_name()const;
196
197         bool get_loop()const { return loop_; }
198         void set_loop(bool x) { loop_=x; }
199
200         ValueBase::Type get_contained_type()const;
201
202
203         template <typename iterator> static Handle
204         create(iterator begin, iterator end)
205         {
206                 Handle ret=create((*begin)->get_type());
207                 for(;begin!=end;++begin)
208                         ret->add(ListEntry(*begin));
209                 return ret;
210         }
211
212         void insert_time(const Time& location, const Time& delta);
213         //void manipulate_time(const Time& old_begin,const Time& old_end,const Time& new_begin,const Time& new_end);
214
215         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
216
217         virtual ListEntry create_list_entry(int index, Time time=0, Real origin=0.5);
218
219 protected:
220
221         virtual bool set_link_vfunc(int i,ValueNode::Handle x);
222         LinkableValueNode* create_new()const;
223
224         virtual void get_times_vfunc(Node::time_set &set) const;
225
226 public:
227         /*! \note The construction parameter (\a id) is the type that the list
228         **      contains, rather than the type that it will yield
229         **      (which is ValueBase::TYPE_LIST)
230         */
231         static Handle create(ValueBase::Type id=ValueBase::TYPE_NIL);
232         using synfig::LinkableValueNode::get_link_vfunc;
233         using synfig::LinkableValueNode::set_link_vfunc;
234         static bool check_type(ValueBase::Type type);
235         static ValueNode_DynamicList* create_from(const ValueBase &x=ValueBase::TYPE_GRADIENT);
236 }; // END of class ValueNode_DynamicList
237
238 typedef ValueNode_DynamicList::ListEntry::Activepoint Activepoint;
239 typedef ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
240
241 }; // END of namespace synfig
242
243 /* === E N D =============================================================== */
244
245 #endif