moreupdates
[synfig.git] / synfig-core / trunk / src / synfig / valuenode_composite.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file valuenode_composite.cpp
3 **      \brief Template File
4 **
5 **      $Id: valuenode_composite.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 "valuenode_composite.h"
32 #include "valuenode_const.h"
33 #include <stdexcept>
34 #include "general.h"
35 #include "valuenode_radialcomposite.h"
36 #include "vector.h"
37 #include "color.h"
38 #include "segment.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_Composite::ValueNode_Composite(const ValueBase &value):
57         LinkableValueNode(value.get_type())
58 {
59         switch(get_type())
60         {
61                 case ValueBase::TYPE_VECTOR:
62                         set_link("x",ValueNode_Const::create(value.get(Vector())[0]));
63                         set_link("y",ValueNode_Const::create(value.get(Vector())[1]));
64                         break;
65                 case ValueBase::TYPE_COLOR:
66                         set_link("r",ValueNode_Const::create(value.get(Color()).get_r()));
67                         set_link("g",ValueNode_Const::create(value.get(Color()).get_g()));
68                         set_link("b",ValueNode_Const::create(value.get(Color()).get_b()));
69                         set_link("a",ValueNode_Const::create(value.get(Color()).get_a()));
70                         break;
71                 case ValueBase::TYPE_SEGMENT:
72                         set_link("p1",ValueNode_Const::create(value.get(Segment()).p1));
73                         set_link("t1",ValueNode_Const::create(value.get(Segment()).t1));
74                         set_link("p2",ValueNode_Const::create(value.get(Segment()).p2));
75                         set_link("t2",ValueNode_Const::create(value.get(Segment()).t2));
76                         break;
77                 case ValueBase::TYPE_BLINEPOINT:
78                 {
79                         BLinePoint bline_point(value);
80                         set_link(0,ValueNode_Const::create(bline_point.get_vertex()));
81                         set_link(1,ValueNode_Const::create(bline_point.get_width()));
82                         set_link(2,ValueNode_Const::create(bline_point.get_origin()));
83                         set_link(3,ValueNode_Const::create(bline_point.get_split_tangent_flag()));
84                         set_link(4,ValueNode_RadialComposite::create(bline_point.get_tangent1()));
85                         set_link(5,ValueNode_RadialComposite::create(bline_point.get_tangent2()));
86                         break;
87                 }
88                 default:
89                         assert(0);
90                         throw Exception::BadType(ValueBase::type_name(get_type()));                     
91         }
92 }
93
94 ValueNode_Composite::~ValueNode_Composite()
95 {
96         unlink_all();
97 }
98
99 ValueNode_Composite*
100 ValueNode_Composite::create(const ValueBase &value)
101 {
102         return new ValueNode_Composite(value);
103 }
104         
105 LinkableValueNode*
106 ValueNode_Composite::create_new()const
107 {
108         return new ValueNode_Composite(ValueBase(get_type()));
109 }
110
111 ValueBase
112 synfig::ValueNode_Composite::operator()(Time t)const
113 {
114         switch(get_type())
115         {
116                 case ValueBase::TYPE_VECTOR:
117                 {
118                         Vector vect;
119                         assert(components[0] && components[1]);
120                         vect[0]=(*components[0])(t).get(Vector::value_type());
121                         vect[1]=(*components[1])(t).get(Vector::value_type());
122                         return vect;
123                 }
124                 case ValueBase::TYPE_COLOR:
125                 {
126                         Color color;
127                         assert(components[0] && components[1] && components[2] && components[3]);
128                         color.set_r((*components[0])(t).get(Vector::value_type()));
129                         color.set_g((*components[1])(t).get(Vector::value_type()));
130                         color.set_b((*components[2])(t).get(Vector::value_type()));
131                         color.set_a((*components[3])(t).get(Vector::value_type()));
132                         return color;
133                 }
134                 case ValueBase::TYPE_SEGMENT:
135                 {
136                         Segment seg;
137                         assert(components[0] && components[1] && components[2] && components[3]);
138                         seg.p1=(*components[0])(t).get(Point());
139                         seg.t1=(*components[1])(t).get(Vector());
140                         seg.p2=(*components[2])(t).get(Point());
141                         seg.t2=(*components[3])(t).get(Vector());
142                         return seg;
143                 }
144                 case ValueBase::TYPE_BLINEPOINT:
145                 {
146                         BLinePoint ret;
147                         assert(components[0] && components[1] && components[2] && components[3] && components[4] && components[5]);
148                         ret.set_vertex((*components[0])(t).get(Point()));
149                         ret.set_width((*components[1])(t).get(Real()));
150                         ret.set_origin((*components[2])(t).get(Real()));
151                         ret.set_split_tangent_flag((*components[3])(t).get(bool()));
152                         ret.set_tangent1((*components[4])(t).get(Vector()));
153                         if(ret.get_split_tangent_flag())
154                                 ret.set_tangent2((*components[5])(t).get(Vector()));
155                         return ret;
156                 }
157                 default:
158                         synfig::error(string("ValueNode_Composite::operator():")+_("Bad type for composite"));
159                         assert(components[0]);
160                         return (*components[0])(t);
161         }
162 }
163
164 int
165 ValueNode_Composite::link_count()const
166 {
167         switch(get_type())
168         {
169         case ValueBase::TYPE_VECTOR:
170                 return 2;
171         case ValueBase::TYPE_COLOR:
172                 return 4;
173         case ValueBase::TYPE_SEGMENT:
174                 return 4;
175         case ValueBase::TYPE_BLINEPOINT:
176                 return 6;
177         default:
178                 synfig::warning(string("ValueNode_Composite::component_count():")+_("Bad type for composite"));
179                 return 1;
180         }
181 }
182
183 bool
184 ValueNode_Composite::set_link_vfunc(int i,ValueNode::Handle x)
185 {
186         assert(i>=0);
187         assert(i<6);
188         
189         if(PlaceholderValueNode::Handle::cast_dynamic(x))
190         {
191                 components[i]=x;
192                 return true;
193         }
194
195         switch(get_type())
196         {
197                 case ValueBase::TYPE_VECTOR:
198                         assert(i<2);
199                         if(x->get_type()==ValueBase(Real()).get_type() || PlaceholderValueNode::Handle::cast_dynamic(x))
200                         {
201                                 components[i]=x;
202                                 return true;
203                         }
204                         break;
205
206                 case ValueBase::TYPE_COLOR:
207                         assert(i<4);
208                         if(x->get_type()==ValueBase(Real()).get_type() || PlaceholderValueNode::Handle::cast_dynamic(x))
209                         {
210                                 components[i]=x;
211                                 return true;
212                         }
213                         break;
214                         
215                 case ValueBase::TYPE_SEGMENT:
216                         assert(i<4);
217                         if(x->get_type()==ValueBase(Point()).get_type() || PlaceholderValueNode::Handle::cast_dynamic(x))
218                         {
219                                 components[i]=x;
220                                 return true;
221                         }
222                         break;
223
224                 case ValueBase::TYPE_BLINEPOINT:
225                         assert(i<6);
226                         if((i==0 || i==4 || i==5) && x->get_type()==ValueBase(Point()).get_type())
227                         {
228                                 components[i]=x;
229                                 return true;
230                         }
231                         if((i==1 || i==2) && x->get_type()==ValueBase(Real()).get_type())
232                         {
233                                 components[i]=x;
234                                 return true;
235                         }
236                         if(i==3 && x->get_type()==ValueBase(bool()).get_type())
237                         {
238                                 components[i]=x;
239                                 return true;
240                         }
241                         break;
242                         
243                 default:
244                         break;
245         }
246         return false;   
247 }
248
249 ValueNode::LooseHandle
250 ValueNode_Composite::get_link_vfunc(int i)const
251 {
252         assert(i>=0 && i<6);
253         return components[i];
254 }
255
256 String
257 ValueNode_Composite::link_local_name(int i)const
258 {
259         assert(i>=0 && i<6);
260         switch(get_type())
261         {
262                 case ValueBase::TYPE_VECTOR:
263                         return strprintf("%c-Axis",'X'+i);
264
265                 case ValueBase::TYPE_COLOR:
266                         if(i==0)
267                                 return _("Red");
268                         else if(i==1)
269                                 return _("Green");
270                         else if(i==2)
271                                 return _("Blue");
272                         else if(i==3)
273                                 return _("Alpha");
274                         
275                 case ValueBase::TYPE_SEGMENT:
276                         if(i==0)
277                                 return _("Vertex 1");
278                         else if(i==1)
279                                 return _("Tangent 1");
280                         else if(i==2)
281                                 return _("Vertex 2");
282                         else if(i==3)
283                                 return _("Tangent 2");
284
285                 case ValueBase::TYPE_BLINEPOINT:
286                         if(i==0)
287                                 return _("Vertex");
288                         else if(i==1)
289                                 return _("Width");
290                         else if(i==2)
291                                 return _("Origin");
292                         else if(i==3)
293                                 return _("Split Tangents");
294                         else if(i==4)
295                                 return _("Tangent 1");
296                         else if(i==5)
297                                 return _("Tangent 2");
298
299                 default:
300                         break;
301         }
302         return etl::strprintf(_("C%d"),i+1);    
303 }       
304
305
306 String
307 ValueNode_Composite::link_name(int i)const
308 {
309         assert(i>=0 && i<5);
310         return strprintf("c%d",i);
311 }       
312
313 int
314 ValueNode_Composite::get_link_index_from_name(const String &name)const
315 {
316         if(name.empty())
317                 throw Exception::BadLinkName(name);
318
319         if(name[0]=='c')
320                 return name[1]-'0';
321
322         switch(get_type())
323         {
324         case ValueBase::TYPE_COLOR:
325                 if(name[0]=='r')
326                         return 0;
327                 if(name[0]=='g')
328                         return 1;
329                 if(name[0]=='b')
330                         return 2;
331                 if(name[0]=='a')
332                         return 3;
333         case ValueBase::TYPE_SEGMENT:
334                 if(name=="p1")
335                         return 0;
336                 if(name=="t1")
337                         return 1;
338                 if(name=="p2")
339                         return 2;
340                 if(name=="t2")
341                         return 3;
342         case ValueBase::TYPE_VECTOR:
343                 if(name[0]=='x')
344                         return 0;
345                 if(name[0]=='y')
346                         return 1;
347                 if(name[0]=='z')
348                         return 2;
349         case ValueBase::TYPE_BLINEPOINT:
350                 if(name[0]=='p' || name=="v1" || name=="p1")
351                         return 0;
352                 if(name=="w" || name=="width")
353                         return 1;
354                 if(name=="o" || name=="origin")
355                         return 2;
356                 if(name=="split")
357                         return 3;
358                 if(name=="t1")
359                         return 4;
360                 if(name=="t2")
361                         return 5;
362         default:                        
363                 break;
364         }
365
366         throw Exception::BadLinkName(name);
367 }
368
369 String
370 ValueNode_Composite::get_name()const
371 {
372         return "composite";
373 }
374
375 String
376 ValueNode_Composite::get_local_name()const
377 {
378         return _("Composite");
379 }
380
381 bool
382 ValueNode_Composite::check_type(ValueBase::Type type)
383 {
384         return
385                 type==ValueBase::TYPE_SEGMENT ||
386                 type==ValueBase::TYPE_VECTOR ||
387                 type==ValueBase::TYPE_COLOR ||
388                 type==ValueBase::TYPE_BLINEPOINT;
389 }