Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_03 / synfig-core / src / synfig / valuenode_subtract.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file valuenode_subtract.cpp
3 **      \brief Template File
4 **
5 **      $Id: valuenode_subtract.cpp,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $
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 "general.h"
33 #include "valuenode_subtract.h"
34 #include "valuenode_const.h"
35 #include <stdexcept>
36 #include "color.h"
37 #include "vector.h"
38 #include "angle.h"
39 #include "real.h"
40
41 #endif
42
43 /* === U S I N G =========================================================== */
44
45 using namespace std;
46 using namespace etl;
47 using namespace synfig;
48
49 /* === M A C R O S ========================================================= */
50
51 /* === G L O B A L S ======================================================= */
52
53 /* === P R O C E D U R E S ================================================= */
54
55 /* === M E T H O D S ======================================================= */
56
57 synfig::ValueNode_Subtract::ValueNode_Subtract():LinkableValueNode(synfig::ValueBase::TYPE_NIL)
58 {
59         set_scalar(1.0);
60 }
61
62 LinkableValueNode*
63 ValueNode_Subtract::create_new()const
64 {
65         return new ValueNode_Subtract();
66 }
67
68 ValueNode_Subtract*
69 ValueNode_Subtract::create(const ValueBase& x)
70 {
71         ValueBase::Type id(x.get_type());
72         
73         ValueNode_Subtract* value_node=new ValueNode_Subtract();
74         switch(id)
75         {
76         case ValueBase::TYPE_NIL:
77                 return value_node;
78         case ValueBase::TYPE_VECTOR:
79         case ValueBase::TYPE_REAL:
80         case ValueBase::TYPE_INTEGER:
81         case ValueBase::TYPE_ANGLE:
82                 value_node->set_link("rhs",ValueNode_Const::create(ValueBase(id)));
83                 value_node->set_link("lhs",ValueNode_Const::create(ValueBase(id)));
84                 assert(value_node->get_rhs()->get_type()==id);
85                 assert(value_node->get_lhs()->get_type()==id);
86                 break;
87         default:
88                 assert(0);
89                 throw runtime_error("synfig::ValueNode_Subtract:Bad type "+ValueBase::type_name(id));                   
90         }
91         assert(value_node->get_type()==id);
92         
93         return value_node;
94 }
95
96 synfig::ValueNode_Subtract::~ValueNode_Subtract()
97 {
98         unlink_all();
99 }
100
101 void
102 ValueNode_Subtract::set_scalar(Real x)
103 {
104         set_link("scalar",ValueNode_Const::create(x));
105 }
106
107 bool
108 synfig::ValueNode_Subtract::set_scalar(ValueNode::Handle x)
109 {
110         if(x->get_type()!=ValueBase::TYPE_REAL&& !PlaceholderValueNode::Handle::cast_dynamic(x))
111                 return false;
112         scalar=x;
113         return true;
114 }
115
116 bool
117 synfig::ValueNode_Subtract::set_lhs(ValueNode::Handle a)
118 {
119         ref_a=a;
120         
121         if(PlaceholderValueNode::Handle::cast_dynamic(a))
122                 return true;
123         
124         if(!ref_a || !ref_b)
125                 set_type(ValueBase::TYPE_NIL);
126         else
127         if(ref_a->get_type()==ValueBase::TYPE_VECTOR && ref_a->get_type()==ValueBase::TYPE_VECTOR)
128                 set_type(ValueBase::TYPE_VECTOR);
129         else
130         if(ref_a->get_type()==ValueBase::TYPE_REAL && ref_a->get_type()==ValueBase::TYPE_REAL)
131                 set_type(ValueBase::TYPE_REAL);
132         else
133         if(ref_a->get_type()==ValueBase::TYPE_INTEGER && ref_a->get_type()==ValueBase::TYPE_INTEGER)
134                 set_type(ValueBase::TYPE_INTEGER);
135         else
136         if(ref_a->get_type()==ValueBase::TYPE_ANGLE && ref_a->get_type()==ValueBase::TYPE_ANGLE)
137                 set_type(ValueBase::TYPE_ANGLE);
138         else
139         if(ref_a->get_type()==ValueBase::TYPE_COLOR && ref_a->get_type()==ValueBase::TYPE_COLOR)
140                 set_type(ValueBase::TYPE_COLOR);
141         else
142         {
143                 synfig::warning(get_id()+":(set_a):"+strprintf(_("Types seem to be off for ValueNodes %s and %s"),ref_a->get_id().c_str(),ref_b->get_id().c_str()));
144                 set_type(ValueBase::TYPE_NIL);
145         }
146
147         return true;
148 }
149
150 bool
151 synfig::ValueNode_Subtract::set_rhs(ValueNode::Handle b)
152 {
153         ref_b=b;
154
155         if(PlaceholderValueNode::Handle::cast_dynamic(b))
156                 return true;
157
158         if(!ref_a || !ref_b)
159                 set_type(ValueBase::TYPE_NIL);
160         else
161         if(ref_a->get_type()==ValueBase::TYPE_VECTOR && ref_a->get_type()==ValueBase::TYPE_VECTOR)
162                 set_type(ValueBase::TYPE_VECTOR);
163         else
164         if(ref_a->get_type()==ValueBase::TYPE_REAL && ref_a->get_type()==ValueBase::TYPE_REAL)
165                 set_type(ValueBase::TYPE_REAL);
166         else
167         if(ref_a->get_type()==ValueBase::TYPE_INTEGER && ref_a->get_type()==ValueBase::TYPE_INTEGER)
168                 set_type(ValueBase::TYPE_INTEGER);
169         else
170         if(ref_a->get_type()==ValueBase::TYPE_ANGLE && ref_a->get_type()==ValueBase::TYPE_ANGLE)
171                 set_type(ValueBase::TYPE_ANGLE);
172         else
173         if(ref_a->get_type()==ValueBase::TYPE_COLOR && ref_a->get_type()==ValueBase::TYPE_COLOR)
174                 set_type(ValueBase::TYPE_COLOR);
175         else
176         {
177                 synfig::warning(get_id()+":(set_b):"+strprintf(_("Types seem to be off for ValueNodes %s and %s"),ref_a->get_id().c_str(),ref_b->get_id().c_str()));
178                 set_type(ValueBase::TYPE_NIL);
179         }
180
181         return true;
182 }
183
184 synfig::ValueBase
185 synfig::ValueNode_Subtract::operator()(Time t)const
186 {
187         if(!ref_a || !ref_b)
188                 throw runtime_error(strprintf("ValueNode_Subtract: %s",_("One or both of my parameters aren't set!")));
189         else
190         if(get_type()==ValueBase::TYPE_VECTOR)
191                 return ((*ref_a)(t).get(Vector())-(*ref_b)(t).get(Vector()))*(*scalar)(t).get(Real());
192         else
193         if(get_type()==ValueBase::TYPE_REAL)
194                 return ((*ref_a)(t).get(Vector::value_type())-(*ref_b)(t).get(Vector::value_type()))*(*scalar)(t).get(Real());
195         else
196         if(get_type()==ValueBase::TYPE_INTEGER)
197                 return ((*ref_a)(t).get(int())-(*ref_b)(t).get(int()))*(*scalar)(t).get(Real());
198         else
199         if(get_type()==ValueBase::TYPE_ANGLE)
200                 return ((*ref_a)(t).get(Angle())-(*ref_b)(t).get(Angle()))*(*scalar)(t).get(Real());
201         else
202         if(get_type()==ValueBase::TYPE_COLOR)
203                 return ((*ref_a)(t).get(Color())-(*ref_b)(t).get(Color()))*(*scalar)(t).get(Real());
204
205         synfig::error(get_id()+':'+strprintf(_("Cannot subtract types of %s and %s"),ValueBase::type_name(ref_a->get_type()).c_str(),ValueBase::type_name(ref_b->get_type()).c_str()));
206         return ValueBase();
207 }
208
209 bool
210 ValueNode_Subtract::set_link_vfunc(int i,ValueNode::Handle x)
211 {
212         assert(i>=0 && i<3);
213         switch(i)
214         {
215                 case 0:
216                         if(set_lhs(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
217                         else { return false; }
218                 case 1:
219                         if(set_rhs(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
220                         else { return false; }
221                 case 2:
222                         scalar=x;
223                         signal_child_changed()(i);signal_value_changed()();
224                         return true;
225         }
226
227         return false;
228 }
229
230 ValueNode::LooseHandle
231 ValueNode_Subtract::get_link_vfunc(int i)const
232 {
233         assert(i>=0 && i<3);
234         switch(i)
235         {
236                 case 0:
237                         return ref_a;
238                 case 1:
239                         return ref_b;
240                 case 2:
241                         return scalar;
242         }
243         return 0;
244 }
245
246 int
247 ValueNode_Subtract::link_count()const
248 {
249         return 3;
250 }
251
252 String
253 ValueNode_Subtract::link_local_name(int i)const
254 {
255         assert(i>=0 && i<3);
256         switch(i)
257         {
258                 case 0:
259                         return _("LHS");
260                 case 1:
261                         return _("RHS");
262                 case 2:
263                         return _("Scalar");
264         }
265         return String();
266 }       
267
268 String
269 ValueNode_Subtract::link_name(int i)const
270 {
271         assert(i>=0 && i<3);
272         switch(i)
273         {
274                 case 0:
275                         return "lhs";
276                 case 1:
277                         return "rhs";
278                 case 2:
279                         return "scalar";
280         }
281         return String();
282 }       
283
284 int
285 ValueNode_Subtract::get_link_index_from_name(const String &name)const
286 {
287         if(name=="lhs")
288                 return 0;
289         if(name=="rhs")
290                 return 1;
291         if(name=="scalar")
292                 return 2;
293         throw Exception::BadLinkName(name);
294 }
295
296 String
297 ValueNode_Subtract::get_name()const
298 {
299         return "subtract";
300 }
301
302 String
303 ValueNode_Subtract::get_local_name()const
304 {
305         return _("Subtract");
306 }
307
308 bool
309 ValueNode_Subtract::check_type(ValueBase::Type type)
310 {
311         return type==ValueBase::TYPE_VECTOR 
312                 || type==ValueBase::TYPE_REAL
313                 || type==ValueBase::TYPE_INTEGER
314                 || type==ValueBase::TYPE_COLOR
315                 || type==ValueBase::TYPE_ANGLE;
316 }