my log
[synfig.git] / synfig-studio / trunk / src / synfigapp / actions / keyframesetdelta.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file keyframeset.cpp
3 **      \brief Template File
4 **
5 **      $Id: keyframesetdelta.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #ifdef USING_PCH
25 #       include "pch.h"
26 #else
27 #ifdef HAVE_CONFIG_H
28 #       include <config.h>
29 #endif
30
31 #include "keyframesetdelta.h"
32 #include <synfigapp/canvasinterface.h>
33 #include <synfig/valuenode_dynamiclist.h>
34 #include <synfig/valuenode_animated.h>
35 #include "activepointsetsmart.h"
36 #include "waypointsetsmart.h"
37
38 #endif
39
40 using namespace std;
41 using namespace etl;
42 using namespace synfig;
43 using namespace synfigapp;
44 using namespace Action;
45
46 /* === M A C R O S ========================================================= */
47
48 ACTION_INIT(Action::KeyframeSetDelta);
49 ACTION_SET_NAME(Action::KeyframeSetDelta,"keyframe_set_delta");
50 ACTION_SET_LOCAL_NAME(Action::KeyframeSetDelta,"Set Keyframe Delta");
51 ACTION_SET_TASK(Action::KeyframeSetDelta,"set");
52 ACTION_SET_CATEGORY(Action::KeyframeSetDelta,Action::CATEGORY_KEYFRAME|Action::CATEGORY_HIDDEN);
53 ACTION_SET_PRIORITY(Action::KeyframeSetDelta,0);
54 ACTION_SET_VERSION(Action::KeyframeSetDelta,"0.0");
55 ACTION_SET_CVS_ID(Action::KeyframeSetDelta,"$Id: keyframesetdelta.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
56
57 /* === G L O B A L S ======================================================= */
58
59 /* === P R O C E D U R E S ================================================= */
60
61 /* === M E T H O D S ======================================================= */
62
63 Action::KeyframeSetDelta::KeyframeSetDelta():
64         delta(0)
65 {
66         keyframe.set_time(Time::end());
67         set_dirty(false);
68 }
69
70 Action::ParamVocab
71 Action::KeyframeSetDelta::get_param_vocab()
72 {
73         ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
74         
75         ret.push_back(ParamDesc("keyframe",Param::TYPE_KEYFRAME)
76                 .set_local_name(_("Keyframe"))
77         );
78         ret.push_back(ParamDesc("delta",Param::TYPE_KEYFRAME)
79                 .set_local_name(_("Delta"))
80         );
81
82         return ret;
83 }
84
85 bool
86 Action::KeyframeSetDelta::is_canidate(const ParamList &x)
87 {
88         return canidate_check(get_param_vocab(),x);
89 }
90
91 bool
92 Action::KeyframeSetDelta::set_param(const synfig::String& name, const Action::Param &param)
93 {
94         if(name=="keyframe" && param.get_type()==Param::TYPE_KEYFRAME)
95         {
96                 keyframe=param.get_keyframe();
97                 return true;
98         }
99         if(name=="delta" && param.get_type()==Param::TYPE_TIME)
100         {
101                 delta=param.get_time();
102                 return true;
103         }
104
105         return Action::CanvasSpecific::set_param(name,param);
106 }
107
108 bool
109 Action::KeyframeSetDelta::is_ready()const
110 {
111         if(keyframe.get_time()==Time::end())
112                 return false;
113         return Action::CanvasSpecific::is_ready();
114 }
115
116 void
117 Action::KeyframeSetDelta::prepare()
118 {
119         clear();
120         value_desc_list.clear();
121         get_canvas_interface()->find_important_value_descs(value_desc_list);
122
123         
124         Time time(get_canvas()->keyframe_list().find(keyframe)->get_time());
125         
126         std::vector<synfigapp::ValueDesc>::iterator iter;
127                 DEBUGPOINT();
128         for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
129         {
130                 ValueDesc& value_desc(*iter);
131                 ValueNode_Animated::Handle value_node(
132                         ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())
133                 );
134                 
135                 if(!value_node)
136                         continue;
137                 
138                 try{
139                         value_node->find(time);
140                         // if we got to this point, then we know that
141                         // a waypoint already exists here and we don't
142                         // need to add a new one.
143                         continue;
144                 }catch(...)
145                 {
146                         // Make sure there is something previous
147                         try{
148                                 value_node->find_prev(time);
149                         }catch(...)
150                         {
151                                 continue;
152                         }
153                 }
154                 Action::Handle action(Action::create("waypoint_set_smart"));
155                 
156                 action->set_param("canvas",get_canvas());
157                 action->set_param("canvas_interface",get_canvas_interface());
158                 action->set_param("value_node",ValueNode::Handle::cast_static(value_node));
159
160                 action->set_param("time",time);
161
162                 assert(action->is_ready());
163                 if(!action->is_ready())
164                         throw Error(Error::TYPE_NOTREADY);
165         
166                 add_action(action);                                             
167         }
168 }
169
170 void
171 Action::KeyframeSetDelta::perform()
172 {
173         if(!delta)
174                 return;
175         Action::Super::perform();
176         
177 //      Time location(keyframe.get_time());
178         Time location(get_canvas()->keyframe_list().find(keyframe)->get_time());        
179         Time delta(delta);
180         
181         get_canvas()->keyframe_list().insert_time(location,delta);
182
183         std::vector<synfigapp::ValueDesc>::iterator iter;
184         for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
185         {
186                 ValueDesc& value_desc(*iter);
187                 if(!value_desc.is_value_node())
188                         continue;
189                 ValueNode_Animated::Handle animated(
190                         ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())
191                 );
192                 if(animated)
193                 {
194                         animated->insert_time(location,delta);
195                         continue;
196                 }
197                 ValueNode_DynamicList::Handle dyn_list(
198                         ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node())
199                 );
200                 if(dyn_list)
201                 {
202                         dyn_list->insert_time(location,delta);
203                         continue;
204                 }
205         }
206
207         // Signal that something has changed
208         if(get_canvas_interface())
209         {
210                 get_canvas_interface()->signal_keyframe_changed()(keyframe);
211         }
212         else synfig::warning("CanvasInterface not set on action");
213 }
214
215 void
216 Action::KeyframeSetDelta::undo()
217 {
218         if(!delta)
219                 return;
220         
221 //      Time location(keyframe.get_time());
222         Time location(get_canvas()->keyframe_list().find(keyframe)->get_time());        
223         Time delta(-delta);
224         
225         get_canvas()->keyframe_list().insert_time(location,delta);
226
227         std::vector<synfigapp::ValueDesc>::iterator iter;
228         for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
229         {
230                 ValueDesc& value_desc(*iter);
231                 if(!value_desc.is_value_node())
232                         continue;
233                 ValueNode_Animated::Handle animated(
234                         ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())
235                 );
236                 if(animated)
237                 {
238                         animated->insert_time(location,delta);
239                         continue;
240                 }
241                 ValueNode_DynamicList::Handle dyn_list(
242                         ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node())
243                 );
244                 if(dyn_list)
245                 {
246                         dyn_list->insert_time(location,delta);
247                         continue;
248                 }
249         }
250
251         Action::Super::undo();
252
253         // Signal that something has changed
254         if(get_canvas_interface())
255         {
256                 get_canvas_interface()->signal_keyframe_changed()(keyframe);
257         }
258         else synfig::warning("CanvasInterface not set on action");
259 }