1 /* === S Y N F I G ========================================================= */ 2 /*! \file valuenode_dynamiclist.h 3 ** \brief Header file for implementation of the "Dynamic List" valuenode conversion. 4 ** 5 ** $Id$ 6 ** 7 ** \legal 8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley 9 ** Copyright (c) 2011 Carlos López 10 ** 11 ** This package is free software; you can redistribute it and/or 12 ** modify it under the terms of the GNU General Public License as 13 ** published by the Free Software Foundation; either version 2 of 14 ** the License, or (at your option) any later version. 15 ** 16 ** This package is distributed in the hope that it will be useful, 17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 ** General Public License for more details. 20 ** \endlegal 21 */ 22 /* ========================================================================= */ 23 24 /* === S T A R T =========================================================== */ 25 26 #ifndef __SYNFIG_VALUENODE_DYNAMICLIST_H 27 #define __SYNFIG_VALUENODE_DYNAMICLIST_H 28 29 /* === H E A D E R S ======================================================= */ 30 31 #include <vector> 32 #include <list> 33 34 #include <synfig/valuenode.h> 35 #include <synfig/time.h> 36 #include <synfig/uniqueid.h> 37 #include <synfig/activepoint.h> 38 39 /* === M A C R O S ========================================================= */ 40 41 /* === C L A S S E S & S T R U C T S ======================================= */ 42 43 namespace synfig { 44 class ValueNode_BLine; 45 class Canvas; 46 47 /*! \class ValueNode_DynamicList 48 ** \brief Animated List ValueNode 49 ** 50 ** This ValueNode was originally set up to have a list 51 ** of ValueNodes and their associated "on" and "off" points. 52 ** ie: Any time that was directly after an "on" point, 53 ** the item would be "on", and any time that was directly 54 ** after an "off" point would be "off". This is pretty intuitive. 55 ** However, it does have its problems. 56 ** 57 ** The problems arise when we introduce the concept of a 58 ** Keyframe. Keyframes can be manipulated via the Synfig 59 ** Application Library. They allow the user to quickly 60 ** and "automagically" rearrange an animation by moving 61 ** the associated keyframes. With the old way that the 62 ** "on" and "off" points were handled, this task became 63 ** overly complicated. 64 ** 65 ** What is required is a "symmetric" system of describing 66 ** "on" and "off" points. Instead of the point representing 67 ** the state of the item after that point in time, we have 68 ** the point represent <i>only that frame</i>. The state 69 ** of the item is calculated by looking at the points 70 ** around it: If either (or both) points are "on", then the 71 ** current state is "on". Otherwise, the point is "off" 72 ** 73 ** This may be a bit confusing at first, but it is required 74 ** if we want the keyframe mechanism to "just work". 75 */ 76 class ValueNode_DynamicList : public LinkableValueNode 77 { 78 public: 79 80 /*! \class ListEntry 81 ** \brief Contains a potential list item, and associated timing information 82 ** 83 ** This structure contains a RHandle to a ValueNode, 84 ** as well as the associated on/off timing information 85 ** which determines when this item is included in the list. 86 ** 87 ** The timing information is stored in the member <tt>timing_info</tt>. 88 */ 89 struct ListEntry : public UniqueID 90 { 91 friend class ValueNode_DynamicList; 92 friend class ValueNode_BLine; 93 friend class ValueNode_WPList; 94 friend class ValueNode_DIList; 95 public: 96 typedef synfig::Activepoint Activepoint; 97 98 typedef std::list<Activepoint> ActivepointList; 99 100 typedef std::pair<ActivepointList::iterator,bool> findresult; 101 typedef std::pair<ActivepointList::const_iterator,bool> const_findresult; 102 103 104 private: 105 mutable Node::time_set times; 106 public: 107 ValueNode::RHandle value_node; 108 109 ActivepointList timing_info; 110 111 private: 112 int index; 113 etl::loose_handle<ValueNode> parent_; set_parent_value_nodeListEntry114 void set_parent_value_node(const etl::loose_handle<ValueNode> &x) { parent_=x; } 115 116 public: 117 get_indexListEntry118 int get_index()const { return index; } 119 120 121 bool status_at_time(const Time &x)const; 122 123 float amount_at_time(const Time &x, bool *rising=0)const; 124 125 ActivepointList::iterator add(Time time, bool status, int priority=0); 126 ActivepointList::iterator add(const Activepoint &x); 127 128 findresult find_uid(const UniqueID& x); 129 const_findresult find_uid(const UniqueID& x)const; 130 131 findresult find_time(const Time& x); 132 const_findresult find_time(const Time& x)const; 133 134 ActivepointList::iterator find(const UniqueID& x); 135 ActivepointList::const_iterator find(const UniqueID& x)const; 136 ActivepointList::iterator find(const Time& x); 137 ActivepointList::const_iterator find(const Time& x)const; 138 ActivepointList::iterator find_prev(const Time& x); 139 ActivepointList::const_iterator find_prev(const Time& x)const; 140 ActivepointList::iterator find_next(const Time& x); 141 ActivepointList::const_iterator find_next(const Time& x)const; 142 143 Activepoint new_activepoint_at_time(const Time& x)const; 144 addListEntry145 ActivepointList::iterator add(Time time) 146 { return add(time, status_at_time(time)); } 147 148 void erase(const UniqueID& x); 149 150 int find(const Time& begin,const Time& end,std::vector<Activepoint*>& list); 151 152 const synfig::Node::time_set &get_times() const; 153 get_parent_value_nodeListEntry154 const etl::loose_handle<ValueNode> &get_parent_value_node()const { return parent_; } 155 156 ListEntry(); 157 ListEntry(const ValueNode::Handle &value_node); 158 ListEntry(const ValueNode::Handle &value_node,Time begin, Time end); 159 }; // END of struct ValueNode_DynamicList::ListEntry 160 161 typedef etl::handle<ValueNode_DynamicList> Handle; 162 typedef etl::handle<const ValueNode_DynamicList> ConstHandle; 163 164 protected: 165 ValueNode_DynamicList(Type &container_type=type_nil, etl::loose_handle<Canvas> canvas = 0); 166 ValueNode_DynamicList(Type &container_type, Type &type, etl::loose_handle<Canvas> canvas = 0); 167 168 Type *container_type; 169 170 bool loop_; 171 172 173 public: 174 std::vector<ListEntry> list; 175 176 public: 177 178 void add(const ValueNode::Handle &value_node, int index=-1); 179 void add(const ListEntry &value_node, int index=-1); 180 void erase(const ValueNode::Handle &value_node); 181 void reindex(); 182 183 int find_next_valid_entry(int x, Time t)const; 184 int find_prev_valid_entry(int x, Time t)const; 185 186 virtual ValueNode::LooseHandle get_link_vfunc(int i)const; 187 188 virtual int link_count()const; 189 190 virtual String link_name(int i)const; 191 192 virtual ValueBase operator()(Time t)const; 193 194 virtual ~ValueNode_DynamicList(); 195 196 virtual String link_local_name(int i)const; 197 virtual int get_link_index_from_name(const String &name)const; 198 199 virtual String get_name()const; 200 virtual String get_local_name()const; 201 get_loop()202 bool get_loop()const { return loop_; } set_loop(bool x)203 void set_loop(bool x) { loop_=x; } 204 205 void set_member_canvas(etl::loose_handle<Canvas>); 206 207 Type& get_contained_type()const; 208 209 210 // TODO: better type-checking 211 template <typename iterator> static Handle create_from_list(iterator begin,iterator end)212 create_from_list(iterator begin, iterator end) 213 { 214 Handle ret = create_on_canvas((*begin)->get_type()); 215 for(;begin!=end;++begin) 216 ret->add(ListEntry(*begin)); 217 return ret; 218 } 219 220 void insert_time(const Time& location, const Time& delta); 221 //void manipulate_time(const Time& old_begin,const Time& old_end,const Time& new_begin,const Time& new_end); 222 223 virtual ValueNode::Handle clone(etl::loose_handle<Canvas> canvas, const GUID& deriv_guid=GUID())const; 224 225 virtual ListEntry create_list_entry(int index, Time time=0, Real origin=0.5); 226 227 protected: 228 229 virtual bool set_link_vfunc(int i,ValueNode::Handle x); 230 LinkableValueNode* create_new()const; 231 232 virtual void get_times_vfunc(Node::time_set &set) const; 233 234 public: 235 /*! \note The construction parameter (\a id) is the type that the list 236 ** contains, rather than the type that it will yield 237 ** (which is ValueBase::TYPE_LIST) 238 */ 239 static Handle create_on_canvas(Type &type=type_nil, etl::loose_handle<Canvas> canvas = 0); 240 using synfig::LinkableValueNode::get_link_vfunc; 241 using synfig::LinkableValueNode::set_link_vfunc; 242 static bool check_type(Type &type); 243 static ValueNode_DynamicList* create(const ValueBase &x=type_gradient); 244 virtual Vocab get_children_vocab_vfunc()const; 245 }; // END of class ValueNode_DynamicList 246 247 typedef ValueNode_DynamicList::ListEntry::Activepoint Activepoint; 248 typedef ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList; 249 250 }; // END of namespace synfig 251 252 /* === E N D =============================================================== */ 253 254 #endif 255