Changed the "tagrelease" and "tagstable" make targets to use subversion. Also increme...
[synfig.git] / synfig-studio / tags / stable / src / sinfgapp / actions / waypointadd.cpp
1 /* === S I N F G =========================================================== */
2 /*!     \file waypointadd.cpp
3 **      \brief Template File
4 **
5 **      $Id: waypointadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #ifdef USING_PCH
25 #       include "pch.h"
26 #else
27 #ifdef HAVE_CONFIG_H
28 #       include <config.h>
29 #endif
30
31 #include "waypointadd.h"
32 #include <sinfgapp/canvasinterface.h>
33 #include <sinfgapp/main.h>
34
35 #endif
36
37 using namespace std;
38 using namespace etl;
39 using namespace sinfg;
40 using namespace sinfgapp;
41 using namespace Action;
42
43 /* === M A C R O S ========================================================= */
44
45 ACTION_INIT(Action::WaypointAdd);
46 ACTION_SET_NAME(Action::WaypointAdd,"waypoint_add");
47 ACTION_SET_LOCAL_NAME(Action::WaypointAdd,"Add Waypoint");
48 ACTION_SET_TASK(Action::WaypointAdd,"add");
49 ACTION_SET_CATEGORY(Action::WaypointAdd,Action::CATEGORY_WAYPOINT);
50 ACTION_SET_PRIORITY(Action::WaypointAdd,0);
51 ACTION_SET_VERSION(Action::WaypointAdd,"0.0");
52 ACTION_SET_CVS_ID(Action::WaypointAdd,"$Id: waypointadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
53
54 /* === G L O B A L S ======================================================= */
55
56 /* === P R O C E D U R E S ================================================= */
57
58 /* === M E T H O D S ======================================================= */
59
60 Action::WaypointAdd::WaypointAdd()
61 {
62         waypoint.set_time(Time::begin()-1);
63         time_set=false;
64         set_dirty(true);
65 }
66
67 Action::ParamVocab
68 Action::WaypointAdd::get_param_vocab()
69 {
70         ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
71         
72         ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
73                 .set_local_name(_("Destination ValueNode (Animated)"))
74         );
75
76         ret.push_back(ParamDesc("waypoint",Param::TYPE_WAYPOINT)
77                 .set_local_name(_("New Waypoint"))
78                 .set_desc(_("Waypoint to be added"))
79                 .set_optional()
80         );
81
82         ret.push_back(ParamDesc("time",Param::TYPE_TIME)
83                 .set_local_name(_("Time"))
84                 .set_desc(_("Time where waypoint is to be added"))
85                 .set_optional()
86         );
87
88         return ret;
89 }
90
91 bool
92 Action::WaypointAdd::is_canidate(const ParamList &x)
93 {
94         if(canidate_check(get_param_vocab(),x))
95         {
96                 if(!ValueNode_Animated::Handle::cast_dynamic(x.find("value_node")->second.get_value_node()))
97                         return false;
98
99                 // We need either a waypoint or a time.
100                 if(x.count("waypoint") || x.count("time"))
101                         return true;
102         }
103         return false;
104 }
105
106 bool
107 Action::WaypointAdd::set_param(const sinfg::String& name, const Action::Param &param)
108 {
109         if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
110         {
111                 value_node=ValueNode_Animated::Handle::cast_dynamic(param.get_value_node());
112                 if(time_set)
113                         calc_waypoint();
114                 
115                 return static_cast<bool>(value_node);
116         }
117         if(name=="waypoint" && param.get_type()==Param::TYPE_WAYPOINT && !time_set)
118         {
119                 waypoint=param.get_waypoint();
120                 
121                 return true;
122         }
123         if(name=="time" && param.get_type()==Param::TYPE_TIME && waypoint.get_time()==Time::begin()-1)
124         {
125                 waypoint.set_time(param.get_time());
126                 time_set=true;
127
128                 if(value_node)
129                         calc_waypoint();
130                 
131                 return true;
132         }
133
134         return Action::CanvasSpecific::set_param(name,param);
135 }
136
137 bool
138 Action::WaypointAdd::is_ready()const
139 {
140         if(!value_node || waypoint.get_time()==(Time::begin()-1))
141                 return false;
142         return Action::CanvasSpecific::is_ready();
143 }
144
145 // This function is called if a time is specified, but not 
146 // a waypoint. In this case, we need to calculate the value
147 // of the waypoint
148 void
149 Action::WaypointAdd::calc_waypoint()
150 {       
151         Time time=waypoint.get_time();
152         Waypoint original(waypoint);
153         waypoint=value_node->new_waypoint_at_time(time);        
154         waypoint.mimic(original);
155         waypoint.set_before(sinfgapp::Main::get_interpolation());
156         waypoint.set_after(sinfgapp::Main::get_interpolation());
157
158 /*
159         ValueNode_Animated::WaypointList &waypoint_list(value_node->waypoint_list());
160         ValueNode_Animated::WaypointList::iterator iter;
161         
162         if(waypoint_list.empty())
163         {
164                 waypoint.set_value((*value_node)(time));
165                 return;
166         }
167
168         ValueNode_Animated::WaypointList::iterator closest=waypoint_list.begin();
169                 
170         for(iter=waypoint_list.begin();iter!=waypoint_list.end();++iter)
171         {
172                 const Real dist(abs(iter->get_time()-time));
173                 if(dist<abs(closest->get_time()-time))
174                         closest=iter;
175         }
176         if(!closest->is_static())
177                 waypoint.set_value_node(closest->get_value_node());
178         else
179                 waypoint.set_value((*value_node)(time));
180         */
181 }
182
183 void
184 Action::WaypointAdd::perform()
185 {               
186         try { value_node->find(waypoint.get_time()); throw Error(_("A Waypoint already exists at this point in time (%s)"),waypoint.get_time().get_string().c_str());}
187         catch(sinfg::Exception::NotFound) { }   
188
189         try { if(value_node->find(waypoint)!=value_node->waypoint_list().end()) throw Error(_("This waypoint is already in the ValueNode"));}
190         catch(sinfg::Exception::NotFound) { }   
191         
192         value_node->add(waypoint);
193         
194         value_node->changed();
195 /*_if(get_canvas_interface())
196         {
197                 get_canvas_interface()->signal_value_node_changed()(value_node);
198         }
199         else sinfg::warning("CanvasInterface not set on action");*/
200 }
201
202 void
203 Action::WaypointAdd::undo()
204 {
205         value_node->erase(waypoint);
206         
207         value_node->changed();
208 /*_if(get_canvas_interface())
209         {
210                 get_canvas_interface()->signal_value_node_changed()(value_node);
211         }
212         else sinfg::warning("CanvasInterface not set on action");*/
213 }