Fix 1501383: "del key deletes object instead of character". Changed the LayerRemove...
[synfig.git] / synfig-studio / trunk / 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         Time delta(delta);
182
183         get_canvas()->keyframe_list().insert_time(location,delta);
184
185         std::vector<synfigapp::ValueDesc>::iterator iter;
186         for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
187         {
188                 ValueDesc& value_desc(*iter);
189                 if(!value_desc.is_value_node())
190                         continue;
191                 ValueNode_Animated::Handle animated(
192                         ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())
193                 );
194                 if(animated)
195                 {
196                         animated->insert_time(location,delta);
197                         continue;
198                 }
199                 ValueNode_DynamicList::Handle dyn_list(
200                         ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node())
201                 );
202                 if(dyn_list)
203                 {
204                         dyn_list->insert_time(location,delta);
205                         continue;
206                 }
207         }
208
209         // Signal that something has changed
210         if(get_canvas_interface())
211         {
212                 get_canvas_interface()->signal_keyframe_changed()(keyframe);
213         }
214         else synfig::warning("CanvasInterface not set on action");
215 }
216
217 void
218 Action::KeyframeSetDelta::undo()
219 {
220         if(!delta)
221                 return;
222
223 //      Time location(keyframe.get_time());
224         Time location(get_canvas()->keyframe_list().find(keyframe)->get_time());
225         Time delta(-delta);
226
227         get_canvas()->keyframe_list().insert_time(location,delta);
228
229         std::vector<synfigapp::ValueDesc>::iterator iter;
230         for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
231         {
232                 ValueDesc& value_desc(*iter);
233                 if(!value_desc.is_value_node())
234                         continue;
235                 ValueNode_Animated::Handle animated(
236                         ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())
237                 );
238                 if(animated)
239                 {
240                         animated->insert_time(location,delta);
241                         continue;
242                 }
243                 ValueNode_DynamicList::Handle dyn_list(
244                         ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node())
245                 );
246                 if(dyn_list)
247                 {
248                         dyn_list->insert_time(location,delta);
249                         continue;
250                 }
251         }
252
253         Action::Super::undo();
254
255         // Signal that something has changed
256         if(get_canvas_interface())
257         {
258                 get_canvas_interface()->signal_keyframe_changed()(keyframe);
259         }
260         else synfig::warning("CanvasInterface not set on action");
261 }