Change the Step valuenode so it can produce any stepped shape, rather than just linea...
[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("offset",ValueNode_Const::create(Time(0)));
59
60         switch(get_type())
61         {
62         case ValueBase::TYPE_ANGLE:
63                 set_link("link",ValueNode_Const::create(value.get(Angle())));
64                 break;
65         case ValueBase::TYPE_COLOR:
66                 set_link("link",ValueNode_Const::create(value.get(Color())));
67                 break;
68         case ValueBase::TYPE_INTEGER:
69                 set_link("link",ValueNode_Const::create(value.get(int())));
70                 break;
71         case ValueBase::TYPE_REAL:
72                 set_link("link",ValueNode_Const::create(value.get(Real())));
73                 break;
74         case ValueBase::TYPE_TIME:
75                 set_link("link",ValueNode_Const::create(value.get(Time())));
76                 break;
77         case ValueBase::TYPE_VECTOR:
78                 set_link("link",ValueNode_Const::create(value.get(Vector())));
79                 break;
80         default:
81                 throw Exception::BadType(ValueBase::type_local_name(get_type()));
82         }
83
84         DCAST_HACK_ENABLE();
85 }
86
87 LinkableValueNode*
88 ValueNode_Step::create_new()const
89 {
90         return new ValueNode_Step(get_type());
91 }
92
93 ValueNode_Step*
94 ValueNode_Step::create(const ValueBase &x)
95 {
96         return new ValueNode_Step(x);
97 }
98
99 ValueNode_Step::~ValueNode_Step()
100 {
101         unlink_all();
102 }
103
104 ValueBase
105 ValueNode_Step::operator()(Time t)const
106 {
107         Time width ((*width_ )(t).get(Time()));
108         Time offset((*offset_)(t).get(Time()));
109
110         t = floor((t - offset) / width) * width + offset;
111
112         switch(get_type())
113         {
114         case ValueBase::TYPE_ANGLE:   return (*link_)(t).get( Angle());
115         case ValueBase::TYPE_COLOR:   return (*link_)(t).get( Color());
116         case ValueBase::TYPE_INTEGER: return (*link_)(t).get(   int());
117         case ValueBase::TYPE_REAL:    return (*link_)(t).get(  Real());
118         case ValueBase::TYPE_TIME:    return (*link_)(t).get(  Time());
119         case ValueBase::TYPE_VECTOR:  return (*link_)(t).get(Vector());
120         default:
121                 assert(0);
122                 return ValueBase();
123         }
124 }
125
126
127 String
128 ValueNode_Step::get_name()const
129 {
130         return "step";
131 }
132
133 String
134 ValueNode_Step::get_local_name()const
135 {
136         return _("Step");
137 }
138
139 bool
140 ValueNode_Step::check_type(ValueBase::Type type)
141 {
142         return
143                 type==ValueBase::TYPE_ANGLE             ||
144                 type==ValueBase::TYPE_COLOR             ||
145                 type==ValueBase::TYPE_INTEGER   ||
146                 type==ValueBase::TYPE_REAL              ||
147                 type==ValueBase::TYPE_TIME              ||
148                 type==ValueBase::TYPE_VECTOR    ;
149 }
150
151 bool
152 ValueNode_Step::set_link_vfunc(int i,ValueNode::Handle value)
153 {
154         assert(i>=0 && i<link_count());
155
156         switch(i)
157         {
158         case 0: CHECK_TYPE_AND_SET_VALUE(link_,   get_type());
159         case 1: CHECK_TYPE_AND_SET_VALUE(width_,  ValueBase::TYPE_TIME);
160         case 2: CHECK_TYPE_AND_SET_VALUE(offset_, ValueBase::TYPE_TIME);
161         }
162         return false;
163 }
164
165 ValueNode::LooseHandle
166 ValueNode_Step::get_link_vfunc(int i)const
167 {
168         assert(i>=0 && i<link_count());
169
170         switch(i)
171         {
172         case 0: return link_;
173         case 1: return width_;
174         case 2: return offset_;
175         default:
176                 return 0;
177         }
178 }
179
180 int
181 ValueNode_Step::link_count()const
182 {
183         return 3;
184 }
185
186 String
187 ValueNode_Step::link_name(int i)const
188 {
189         assert(i>=0 && i<link_count());
190
191         switch(i)
192         {
193         case 0: return "link";
194         case 1: return "width";
195         case 2: return "offset";
196         default:
197                 return String();
198         }
199 }
200
201 String
202 ValueNode_Step::link_local_name(int i)const
203 {
204         assert(i>=0 && i<link_count());
205
206         switch(i)
207         {
208         case 0: return _("Link");
209         case 1: return _("Width");
210         case 2: return _("Offset");
211         default:
212                 return String();
213         }
214 }
215
216 int
217 ValueNode_Step::get_link_index_from_name(const String &name)const
218 {
219         if(name=="link")  return 0;
220         if(name=="width")  return 1;
221         if(name=="offset")  return 2;
222
223         throw Exception::BadLinkName(name);
224 }