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