source: synfigstudio/trunk/fuentes/src/synfigapp/actions/blinepointtangentmerge.cpp @ 481

Last change on this file since 481 was 481, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 17.4 KB
Line 
1/* === S Y N F I G ========================================================= */
2/*!     \file blinepointtangentmerge.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, 2008 Chris Moore
10**      Copyright (c) 2009 Nikita Kitaev
11**      Copyright (c) 2012 Carlos López
12**
13**      This package is free software; you can redistribute it and/or
14**      modify it under the terms of the GNU General Public License as
15**      published by the Free Software Foundation; either version 2 of
16**      the License, or (at your option) any later version.
17**
18**      This package is distributed in the hope that it will be useful,
19**      but WITHOUT ANY WARRANTY; without even the implied warranty of
20**      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21**      General Public License for more details.
22**      \endlegal
23*/
24/* ========================================================================= */
25
26/* === H E A D E R S ======================================================= */
27
28#ifdef USING_PCH
29#       include "pch.h"
30#else
31#ifdef HAVE_CONFIG_H
32#       include <config.h>
33#endif
34
35#include "blinepointtangentmerge.h"
36#include "valuedescset.h"
37
38#include "activepointset.h"
39#include "activepointadd.h"
40
41#include "valuedescconnect.h"
42#include <synfigapp/canvasinterface.h>
43
44#include <synfigapp/general.h>
45#include <synfig/valuenodes/valuenode_radialcomposite.h>
46
47#endif
48
49using namespace std;
50using namespace etl;
51using namespace synfig;
52using namespace synfigapp;
53using namespace Action;
54
55/* === M A C R O S ========================================================= */
56
57ACTION_INIT_NO_GET_LOCAL_NAME(Action::BLinePointTangentMerge);
58ACTION_SET_NAME(Action::BLinePointTangentMerge,"BLinePointTangentMerge");
59ACTION_SET_LOCAL_NAME(Action::BLinePointTangentMerge,N_("Merge Tangents"));
60ACTION_SET_TASK(Action::BLinePointTangentMerge,"connect");
61ACTION_SET_CATEGORY(Action::BLinePointTangentMerge,Action::CATEGORY_VALUENODE);
62ACTION_SET_PRIORITY(Action::BLinePointTangentMerge,0);
63ACTION_SET_VERSION(Action::BLinePointTangentMerge,"0.1");
64ACTION_SET_CVS_ID(Action::BLinePointTangentMerge,"$Id$");
65
66ACTION_INIT_NO_GET_LOCAL_NAME(Action::BLinePointTangentMergeRadius);
67ACTION_SET_NAME(Action::BLinePointTangentMergeRadius,"BLinePointTangentMergeRadius");
68ACTION_SET_LOCAL_NAME(Action::BLinePointTangentMergeRadius,N_("Merge Tangents's Radius"));
69ACTION_SET_TASK(Action::BLinePointTangentMergeRadius,"type_vector");
70ACTION_SET_CATEGORY(Action::BLinePointTangentMergeRadius,Action::CATEGORY_VALUENODE);
71ACTION_SET_PRIORITY(Action::BLinePointTangentMergeRadius,0);
72ACTION_SET_VERSION(Action::BLinePointTangentMergeRadius,"0.0");
73ACTION_SET_CVS_ID(Action::BLinePointTangentMergeRadius,"$Id$");
74
75ACTION_INIT_NO_GET_LOCAL_NAME(Action::BLinePointTangentMergeAngle);
76ACTION_SET_NAME(Action::BLinePointTangentMergeAngle,"BLinePointTangentMergeAngle");
77ACTION_SET_LOCAL_NAME(Action::BLinePointTangentMergeAngle,N_("Merge Tangents's Angle"));
78ACTION_SET_TASK(Action::BLinePointTangentMergeAngle,"type_angle");
79ACTION_SET_CATEGORY(Action::BLinePointTangentMergeAngle,Action::CATEGORY_VALUENODE);
80ACTION_SET_PRIORITY(Action::BLinePointTangentMergeAngle,0);
81ACTION_SET_VERSION(Action::BLinePointTangentMergeAngle,"0.0");
82ACTION_SET_CVS_ID(Action::BLinePointTangentMergeAngle,"$Id$");
83
84/* === G L O B A L S ======================================================= */
85
86/* === P R O C E D U R E S ================================================= */
87
88/* === M E T H O D S ======================================================= */
89
90
91//// BLINEPOINT TANGENT MERGE //////////
92Action::BLinePointTangentMerge::BLinePointTangentMerge()
93{
94        time=(Time::begin()-1);
95        set_dirty(true);
96}
97
98synfig::String
99Action::BLinePointTangentMerge::get_local_name()const
100{
101        return strprintf(_("Merge Tangents of '%s'"), ((ValueNode::Handle)(value_node))->get_description().c_str());
102}
103
104Action::ParamVocab
105Action::BLinePointTangentMerge::get_param_vocab()
106{
107        ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
108        ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
109                .set_local_name(_("ValueNode of Spline Point"))
110        );
111        ret.push_back(ParamDesc("time",Param::TYPE_TIME)
112                .set_local_name(_("Time"))
113        );
114        return ret;
115}
116
117bool
118Action::BLinePointTangentMerge::is_candidate(const ParamList &x)
119{
120        if(candidate_check(get_param_vocab(),x))
121        {
122                ValueNode_Composite::Handle value_node;
123                value_node=ValueNode_Composite::Handle::cast_dynamic(x.find("value_node")->second.get_value_node());
124                if(!value_node || value_node->get_type()!=type_bline_point)
125                {
126                        // Before return false, let's check whether the value_node
127                        // is radial composite and vector type
128                        ValueNode_RadialComposite::Handle radial_value_node;
129                        radial_value_node=ValueNode_RadialComposite::Handle::cast_dynamic(x.find("value_node")->second.get_value_node());
130                        if(radial_value_node && radial_value_node->get_type()==type_vector)
131                        // value_node is radial composite and vector (user rigth click on a tangent)
132                        {
133                                ValueNode_Composite::Handle blinepoint=NULL;
134                                std::set<Node*>::iterator iter;
135                                // now check if the parent of radial_value_node is a blinepoint type
136                                for(iter=radial_value_node->parent_set.begin();iter!=radial_value_node->parent_set.end();++iter)
137                                        {
138                                                blinepoint=ValueNode_Composite::Handle::cast_dynamic(*iter);
139                                                if(blinepoint && blinepoint->get_type()==type_bline_point)
140                                                        break;
141                                        }
142                                if(blinepoint)
143                                        value_node=blinepoint;
144                        }
145                }
146                // at this point we should have a value node and it should be blinepoint
147                // if we haven't, then return false
148                if(!value_node || value_node->get_type()!=type_bline_point)
149                        return false;
150                synfig::Time time(x.find("time")->second.get_time());
151                bool split_radius=(*value_node->get_link("split_radius"))(time).get(bool());
152                bool split_angle=(*value_node->get_link("split_angle"))(time).get(bool());
153                if(split_radius==false && split_angle==false)
154                        return false;
155                return true;
156        }
157        return false;
158}
159
160bool
161Action::BLinePointTangentMerge::set_param(const synfig::String& name, const Action::Param &param)
162{
163        if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
164        {
165                value_node=value_node.cast_dynamic(param.get_value_node());
166                if(value_node && value_node->get_type()==type_bline_point)
167                        return true;
168                ValueNode_RadialComposite::Handle radial_value_node;
169                radial_value_node=ValueNode_RadialComposite::Handle::cast_dynamic(param.get_value_node());
170                if(radial_value_node && radial_value_node->get_type()==type_vector)
171                // value_node is radial composite and vector (user rigth click on a tangent)
172                {
173                        ValueNode_Composite::Handle blinepoint;
174                        std::set<Node*>::iterator iter;
175                        // now check if the parent of value_node is a blinepoint type
176                        for(iter=radial_value_node->parent_set.begin();iter!=radial_value_node->parent_set.end();++iter)
177                                {
178                                        blinepoint=ValueNode_Composite::Handle::cast_dynamic(*iter);
179                                        if(blinepoint && blinepoint->get_type()==type_bline_point)
180                                        {
181                                                value_node=blinepoint;
182                                                return true;
183                                        }
184                                }
185                        return false;
186                }
187                return false;
188        }
189        if(name=="time" && param.get_type()==Param::TYPE_TIME)
190        {
191                time=param.get_time();
192                return true;
193        }
194        return Action::CanvasSpecific::set_param(name,param);
195}
196
197bool
198Action::BLinePointTangentMerge::is_ready()const
199{
200        if(!value_node)
201                synfig::error("Missing or bad value_node");
202        if(time==(Time::begin()-1))
203                synfig::error("Missing time");
204        if(!value_node || time==(Time::begin()-1))
205                return false;
206        return Action::CanvasSpecific::is_ready();
207}
208
209void
210Action::BLinePointTangentMerge::prepare()
211{
212        clear();
213        {
214                Action::Handle action;
215                action=Action::create("ValueDescSet");
216                if(!action)
217                        throw Error(_("Couldn't find action \"ValueDescSet\""));
218                action->set_param("canvas",get_canvas());
219                action->set_param("canvas_interface",get_canvas_interface());
220                action->set_param("value_desc",ValueDesc(value_node,value_node->get_link_index_from_name("split_radius")));
221                action->set_param("time",time);
222                action->set_param("new_value",synfig::ValueBase(false));
223                assert(action->is_ready());
224                if(!action->is_ready())
225                        throw Error(Error::TYPE_NOTREADY);
226                add_action(action);
227        }
228        {
229                Action::Handle action;
230                action=Action::create("ValueDescSet");
231                if(!action)
232                        throw Error(_("Couldn't find action \"ValueDescSet\""));
233                action->set_param("canvas",get_canvas());
234                action->set_param("canvas_interface",get_canvas_interface());
235                action->set_param("value_desc",ValueDesc(value_node,value_node->get_link_index_from_name("split_angle")));
236                action->set_param("time",time);
237                action->set_param("new_value",synfig::ValueBase(false));
238                assert(action->is_ready());
239                if(!action->is_ready())
240                        throw Error(Error::TYPE_NOTREADY);
241                add_action(action);
242        }
243}
244
245
246
247////// BLINEPOINT TANGENT MERGE RADIUS   //////
248
249Action::BLinePointTangentMergeRadius::BLinePointTangentMergeRadius()
250{
251        time=(Time::begin()-1);
252        set_dirty(true);
253}
254
255synfig::String
256Action::BLinePointTangentMergeRadius::get_local_name()const
257{
258        return strprintf(_("Merge Tangents's Radius of '%s'"), ((ValueNode::Handle)(value_node))->get_description().c_str());
259}
260
261Action::ParamVocab
262Action::BLinePointTangentMergeRadius::get_param_vocab()
263{
264        ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
265        ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
266                                  .set_local_name(_("ValueNode of Spline Point"))
267                                  );
268        ret.push_back(ParamDesc("time",Param::TYPE_TIME)
269                                  .set_local_name(_("Time"))
270                                  );
271        return ret;
272}
273
274bool
275Action::BLinePointTangentMergeRadius::is_candidate(const ParamList &x)
276{
277        if(candidate_check(get_param_vocab(),x))
278        {
279                ValueNode_Composite::Handle value_node;
280                value_node=ValueNode_Composite::Handle::cast_dynamic(x.find("value_node")->second.get_value_node());
281                if(!value_node || value_node->get_type()!=type_bline_point)
282                {
283                        // Before return false, let's check whether the value_node
284                        // is radial composite and vector type
285                        ValueNode_RadialComposite::Handle radial_value_node;
286                        radial_value_node=ValueNode_RadialComposite::Handle::cast_dynamic(x.find("value_node")->second.get_value_node());
287                        if(radial_value_node && radial_value_node->get_type()==type_vector)
288                                // value_node is radial composite and vector (user rigth click on a tangent)
289                        {
290                                ValueNode_Composite::Handle blinepoint=NULL;
291                                std::set<Node*>::iterator iter;
292                                // now check if the parent of radial_value_node is a blinepoint type
293                                for(iter=radial_value_node->parent_set.begin();iter!=radial_value_node->parent_set.end();++iter)
294                                {
295                                        blinepoint=ValueNode_Composite::Handle::cast_dynamic(*iter);
296                                        if(blinepoint && blinepoint->get_type()==type_bline_point)
297                                                break;
298                                }
299                                if(blinepoint)
300                                        value_node=blinepoint;
301                        }
302                }
303                // at this point we should have a value node and it should be blinepoint
304                // if we haven't, then return false
305                if(!value_node || value_node->get_type()!=type_bline_point)
306                        return false;
307                synfig::Time time(x.find("time")->second.get_time());
308                bool split_radius=(*value_node->get_link("split_radius"))(time).get(bool());
309                if(split_radius==false)
310                        return false;
311                return true;
312        }
313        return false;
314}
315
316bool
317Action::BLinePointTangentMergeRadius::set_param(const synfig::String& name, const Action::Param &param)
318{
319        if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
320        {
321                value_node=value_node.cast_dynamic(param.get_value_node());
322                if(value_node && value_node->get_type()==type_bline_point)
323                        return true;
324                ValueNode_RadialComposite::Handle radial_value_node;
325                radial_value_node=ValueNode_RadialComposite::Handle::cast_dynamic(param.get_value_node());
326                if(radial_value_node && radial_value_node->get_type()==type_vector)
327                        // value_node is radial composite and vector (user rigth click on a tangent)
328                {
329                        ValueNode_Composite::Handle blinepoint;
330                        std::set<Node*>::iterator iter;
331                        // now check if the parent of value_node is a blinepoint type
332                        for(iter=radial_value_node->parent_set.begin();iter!=radial_value_node->parent_set.end();++iter)
333                        {
334                                blinepoint=ValueNode_Composite::Handle::cast_dynamic(*iter);
335                                if(blinepoint && blinepoint->get_type()==type_bline_point)
336                                {
337                                        value_node=blinepoint;
338                                        return true;
339                                }
340                        }
341                        return false;
342                }
343                return false;
344        }
345        if(name=="time" && param.get_type()==Param::TYPE_TIME)
346        {
347                time=param.get_time();
348                return true;
349        }
350        return Action::CanvasSpecific::set_param(name,param);
351}
352
353bool
354Action::BLinePointTangentMergeRadius::is_ready()const
355{
356        if(!value_node)
357                synfig::error("Missing or bad value_node");
358        if(time==(Time::begin()-1))
359                synfig::error("Missing time");
360        if(!value_node || time==(Time::begin()-1))
361                return false;
362        return Action::CanvasSpecific::is_ready();
363}
364
365void
366Action::BLinePointTangentMergeRadius::prepare()
367{
368        clear();
369        {
370                Action::Handle action;
371                action=Action::create("ValueDescSet");
372                if(!action)
373                        throw Error(_("Couldn't find action \"ValueDescSet\""));
374                action->set_param("canvas",get_canvas());
375                action->set_param("canvas_interface",get_canvas_interface());
376                action->set_param("value_desc",ValueDesc(value_node,value_node->get_link_index_from_name("split_radius")));
377                action->set_param("time",time);
378                action->set_param("new_value",synfig::ValueBase(false));
379                assert(action->is_ready());
380                if(!action->is_ready())
381                        throw Error(Error::TYPE_NOTREADY);
382                add_action(action);
383        }
384}
385
386
387////// BLINEPOINT TANGENT MERGE ANGLE   //////
388
389Action::BLinePointTangentMergeAngle::BLinePointTangentMergeAngle()
390{
391        time=(Time::begin()-1);
392        set_dirty(true);
393}
394
395synfig::String
396Action::BLinePointTangentMergeAngle::get_local_name()const
397{
398        return strprintf(_("Merge Tangents's Angle of '%s'"), ((ValueNode::Handle)(value_node))->get_description().c_str());
399}
400
401Action::ParamVocab
402Action::BLinePointTangentMergeAngle::get_param_vocab()
403{
404        ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
405        ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
406                                  .set_local_name(_("ValueNode of Spline Point"))
407                                  );
408        ret.push_back(ParamDesc("time",Param::TYPE_TIME)
409                                  .set_local_name(_("Time"))
410                                  );
411        return ret;
412}
413
414bool
415Action::BLinePointTangentMergeAngle::is_candidate(const ParamList &x)
416{
417        if(candidate_check(get_param_vocab(),x))
418        {
419                ValueNode_Composite::Handle value_node;
420                value_node=ValueNode_Composite::Handle::cast_dynamic(x.find("value_node")->second.get_value_node());
421                if(!value_node || value_node->get_type()!=type_bline_point)
422                {
423                        // Before return false, let's check whether the value_node
424                        // is radial composite and vector type
425                        ValueNode_RadialComposite::Handle radial_value_node;
426                        radial_value_node=ValueNode_RadialComposite::Handle::cast_dynamic(x.find("value_node")->second.get_value_node());
427                        if(radial_value_node && radial_value_node->get_type()==type_vector)
428                                // value_node is radial composite and vector (user rigth click on a tangent)
429                        {
430                                ValueNode_Composite::Handle blinepoint=NULL;
431                                std::set<Node*>::iterator iter;
432                                // now check if the parent of radial_value_node is a blinepoint type
433                                for(iter=radial_value_node->parent_set.begin();iter!=radial_value_node->parent_set.end();++iter)
434                                {
435                                        blinepoint=ValueNode_Composite::Handle::cast_dynamic(*iter);
436                                        if(blinepoint && blinepoint->get_type()==type_bline_point)
437                                                break;
438                                }
439                                if(blinepoint)
440                                        value_node=blinepoint;
441                        }
442                }
443                // at this point we should have a value node and it should be blinepoint
444                // if we haven't, then return false
445                if(!value_node || value_node->get_type()!=type_bline_point)
446                        return false;
447                synfig::Time time(x.find("time")->second.get_time());
448                bool split_angle=(*value_node->get_link("split_angle"))(time).get(bool());
449                if(split_angle==false)
450                        return false;
451                return true;
452        }
453        return false;
454}
455
456bool
457Action::BLinePointTangentMergeAngle::set_param(const synfig::String& name, const Action::Param &param)
458{
459        if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
460        {
461                value_node=value_node.cast_dynamic(param.get_value_node());
462                if(value_node && value_node->get_type()==type_bline_point)
463                        return true;
464                ValueNode_RadialComposite::Handle radial_value_node;
465                radial_value_node=ValueNode_RadialComposite::Handle::cast_dynamic(param.get_value_node());
466                if(radial_value_node && radial_value_node->get_type()==type_vector)
467                        // value_node is radial composite and vector (user rigth click on a tangent)
468                {
469                        ValueNode_Composite::Handle blinepoint;
470                        std::set<Node*>::iterator iter;
471                        // now check if the parent of value_node is a blinepoint type
472                        for(iter=radial_value_node->parent_set.begin();iter!=radial_value_node->parent_set.end();++iter)
473                        {
474                                blinepoint=ValueNode_Composite::Handle::cast_dynamic(*iter);
475                                if(blinepoint && blinepoint->get_type()==type_bline_point)
476                                {
477                                        value_node=blinepoint;
478                                        return true;
479                                }
480                        }
481                        return false;
482                }
483                return false;
484        }
485        if(name=="time" && param.get_type()==Param::TYPE_TIME)
486        {
487                time=param.get_time();
488                return true;
489        }
490        return Action::CanvasSpecific::set_param(name,param);
491}
492
493bool
494Action::BLinePointTangentMergeAngle::is_ready()const
495{
496        if(!value_node)
497                synfig::error("Missing or bad value_node");
498        if(time==(Time::begin()-1))
499                synfig::error("Missing time");
500        if(!value_node || time==(Time::begin()-1))
501                return false;
502        return Action::CanvasSpecific::is_ready();
503}
504
505void
506Action::BLinePointTangentMergeAngle::prepare()
507{
508        clear();
509        {
510                Action::Handle action;
511                action=Action::create("ValueDescSet");
512                if(!action)
513                        throw Error(_("Couldn't find action \"ValueDescSet\""));
514                action->set_param("canvas",get_canvas());
515                action->set_param("canvas_interface",get_canvas_interface());
516                action->set_param("value_desc",ValueDesc(value_node,value_node->get_link_index_from_name("split_angle")));
517                action->set_param("time",time);
518                action->set_param("new_value",synfig::ValueBase(false));
519                assert(action->is_ready());
520                if(!action->is_ready())
521                        throw Error(Error::TYPE_NOTREADY);
522                add_action(action);
523        }
524}
Note: See TracBrowser for help on using the repository browser.