1 /* === S Y N F I G ========================================================= */
2 /*! \file valuenode_dynamiclist.h
3 ** \brief Header file for implementation of the "Dynamic List" 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_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;
46 /*! \class ValueNode_DynamicList
47 ** \brief Animated List ValueNode
49 ** This ValueNode was originally set up to have a list
50 ** of ValueNodes and their associated "on" and "off" points.
51 ** ie: Any time that was directly after an "on" point,
52 ** the item would be "on", and any time that was directly
53 ** after an "off" point would be "off". This is pretty intuitive.
54 ** However, it does have its problems.
56 ** The problems arise when we introduce the concept of a
57 ** Keyframe. Keyframes can be manipulated via the Synfig
58 ** Application Library. They allow the user to quickly
59 ** and "automagically" rearrange an animation by moving
60 ** the associated keyframes. With the old way that the
61 ** "on" and "off" points were handled, this task became
62 ** overly complicated.
64 ** What is required is a "symmetric" system of describing
65 ** "on" and "off" points. Instead of the point representing
66 ** the state of the item after that point in time, we have
67 ** the point represent <i>only that frame</i>. The state
68 ** of the item is calculated by looking at the points
69 ** around it: If either (or both) points are "on", then the
70 ** current state is "on". Otherwise, the point is "off"
72 ** This may be a bit confusing at first, but it is required
73 ** if we want the keyframe mechanism to "just work".
75 class ValueNode_DynamicList : public LinkableValueNode
80 ** \brief Contains a potential list item, and associated timing information
82 ** This structure contains a RHandle to a ValueNode,
83 ** as well as the associated on/off timing information
84 ** which determines when this item is included in the list.
86 ** The timing information is stored in the member <tt>timing_info</tt>.
88 struct ListEntry : public UniqueID
90 friend class ValueNode_DynamicList;
91 friend class ValueNode_BLine;
93 typedef synfig::Activepoint Activepoint;
95 typedef std::list<Activepoint> ActivepointList;
97 typedef std::pair<ActivepointList::iterator,bool> findresult;
98 typedef std::pair<ActivepointList::const_iterator,bool> const_findresult;
102 mutable Node::time_set times;
104 ValueNode::RHandle value_node;
106 ActivepointList timing_info;
110 etl::loose_handle<ValueNode> parent_;
111 void set_parent_value_node(const etl::loose_handle<ValueNode> &x) { parent_=x; }
115 int get_index()const { return index; }
118 bool status_at_time(const Time &x)const;
120 float amount_at_time(const Time &x, bool *rising=0)const;
122 ActivepointList::iterator add(Time time, bool status, int priority=0);
123 ActivepointList::iterator add(const Activepoint &x);
125 findresult find_uid(const UniqueID& x);
126 const_findresult find_uid(const UniqueID& x)const;
128 findresult find_time(const Time& x);
129 const_findresult find_time(const Time& x)const;
131 ActivepointList::iterator find(const UniqueID& x);
132 ActivepointList::const_iterator find(const UniqueID& x)const;
133 ActivepointList::iterator find(const Time& x);
134 ActivepointList::const_iterator find(const Time& x)const;
135 ActivepointList::iterator find_prev(const Time& x);
136 ActivepointList::const_iterator find_prev(const Time& x)const;
137 ActivepointList::iterator find_next(const Time& x);
138 ActivepointList::const_iterator find_next(const Time& x)const;
140 Activepoint new_activepoint_at_time(const Time& x)const;
142 ActivepointList::iterator add(Time time)
143 { return add(time, status_at_time(time)); }
145 void erase(const UniqueID& x);
147 int find(const Time& begin,const Time& end,std::vector<Activepoint*>& list);
149 const synfig::Node::time_set &get_times() const;
151 const etl::loose_handle<ValueNode> &get_parent_value_node()const { return parent_; }
154 ListEntry(const ValueNode::Handle &value_node);
155 ListEntry(const ValueNode::Handle &value_node,Time begin, Time end);
156 }; // END of struct ValueNode_DynamicList::ListEntry
158 typedef etl::handle<ValueNode_DynamicList> Handle;
159 typedef etl::handle<const ValueNode_DynamicList> ConstHandle;
162 ValueNode_DynamicList(ValueBase::Type container_type=ValueBase::TYPE_NIL);
164 ValueBase::Type container_type;
170 std::vector<ListEntry> list;
174 void add(const ValueNode::Handle &value_node, int index=-1);
175 void add(const ListEntry &value_node, int index=-1);
176 void erase(const ValueNode::Handle &value_node);
179 int find_next_valid_entry(int x, Time t)const;
180 int find_prev_valid_entry(int x, Time t)const;
182 virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
184 virtual int link_count()const;
186 virtual String link_name(int i)const;
188 virtual ValueBase operator()(Time t)const;
190 virtual ~ValueNode_DynamicList();
192 virtual String link_local_name(int i)const;
193 virtual int get_link_index_from_name(const String &name)const;
195 virtual String get_name()const;
196 virtual String get_local_name()const;
198 bool get_loop()const { return loop_; }
199 void set_loop(bool x) { loop_=x; }
201 void set_member_canvas(etl::loose_handle<Canvas>);
203 ValueBase::Type get_contained_type()const;
206 template <typename iterator> static Handle
207 create(iterator begin, iterator end)
209 Handle ret=create((*begin)->get_type());
210 for(;begin!=end;++begin)
211 ret->add(ListEntry(*begin));
215 void insert_time(const Time& location, const Time& delta);
216 //void manipulate_time(const Time& old_begin,const Time& old_end,const Time& new_begin,const Time& new_end);
218 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
220 virtual ListEntry create_list_entry(int index, Time time=0, Real origin=0.5);
224 virtual bool set_link_vfunc(int i,ValueNode::Handle x);
225 LinkableValueNode* create_new()const;
227 virtual void get_times_vfunc(Node::time_set &set) const;
230 /*! \note The construction parameter (\a id) is the type that the list
231 ** contains, rather than the type that it will yield
232 ** (which is ValueBase::TYPE_LIST)
234 static Handle create(ValueBase::Type id=ValueBase::TYPE_NIL);
235 using synfig::LinkableValueNode::get_link_vfunc;
236 using synfig::LinkableValueNode::set_link_vfunc;
237 static bool check_type(ValueBase::Type type);
238 static ValueNode_DynamicList* create_from(const ValueBase &x=ValueBase::TYPE_GRADIENT);
239 }; // END of class ValueNode_DynamicList
241 typedef ValueNode_DynamicList::ListEntry::Activepoint Activepoint;
242 typedef ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
244 }; // END of namespace synfig
246 /* === E N D =============================================================== */