1 /* === S Y N F I G ========================================================= */
2 /*! \file valuenode_dynamiclist.h
3 ** \brief Template Header
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_DYNAMICLIST_H
26 #define __SYNFIG_VALUENODE_DYNAMICLIST_H
28 /* === H E A D E R S ======================================================= */
33 #include "valuenode.h"
36 #include "activepoint.h"
38 /* === M A C R O S ========================================================= */
40 /* === C L A S S E S & S T R U C T S ======================================= */
43 class ValueNode_BLine;
45 /*! \class ValueNode_DynamicList
46 ** \brief Animated List ValueNode
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.
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 "automagically" rearrange 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.
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"
71 ** This may be a bit confusing at first, but it is required
72 ** if we want the keyframe mechanism to "just work".
74 class ValueNode_DynamicList : public LinkableValueNode
79 ** \brief Contains a potential list item, and associated timing information
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.
85 ** The timing information is stored in the member <tt>timing_info</tt>.
87 struct ListEntry : public UniqueID
89 friend class ValueNode_DynamicList;
90 friend class ValueNode_BLine;
92 typedef synfig::Activepoint Activepoint;
94 typedef std::list<Activepoint> ActivepointList;
96 typedef std::pair<ActivepointList::iterator,bool> findresult;
97 typedef std::pair<ActivepointList::const_iterator,bool> const_findresult;
101 mutable Node::time_set times;
103 ValueNode::RHandle value_node;
105 ActivepointList timing_info;
109 etl::loose_handle<ValueNode> parent_;
110 void set_parent_value_node(const etl::loose_handle<ValueNode> &x) { parent_=x; }
114 int get_index()const { return index; }
117 bool status_at_time(const Time &x)const;
119 float amount_at_time(const Time &x, bool *rising=0)const;
121 ActivepointList::iterator add(Time time, bool status, int priority=0);
122 ActivepointList::iterator add(const Activepoint &x);
124 findresult find_uid(const UniqueID& x);
125 const_findresult find_uid(const UniqueID& x)const;
127 findresult find_time(const Time& x);
128 const_findresult find_time(const Time& x)const;
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;
139 Activepoint new_activepoint_at_time(const Time& x)const;
141 ActivepointList::iterator add(Time time)
142 { return add(time, status_at_time(time)); }
144 void erase(const UniqueID& x);
146 int find(const Time& begin,const Time& end,std::vector<Activepoint*>& list);
148 const synfig::Node::time_set &get_times() const;
150 const etl::loose_handle<ValueNode> &get_parent_value_node()const { return parent_; }
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
157 typedef etl::handle<ValueNode_DynamicList> Handle;
158 typedef etl::handle<const ValueNode_DynamicList> ConstHandle;
161 ValueNode_DynamicList(ValueBase::Type container_type=ValueBase::TYPE_NIL);
163 ValueBase::Type container_type;
169 std::vector<ListEntry> list;
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);
178 int find_next_valid_entry(int x, Time t)const;
179 int find_prev_valid_entry(int x, Time t)const;
181 virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
183 virtual int link_count()const;
185 virtual String link_name(int i)const;
187 virtual ValueBase operator()(Time t)const;
189 virtual ~ValueNode_DynamicList();
191 virtual String link_local_name(int i)const;
192 virtual int get_link_index_from_name(const String &name)const;
194 virtual String get_name()const;
195 virtual String get_local_name()const;
197 bool get_loop()const { return loop_; }
198 void set_loop(bool x) { loop_=x; }
200 ValueBase::Type get_contained_type()const;
203 template <typename iterator> static Handle
204 create(iterator begin, iterator end)
206 Handle ret=create((*begin)->get_type());
207 for(;begin!=end;++begin)
208 ret->add(ListEntry(*begin));
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);
215 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
217 virtual ListEntry create_list_entry(int index, Time time=0, Real origin=0.5);
221 virtual bool set_link_vfunc(int i,ValueNode::Handle x);
222 LinkableValueNode* create_new()const;
224 virtual void get_times_vfunc(Node::time_set &set) const;
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)
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
238 typedef ValueNode_DynamicList::ListEntry::Activepoint Activepoint;
239 typedef ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
241 }; // END of namespace synfig
243 /* === E N D =============================================================== */