my log
[synfig.git] / synfig-studio / trunk / src / gtkmm / duckmatic.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file duckmatic.cpp
3 **      \brief Template File
4 **
5 **      $Id: duckmatic.cpp,v 1.1.1.1 2005/01/07 03:34:36 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 #include <fstream>
31 #include <iostream>
32 #include <algorithm>
33
34 #include <ETL/hermite>
35
36 #include "duckmatic.h"
37 #include <synfigapp/value_desc.h>
38 #include <synfig/general.h>
39 #include <synfig/paramdesc.h>
40 #include <synfig/valuenode_timedswap.h>
41 #include <synfig/valuenode_animated.h>
42 #include <synfig/valuenode_composite.h>
43 #include <synfig/valuenode_scale.h>
44 #include <synfig/valuenode_bline.h>
45
46 #include <synfig/curve_helper.h>
47
48 #include <sigc++/retype_return.h>
49 #include <sigc++/retype.h>
50 #include <sigc++/hide.h>
51 #include <sigc++/bind.h>
52
53 #include "canvasview.h"
54
55 #include "onemoment.h"
56
57 #endif
58
59 /* === U S I N G =========================================================== */
60
61 using namespace std;
62 using namespace etl;
63 using namespace synfig;
64 using namespace studio;
65
66 /* === M A C R O S ========================================================= */
67
68 /* === G L O B A L S ======================================================= */
69
70 /* === P R O C E D U R E S ================================================= */
71
72 /* === M E T H O D S ======================================================= */
73
74 /* === E N T R Y P O I N T ================================================= */
75
76 Duckmatic::Duckmatic():
77         type_mask(Duck::TYPE_ALL-Duck::TYPE_WIDTH),
78         grid_snap(false),
79         guide_snap(false),
80         grid_size(1.0/4.0,1.0/4.0),
81         show_persistant_strokes(true)
82 {
83         axis_lock=false;
84         drag_offset_=Point(0,0);
85         clear_duck_dragger();
86 }
87
88 Duckmatic::~Duckmatic()
89 {
90         clear_ducks();
91         //synfig::info("Duckmatic::~Duckmatic(): Deleted. Duck Count=%d",Duck::duck_count);
92 }
93
94 void
95 Duckmatic::clear_ducks()
96 {
97         duck_data_share_map.clear();
98         duck_map.clear();
99
100         //duck_list_.clear();
101         bezier_list_.clear();
102         stroke_list_.clear();
103
104         if(show_persistant_strokes)
105                 stroke_list_=persistant_stroke_list_;
106 }
107
108 //! Returns \a true if the given duck is currently selected
109 bool
110 Duckmatic::duck_is_selected(const etl::handle<Duck> &duck)const
111 {
112         return duck && selected_ducks.count(duck->get_guid());
113 }
114
115 void
116 Duckmatic::set_grid_size(const synfig::Vector &s)
117 {
118         if(grid_size!=s)
119         {
120                 grid_size=s;
121                 signal_grid_changed();
122         }
123 }
124
125 void
126 Duckmatic::set_grid_snap(bool x)
127 {
128         if(grid_snap!=x)
129         {
130                 grid_snap=x;
131                 signal_grid_changed();
132         }
133 }
134
135 void
136 Duckmatic::set_guide_snap(bool x)
137 {
138         if(guide_snap!=x)
139         {
140                 guide_snap=x;
141                 signal_grid_changed();
142         }
143 }
144
145
146
147 Duckmatic::GuideList::iterator
148 Duckmatic::find_guide_x(synfig::Point pos, float radius)
149 {
150         GuideList::iterator iter,best(guide_list_x_.end());
151         float dist(radius);
152         for(iter=guide_list_x_.begin();iter!=guide_list_x_.end();++iter)
153         {
154                 float amount(abs(*iter-pos[0]));
155                 if(amount<dist)
156                 {
157                         dist=amount;
158                         best=iter;
159                 }
160         }
161         return best;
162 }
163
164 Duckmatic::GuideList::iterator
165 Duckmatic::find_guide_y(synfig::Point pos, float radius)
166 {
167         GuideList::iterator iter,best(guide_list_y_.end());
168         float dist(radius);
169         for(iter=guide_list_y_.begin();iter!=guide_list_y_.end();++iter)
170         {
171                 float amount(abs(*iter-pos[1]));
172                 if(amount<=dist)
173                 {
174                         dist=amount;
175                         best=iter;
176                 }
177         }
178         return best;
179 }
180
181 void
182 Duckmatic::clear_selected_ducks()
183 {
184         selected_ducks.clear();
185         signal_duck_selection_changed_();
186 }
187
188 etl::handle<Duckmatic::Duck>
189 Duckmatic::get_selected_duck()const
190 {
191         if(selected_ducks.empty() || duck_map.empty())
192                 return 0;
193         return duck_map.find(*selected_ducks.begin())->second;
194 }
195
196 void
197 Duckmatic::refresh_selected_ducks()
198 {
199 /*
200         std::set<etl::handle<Duck> >::iterator iter;
201         std::set<etl::handle<Duck> > new_set;
202         if(duck_list().empty())
203         {
204                 selected_duck_list.clear();
205                 signal_duck_selection_changed_();
206                 return;
207         }
208         
209         for(iter=selected_duck_list.begin();iter!=selected_duck_list.end();++iter)
210         {
211                 etl::handle<Duck> similar(find_similar_duck(*iter));
212                 if(similar)
213                 {
214                         new_set.insert(similar);
215                 }
216         }
217         selected_duck_list=new_set;
218 */
219         GUIDSet old_set(selected_ducks);
220         GUIDSet::const_iterator iter;
221         
222         for(iter=old_set.begin();iter!=old_set.end();++iter)
223         {
224                 if(duck_map.count(*iter)==0)
225                         selected_ducks.erase(*iter);
226         }
227
228         signal_duck_selection_changed_();
229 }
230
231 bool
232 Duckmatic::is_duck_group_selectable(const etl::handle<Duck>& x)const
233 {
234         const Type type(get_type_mask());
235
236         if(( x->get_type() && (!(type & x->get_type())) ) )
237         {
238                 return false;
239         }
240         if(x->get_value_desc().parent_is_layer_param() && type & Duck::TYPE_POSITION)
241         {
242                 Layer::Handle layer(x->get_value_desc().get_layer());
243                 String layer_name(layer->get_name());
244                 if(
245                         layer_name=="outline" ||
246                         layer_name=="region" ||
247                         layer_name=="polygon" ||
248                         layer_name=="curve_gradient"
249                 )
250                         return false;
251                 if(
252                         (layer_name=="PasteCanvas"||
253                         layer_name=="paste_canvas")
254                         && !layer->get_param("children_lock").get(bool())
255                 )
256                         return false;
257         }
258         return true;
259 }
260
261 void
262 Duckmatic::select_all_ducks()
263 {
264         DuckMap::const_iterator iter;   
265         for(iter=duck_map.begin();iter!=duck_map.end();++iter)
266                 if(is_duck_group_selectable(iter->second))
267                         select_duck(iter->second);
268 }
269
270 void
271 Duckmatic::select_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br)
272 {
273         Vector vmin, vmax;
274         vmin[0]=std::min(tl[0],br[0]);
275         vmin[1]=std::min(tl[1],br[1]);
276         vmax[0]=std::max(tl[0],br[0]);
277         vmax[1]=std::max(tl[1],br[1]);
278
279 //      Type type(get_type_mask());
280         
281         DuckMap::const_iterator iter;   
282         for(iter=duck_map.begin();iter!=duck_map.end();++iter)
283         {
284                 Point p(iter->second->get_trans_point());
285                 if(p[0]<=vmax[0] && p[0]>=vmin[0] && p[1]<=vmax[1] && p[1]>=vmin[1])
286                 {
287                         if(is_duck_group_selectable(iter->second))
288                                 select_duck(iter->second);
289                 }
290         }
291 }
292
293 int
294 Duckmatic::count_selected_ducks()const
295 {
296         return selected_ducks.size();
297 }
298
299 void
300 Duckmatic::select_duck(const etl::handle<Duck> &duck)
301 {
302         if(duck)
303         {
304                 selected_ducks.insert(duck->get_guid());
305                 signal_duck_selection_changed_();
306         }
307 }
308
309 DuckList
310 Duckmatic::get_selected_ducks()const
311 {
312         DuckList ret;
313         GUIDSet::const_iterator iter;
314         const Type type(get_type_mask());
315         
316         for(iter=selected_ducks.begin();iter!=selected_ducks.end();++iter)
317         {
318                 const DuckMap::const_iterator d_iter(duck_map.find(*iter));
319                 
320                 if(d_iter==duck_map.end())
321                         continue;
322         
323                 if(( d_iter->second->get_type() && (!(type & d_iter->second->get_type())) ) )
324                         continue;
325
326                 ret.push_back(d_iter->second);
327         }
328         return ret;
329 }
330
331 DuckList
332 Duckmatic::get_duck_list()const
333 {
334         DuckList ret;
335         DuckMap::const_iterator iter;
336         for(iter=duck_map.begin();iter!=duck_map.end();++iter)
337                 ret.push_back(iter->second);
338         return ret;
339 }
340
341 void
342 Duckmatic::unselect_duck(const etl::handle<Duck> &duck)
343 {
344         if(duck && selected_ducks.count(duck->get_guid()))
345         {
346                 selected_ducks.erase(duck->get_guid());
347                 signal_duck_selection_changed_();
348         }
349 }
350
351 void
352 Duckmatic::toggle_select_duck(const etl::handle<Duck> &duck)
353 {
354         if(duck_is_selected(duck))
355                 unselect_duck(duck);
356         else
357                 select_duck(duck);
358 }
359
360
361 void
362 Duckmatic::translate_selected_ducks(const synfig::Vector& vector)
363 {
364         if(duck_dragger_)
365                 duck_dragger_->duck_drag(this,vector);
366 }
367
368 void
369 Duckmatic::start_duck_drag(const synfig::Vector& offset)
370 {
371         if(duck_dragger_)
372                 duck_dragger_->begin_duck_drag(this,offset);
373
374         //drag_offset_=offset;
375         drag_offset_=find_duck(offset)->get_trans_point();
376 }
377
378 bool
379 Duckmatic::end_duck_drag()
380 {
381         if(duck_dragger_)
382                 return duck_dragger_->end_duck_drag(this);
383         return false;
384 }
385
386 Point
387 Duckmatic::snap_point_to_grid(const Point& x, float radius)const
388 {
389         Point ret(x);
390
391         GuideList::const_iterator guide_x,guide_y;
392         bool has_guide_x(false), has_guide_y(false);
393         
394         guide_x=find_guide_x(ret,radius);
395         if(guide_x!=guide_list_x_.end())
396                 has_guide_x=true;
397
398         guide_y=find_guide_y(ret,radius);
399         if(guide_y!=guide_list_y_.end())
400                 has_guide_y=true;
401
402         if(get_grid_snap())
403         {
404                 Point snap(
405                         floor(ret[0]/get_grid_size()[0]+0.5)*get_grid_size()[0],
406                         floor(ret[1]/get_grid_size()[1]+0.5)*get_grid_size()[1]
407                 );
408
409                 if(abs(snap[0]-ret[0])<=radius && (!has_guide_x || abs(snap[0]-ret[0])<=abs(*guide_x-ret[0])))
410                         ret[0]=snap[0],has_guide_x=false;
411                 if(abs(snap[1]-ret[1])<=radius && (!has_guide_y || abs(snap[1]-ret[1])<=abs(*guide_y-ret[1])))
412                         ret[1]=snap[1],has_guide_y=false;
413         }
414
415         if(guide_snap)
416         {
417                 if(has_guide_x)
418                         ret[0]=*guide_x;
419                 if(has_guide_y)
420                         ret[1]=*guide_y;
421         }
422         
423         if(axis_lock)
424         {
425                 ret-=drag_offset_;
426                 if(abs(ret[0])<abs(ret[1]))
427                         ret[0]=0;
428                 else
429                         ret[1]=0;
430                 ret+=drag_offset_;
431         }
432         
433         return ret;
434 }
435
436 void
437 DuckDrag_Translate::begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& offset)
438 {
439         last_translate_=Vector(0,0);
440         {
441                 drag_offset_=duckmatic->find_duck(offset)->get_trans_point();
442
443                 snap=Vector(0,0);
444         }
445         
446         const DuckList selected_ducks(duckmatic->get_selected_ducks());
447         DuckList::const_iterator iter;
448         
449         positions.clear();
450         for(iter=selected_ducks.begin();iter!=selected_ducks.end();++iter)
451         {
452                 Point p((*iter)->get_trans_point());
453                 positions.push_back(p);
454         }
455 }
456
457 bool
458 DuckDrag_Translate::end_duck_drag(Duckmatic* duckmatic)
459 {
460         if(last_translate_.mag()>0.0001)
461         {
462                 duckmatic->signal_edited_selected_ducks();
463                 return true;
464         }
465         else
466         {
467                 duckmatic->signal_user_click_selected_ducks(0);
468                 return false;
469         }
470 }
471
472 void
473 DuckDrag_Translate::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector)
474 {
475         const DuckList selected_ducks(duckmatic->get_selected_ducks());
476         DuckList::const_iterator iter;
477
478         synfig::Vector vect(duckmatic->snap_point_to_grid(vector)-drag_offset_);
479         int i;
480         
481         for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
482         {
483                 if((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION)continue;
484                 (*iter)->set_trans_point(positions[i]+vect);
485         }
486         for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
487         {
488                 if((*iter)->get_type()==Duck::TYPE_VERTEX||(*iter)->get_type()==Duck::TYPE_POSITION)continue;
489                 (*iter)->set_trans_point(positions[i]+vect);
490         }
491         last_translate_=vect;
492 }
493
494
495
496
497
498
499
500
501
502
503 void
504 Duckmatic::signal_edited_selected_ducks()
505 {
506         const DuckList ducks(get_selected_ducks());
507         DuckList::const_iterator iter;
508
509         synfig::GUIDSet old_set(selected_ducks);
510         
511         // If we have more than 20 things to move, then display
512         // something to explain that it may take a moment
513         smart_ptr<OneMoment> wait; if(ducks.size()>20)wait.spawn();
514                 
515         // Go ahead and call everyone's signals
516         for(iter=ducks.begin();iter!=ducks.end();++iter)
517         {
518                 if(!(*iter)->signal_edited()((*iter)->get_point()))
519                 {
520                         selected_ducks=old_set;
521                         throw String("Bad edit");
522                 }
523         }
524         selected_ducks=old_set;
525 }
526
527 void
528 Duckmatic::signal_user_click_selected_ducks(int button)
529 {
530         const DuckList ducks(get_selected_ducks());
531         DuckList::const_iterator iter;
532
533         for(iter=ducks.begin();iter!=ducks.end();++iter)
534         {
535                 (*iter)->signal_user_click(button)();
536         }
537 }
538
539
540
541
542
543 void
544 Duckmatic::add_duck(const etl::handle<Duck> &duck)
545 {
546         //if(!duck_map.count(duck->get_guid()))
547         {
548                 if(duck_data_share_map.count(duck->get_data_guid()))
549                 {
550                         duck->set_shared_point(duck_data_share_map[duck->get_data_guid()]);
551                 }
552                 else
553                 {
554                         etl::smart_ptr<synfig::Point> point(new Point(duck->get_point()));
555                         duck->set_shared_point(point);
556                         duck_data_share_map[duck->get_data_guid()]=point;
557                 }
558                 
559                 duck_map.insert(duck);
560         }
561
562         last_duck_guid=duck->get_guid();
563 }
564
565 void
566 Duckmatic::add_bezier(const etl::handle<Bezier> &bezier)
567 {
568         bezier_list_.push_back(bezier);
569 }
570
571 void
572 Duckmatic::add_stroke(etl::smart_ptr<std::list<synfig::Point> > stroke_point_list, const synfig::Color& color)
573 {
574         assert(stroke_point_list);
575
576         std::list<etl::handle<Stroke> >::iterator iter;
577
578         for(iter=stroke_list_.begin();iter!=stroke_list_.end();++iter)
579         {
580                 if((*iter)->stroke_data==stroke_point_list)
581                         return;
582         }
583
584         etl::handle<Stroke> stroke(new Stroke());
585
586         stroke->stroke_data=stroke_point_list;
587         stroke->color=color;
588
589         stroke_list_.push_back(stroke); 
590 }
591
592 void
593 Duckmatic::add_persistant_stroke(etl::smart_ptr<std::list<synfig::Point> > stroke_point_list, const synfig::Color& color)
594 {
595         add_stroke(stroke_point_list,color);
596         persistant_stroke_list_.push_back(stroke_list_.back());
597 }
598
599 void
600 Duckmatic::clear_persistant_strokes()
601 {
602         persistant_stroke_list_.clear();
603 }
604
605 void
606 Duckmatic::set_show_persistant_strokes(bool x)
607 {
608         if(x!=show_persistant_strokes)
609         {
610                 show_persistant_strokes=x;
611                 if(x)
612                         stroke_list_=persistant_stroke_list_;
613                 else
614                         stroke_list_.clear();
615         }
616 }
617
618 void
619 Duckmatic::erase_duck(const etl::handle<Duck> &duck)
620 {
621         duck_map.erase(duck->get_guid());       
622 }
623
624 etl::handle<Duckmatic::Duck>
625 Duckmatic::find_similar_duck(etl::handle<Duck> duck)
626 {
627         DuckMap::const_iterator iter(duck_map.find(duck->get_guid()));
628         if(iter!=duck_map.end())
629                 return iter->second;
630         return 0;
631                 
632 /*      std::list<handle<Duck> >::reverse_iterator iter;
633
634         for(iter=duck_list_.rbegin();iter!=duck_list_.rend();++iter)
635         {
636                 if(*iter!=duck && **iter==*duck)
637                 {
638                         //synfig::info("Found similar duck! (iter:%08x vs. duck:%08x)",iter->get(), duck.get());
639                         return *iter;
640                 }
641         }
642         return 0;
643 */
644 }
645
646 etl::handle<Duckmatic::Duck>
647 Duckmatic::add_similar_duck(etl::handle<Duck> duck)
648 {
649         etl::handle<Duck> similar(find_similar_duck(duck));
650         if(!similar)
651         {
652                 add_duck(duck);
653                 return duck;
654         }
655         return similar;
656 }
657
658 void
659 Duckmatic::erase_bezier(const etl::handle<Bezier> &bezier)
660 {
661         std::list<handle<Bezier> >::iterator iter;
662
663         for(iter=bezier_list_.begin();iter!=bezier_list_.end();++iter)
664         {
665                 if(*iter==bezier)
666                 {
667                         bezier_list_.erase(iter);
668                         return;
669                 }
670         }
671         synfig::warning("Unable to find bezier to erase!");
672 }
673
674 etl::handle<Duckmatic::Duck>
675 Duckmatic::last_duck()const
676 {
677         DuckMap::const_iterator iter(duck_map.find(last_duck_guid));
678         if(iter!=duck_map.end())
679                 return iter->second;
680         return 0;
681 }
682
683 etl::handle<Duckmatic::Bezier>
684 Duckmatic::last_bezier()const
685 {
686         return bezier_list_.back();
687 }
688
689
690 etl::handle<Duckmatic::Duck>
691 Duckmatic::find_duck(synfig::Point point, synfig::Real radius, Duck::Type type)
692 {
693         if(radius==0)radius=10000000;
694         
695         if(type==Duck::TYPE_DEFAULT)
696                 type=get_type_mask();
697         
698         Real closest(10000000);
699         etl::handle<Duck> ret;
700
701         DuckMap::const_iterator iter;
702
703         for(iter=duck_map.begin();iter!=duck_map.end();++iter)
704         {
705                 const Duck::Handle& duck(iter->second);
706                 
707                 if(!duck->get_editable())
708                         continue;
709                 Real dist((duck->get_trans_point()-point).mag_squared());
710
711                 if(duck->get_type()&Duck::TYPE_VERTEX)
712                         dist*=1.0001;
713
714                 if(dist<=closest && !( duck->get_type() && (!(type & duck->get_type())) ) )
715                 {
716                         {
717                                 closest=dist;
718                                 ret=duck;
719                         }
720                 }
721         }
722
723         if(radius==0 || closest<radius*radius)
724                 return ret;
725
726         return 0;
727 }
728
729 etl::handle<Duckmatic::Bezier>
730 Duckmatic::find_bezier(synfig::Point point, synfig::Real radius,float* location)
731 {
732         return find_bezier(point,radius,radius,location);       
733 }
734
735 etl::handle<Duckmatic::Bezier> 
736 Duckmatic::find_bezier(synfig::Point pos, synfig::Real scale, synfig::Real radius, float* location)
737 {
738         if(radius==0)radius=10000000;
739         Real closest(10000000);
740         etl::handle<Bezier> ret;
741         
742         bezier<Point>   curve;
743         
744         Real    d,step;
745         float   time = 0;
746         float   best_time = 0;
747         
748         for(std::list<handle<Bezier> >::const_iterator iter=bezier_list().begin();iter!=bezier_list().end();++iter)
749         {
750                 curve[0] = (*iter)->p1->get_trans_point();
751                 curve[1] = (*iter)->c1->get_trans_point();
752                 curve[2] = (*iter)->c2->get_trans_point();
753                 curve[3] = (*iter)->p2->get_trans_point();
754                 curve.sync();
755                 
756 #if 0
757                 // I don't know why this doesn't work
758                 time=curve.find_closest(pos,6);
759                 d=((curve(time)-pos).mag_squared());
760
761 #else           
762                 //set the step size based on the size of the picture
763                 d = (curve[1] - curve[0]).mag() + (curve[2]-curve[1]).mag()     + (curve[3]-curve[2]).mag();
764                 
765                 step = d/(2*scale); //want to make the distance between lines happy
766                 
767                 step = max(step,0.01); //100 samples should be plenty
768                 step = min(step,0.1); //10 is minimum           
769                 
770                 d = find_closest(curve,pos,step,&closest,&time);
771 #endif
772
773                 if(d < closest)
774                 {
775                         closest = d;
776                         ret = *iter;
777                         best_time=time;
778                 }               
779         }
780
781         if(closest < radius*radius)
782         {
783                 if(location)
784                         *location = best_time;  // We need to square-root this because we were dealing with squared distances
785                 
786                 return ret;
787         }
788         
789         return 0;       
790 }
791
792
793
794 bool
795 Duckmatic::save_sketch(const synfig::String& filename)const
796 {
797         std::ofstream file(filename.c_str());
798
799         if(!file)return false;
800
801         file<<"SKETCH"<<endl;
802         
803         std::list<etl::handle<Stroke> >::const_iterator iter;
804         
805         for(iter=persistant_stroke_list_.begin();iter!=persistant_stroke_list_.end();++iter)
806         {
807                 file<<"C "
808                         <<(*iter)->color.get_r()<<' '
809                         <<(*iter)->color.get_g()<<' '
810                         <<(*iter)->color.get_b()
811                 <<endl;
812                 std::list<synfig::Point>::const_iterator viter;
813                 for(viter=(*iter)->stroke_data->begin();viter!=(*iter)->stroke_data->end();++viter)
814                 {
815                         file<<"V "
816                                 <<(*viter)[0]<<' '
817                                 <<(*viter)[1]
818                         <<endl;
819                 }
820         }
821         if(!file)return false;
822         sketch_filename_=filename;
823         signal_sketch_saved_();
824         return true;
825 }
826
827 bool
828 Duckmatic::load_sketch(const synfig::String& filename)
829 {
830         std::ifstream file(filename.c_str());
831                         
832         if(!file)
833                 return false;
834
835         std::string line;
836         getline(file,line);
837
838         if(line!="SKETCH")
839         {
840                 synfig::error("Not a sketch");
841                 return false;
842         }
843
844
845         etl::smart_ptr<std::list<synfig::Point> > stroke_data;
846         
847         while(file)
848         {
849                 getline(file,line);
850
851                 if(line.empty())
852                         continue;
853                 
854                 switch(line[0])
855                 {
856                 case 'C':
857                 case 'c':
858                         {
859                                 stroke_data.spawn();
860                                 float r,g,b;
861                                 if(!strscanf(line,"C %f %f %f",&r, &g, &b))
862                                 {
863                                         synfig::warning("Bad color line \"%s\"",line.c_str());
864                                         r=0;g=0;b=0;
865                                 }
866                                 add_persistant_stroke(stroke_data, synfig::Color(r,g,b));
867                         }
868                         break;
869                 case 'V':
870                 case 'v':
871                         if(!stroke_data)
872                         {
873                                 stroke_data.spawn();
874                                 add_persistant_stroke(stroke_data, synfig::Color(0,0,0));
875                         }
876                         float x,y;
877                         if(!strscanf(line,"V %f %f",&x, &y))
878                                 synfig::warning("Bad vertex \"%s\"",line.c_str());
879                         else
880                                 stroke_data->push_back(synfig::Vector(x,y));
881                         break;
882                 default:
883                         synfig::warning("Unexpected sketch token '%c'",line[0]);
884                         break;
885                 }
886         }
887         
888         sketch_filename_=filename;
889         return true;
890 }
891
892
893
894
895
896
897
898
899 Duckmatic::Push::Push(Duckmatic *duckmatic_):
900         duckmatic_(duckmatic_)
901 {
902         duck_map=duckmatic_->duck_map;  
903         bezier_list_=duckmatic_->bezier_list_;  
904         duck_data_share_map=duckmatic_->duck_data_share_map;
905         stroke_list_=duckmatic_->stroke_list_;
906         duck_dragger_=duckmatic_->duck_dragger_;
907         needs_restore=true;
908 }
909
910 Duckmatic::Push::~Push()
911 {
912         if(needs_restore)
913                 restore();
914 }
915
916 void
917 Duckmatic::Push::restore()
918 {
919         duckmatic_->duck_map=duck_map;  
920         duckmatic_->bezier_list_=bezier_list_;  
921         duckmatic_->duck_data_share_map=duck_data_share_map;
922         duckmatic_->stroke_list_=stroke_list_;
923         duckmatic_->duck_dragger_=duck_dragger_;
924         needs_restore=false;
925 }
926
927
928
929
930
931
932
933
934
935 inline String guid_string(const synfigapp::ValueDesc& x)
936 {
937         if(x.parent_is_layer_param())
938                 return strprintf("%s",x.get_layer()->get_guid().get_string().c_str())+x.get_param_name();               
939         //if(x.is_value_node())
940                 return strprintf("%s",x.get_value_node()->get_guid().get_string().c_str());
941 }
942
943 inline GUID calc_duck_guid(const synfigapp::ValueDesc& x,const synfig::TransformStack& transform_stack)
944 {
945         GUID ret(0);
946         
947         if(x.parent_is_layer_param())
948         {
949                 ret=x.get_layer()->get_guid()^GUID::hasher(x.get_param_name());
950         }
951         else
952         {
953                 ret=x.get_value_node()->get_guid();
954         }
955
956         ret^=transform_stack.get_guid();
957         return ret;     
958 }
959
960 /*
961 Duck::Handle
962 Duckmatic::create_duck_from(const synfigapp::ValueDesc& value_desc,etl::handle<CanvasView> canvas_view, const synfig::TransformStack& transform_stack, int modifier, synfig::ParamDesc *param_desc)
963 {
964         GUID duck_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(modifier));
965         etl::handle<Duck> duck=new Duck();
966         
967         return duck;
968 }
969 */
970
971 bool
972 Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<CanvasView> canvas_view, const synfig::TransformStack& transform_stack, synfig::ParamDesc *param_desc, int multiple)
973 {
974         ValueBase::Type type=value_desc.get_value_type();
975 #define REAL_COOKIE             reinterpret_cast<synfig::ParamDesc*>(28)                
976         switch(type)
977         {
978         case ValueBase::TYPE_REAL:
979                 
980                 if(!param_desc || param_desc==REAL_COOKIE || !param_desc->get_origin().empty())
981                 {
982                         etl::handle<Duck> duck=new Duck();
983                         duck->set_transform_stack(transform_stack);
984                         duck->set_radius(true);
985                         duck->set_type(Duck::TYPE_RADIUS);
986
987                         duck->set_point(Point(value_desc.get_value(get_time()).get(Real()),0));
988                         duck->set_name(guid_string(value_desc));
989                         if(value_desc.is_value_node())
990                         {
991                                 // If the ValueNode can be directly manipulated,
992                                 // then set it as so.
993                                 duck->set_editable(synfigapp::is_editable(value_desc.get_value_node()));
994                         }
995                         else
996                         {
997                                 duck->set_editable(true);
998                         }
999                         
1000                         if(param_desc && param_desc!=REAL_COOKIE)
1001                         {
1002                                 if(!param_desc->get_origin().empty())
1003                                 {
1004                                         synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
1005                                         /*
1006                                         duck->set_origin(value_desc_origin.get_value(get_time()).get(synfig::Point()));
1007                                         */
1008                                         add_to_ducks(value_desc_origin,canvas_view, transform_stack);
1009                                         duck->set_origin(last_duck());
1010                                 }
1011                                 duck->set_scalar(param_desc->get_scalar());
1012                         }
1013
1014                         duck->signal_edited().clear();
1015                         duck->signal_edited().connect(
1016                                 sigc::bind(
1017                                         sigc::mem_fun(
1018                                                 *canvas_view,
1019                                                 &studio::CanvasView::on_duck_changed
1020                                         ),
1021                                         value_desc
1022                                 )
1023                         );
1024                         duck->set_value_desc(value_desc);
1025
1026                         duck->signal_user_click(2).connect(
1027                                 sigc::bind(
1028                                         sigc::bind(
1029                                                 sigc::mem_fun(
1030                                                         *canvas_view,
1031                                                         &studio::CanvasView::popup_param_menu
1032                                                 ),
1033                                                 0.0f
1034                                         ),
1035                                         value_desc
1036                                 )       
1037                         );
1038
1039                         duck->set_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(multiple));
1040                         
1041                         add_duck(duck);
1042
1043                         return true;
1044                 }
1045                 break;
1046
1047         case ValueBase::TYPE_ANGLE:
1048                 
1049                 if(!param_desc || param_desc==REAL_COOKIE || !param_desc->get_origin().empty())
1050                 {
1051                         etl::handle<Duck> duck=new Duck();
1052                         duck->set_type(Duck::TYPE_ANGLE);
1053                         duck->set_transform_stack(transform_stack);
1054                         synfig::Angle angle;
1055                         
1056                         angle=value_desc.get_value(get_time()).get(Angle());
1057                         duck->set_point(Point(Angle::cos(angle).get(),Angle::sin(angle).get()));
1058                         duck->set_name(guid_string(value_desc));
1059                         if(value_desc.is_value_node())
1060                         {
1061                                 ValueNode::Handle value_node=value_desc.get_value_node();
1062                                 //duck->set_name(strprintf("%x",value_node.get()));
1063                                 
1064                                 // If the ValueNode can be directly manipulated,
1065                                 // then set it as so.
1066                                 duck->set_editable(synfigapp::is_editable(value_desc.get_value_node()));
1067                         }
1068                         else
1069                         {
1070                                 //angle=(value_desc.get_value().get(Angle()));
1071                                 //duck->set_point(Point(Angle::cos(angle).get(),Angle::sin(angle).get()));
1072                                 //duck->set_name(strprintf("%x",value_desc.get_layer().get())+value_desc.get_param_name());
1073                                 duck->set_editable(true);
1074                         }
1075                         
1076                         if(param_desc && param_desc!=REAL_COOKIE)
1077                         {
1078                                 if(!param_desc->get_origin().empty())
1079                                 {
1080                                         synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
1081                                         /*
1082                                         duck->set_origin(value_desc_origin.get_value(get_time()).get(synfig::Point()));
1083                                         */
1084                                         add_to_ducks(value_desc_origin,canvas_view, transform_stack);
1085                                         duck->set_origin(last_duck());
1086                                 }
1087                                 duck->set_scalar(param_desc->get_scalar());
1088                         }
1089
1090                         duck->signal_edited().clear();
1091                         duck->signal_edited().connect(
1092                                 sigc::bind(
1093                                         sigc::mem_fun(
1094                                                 *canvas_view,
1095                                                 &studio::CanvasView::on_duck_changed
1096                                         ),
1097                                         value_desc
1098                                 )
1099                         );
1100                         duck->set_value_desc(value_desc);
1101
1102                         duck->signal_user_click(2).connect(
1103                                 sigc::bind(
1104                                         sigc::bind(
1105                                                 sigc::mem_fun(
1106                                                         *canvas_view,
1107                                                         &studio::CanvasView::popup_param_menu
1108                                                 ),
1109                                                 0.0f
1110                                         ),
1111                                         value_desc
1112                                 )       
1113                         );
1114                         duck->set_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(multiple));
1115
1116                         add_duck(duck);
1117
1118                         return true;
1119                 }
1120                 break;
1121                 
1122         case ValueBase::TYPE_VECTOR:
1123                 {
1124                         etl::handle<Duck> duck=new Duck();
1125                         duck->set_transform_stack(transform_stack);
1126                         
1127                         duck->set_point(value_desc.get_value(get_time()).get(Point()));
1128                         duck->set_name(guid_string(value_desc));
1129                         if(value_desc.is_value_node())
1130                         {
1131                                 //duck->set_name(strprintf("%x",value_desc.get_value_node().get()));
1132                                 
1133                                 // If the ValueNode can be directly manipulated,
1134                                 // then set it as so.
1135                                 duck->set_editable(synfigapp::is_editable(value_desc.get_value_node()));
1136                         }
1137                         else
1138                         {
1139                                 //duck->set_point(value_desc.get_value().get(Point()));
1140                                 //duck->set_name(strprintf("%x",value_desc.get_layer().get())+value_desc.get_param_name());
1141                                 duck->set_editable(true);
1142                         }
1143                         
1144                         // If we were passed a parameter description
1145                         if(param_desc)
1146                         {
1147                                 if(!param_desc->get_connect().empty())
1148                                 {
1149                                         synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_connect());
1150                                         Duck::Handle connect_duck;
1151                                         if(duck_map.find(calc_duck_guid(value_desc_origin,transform_stack)^GUID::hasher(0))!=duck_map.end())
1152                                         {
1153                                                 connect_duck=duck_map[calc_duck_guid(value_desc_origin,transform_stack)^GUID::hasher(0)];
1154                                         }
1155                                         else
1156                                         {
1157                                                 add_to_ducks(value_desc_origin,canvas_view, transform_stack);
1158                                                 connect_duck=last_duck();
1159                                         }
1160                                         duck->set_connect_duck(connect_duck);
1161                                 }
1162                                 if(!param_desc->get_box().empty())
1163                                 {
1164                                         synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_box());
1165                                         add_to_ducks(value_desc_origin,canvas_view, transform_stack);
1166                                         duck->set_box_duck(last_duck());
1167                                 }
1168                                 
1169                                 // If we have an origin
1170                                 if(!param_desc->get_origin().empty())
1171                                 {
1172                                         synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
1173                                         /*
1174                                         duck->set_origin(value_desc_origin.get_value(get_time()).get(synfig::Point()));
1175                                         */
1176                                         add_to_ducks(value_desc_origin,canvas_view, transform_stack);
1177                                         duck->set_origin(last_duck());
1178                                         duck->set_type(Duck::TYPE_VERTEX);
1179                                 }
1180                                 else
1181                                         duck->set_type(Duck::TYPE_POSITION);
1182                                         
1183                                 duck->set_scalar(param_desc->get_scalar());
1184                         }
1185                         else
1186                                 duck->set_type(Duck::TYPE_POSITION);
1187
1188
1189                         duck->signal_edited().clear();
1190                         duck->signal_edited().connect(
1191                                 sigc::bind(
1192                                         sigc::mem_fun(
1193                                                 *canvas_view,
1194                                                 &studio::CanvasView::on_duck_changed
1195                                         ),
1196                                         value_desc
1197                                 )
1198                         );
1199                         duck->set_value_desc(value_desc);
1200
1201                         duck->signal_user_click(2).connect(
1202                                 sigc::bind(
1203                                         sigc::bind(
1204                                                 sigc::mem_fun(
1205                                                         *canvas_view,
1206                                                         &studio::CanvasView::popup_param_menu
1207                                                 ),
1208                                                 1.0f
1209                                         ),
1210                                         value_desc
1211                                 )
1212                         );
1213                         duck->set_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(multiple));
1214                         add_duck(duck);
1215
1216                         return true;
1217                 }
1218                 break;
1219 /*      case ValueBase::TYPE_SEGMENT:
1220                 {
1221                         etl::handle<Bezier> bezier(new Bezier());
1222                         ValueNode_Composite::Handle value_node;
1223                         
1224                         if(value_desc.is_value_node() &&
1225                                 (value_node=ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()))
1226                         )
1227                         {
1228                                 if(!add_to_ducks(synfigapp::ValueDesc(value_node,0),canvas_view,transform_stack))
1229                                         return false;
1230                                 bezier->p1=last_duck();
1231                                 bezier->p1->set_type(Duck::TYPE_VERTEX);
1232                                 if(!add_to_ducks(synfigapp::ValueDesc(value_node,1),canvas_view,transform_stack))
1233                                         return false;
1234                                 bezier->c1=last_duck();                         
1235                                 bezier->c1->set_type(Duck::TYPE_TANGENT);
1236                                 bezier->c1->set_origin(bezier->p1);
1237                                 bezier->c1->set_scalar(0.33333333333333333);
1238                                 bezier->c1->set_tangent(true);
1239
1240                                 
1241                                 if(!add_to_ducks(synfigapp::ValueDesc(value_node,2),canvas_view,transform_stack))
1242                                         return false;
1243                                 bezier->p2=last_duck();
1244                                 bezier->p2->set_type(Duck::TYPE_VERTEX);
1245                                 if(!add_to_ducks(synfigapp::ValueDesc(value_node,3),canvas_view,transform_stack))
1246                                         return false;
1247                                 bezier->c2=last_duck();                         
1248                                 bezier->c2->set_type(Duck::TYPE_TANGENT);
1249                                 bezier->c2->set_origin(bezier->p2);
1250                                 bezier->c2->set_scalar(-0.33333333333333333);
1251                                 bezier->c2->set_tangent(true);
1252
1253                                 bezier->signal_user_click(2).connect(
1254                                         sigc::bind(
1255                                                 sigc::mem_fun(
1256                                                         *canvas_view,
1257                                                         &studio::CanvasView::popup_param_menu_bezier
1258                                                 ),
1259                                                 value_desc
1260                                         )
1261                                 );
1262                                 
1263                                 add_bezier(bezier);
1264                         }
1265                         else if(value_desc.get_value().is_valid())
1266                         {
1267                                 Segment segment=value_desc.get_value();
1268                                 etl::handle<Duck> duck_p,duck_c;
1269                                 synfig::String name;
1270                                 if(param_desc)
1271                                 {
1272                                         name=param_desc->get_local_name();
1273                                 }
1274                                 else
1275                                 {
1276                                         name=guid_string(value_desc);
1277                                 }
1278
1279                                 duck_p=new class Duck(segment.p1);              
1280                                 duck_p->set_name(name+".P1");                                   
1281                                 duck_p->set_type(Duck::TYPE_VERTEX);
1282                                 add_duck(duck_p);                                               
1283
1284                                 duck_c=new class Duck(segment.t1);              
1285                                 duck_c->set_name(name+".T1");                                   
1286                                 duck_c->set_type(Duck::TYPE_TANGENT);
1287                                 add_duck(duck_c);                                               
1288                                 duck_c->set_origin(duck_p);
1289                                 duck_c->set_scalar(0.33333333333333333);
1290                                 duck_c->set_tangent(true);
1291
1292                                 bezier->p1=duck_p;
1293                                 bezier->c1=duck_c;
1294
1295                                 duck_p=new class Duck(segment.p2);              
1296                                 duck_p->set_name(name+".P2");                                   
1297                                 duck_p->set_type(Duck::TYPE_VERTEX);
1298                                 add_duck(duck_p);                                               
1299
1300                                 duck_c=new class Duck(segment.t2);              
1301                                 duck_c->set_type(Duck::TYPE_TANGENT);
1302                                 duck_c->set_name(name+".T2");                                   
1303                                 add_duck(duck_c);                                               
1304                                 duck_c->set_origin(duck_p);
1305                                 duck_c->set_scalar(-0.33333333333333333);
1306                                 duck_c->set_tangent(true);
1307
1308                                 bezier->p2=duck_p;
1309                                 bezier->c2=duck_c;
1310                                 add_bezier(bezier);
1311                         }
1312                         
1313                         return true;
1314                 }
1315                 break;
1316 */
1317         case ValueBase::TYPE_BLINEPOINT:
1318         {
1319                         
1320                 if(value_desc.is_value_node() &&
1321                         ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node())
1322                 )
1323                 {
1324                         ValueNode_Composite::Handle value_node;
1325                         value_node=ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node());
1326
1327                         
1328                         if(!add_to_ducks(synfigapp::ValueDesc(value_node,0),canvas_view,transform_stack))
1329                                 return false;
1330                         etl::handle<Duck> vertex_duck(last_duck());
1331                         vertex_duck->set_type(Duck::TYPE_VERTEX);
1332                         if(!add_to_ducks(synfigapp::ValueDesc(value_node,4),canvas_view,transform_stack))
1333                                 return false;
1334                         etl::handle<Duck> t1_duck(last_duck());
1335                         
1336                         t1_duck->set_origin(vertex_duck);
1337                         t1_duck->set_scalar(-0.33333333333333333);
1338                         t1_duck->set_tangent(true);
1339                         
1340                         etl::handle<Duck> t2_duck;
1341                         
1342                         // If the tangents are split
1343                         if((*value_node->get_link("split"))(get_time()).get(bool()))
1344                         {
1345                                 if(!add_to_ducks(synfigapp::ValueDesc(value_node,5),canvas_view,transform_stack))
1346                                         return false;
1347                                 t2_duck=last_duck();
1348                                 t2_duck->set_origin(vertex_duck);
1349                                 t2_duck->set_scalar(0.33333333333333333);
1350                                 t2_duck->set_tangent(true);
1351                         }
1352                         else
1353                         {
1354                                 if(!add_to_ducks(synfigapp::ValueDesc(value_node,4),canvas_view,transform_stack))
1355                                         return false;
1356                                 t2_duck=last_duck();
1357                                 t2_duck->set_origin(vertex_duck);
1358                                 t2_duck->set_scalar(0.33333333333333333);
1359                                 t2_duck->set_tangent(true);
1360                         }
1361                         return true;
1362                 }
1363                 
1364         }
1365         break;
1366         case ValueBase::TYPE_LIST:
1367         {
1368                 // Check for BLine
1369                 if(value_desc.is_value_node() &&
1370                         ValueNode_BLine::Handle::cast_dynamic(value_desc.get_value_node())
1371                 )
1372                 {
1373                         ValueNode_BLine::Handle value_node;
1374                         value_node=ValueNode_BLine::Handle::cast_dynamic(value_desc.get_value_node());
1375                         
1376                         int i,first=-1;
1377
1378                         etl::handle<Bezier> bezier;
1379                         etl::handle<Duck> first_duck;
1380                         etl::handle<Duck> duck, tduck;
1381                         
1382                         for(i=0;i<value_node->link_count();i++)
1383                         {
1384                                 float amount(value_node->list[i].amount_at_time(get_time()));
1385                                 if(amount<0.9999f)
1386                                         continue;
1387                                 if(first==-1)first=i;
1388                                         
1389                                 BLinePoint bline_point((*value_node->get_link(i))(get_time()));
1390                                 
1391                                 ValueNode_Composite::Handle vertex_value_node(
1392                                         ValueNode_Composite::Handle::cast_dynamic(
1393                                                 value_node->get_link(i)
1394                                         )
1395                                 );
1396                                                                 
1397                                 // Add the vertex duck
1398                                 if(vertex_value_node)
1399                                 {
1400                                         if(add_to_ducks(synfigapp::ValueDesc(vertex_value_node,0),canvas_view,transform_stack))
1401                                         {
1402                                                 duck=last_duck();
1403                                                 if(i==first)
1404                                                         first_duck=duck;
1405                                                 duck->set_type(Duck::TYPE_VERTEX);
1406
1407                                                 duck->signal_user_click(2).clear();
1408                                                 duck->signal_user_click(2).connect(
1409                                                         sigc::bind(
1410                                                                 sigc::bind(
1411                                                                         sigc::mem_fun(
1412                                                                                 *canvas_view,
1413                                                                                 &studio::CanvasView::popup_param_menu
1414                                                                         ),
1415                                                                         1.0f
1416                                                                 ),
1417                                                                 synfigapp::ValueDesc(value_node,i)
1418                                                         )
1419                                                 );
1420                                                 duck->set_value_desc(synfigapp::ValueDesc(value_node,i));
1421                         
1422                                                 if(param_desc)
1423                                                 {
1424                                                         if(!param_desc->get_origin().empty())
1425                                                         {
1426                                                                 synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
1427                                                                 add_to_ducks(value_desc_origin,canvas_view, transform_stack);
1428                                                                 duck->set_origin(last_duck());
1429 /*
1430                                                                 ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
1431                                                                 if(value.same_as(synfig::Point()))
1432                                                                         duck->set_origin(value.get(synfig::Point()));
1433 */
1434                                                         }
1435                                                 }
1436                                         }
1437                                         else
1438                                                 return false;
1439                                 }
1440                                 else
1441                                 {
1442                                         duck=new Duck(bline_point.get_vertex());
1443                                         if(i==first)
1444                                                 first_duck=duck;
1445                                         duck->set_transform_stack(transform_stack);
1446                                         duck->set_editable(false);
1447                                         //duck->set_name(strprintf("%x-vertex",value_node->get_link(i).get()));                 
1448                                         duck->set_name(guid_string(synfigapp::ValueDesc(value_node,i))+".v");
1449
1450                                         duck->set_type(Duck::TYPE_VERTEX);
1451                                         if(param_desc)
1452                                         {
1453                                                 if(!param_desc->get_origin().empty())
1454                                                 {
1455                                                                 synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
1456                                                                 add_to_ducks(value_desc_origin,canvas_view, transform_stack);
1457                                                                 duck->set_origin(last_duck());
1458 /*
1459                                                                 ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
1460                                                                 if(value.same_as(synfig::Point()))
1461                                                                         duck->set_origin(value.get(synfig::Point()));
1462 */
1463                                                 }
1464                                         }
1465                                         duck->set_guid(calc_duck_guid(synfigapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".v"));
1466                                         duck=add_similar_duck(duck);
1467 //                                      add_duck(duck);                 
1468                                 }
1469
1470                                 // Add the width duck only if we have a hint of scale
1471                                 if(param_desc && !param_desc->get_hint().empty())
1472                                 {
1473                                         etl::handle<Duck> width;
1474                                         if(add_to_ducks(synfigapp::ValueDesc(vertex_value_node,1),canvas_view,transform_stack,REAL_COOKIE))
1475                                         {
1476                                                 width=last_duck();
1477                                                 width->set_origin(duck);
1478                                                 width->set_type(Duck::TYPE_WIDTH);
1479                                                 width->set_name(guid_string(synfigapp::ValueDesc(value_node,i))+".w");
1480                                                 {
1481                                                         ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_hint()).get_value(get_time()));
1482                                                         if(value.same_as(synfig::Real()))
1483                                                                 width->set_scalar(value.get(synfig::Real())*0.5f);
1484                                                 }
1485                                         }
1486                                         else
1487                                                 synfig::error("Unable to add width duck!");
1488                                 }
1489                                 
1490                                 if(bezier)
1491                                 {
1492                                         // Add the tangent1 duck
1493                                         if(vertex_value_node)
1494                                         {
1495                                                 if(!add_to_ducks(synfigapp::ValueDesc(vertex_value_node,4),canvas_view,transform_stack))
1496                                                         return false;
1497                                                 tduck=last_duck();
1498                                         }
1499                                         else
1500                                         {
1501                                                 tduck=new Duck(bline_point.get_tangent1());
1502                                                 tduck->set_transform_stack(transform_stack);
1503                                                 tduck->set_editable(false);
1504                                                 tduck->set_name(guid_string(synfigapp::ValueDesc(value_node,i))+".t1");
1505 //                                              tduck->set_name(strprintf("%x-tangent1",value_node->get_link(i).get()));                        
1506                                                 tduck->set_guid(calc_duck_guid(synfigapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t1"));
1507                                                 tduck=add_similar_duck(tduck);
1508 //                                              add_duck(duck);
1509                                         }
1510
1511                                         tduck->set_origin(duck);
1512                                         tduck->set_scalar(-0.33333333333333333);
1513                                         tduck->set_tangent(true);
1514                                         
1515                                         bezier->p2=duck;
1516                                         bezier->c2=tduck;
1517
1518                                         bezier->signal_user_click(2).connect(
1519                                                 sigc::bind(
1520                                                         sigc::mem_fun(
1521                                                                 *canvas_view,
1522                                                                 &studio::CanvasView::popup_param_menu_bezier
1523                                                         ),
1524                                                         synfigapp::ValueDesc(value_node,i)
1525                                                 )
1526                                         );
1527
1528                                         duck->signal_user_click(2).clear();
1529                                         duck->signal_user_click(2).connect(
1530                                                 sigc::bind(
1531                                                         sigc::bind(
1532                                                                 sigc::mem_fun(
1533                                                                         *canvas_view,
1534                                                                         &studio::CanvasView::popup_param_menu
1535                                                                 ),
1536                                                                 1.0f
1537                                                         ),
1538                                                         synfigapp::ValueDesc(value_node,i)
1539                                                 )
1540                                         );
1541                                         duck->set_value_desc(synfigapp::ValueDesc(value_node,i));
1542
1543                                         add_bezier(bezier);
1544                                         bezier=0;
1545                                 }
1546                                 
1547                                 if(i+1>=value_node->link_count() && !value_node->get_loop())
1548                                         continue;
1549                                 
1550                                 bezier=new Bezier();
1551                                 
1552                                 // Add the tangent2 duck
1553                                 if(vertex_value_node)
1554                                 {
1555                                         int i=bline_point.get_split_tangent_flag()?5:4;
1556                                         if(!add_to_ducks(synfigapp::ValueDesc(vertex_value_node,i),canvas_view,transform_stack,0,2))
1557                                                 return false;
1558                                         tduck=last_duck();
1559                                 }
1560                                 else
1561                                 {
1562                                         if(bline_point.get_split_tangent_flag())
1563                                         {
1564                                                 tduck=new Duck(bline_point.get_tangent2());
1565                                                 tduck->set_transform_stack(transform_stack);
1566                                                 //tduck->set_name(strprintf("%x-tangent2",value_node->get_link(i).get()));                      
1567                                                 tduck->set_name(guid_string(synfigapp::ValueDesc(value_node,i))+".t2");
1568                                                 tduck->set_guid(calc_duck_guid(synfigapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t2"));
1569                                         }
1570                                         else
1571                                         {
1572                                                 tduck=new Duck(bline_point.get_tangent1());
1573                                                 tduck->set_transform_stack(transform_stack);
1574                                                 //tduck->set_name(strprintf("%x-tangent1",value_node->get_link(i).get()));                      
1575                                                 tduck->set_name(guid_string(synfigapp::ValueDesc(value_node,i))+".t1");
1576                                                 tduck->set_guid(calc_duck_guid(synfigapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t1"));
1577                                         }
1578                                         tduck->set_editable(false);
1579                                         tduck=add_similar_duck(tduck);
1580 //                                      add_duck(duck);
1581                                         if(param_desc)
1582                                         {
1583                                                                 synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
1584                                                                 add_to_ducks(value_desc_origin,canvas_view, transform_stack);
1585                                                                 duck->set_origin(last_duck());
1586 /*
1587                                                                 ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
1588                                                                 if(value.same_as(synfig::Point()))
1589                                                                         duck->set_origin(value.get(synfig::Point()));
1590 */
1591 //                                              if(!param_desc->get_origin().empty())
1592 //                                                      duck->set_origin(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()).get(synfig::Point()));
1593                                         }
1594                                         duck->signal_user_click(2).clear();
1595                                         duck->signal_user_click(2).connect(
1596                                                 sigc::bind(
1597                                                         sigc::bind(
1598                                                                 sigc::mem_fun(
1599                                                                         *canvas_view,
1600                                                                         &studio::CanvasView::popup_param_menu
1601                                                                 ),
1602                                                                 1.0f
1603                                                         ),
1604                                                         synfigapp::ValueDesc(value_node,0)
1605                                                 )
1606                                         );
1607                                         duck->set_value_desc(synfigapp::ValueDesc(value_node,0));
1608
1609                                 }
1610
1611                                 tduck->set_origin(duck);
1612                                 tduck->set_scalar(0.33333333333333333);
1613                                 tduck->set_tangent(true);
1614                                 
1615                                 bezier->p1=duck;
1616                                 bezier->c1=tduck;
1617                                 
1618                         }
1619                         // Loop if necessary
1620                         if(bezier && value_node->get_loop())
1621                         {
1622                                 BLinePoint bline_point((*value_node->get_link(first))(get_time()));
1623                                 
1624                                 ValueNode_Composite::Handle vertex_value_node(
1625                                         ValueNode_Composite::Handle::cast_dynamic(
1626                                                 value_node->get_link(first)
1627                                         )
1628                                 );
1629                                 
1630                                 // Add the vertex duck
1631                                 duck=first_duck;
1632                                 /*
1633                                 if(vertex_value_node)
1634                                 {
1635                                         if(!add_to_ducks(synfigapp::ValueDesc(vertex_value_node,0),canvas_view,transform_stack))
1636                                                 return false;
1637                                         duck=last_duck();
1638                                         if(param_desc)
1639                                         {
1640                                                 if(!param_desc->get_origin().empty())
1641                                                         duck->set_origin(value_desc.get_layer()->get_param(param_desc->get_origin()).get(synfig::Point()));
1642                                         }
1643                                         duck->set_type(Duck::TYPE_VERTEX);
1644                                 }
1645                                 else
1646                                 {
1647                                         duck=new Duck(bline_point.get_vertex());
1648                                         duck->set_transform_stack(transform_stack);
1649                                         if(param_desc)
1650                                         {
1651                                                 if(!param_desc->get_origin().empty())
1652                                                         duck->set_origin(value_desc.get_layer()->get_param(param_desc->get_origin()).get(synfig::Point()));
1653                                         }
1654                                         duck->set_editable(false);
1655                                         duck->set_name(strprintf("%x-vertex",value_node->get_link(first).get()));                       
1656                                         duck->set_type(Duck::TYPE_VERTEX);
1657                                         duck=add_similar_duck(duck);
1658                                 }
1659                                 */
1660                                 
1661                                         // Add the tangent1 duck
1662                                         if(vertex_value_node)
1663                                         {
1664                                                 if(!add_to_ducks(synfigapp::ValueDesc(vertex_value_node,4),canvas_view,transform_stack))
1665                                                         return false;
1666                                                 tduck=last_duck();
1667                                         }
1668                                         else
1669                                         {
1670                                                 tduck=new Duck(bline_point.get_tangent1());
1671                                                 tduck->set_transform_stack(transform_stack);
1672                                                 tduck->set_editable(false);
1673                                                 tduck->set_name(guid_string(synfigapp::ValueDesc(value_node,first))+".t1");
1674                                                 //tduck->set_name(strprintf("%x-tangent1",value_node->get_link(first).get()));                  
1675                                                 tduck=add_similar_duck(tduck);
1676                                                 tduck->set_guid(calc_duck_guid(synfigapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t1"));
1677                                                 //add_duck(duck);
1678                                         }
1679
1680                                         tduck->set_origin(duck);
1681                                         tduck->set_scalar(-0.33333333333333333);
1682                                         tduck->set_tangent(true);
1683                                         
1684                                         bezier->p2=duck;
1685                                         bezier->c2=tduck;
1686                                         bezier->signal_user_click(2).connect(
1687                                                 sigc::bind(
1688                                                         sigc::mem_fun(
1689                                                                 *canvas_view,
1690                                                                 &studio::CanvasView::popup_param_menu_bezier
1691                                                         ),
1692                                                         synfigapp::ValueDesc(value_node,first)
1693                                                 )
1694                                         );
1695                                         duck->signal_user_click(2).clear();
1696                                         duck->signal_user_click(2).connect(
1697                                                 sigc::bind(
1698                                                         sigc::bind(
1699                                                                 sigc::mem_fun(
1700                                                                         *canvas_view,
1701                                                                         &studio::CanvasView::popup_param_menu
1702                                                                 ),
1703                                                                 1.0f
1704                                                         ),
1705                                                         synfigapp::ValueDesc(value_node,first)
1706                                                 )
1707                                         );
1708                                         duck->set_value_desc(synfigapp::ValueDesc(value_node,first));
1709
1710                                         add_bezier(bezier);
1711                                         bezier=0;
1712                                 
1713                         }
1714                         return true;
1715                 }
1716                 else // Check for DynamicList           
1717                 if(value_desc.is_value_node() &&
1718                         ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node())
1719                 )
1720                 {
1721                         ValueNode_DynamicList::Handle value_node;
1722                         value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node());
1723                         int i;
1724                         
1725                         if(value_node->get_contained_type()==ValueBase::TYPE_VECTOR)
1726                         {
1727                                 Bezier bezier;
1728                                 for(i=0;i<value_node->link_count();i++)
1729                                 {                                       
1730                                         if(!value_node->list[i].status_at_time(get_time()))
1731                                                 continue;
1732                                         if(!add_to_ducks(synfigapp::ValueDesc(value_node,i),canvas_view,transform_stack))
1733                                                 return false;
1734                                         etl::handle<Duck> duck(last_duck());
1735                                         
1736                                         if(param_desc)
1737                                         {
1738                                                                 synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
1739                                                                 add_to_ducks(value_desc_origin,canvas_view, transform_stack);
1740                                                                 duck->set_origin(last_duck());
1741 /*
1742                                                                 ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
1743                                                                 if(value.same_as(synfig::Point()))
1744                                                                         duck->set_origin(value.get(synfig::Point()));
1745 */
1746 //                                              if(!param_desc->get_origin().empty())
1747 //                                                      last_duck()->set_origin(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()).get(synfig::Point()));
1748                                         }
1749                                         duck->set_type(Duck::TYPE_VERTEX);
1750                                         bezier.p1=bezier.p2;bezier.c1=bezier.c2;
1751                                         bezier.p2=bezier.c2=duck;
1752
1753                                         if(i>0)
1754                                         {
1755                                                 handle<Bezier> bezier_(new Bezier());
1756                                                 bezier_->p1=bezier.p1;
1757                                                 bezier_->c1=bezier.c1;
1758                                                 bezier_->p2=bezier.p2;
1759                                                 bezier_->c2=bezier.c2;
1760                                                 add_bezier(bezier_);
1761                                                 last_bezier()->signal_user_click(2).connect(
1762                                                         sigc::bind(
1763                                                                 sigc::mem_fun(
1764                                                                         *canvas_view,
1765                                                                         &studio::CanvasView::popup_param_menu_bezier
1766                                                                 ),
1767                                                                 synfigapp::ValueDesc(value_node,i)
1768                                                         )
1769                                                 );
1770                                         }
1771                                 }
1772                         }
1773                         /*else if(value_node->get_contained_type()==ValueBase::TYPE_SEGMENT)
1774                         {
1775                                 for(i=0;i<value_node->link_count();i++)
1776                                 {
1777                                         if(!value_node->list[i].status_at_time(get_time()))
1778                                                 continue;
1779                                         if(!add_to_ducks(synfigapp::ValueDesc(value_node,i),canvas_view,transform_stack))
1780                                                 return false;
1781                                 }
1782                         }
1783                         */
1784                         else
1785                                 return false;
1786                 }
1787                 else
1788                 {
1789                         // WRITEME
1790                 }
1791                 
1792                 return true;
1793         }
1794
1795
1796         break;
1797         default:
1798                 break;
1799         }
1800         return false;
1801 }