1 /* === S Y N F I G ========================================================= */
2 /*! \file timepointscopy.cpp
3 ** \brief Copy the Time Points File
4 **
5 ** $Id$
6 **
7 ** \legal
8 ** Copyright (c) 2004 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 <synfig/general.h>
33
34 #include "timepointscopy.h"
35 #include <synfig/layers/layer_pastecanvas.h>
36 #include <synfigapp/canvasinterface.h>
37 #include <synfig/valuenodes/valuenode_dynamiclist.h>
38 #include <synfig/valuenodes/valuenode_animated.h>
39
40 #include "activepointsimpleadd.h"
41 #include "waypointsimpleadd.h"
42 #include <synfigapp/timegather.h>
43
44 #include <typeinfo>
45
46 #include <synfigapp/localization.h>
47
48 #endif
49
50 using namespace std;
51 using namespace etl;
52 using namespace synfig;
53 using namespace synfigapp;
54 using namespace Action;
55
56 /* === M A C R O S ========================================================= */
57
58 ACTION_INIT(Action::TimepointsCopy);
59 ACTION_SET_NAME(Action::TimepointsCopy,"TimepointsCopy");
60 ACTION_SET_LOCAL_NAME(Action::TimepointsCopy,N_("Copy Time Points"));
61 ACTION_SET_TASK(Action::TimepointsCopy,"copy");
62 ACTION_SET_CATEGORY(Action::TimepointsCopy,Action::CATEGORY_WAYPOINT|Action::CATEGORY_ACTIVEPOINT);
63 ACTION_SET_PRIORITY(Action::TimepointsCopy,0);
64 ACTION_SET_VERSION(Action::TimepointsCopy,"0.0");
65 ACTION_SET_CVS_ID(Action::TimepointsCopy,"$Id$");
66
67 /* === G L O B A L S ======================================================= */
68
69 /* === P R O C E D U R E S ================================================= */
70
71 /* === M E T H O D S ======================================================= */
72
TimepointsCopy()73 Action::TimepointsCopy::TimepointsCopy()
74 {
75 timedelta = 0;
76 set_dirty(false);
77 }
78
79 Action::ParamVocab
get_param_vocab()80 Action::TimepointsCopy::get_param_vocab()
81 {
82 ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
83
84 ret.push_back(ParamDesc("addlayer",Param::TYPE_VALUE)
85 .set_local_name(_("New Selected Layer"))
86 .set_desc(_("A layer to add to our selected list"))
87 .set_supports_multiple()
88 .set_optional()
89 );
90
91 ret.push_back(ParamDesc("addcanvas",Param::TYPE_CANVAS)
92 .set_local_name(_("New Selected Canvas"))
93 .set_desc(_("A canvas to add to our selected list"))
94 .set_supports_multiple()
95 .set_optional()
96 );
97
98 ret.push_back(ParamDesc("addvaluedesc",Param::TYPE_VALUEDESC)
99 .set_local_name(_("New Selected ValueBase"))
100 .set_desc(_("A valuenode's description to add to our selected list"))
101 .set_supports_multiple()
102 .set_optional()
103 );
104
105 ret.push_back(ParamDesc("addtime",Param::TYPE_TIME)
106 .set_local_name(_("New Selected Time Point"))
107 .set_desc(_("A time point to add to our selected list"))
108 .set_supports_multiple()
109 );
110
111 ret.push_back(ParamDesc("deltatime",Param::TYPE_TIME)
112 .set_local_name(_("Time adjustment"))
113 .set_desc(_("The amount of time to adjust all the selected points"))
114 );
115
116 return ret;
117 }
118
119 bool
is_candidate(const ParamList & x)120 Action::TimepointsCopy::is_candidate(const ParamList &x)
121 {
122 if(!candidate_check(get_param_vocab(),x))
123 return false;
124
125 if( x.find("addlayer") == x.end() &&
126 x.find("addcanvas") == x.end() &&
127 x.find("addvaluedesc") == x.end())
128 return false;
129 return true;
130 }
131
132 bool
set_param(const synfig::String & name,const Action::Param & param)133 Action::TimepointsCopy::set_param(const synfig::String& name, const Action::Param ¶m)
134 {
135 if(name=="addlayer" && param.get_type()==Param::TYPE_LAYER)
136 {
137 //add a layer to the list
138 sel_layers.push_back(param.get_layer());
139 //synfig::info("action got layer");
140
141 return true;
142 }
143
144 if(name=="addcanvas" && param.get_type()==Param::TYPE_CANVAS)
145 {
146 //add a layer to the list
147 sel_canvases.push_back(param.get_canvas());
148 //synfig::info("action got canvas");
149
150 return true;
151 }
152
153 if(name=="addvaluedesc" && param.get_type()==Param::TYPE_VALUEDESC)
154 {
155 //add a layer to the list
156 sel_values.push_back(param.get_value_desc());
157 //synfig::info("action got valuedesc");
158
159 return true;
160 }
161
162 if(name=="addtime" && param.get_type()==Param::TYPE_TIME)
163 {
164 //add a layer to the list
165 sel_times.insert(param.get_time());
166 //synfig::info("action got time");
167
168 return true;
169 }
170
171 if(name=="deltatime" && param.get_type()==Param::TYPE_TIME)
172 {
173 timedelta = param.get_time();
174 //synfig::info("action got time to move");
175
176 return true;
177 }
178
179 return Action::CanvasSpecific::set_param(name,param);
180 }
181
182 bool
is_ready() const183 Action::TimepointsCopy::is_ready()const
184 {
185 if((sel_layers.empty() && sel_canvases.empty() && sel_values.empty()) || sel_times.empty())
186 return false;
187 return Action::CanvasSpecific::is_ready();
188 }
189
190 void
prepare()191 Action::TimepointsCopy::prepare()
192 {
193 clear();
194
195 //synfig::info("Preparing TimepointsCopy by %f secs",(float)timemove);
196
197 if(sel_times.empty()) return;
198
199 //all our lists should be set correctly...
200
201 //build our sub-action list
202 // and yes we do need to store it temporarily so we don't duplicate
203 // an operation on a specific valuenode, etc....
204 timepoints_ref match;
205
206 Time fps = get_canvas()->rend_desc().get_frame_rate();
207
208 //std::vector<synfig::Layer::Handle>
209 //synfig::info("Layers %d", sel_layers.size());
210 {
211 std::vector<synfig::Layer::Handle>::iterator i = sel_layers.begin(),
212 end = sel_layers.end();
213
214 for(; i != end; ++i)
215 {
216 //synfig::info("Recurse through a layer");
217 recurse_layer(*i,sel_times,match);
218 }
219 }
220
221 //std::vector<synfig::Canvas::Handle> sel_canvases;
222 //synfig::info("Canvases %d", sel_canvases.size());
223 {
224 std::vector<synfig::Canvas::Handle>::iterator i = sel_canvases.begin(),
225 end = sel_canvases.end();
226
227 for(; i != end; ++i)
228 {
229 //synfig::info("Recurse through a canvas");
230 recurse_canvas(*i,sel_times,match);
231 }
232 }
233
234 //std::vector<synfigapp::ValueDesc>
235 //synfig::info("ValueBasedescs %d", sel_values.size());
236 {
237 std::vector<synfigapp::ValueDesc>::iterator i = sel_values.begin(),
238 end = sel_values.end();
239
240 for(; i != end; ++i)
241 {
242 //synfig::info("Recurse through a valuedesc");
243 recurse_valuedesc(*i,sel_times,match);
244 }
245 }
246
247 //synfig::info("built list of waypoints/activepoints to modify");
248 //synfig::info("\t There are %d waypoint sets and %d activepointsets",
249 // match.waypointbiglist.size(), match.actpointbiglist.size());
250 //process them...
251 {
252 //must build from both lists
253 timepoints_ref::waytracker::const_iterator i = match.waypointbiglist.begin(),
254 end = match.waypointbiglist.end();
255 for(; i != end; ++i)
256 {
257 synfig::Time dilated_timedelta(timedelta * i->time_dilation);
258 //iterate through each waypoint for this specific valuenode
259 std::set<synfig::Waypoint>::const_iterator j = i->waypoints.begin(),
260 end = i->waypoints.end();
261 for(; j != end; ++j)
262 {
263 Action::Handle action(WaypointSimpleAdd::create());
264
265 action->set_param("canvas",get_canvas());
266 action->set_param("canvas_interface",get_canvas_interface());
267 action->set_param("value_node",ValueNode::Handle(i->val));
268
269 //synfig::info("add waypoint mod...");
270 //NOTE: We may want to store the old time for undoing the action...
271 Waypoint neww;
272 Waypoint w = *j;
273 w.set_time((w.get_time() + dilated_timedelta).round(fps));
274 w.mimic(neww); //make sure the new waypoint has a new id
275
276 action->set_param("waypoint",w);
277
278 //run the action now that we've added everything
279 assert(action->is_ready());
280 if(!action->is_ready())
281 throw Error(Error::TYPE_NOTREADY);
282
283 add_action_front(action);
284 }
285 }
286 }
287 {
288 //must build from both lists
289 timepoints_ref::acttracker::const_iterator i = match.actpointbiglist.begin(),
290 end = match.actpointbiglist.end();
291 for(; i != end; ++i)
292 {
293 synfig::Time dilated_timedelta(timedelta * i->time_dilation);
294 //iterate through each activepoint for this specific valuenode
295 std::set<synfig::Activepoint>::const_iterator j = i->activepoints.begin(),
296 jend = i->activepoints.end();
297 for(; j != jend; ++j)
298 {
299 Action::Handle action(ActivepointSimpleAdd::create());
300
301 action->set_param("canvas",get_canvas());
302 action->set_param("canvas_interface",get_canvas_interface());
303 action->set_param("value_desc",i->val);
304
305 //NOTE: We may want to store the old time for undoing the action...
306 Activepoint newa;
307 Activepoint a = *j;
308 a.set_time((a.get_time() + dilated_timedelta).round(fps));
309 a.mimic(newa); //make sure the new activepoint has a new id
310
311 action->set_param("activepoint",a);
312
313 assert(action->is_ready());
314 if(!action->is_ready())
315 {
316 throw Error(Error::TYPE_NOTREADY);
317 }
318
319 add_action_front(action);
320 }
321 }
322 }
323 }
324
325 void
perform()326 Action::TimepointsCopy::perform()
327 {
328 Action::Super::perform();
329 }
330