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