more updates
[synfig.git] / synfig-core / trunk / src / synfig / valuenode_stripes.cpp
1 /* === S I N F G =========================================================== */
2 /*!     \file valuenode_subtract.cpp
3 **      \brief Template File
4 **
5 **      $Id: valuenode_stripes.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_stripes.h"
33 #include "valuenode_const.h"
34 #include <stdexcept>
35 #include "color.h"
36 #include "gradient.h"
37
38 #endif
39
40 /* === U S I N G =========================================================== */
41
42 using namespace std;
43 using namespace etl;
44 using namespace sinfg;
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 sinfg::ValueNode_Stripes::ValueNode_Stripes():LinkableValueNode(sinfg::ValueBase::TYPE_GRADIENT)
55 {
56         set_link("color1",ValueNode_Const::create(Color::alpha()));
57         set_link("color2",ValueNode_Const::create(Color::black()));
58         set_link("stripes",stripes_=ValueNode_Const::create(int(5)));
59         set_link("width",ValueNode_Const::create(0.5));
60 }
61
62 LinkableValueNode*
63 ValueNode_Stripes::create_new()const
64 {
65         return new ValueNode_Stripes();
66 }
67
68 ValueNode_Stripes*
69 ValueNode_Stripes::create(const ValueBase& x)
70 {
71         ValueBase::Type id(x.get_type());
72         
73         if(id!=ValueBase::TYPE_GRADIENT)
74         {
75                 assert(0);
76                 throw runtime_error("sinfg::ValueNode_Stripes:Bad type "+ValueBase::type_name(id));                     
77         }               
78
79         ValueNode_Stripes* value_node=new ValueNode_Stripes();
80
81         assert(value_node->get_type()==id);
82         
83         return value_node;
84 }
85
86 sinfg::ValueNode_Stripes::~ValueNode_Stripes()
87 {
88         unlink_all();
89 }
90
91 bool
92 sinfg::ValueNode_Stripes::set_color1(ValueNode::Handle a)
93 {
94         if(a->get_type()!=ValueBase::TYPE_COLOR)
95                 return false;
96
97         color1_=a;
98
99         return true;
100 }
101
102 bool
103 sinfg::ValueNode_Stripes::set_color2(ValueNode::Handle a)
104 {
105         if(a->get_type()!=ValueBase::TYPE_COLOR)
106                 return false;
107
108         color2_=a;
109
110         return true;
111 }
112
113 bool
114 sinfg::ValueNode_Stripes::set_width(ValueNode::Handle x)
115 {
116         if(x->get_type()!=ValueBase::TYPE_REAL)
117                 return false;
118
119         width_=x;
120
121         return true;
122 }
123
124 bool
125 sinfg::ValueNode_Stripes::set_stripes(ValueNode::Handle b)
126 {
127         if(b->get_type()!=ValueBase::TYPE_INTEGER)
128                 return false;
129         stripes_=b;
130         return true;
131 }
132
133 sinfg::ValueBase
134 sinfg::ValueNode_Stripes::operator()(Time t)const
135 {
136         const int total((*stripes_)(t).get(int()));             
137         int i;
138         Gradient ret;
139
140         if(total<=0)
141                 return ret;
142
143         const Color color1((*color1_)(t).get(Color()));
144         const Color color2((*color2_)(t).get(Color()));
145         const float width(max(0.0,min(1.0,(*width_)(t).get(Real()))));
146         
147         const float stripe_width_a(width/total);
148         const float stripe_width_b((1.0-width)/total);
149         
150         for(i=0;i<total;i++)
151         {
152                 float pos(float(i)/total+stripe_width_b/2);
153                 ret.push_back(Gradient::CPoint(pos,color1));
154                 ret.push_back(Gradient::CPoint(pos,color2));
155                 pos+=stripe_width_a;
156                 ret.push_back(Gradient::CPoint(pos,color2));
157                 ret.push_back(Gradient::CPoint(pos,color1));
158         }
159         return ret;
160 }
161
162 bool
163 ValueNode_Stripes::set_link_vfunc(int i,ValueNode::Handle x)
164 {
165         assert(i>=0 && i<link_count());
166         switch(i)
167         {
168                 case 0:
169                         if(set_color1(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
170                         else { return false; }
171                 case 1:
172                         if(set_color2(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
173                         else { return false; }
174                 case 2:
175                         if(set_stripes(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
176                         else { return false; }
177                 case 3:
178                         if(set_width(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
179                         else { return false; }
180         }
181
182         return false;
183 }
184
185 ValueNode::LooseHandle
186 ValueNode_Stripes::get_link_vfunc(int i)const
187 {
188         assert(i>=0 && i<link_count());
189         switch(i)
190         {
191                 case 0:
192                         return color1_;
193                 case 1:
194                         return color2_;
195                 case 2:
196                         return stripes_;
197                 case 3:
198                         return width_;
199         }
200         return 0;
201 }
202
203 int
204 ValueNode_Stripes::link_count()const
205 {
206         return 4;
207 }
208
209 String
210 ValueNode_Stripes::link_local_name(int i)const
211 {
212         assert(i>=0 && i<link_count());
213         switch(i)
214         {
215                 case 0:
216                         return _("Color 1");
217                 case 1:
218                         return _("Color 2");
219                 case 2:
220                         return _("Stripe Count");
221                 case 3:
222                         return _("Width");
223         }
224         return String();
225 }       
226
227 String
228 ValueNode_Stripes::link_name(int i)const
229 {
230         assert(i>=0 && i<link_count());
231         switch(i)
232         {
233                 case 0:
234                         return "color1";
235                 case 1:
236                         return "color2";
237                 case 2:
238                         return "stripes";
239                 case 3:
240                         return "width";
241         }
242         return String();
243 }       
244
245 int
246 ValueNode_Stripes::get_link_index_from_name(const String &name)const
247 {
248         if(name=="color1")
249                 return 0;
250         if(name=="color2")
251                 return 1;
252         if(name=="stripes")
253                 return 2;
254         if(name=="width")
255                 return 3;
256         throw Exception::BadLinkName(name);
257 }
258
259 String
260 ValueNode_Stripes::get_name()const
261 {
262         return "stripes";
263 }
264
265 String
266 ValueNode_Stripes::get_local_name()const
267 {
268         return _("Stripes");
269 }
270
271 bool
272 ValueNode_Stripes::check_type(ValueBase::Type type)
273 {
274         return type==ValueBase::TYPE_GRADIENT;
275 }