Add new valuenode type "Step" to allow values to have a linear stepped value. The...
[synfig.git] / synfig-core / trunk / src / synfig / valuenode_step.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file valuenode_step.cpp
3 **      \brief Implementation of the "Step" valuenode conversion.
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2008 Chris Moore
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 "valuenode_step.h"
33 #include "valuenode_const.h"
34 #include "general.h"
35 #include "color.h"
36 #include <ETL/misc>
37
38 #endif
39
40 /* === U S I N G =========================================================== */
41
42 using namespace std;
43 using namespace etl;
44 using namespace synfig;
45
46 /* === M A C R O S ========================================================= */
47
48 /* === G L O B A L S ======================================================= */
49
50 /* === P R O C E D U R E S ================================================= */
51
52 /* === M E T H O D S ======================================================= */
53
54 ValueNode_Step::ValueNode_Step(const ValueBase &value):
55         LinkableValueNode(value.get_type())
56 {
57         set_link("width",ValueNode_Const::create(Time(1)));
58         set_link("time",ValueNode_Const::create(Time(0)));
59
60         switch(get_type())
61         {
62         case ValueBase::TYPE_ANGLE:
63                 set_link("height",ValueNode_Const::create(Angle::deg(0)));
64                 set_link("value",ValueNode_Const::create(value.get(Angle())));
65                 break;
66         case ValueBase::TYPE_COLOR:
67                 set_link("height",ValueNode_Const::create(Color(0,0,0,0)));
68                 set_link("value",ValueNode_Const::create(value.get(Color())));
69                 break;
70         case ValueBase::TYPE_INTEGER:
71                 set_link("height",ValueNode_Const::create(int(0)));
72                 set_link("value",ValueNode_Const::create(value.get(int())));
73                 break;
74         case ValueBase::TYPE_REAL:
75                 set_link("height",ValueNode_Const::create(Real(0)));
76                 set_link("value",ValueNode_Const::create(value.get(Real())));
77                 break;
78         case ValueBase::TYPE_TIME:
79                 set_link("height",ValueNode_Const::create(Time(0)));
80                 set_link("value",ValueNode_Const::create(value.get(Time())));
81                 break;
82         case ValueBase::TYPE_VECTOR:
83                 set_link("height",ValueNode_Const::create(Vector(0,0)));
84                 set_link("value",ValueNode_Const::create(value.get(Vector())));
85                 break;
86         default:
87                 throw Exception::BadType(ValueBase::type_local_name(get_type()));
88         }
89
90         DCAST_HACK_ENABLE();
91 }
92
93 LinkableValueNode*
94 ValueNode_Step::create_new()const
95 {
96         return new ValueNode_Step(get_type());
97 }
98
99 ValueNode_Step*
100 ValueNode_Step::create(const ValueBase &x)
101 {
102         return new ValueNode_Step(x);
103 }
104
105 ValueNode_Step::~ValueNode_Step()
106 {
107         unlink_all();
108 }
109
110 ValueBase
111 ValueNode_Step::operator()(Time t)const
112 {
113         int step = floor((t - ((*time_)(t).get(Time()))) /
114                                          ((*width_)(t).get(Time())));
115
116         switch(get_type())
117         {
118         case ValueBase::TYPE_ANGLE:   return (*value_)(t).get( Angle()) + (*height_)(t).get( Angle())*step;
119         case ValueBase::TYPE_COLOR:   return (*value_)(t).get( Color()) + (*height_)(t).get( Color())*step;
120         case ValueBase::TYPE_INTEGER: return (*value_)(t).get(   int()) + (*height_)(t).get(   int())*step;
121         case ValueBase::TYPE_REAL:    return (*value_)(t).get(  Real()) + (*height_)(t).get(  Real())*step;
122         case ValueBase::TYPE_TIME:    return (*value_)(t).get(  Time()) + (*height_)(t).get(  Time())*step;
123         case ValueBase::TYPE_VECTOR:  return (*value_)(t).get(Vector()) + (*height_)(t).get(Vector())*step;
124         default:
125                 assert(0);
126                 return ValueBase();
127         }
128 }
129
130
131 String
132 ValueNode_Step::get_name()const
133 {
134         return "step";
135 }
136
137 String
138 ValueNode_Step::get_local_name()const
139 {
140         return _("Step");
141 }
142
143 bool
144 ValueNode_Step::check_type(ValueBase::Type type)
145 {
146         return
147                 type==ValueBase::TYPE_ANGLE             ||
148                 type==ValueBase::TYPE_COLOR             ||
149                 type==ValueBase::TYPE_INTEGER   ||
150                 type==ValueBase::TYPE_REAL              ||
151                 type==ValueBase::TYPE_TIME              ||
152                 type==ValueBase::TYPE_VECTOR    ;
153 }
154
155 bool
156 ValueNode_Step::set_link_vfunc(int i,ValueNode::Handle value)
157 {
158         assert(i>=0 && i<link_count());
159
160         switch(i)
161         {
162         case 0: CHECK_TYPE_AND_SET_VALUE(width_,  ValueBase::TYPE_TIME);
163         case 1: CHECK_TYPE_AND_SET_VALUE(height_, get_type());
164         case 2: CHECK_TYPE_AND_SET_VALUE(time_,   ValueBase::TYPE_TIME);
165         case 3: CHECK_TYPE_AND_SET_VALUE(value_,  get_type());
166         }
167         return false;
168 }
169
170 ValueNode::LooseHandle
171 ValueNode_Step::get_link_vfunc(int i)const
172 {
173         assert(i>=0 && i<link_count());
174
175         switch(i)
176         {
177         case 0: return width_;
178         case 1: return height_;
179         case 2: return time_;
180         case 3: return value_;
181         default:
182                 return 0;
183         }
184 }
185
186 int
187 ValueNode_Step::link_count()const
188 {
189         return 4;
190 }
191
192 String
193 ValueNode_Step::link_name(int i)const
194 {
195         assert(i>=0 && i<link_count());
196
197         switch(i)
198         {
199         case 0: return "width";
200         case 1: return "height";
201         case 2: return "time";
202         case 3: return "value";
203         default:
204                 return String();
205         }
206 }
207
208 String
209 ValueNode_Step::link_local_name(int i)const
210 {
211         assert(i>=0 && i<link_count());
212
213         switch(i)
214         {
215         case 0: return _("Width");
216         case 1: return _("Height");
217         case 2: return _("Time");
218         case 3: return _("Value");
219         default:
220                 return String();
221         }
222 }
223
224 int
225 ValueNode_Step::get_link_index_from_name(const String &name)const
226 {
227         if(name=="width")  return 0;
228         if(name=="height") return 1;
229         if(name=="time")   return 2;
230         if(name=="value")  return 3;
231
232         throw Exception::BadLinkName(name);
233 }