Removed a bunch more DEBUGPOINT()s.
[synfig.git] / synfig-studio / trunk / src / synfigapp / actions / valuedescset.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file valuedescset.cpp
3 **      \brief Template File
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **      Copyright (c) 2007 Chris Moore
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 /* === H E A D E R S ======================================================= */
25
26 #ifdef USING_PCH
27 #       include "pch.h"
28 #else
29 #ifdef HAVE_CONFIG_H
30 #       include <config.h>
31 #endif
32
33 #include "layerparamset.h"
34 #include "valuenodeconstset.h"
35 #include "valuedescconnect.h"
36 #include "waypointsetsmart.h"
37
38 #include "valuedescset.h"
39 #include <synfigapp/canvasinterface.h>
40 #include <synfig/valuenode_composite.h>
41 #include <synfig/valuenode_radialcomposite.h>
42 #include <synfig/valuenode_reference.h>
43 #include <synfigapp/main.h>
44
45 #include <synfigapp/general.h>
46
47 #endif
48
49 using namespace std;
50 using namespace etl;
51 using namespace synfig;
52 using namespace synfigapp;
53 using namespace Action;
54
55 /* === M A C R O S ========================================================= */
56
57 ACTION_INIT_NO_GET_LOCAL_NAME(Action::ValueDescSet);
58 ACTION_SET_NAME(Action::ValueDescSet,"value_desc_set");
59 ACTION_SET_LOCAL_NAME(Action::ValueDescSet,N_("Set ValueDesc"));
60 ACTION_SET_TASK(Action::ValueDescSet,"set");
61 ACTION_SET_CATEGORY(Action::ValueDescSet,Action::CATEGORY_VALUEDESC);
62 ACTION_SET_PRIORITY(Action::ValueDescSet,0);
63 ACTION_SET_VERSION(Action::ValueDescSet,"0.0");
64 ACTION_SET_CVS_ID(Action::ValueDescSet,"$Id$");
65
66 /* === G L O B A L S ======================================================= */
67
68 /* === P R O C E D U R E S ================================================= */
69
70 /* === M E T H O D S ======================================================= */
71
72 Action::ValueDescSet::ValueDescSet():
73         time(0)
74 {
75 }
76
77 synfig::String
78 Action::ValueDescSet::get_local_name()const
79 {
80         String name("ValueDesc");
81
82         if(!value_desc)
83         {
84         }
85         else if(value_desc.parent_is_layer_param())
86                 name = strprintf(_("'%s' -> %s"),
87                                                  value_desc.get_layer()->get_non_empty_description().c_str(),
88                                                  value_desc.get_param_name().c_str());
89         else if(value_desc.parent_is_value_node())
90         {
91                 synfig::LinkableValueNode::Handle value_node(synfig::LinkableValueNode::Handle::cast_reinterpret(value_desc.get_parent_value_node()));
92                 synfig::Node* node;
93                 for(node=value_node.get();!node->parent_set.empty() && !dynamic_cast<Layer*>(node);node=*node->parent_set.begin());
94                 Layer::Handle parent_layer(dynamic_cast<Layer*>(node));
95                 if(parent_layer)
96                         name = strprintf(_("'%s' => %s"),
97                                                          parent_layer->get_non_empty_description().c_str(),
98                                                          value_node->link_local_name(value_desc.get_index()).c_str());
99                 else
100                         name = value_node->link_local_name(value_desc.get_index());
101         }
102
103         return strprintf(_("Set %s"), name.c_str());
104 }
105
106 Action::ParamVocab
107 Action::ValueDescSet::get_param_vocab()
108 {
109         ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
110
111         ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
112                 .set_local_name(_("ValueDesc"))
113         );
114
115         ret.push_back(ParamDesc("new_value",Param::TYPE_VALUE)
116                 .set_local_name(_("ValueBase"))
117         );
118
119         ret.push_back(ParamDesc("time",Param::TYPE_TIME)
120                 .set_local_name(_("Time"))
121                 .set_optional()
122         );
123
124         return ret;
125 }
126
127 bool
128 Action::ValueDescSet::is_candidate(const ParamList &x)
129 {
130         return candidate_check(get_param_vocab(),x);
131 }
132
133 bool
134 Action::ValueDescSet::set_param(const synfig::String& name, const Action::Param &param)
135 {
136         if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
137         {
138                 value_desc=param.get_value_desc();
139
140                 return true;
141         }
142
143         if(name=="new_value" && param.get_type()==Param::TYPE_VALUE)
144         {
145                 value=param.get_value();
146
147                 return true;
148         }
149
150         if(name=="time" && param.get_type()==Param::TYPE_TIME)
151         {
152                 time=param.get_time();
153
154                 return true;
155         }
156
157         return Action::CanvasSpecific::set_param(name,param);
158 }
159
160 bool
161 Action::ValueDescSet::is_ready()const
162 {
163         if(!value_desc || !value.is_valid())
164                 return false;
165         return Action::CanvasSpecific::is_ready();
166 }
167
168 void
169 Action::ValueDescSet::prepare()
170 {
171         clear();
172
173         // If our tangents are merged, and
174         // our first tangent is being manipulated,
175         // then we also need to adjust the other
176         // tangent.
177         if(     value_desc.parent_is_value_node() &&
178                 value_desc.get_parent_value_node()->get_type()==ValueBase::TYPE_BLINEPOINT &&
179                 (value_desc.get_index()==4 || value_desc.get_index()==5) &&
180                 (*value_desc.get_parent_value_node())(time).get(BLinePoint()).get_split_tangent_flag()==false)
181         {
182                 printf("a tangent got changed - #%d\n", value_desc.get_index()-3);
183
184                 {
185                         ValueNode_Composite::Handle parent_value_node;
186                         parent_value_node=parent_value_node.cast_dynamic(value_desc.get_parent_value_node());
187                         assert(parent_value_node);
188
189                         Vector t1((*parent_value_node->get_link("t1"))(time));
190                         Vector t2((*parent_value_node->get_link("t2"))(time));
191                         printf("current values are: t1(%.2f, %2.f)  t2(%.2f, %.2f)\n", t1[0], t1[1], t2[0], t2[1]);
192                 }
193
194                 if (value_desc.get_index()==4) {
195                         printf("copying change to tangent 2\n");
196                         ValueNode_Composite::Handle parent_value_node;
197                         parent_value_node=parent_value_node.cast_dynamic(value_desc.get_parent_value_node());
198
199                         assert(parent_value_node);
200
201                         Action::Handle action(Action::create("value_desc_set"));
202
203                         if(!action)
204                                 throw Error(_("Unable to find action value_desc_set (bug)"));
205
206                         action->set_param("canvas",get_canvas());
207                         action->set_param("canvas_interface",get_canvas_interface());
208                         action->set_param("time",time);
209                         action->set_param("new_value",value);
210                         action->set_param("value_desc",ValueDesc(parent_value_node,5));
211
212                         if(!action->is_ready())
213                                 throw Error(Error::TYPE_NOTREADY);
214
215                         add_action(action);
216                 }
217         }
218
219         // If we are a reference value node, then
220         // we need to distribute the changes to the
221         // referenced value node
222         if(value_desc.is_value_node() && ValueNode_Reference::Handle::cast_dynamic(value_desc.get_value_node()))
223         {
224                 ValueDesc reference_value_desc(ValueNode_Reference::Handle::cast_dynamic(value_desc.get_value_node()),0);
225
226                 Action::Handle action(Action::create("value_desc_set"));
227
228                 if(!action)
229                         throw Error(_("Unable to find action value_desc_set (bug)"));
230
231                 action->set_param("canvas",get_canvas());
232                 action->set_param("canvas_interface",get_canvas_interface());
233                 action->set_param("time",time);
234                 action->set_param("new_value",value);
235                 action->set_param("value_desc",reference_value_desc);
236
237                 if(!action->is_ready())
238                         throw Error(Error::TYPE_NOTREADY);
239
240                 add_action(action);
241
242                 return;
243         }
244
245         // If we are a composite value node, then
246         // we need to distribute the changes to the
247         // individual parts
248         if(value_desc.is_value_node() && ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()))
249         {
250                 ValueBase components[6];
251                 int n_components(0);
252                 switch(value.get_type())
253                 {
254                 case ValueBase::TYPE_VECTOR:
255                         components[0]=value.get(Vector())[0];
256                         components[1]=value.get(Vector())[1];
257                         n_components=2;
258                         break;
259                 case ValueBase::TYPE_COLOR:
260                         components[0]=value.get(Color()).get_r();
261                         components[1]=value.get(Color()).get_g();
262                         components[2]=value.get(Color()).get_b();
263                         components[3]=value.get(Color()).get_a();
264                         n_components=4;
265                         break;
266                 case ValueBase::TYPE_SEGMENT:
267                         components[0]=value.get(Segment()).p1;
268                         components[1]=value.get(Segment()).t1;
269                         components[2]=value.get(Segment()).p2;
270                         components[3]=value.get(Segment()).t2;
271                         n_components=4;
272                         break;
273                 case ValueBase::TYPE_BLINEPOINT:
274                 {
275                         BLinePoint bline_point(value);
276                         components[0]=bline_point.get_vertex();
277                         components[1]=bline_point.get_width();
278                         components[2]=bline_point.get_origin();
279                         components[3]=bline_point.get_split_tangent_flag();
280                         components[4]=bline_point.get_tangent1();
281                         components[5]=bline_point.get_tangent2();
282                         n_components=6;
283                         break;
284                 }
285                 default:
286                         throw Error(_("Bad type for composite (%s)"),ValueBase::type_local_name(value.get_type()).c_str());
287                         break;
288                 }
289
290                 for(int i=0;i<n_components;i++)
291                 {
292                         ValueDesc component_value_desc(ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()),i);
293
294                         Action::Handle action(Action::create("value_desc_set"));
295
296                         if(!action)
297                                 throw Error(_("Unable to find action value_desc_set (bug)"));
298
299                         action->set_param("canvas",get_canvas());
300                         action->set_param("canvas_interface",get_canvas_interface());
301                         action->set_param("time",time);
302                         action->set_param("new_value",components[i]);
303                         action->set_param("value_desc",component_value_desc);
304
305                         if(!action->is_ready())
306                                 throw Error(Error::TYPE_NOTREADY);
307
308                         add_action(action);
309                 }
310
311                 return;
312         }
313
314
315         // If we are a RADIAL composite value node, then
316         // we need to distribute the changes to the
317         // individual parts
318         if(value_desc.is_value_node() && ValueNode_RadialComposite::Handle::cast_dynamic(value_desc.get_value_node()))
319         {
320                 ValueBase components[6];
321                 int n_components(0);
322                 switch(value.get_type())
323                 {
324                 case ValueBase::TYPE_VECTOR:
325                 {
326                         Angle old_angle = (*(ValueNode_RadialComposite::Handle::cast_dynamic(
327                                                                          value_desc.get_value_node())->get_link_vfunc(1)))(time).get(Angle());
328                         Vector vect(value.get(Vector()));
329                         components[0]=vect.mag();
330                         Angle change = Angle(Angle::tan(vect[1],vect[0])) - old_angle;
331                         while (change < Angle::deg(-180)) change += Angle::deg(360);
332                         while (change > Angle::deg(180)) change -= Angle::deg(360);
333                         components[1]=old_angle + change;
334                         n_components=2;
335                 }
336                         break;
337                 case ValueBase::TYPE_COLOR:
338                         components[0]=value.get(Color()).get_y();
339                         components[1]=value.get(Color()).get_s();
340                         components[2]=value.get(Color()).get_hue();
341                         components[3]=value.get(Color()).get_a();
342                         n_components=4;
343                         break;
344                 default:
345                         throw Error(_("Bad type for radial composite (%s)"),ValueBase::type_local_name(value.get_type()).c_str());
346                         break;
347                 }
348                 for(int i=0;i<n_components;i++)
349                 {
350                         ValueDesc component_value_desc(ValueNode_RadialComposite::Handle::cast_dynamic(value_desc.get_value_node()),i);
351
352                         Action::Handle action(Action::create("value_desc_set"));
353
354                         if(!action)
355                                 throw Error(_("Unable to find action value_desc_set (bug)"));
356
357                         action->set_param("canvas",get_canvas());
358                         action->set_param("canvas_interface",get_canvas_interface());
359                         action->set_param("time",time);
360                         action->set_param("new_value",components[i]);
361                         action->set_param("value_desc",component_value_desc);
362
363                         if(!action->is_ready())
364                                 throw Error(Error::TYPE_NOTREADY);
365
366                         add_action(action);
367                 }
368
369                 return;
370         }
371
372         // If we are merging the tangents of a BLinePoint,
373         // we must also set the second tangent for things
374         // to interpolate properly
375         if (value_desc.parent_is_value_node() &&
376             value_desc.get_parent_value_node()->get_type()==ValueBase::TYPE_BLINEPOINT &&
377             value_desc.get_index()==3)
378         {
379                 ValueNode_Composite::Handle parent_value_node;
380                 parent_value_node=parent_value_node.cast_dynamic(value_desc.get_parent_value_node());
381
382                 assert(parent_value_node);
383
384                 // are we splitting or merging the tangents?
385             if (value.get(bool()))
386             {
387                         // we are splitting tangents
388
389                         Action::Handle action(Action::create("value_desc_set"));
390
391                         if(!action)
392                                 throw Error(_("Unable to find action value_desc_set (bug)"));
393
394                         action->set_param("canvas",get_canvas());
395                         action->set_param("canvas_interface",get_canvas_interface());
396                         action->set_param("time",time);
397                         action->set_param("new_value",(*parent_value_node->get_link(4))(time));
398                         action->set_param("value_desc",ValueDesc(parent_value_node,5));
399
400                         if(!action->is_ready())
401                                 throw Error(Error::TYPE_NOTREADY);
402
403                         add_action(action);
404             }
405             else
406             {
407                         // we are merging tangents
408
409                         // the merged tangent should be the average of the 2 tangents we're merging
410                         ValueBase average(((Vector)((*parent_value_node->get_link("t1"))(time)) +
411                                                            (Vector)((*parent_value_node->get_link("t2"))(time))) / 2);
412
413                         {
414                                 Action::Handle action(Action::create("value_desc_set"));
415
416                                 if(!action)
417                                         throw Error(_("Unable to find action value_desc_set (bug)"));
418
419                                 action->set_param("canvas",get_canvas());
420                                 action->set_param("canvas_interface",get_canvas_interface());
421                                 action->set_param("time",time);
422                                 action->set_param("new_value",average);
423                                 action->set_param("value_desc",ValueDesc(parent_value_node,4));
424
425                                 if(!action->is_ready())
426                                         throw Error(Error::TYPE_NOTREADY);
427
428                                 add_action(action);
429                         }
430
431                         {
432                                 Action::Handle action(Action::create("value_desc_set"));
433
434                                 if(!action)
435                                         throw Error(_("Unable to find action value_desc_set (bug)"));
436
437                                 action->set_param("canvas",get_canvas());
438                                 action->set_param("canvas_interface",get_canvas_interface());
439                                 action->set_param("time",time);
440                                 action->set_param("new_value",average);
441                                 action->set_param("value_desc",ValueDesc(parent_value_node,5));
442
443                                 if(!action->is_ready())
444                                         throw Error(Error::TYPE_NOTREADY);
445
446                                 add_action(action);
447                         }
448             }
449
450         }
451
452 /*      DEBUGPOINT();
453         if(     value_desc.parent_is_value_node())
454         {
455                 DEBUGPOINT();
456                 if(value_desc.get_parent_value_node()->get_type()==ValueBase::TYPE_BLINEPOINT)
457                 {
458                         DEBUGPOINT();
459                         if(value_desc.get_index()==4)
460                         {
461                                 DEBUGPOINT();
462                                 if((*value_desc.get_parent_value_node())(time).get(BLinePoint()).get_split_tangent_flag()==false)
463                                 {
464                                         DEBUGPOINT();
465                                 }
466                         }
467                 }
468         }
469 */
470
471
472         // If we are in animate editing mode
473         if(get_edit_mode()&MODE_ANIMATE)
474         {
475
476                 ValueNode_Animated::Handle& value_node(value_node_animated);
477
478                 // If this value isn't a ValueNode_Animated, but
479                 // it is somewhat constant, then go ahead and convert
480                 // it to a ValueNode_Animated.
481                 if(!value_desc.is_value_node() || ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
482                 {
483                         ValueBase value;
484                         if(value_desc.is_value_node())
485                                 value=ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())->get_value();
486                         else
487                                 value=value_desc.get_value();
488
489                         if(!value_node)value_node=ValueNode_Animated::create(value,time);
490                         //if(!value_node)value_node=ValueNode_Animated::create(value.get_type());
491
492                         Action::Handle action;
493
494                         if(!value_desc.is_value_node())
495                         {
496                                 action=(ValueDescConnect::create());
497                                 action->set_param("dest",value_desc);
498                                 action->set_param("src",ValueNode::Handle(value_node));
499                         }
500                         else
501                         {
502                                 action=Action::create("value_node_replace");
503                                 action->set_param("dest",value_desc.get_value_node());
504                                 action->set_param("src",ValueNode::Handle(value_node));
505                         }
506
507                         action->set_param("canvas",get_canvas());
508                         action->set_param("canvas_interface",get_canvas_interface());
509
510                         if(!action->is_ready())
511                                 throw Error(Error::TYPE_NOTREADY);
512
513                         add_action_front(action);
514                 }
515                 else
516                 {
517                         value_node=value_node.cast_dynamic(value_desc.get_value_node());
518                 }
519
520                 if(!value_node)
521                         throw Error(_("Direct manipulation of this ValueNode type is not yet supported"));
522
523                 Action::Handle action(WaypointSetSmart::create());
524
525                 //Waypoint waypoint(value,time);
526
527                 Waypoint waypoint(value_node->new_waypoint_at_time(time));
528                 waypoint.set_value(value);
529
530                 waypoint.set_before(synfigapp::Main::get_interpolation());
531                 waypoint.set_after(synfigapp::Main::get_interpolation());
532
533                 action->set_param("canvas",get_canvas());
534                 action->set_param("canvas_interface",get_canvas_interface());
535                 action->set_param("value_node",ValueNode::Handle(value_node));
536                 action->set_param("waypoint",waypoint);
537
538                 if(!action->is_ready())
539                         throw Error(Error::TYPE_NOTREADY);
540
541                 add_action(action);
542
543                 return;
544         }
545         else
546         {
547                 if(value_desc.is_value_node())
548                 {
549                         if(ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
550                         {
551                                 Action::Handle action(ValueNodeConstSet::create());
552
553                                 action->set_param("canvas",get_canvas());
554                                 action->set_param("canvas_interface",get_canvas_interface());
555                                 action->set_param("value_node",value_desc.get_value_node());
556                                 action->set_param("new_value",value);
557
558                                 if(!action->is_ready())
559                                         throw Error(Error::TYPE_NOTREADY);
560
561                                 add_action_front(action);
562                                 return;
563                         }
564                         else
565                         if(ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node()))
566                                 throw Error(_("You must be in Animate-Editing-Mode to directly manipulate this value"));
567                         else
568                                 throw Error(_("Direct manipulation of this ValueNode type is not yet supported"));
569                 }
570                 else
571                 if(value_desc.parent_is_layer_param() && !value_desc.is_value_node())
572                 {
573                         Action::Handle layer_param_set(LayerParamSet::create());
574
575                         layer_param_set->set_param("canvas",get_canvas());
576                         layer_param_set->set_param("canvas_interface",get_canvas_interface());
577                         layer_param_set->set_param("layer",value_desc.get_layer());
578                         layer_param_set->set_param("param",value_desc.get_param_name());
579                         layer_param_set->set_param("new_value",value);
580
581                         if(!layer_param_set->is_ready())
582                                 throw Error(Error::TYPE_NOTREADY);
583
584                         add_action_front(layer_param_set);
585                         return;
586                 }
587
588                 throw Error(_("Unsupported ValueDesc type"));
589         }
590 }