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