Remove ancient trunk folder from svn repository
[synfig.git] / synfig-core / src / synfig / layer.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file layer.cpp
3 **      \brief Layer class implementation
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **      Copyright (c) 2007, 2008 Chris Moore
10 **
11 **      This package is free software; you can redistribute it and/or
12 **      modify it under the terms of the GNU General Public License as
13 **      published by the Free Software Foundation; either version 2 of
14 **      the License, or (at your option) any later version.
15 **
16 **      This package is distributed in the hope that it will be useful,
17 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 **      General Public License for more details.
20 **      \endlegal
21 */
22 /* ========================================================================= */
23
24 /* === H E A D E R S ======================================================= */
25
26 #define SYNFIG_NO_ANGLE
27
28 #ifdef USING_PCH
29 #       include "pch.h"
30 #else
31 #ifdef HAVE_CONFIG_H
32 #       include <config.h>
33 #endif
34
35 #include "canvas.h"
36 #include "layer.h"
37 #include "render.h"
38 #include "value.h"
39 #include "layer_bitmap.h"
40 #include "layer_mime.h"
41 #include "context.h"
42 #include "paramdesc.h"
43
44 #include "layer_solidcolor.h"
45 #include "layer_polygon.h"
46 #include "layer_pastecanvas.h"
47 #include "layer_motionblur.h"
48 #include "layer_duplicate.h"
49
50 #include "valuenode_const.h"
51
52 #include "transform.h"
53 #include "rect.h"
54 #include "guid.h"
55
56 #include <sigc++/adaptors/bind.h>
57 #endif
58
59 /* === U S I N G =========================================================== */
60
61 using namespace etl;
62 using namespace std;
63 using namespace synfig;
64
65 /* === G L O B A L S ======================================================= */
66
67 static Layer::Book* _layer_book;
68
69 struct _LayerCounter
70 {
71         static int counter;
72         ~_LayerCounter()
73         {
74                 if(counter)
75                         synfig::error("%d layers not yet deleted!",counter);
76         }
77 } _layer_counter;
78
79 int _LayerCounter::counter(0);
80
81 /* === P R O C E D U R E S ================================================= */
82
83 Layer::Book&
84 Layer::book()
85 {
86         return *_layer_book;
87 }
88
89 void
90 Layer::register_in_book(const BookEntry &entry)
91 {
92         book()[entry.name]=entry;
93 }
94
95 bool
96 Layer::subsys_init()
97 {
98         _layer_book=new Book();
99
100 #define INCLUDE_LAYER(class)                                                                    \
101         synfig::Layer::book() [synfig::String(class::name__)] =         \
102                 BookEntry(class::create,                                                                \
103                                   class::name__,                                                                \
104                                   dgettext("synfig", class::local_name__),              \
105                                   class::category__,                                                    \
106                                   class::cvs_id__,                                                              \
107                                   class::version__)
108
109 #define LAYER_ALIAS(class,alias)                                                                \
110         synfig::Layer::book()[synfig::String(alias)] =                          \
111                 BookEntry(class::create,                                                                \
112                                   alias,                                                                                \
113                                   alias,                                                                                \
114                                   CATEGORY_DO_NOT_USE,                                                  \
115                                   class::cvs_id__,                                                              \
116                                   class::version__)
117
118         INCLUDE_LAYER(Layer_SolidColor);        LAYER_ALIAS(Layer_SolidColor,   "solid_color");
119         INCLUDE_LAYER(Layer_PasteCanvas);       LAYER_ALIAS(Layer_PasteCanvas,  "paste_canvas");
120         INCLUDE_LAYER(Layer_Polygon);           LAYER_ALIAS(Layer_Polygon,              "Polygon");
121         INCLUDE_LAYER(Layer_MotionBlur);        LAYER_ALIAS(Layer_MotionBlur,   "motion_blur");
122         INCLUDE_LAYER(Layer_Duplicate);
123
124 #undef INCLUDE_LAYER
125
126         return true;
127 }
128
129 bool
130 Layer::subsys_stop()
131 {
132         delete _layer_book;
133         return true;
134 }
135
136 /* === M E T H O D S ======================================================= */
137
138 Layer::Layer():
139         active_(true),
140         z_depth_(0.0f),
141         dirty_time_(Time::end())
142 {
143         _LayerCounter::counter++;
144 }
145
146 Layer::LooseHandle
147 synfig::Layer::create(const String &name)
148 {
149         if(!book().count(name))
150         {
151                 return Layer::LooseHandle(new Layer_Mime(name));
152         }
153
154         Layer* layer(book()[name].factory());
155         return Layer::LooseHandle(layer);
156 }
157
158 synfig::Layer::~Layer()
159 {
160         _LayerCounter::counter--;
161         while(!dynamic_param_list_.empty())
162         {
163                 remove_child(dynamic_param_list_.begin()->second.get());
164                 dynamic_param_list_.erase(dynamic_param_list_.begin());
165         }
166
167         remove_from_all_groups();
168
169         parent_death_connect_.disconnect();
170         begin_delete();
171 }
172
173 void
174 synfig::Layer::set_canvas(etl::loose_handle<Canvas> x)
175 {
176         if(canvas_!=x)
177         {
178                 parent_death_connect_.disconnect();
179                 canvas_=x;
180                 if(x)
181                 {
182                         parent_death_connect_=x->signal_deleted().connect(
183                                 sigc::bind(
184                                         sigc::mem_fun(
185                                                 *this,
186                                                 &Layer::set_canvas
187                                         ),
188                                         etl::loose_handle<synfig::Canvas>(0)
189                                 )
190                         );
191                 }
192                 on_canvas_set();
193         }
194 }
195
196 void
197 synfig::Layer::on_canvas_set()
198 {
199 }
200
201 etl::loose_handle<synfig::Canvas>
202 synfig::Layer::get_canvas()const
203 {
204         return canvas_;
205 }
206
207 int
208 Layer::get_depth()const
209 {
210         if(!get_canvas())
211                 return -1;
212         return get_canvas()->get_depth(const_cast<synfig::Layer*>(this));
213 }
214
215 void
216 Layer::set_active(bool x)
217 {
218         if(active_!=x)
219         {
220                 active_=x;
221
222                 Node::on_changed();
223                 signal_status_changed_();
224         }
225 }
226
227 void
228 Layer::set_description(const String& x)
229 {
230         if(description_!=x)
231         {
232                 description_=x;
233                 signal_description_changed_();
234         }
235 }
236
237 bool
238 Layer::connect_dynamic_param(const String& param, etl::loose_handle<ValueNode> value_node)
239 {
240         ValueNode::Handle previous(dynamic_param_list_[param]);
241
242         if(previous==value_node)
243                 return true;
244
245         dynamic_param_list_[param]=ValueNode::Handle(value_node);
246
247         if(previous)
248                 remove_child(previous.get());
249
250         add_child(value_node.get());
251
252         if(!value_node->is_exported() && get_canvas())
253         {
254                 value_node->set_parent_canvas(get_canvas());
255         }
256
257         changed();
258         return true;
259 }
260
261 bool
262 Layer::disconnect_dynamic_param(const String& param)
263 {
264         ValueNode::Handle previous(dynamic_param_list_[param]);
265
266         if(previous)
267         {
268                 dynamic_param_list_.erase(param);
269
270                 // fix 2353284: if two parameters in the same layer are
271                 // connected to the same valuenode and we disconnect one of
272                 // them, the parent-child relationship for the remaining
273                 // connection was being deleted.  now we search the parameter
274                 // list to see if another parameter uses the same valuenode
275                 DynamicParamList::const_iterator iter;
276                 for (iter = dynamic_param_list().begin(); iter != dynamic_param_list().end(); iter++)
277                         if (iter->second == previous)
278                                 break;
279                 if (iter == dynamic_param_list().end())
280                         remove_child(previous.get());
281
282                 changed();
283         }
284         return true;
285 }
286
287 void
288 Layer::on_changed()
289 {
290         dirty_time_=Time::end();
291         Node::on_changed();
292 }
293
294 bool
295 Layer::set_param(const String &param, const ValueBase &value)
296 {
297         if(param=="z_depth" && value.same_type_as(z_depth_))
298         {
299                 z_depth_=value.get(z_depth_);
300                 return true;
301         }
302         return false;
303 }
304
305 etl::handle<Transform>
306 Layer::get_transform()const
307 {
308         return 0;
309 }
310
311 float
312 Layer::get_z_depth(const synfig::Time& t)const
313 {
314         if(!dynamic_param_list().count("z_depth"))
315                 return z_depth_;
316         return (*dynamic_param_list().find("z_depth")->second)(t).get(Real());
317 }
318
319 Layer::Handle
320 Layer::simple_clone()const
321 {
322         if(!book().count(get_name())) return 0;
323         Handle ret = create(get_name()).get();
324         ret->group_=group_;
325         //ret->set_canvas(get_canvas());
326         ret->set_description(get_description());
327         ret->set_active(active());
328         ret->set_param_list(get_param_list());
329         for(DynamicParamList::const_iterator iter=dynamic_param_list().begin();iter!=dynamic_param_list().end();++iter)
330                 ret->connect_dynamic_param(iter->first, iter->second);
331         return ret;
332 }
333
334 Layer::Handle
335 Layer::clone(const GUID& deriv_guid) const
336 {
337         if(!book().count(get_name())) return 0;
338
339         //Layer *ret = book()[get_name()].factory();//create(get_name()).get();
340         Handle ret = create(get_name()).get();
341
342         ret->group_=group_;
343         //ret->set_canvas(get_canvas());
344         ret->set_description(get_description());
345         ret->set_active(active());
346         ret->set_guid(get_guid()^deriv_guid);
347
348         //ret->set_param_list(get_param_list());
349         // Process the parameter list so that
350         // we can duplicate any inline canvases
351         ParamList param_list(get_param_list());
352         for(ParamList::const_iterator iter(param_list.begin()); iter != param_list.end(); ++iter)
353         {
354                 if(dynamic_param_list().count(iter->first)==0 && iter->second.get_type()==ValueBase::TYPE_CANVAS)
355                 {
356                         // This parameter is a canvas.  We need a close look.
357                         Canvas::Handle canvas(iter->second.get(Canvas::Handle()));
358                         if(canvas && canvas->is_inline())
359                         {
360                                 // This parameter is an inline canvas! we need to clone it
361                                 // before we set it as a parameter.
362                                 Canvas::Handle new_canvas(canvas->clone(deriv_guid));
363                                 ValueBase value(new_canvas);
364                                 ret->set_param(iter->first, value);
365                                 continue;
366                         }
367                 }
368
369                 // This is a normal parameter,go ahead and set it.
370                 ret->set_param(iter->first, iter->second);
371         }
372
373         // Duplicate the dynamic paramlist, but only the exported data nodes
374         DynamicParamList::const_iterator iter;
375         for(iter=dynamic_param_list().begin();iter!=dynamic_param_list().end();++iter)
376         {
377                 // Make sure we clone inline canvases
378                 if(iter->second->get_type()==ValueBase::TYPE_CANVAS)
379                 {
380                         Canvas::Handle canvas((*iter->second)(0).get(Canvas::Handle()));
381                         if(canvas->is_inline())
382                         {
383                                 Canvas::Handle new_canvas(canvas->clone(deriv_guid));
384                                 ValueBase value(new_canvas);
385                                 ret->connect_dynamic_param(iter->first,ValueNode_Const::create(value));
386                                 continue;
387                         }
388                 }
389
390                 if(iter->second->is_exported())
391                         ret->connect_dynamic_param(iter->first,iter->second);
392                 else
393                         ret->connect_dynamic_param(iter->first,iter->second->clone(deriv_guid));
394         }
395
396         //ret->set_canvas(0);
397
398         return ret;
399 }
400
401 bool
402 Layer::reads_context() const
403 {
404         return false;
405 }
406
407 Rect
408 Layer::get_full_bounding_rect(Context context)const
409 {
410         if(active())
411                 return context.get_full_bounding_rect()|get_bounding_rect();
412         return context.get_full_bounding_rect();
413 }
414
415 Rect
416 Layer::get_bounding_rect()const
417 {
418         return Rect::full_plane();
419 }
420
421 bool
422 Layer::set_param_list(const ParamList &list)
423 {
424         bool ret=true;
425         if(!list.size())
426                 return false;
427         ParamList::const_iterator iter(list.begin());
428         for(;iter!=list.end();++iter)
429         {
430                 if(!set_param(iter->first, iter->second))ret=false;
431         }
432         return ret;
433 }
434
435 Layer::ParamList
436 Layer::get_param_list()const
437 {
438         ParamList ret;
439
440         Vocab vocab(get_param_vocab());
441
442         Vocab::const_iterator iter=vocab.begin();
443         for(;iter!=vocab.end();++iter)
444         {
445                 ret[iter->get_name()]=get_param(iter->get_name());
446         }
447         return ret;
448 }
449
450 ValueBase
451 Layer::get_param(const String & param)const
452 {
453         if(param=="z_depth")
454                 return get_z_depth();
455
456         return ValueBase();
457 }
458
459 String
460 Layer::get_version()const
461 {
462         return get_param("version__").get(String());
463 }
464
465 bool
466 Layer::set_version(const String &/*ver*/)
467 {
468         return false;
469 }
470
471 void
472 Layer::reset_version()
473 {
474 }
475
476
477 void
478 Layer::set_time(Context context, Time time)const
479 {
480         context.set_time(time);
481         dirty_time_=time;
482 }
483
484 void
485 Layer::set_time(Context context, Time time, const Point &pos)const
486 {
487         context.set_time(time,pos);
488         dirty_time_=time;
489 }
490
491 Color
492 Layer::get_color(Context context, const Point &pos)const
493 {
494         return context.get_color(pos);
495 }
496
497 synfig::Layer::Handle
498 Layer::hit_check(synfig::Context context, const synfig::Point &pos)const
499 {
500         return context.hit_check(pos);
501 }
502
503 /*      The default accelerated renderer
504 **      is anything but accelerated...
505 */
506 bool
507 Layer::accelerated_render(Context context,Surface *surface,int /*quality*/, const RendDesc &renddesc, ProgressCallback *cb)  const
508 {
509         handle<Target> target=surface_target(surface);
510         if(!target)
511         {
512                 if(cb)cb->error(_("Unable to create surface target"));
513                 return false;
514         }
515         RendDesc desc=renddesc;
516         target->set_rend_desc(&desc);
517
518         // When we render, we want to
519         // make sure that we are rendered too...
520         // Since the context iterator is for
521         // the layer after us, we need to back up.
522         // This could be considered a hack, as
523         // it is a possibility that we are indeed
524         // not the previous layer.
525         --context;
526
527         return render(context,target,desc,cb);
528         //return render_threaded(context,target,desc,cb,2);
529 }
530
531 String
532 Layer::get_name()const
533 {
534         return get_param("name__").get(String());
535 }
536
537 String
538 Layer::get_local_name()const
539 {
540         return get_param("local_name__").get(String());
541 }
542
543
544 Layer::Vocab
545 Layer::get_param_vocab()const
546 {
547         Layer::Vocab ret;
548
549         ret.push_back(ParamDesc(z_depth_,"z_depth")
550                 .set_local_name(_("Z Depth"))
551                 .set_animation_only(true)
552         );
553
554         return ret;
555 }
556
557 void
558 Layer::get_times_vfunc(Node::time_set &set) const
559 {
560         DynamicParamList::const_iterator        i = dynamic_param_list_.begin(),
561                                                                                 end = dynamic_param_list_.end();
562
563         for(; i != end; ++i)
564         {
565                 const Node::time_set &tset = i->second->get_times();
566                 set.insert(tset.begin(),tset.end());
567         }
568 }
569
570
571 void
572 Layer::add_to_group(const String&x)
573 {
574         if(x==group_)
575                 return;
576         if(!group_.empty())
577                 remove_from_all_groups();
578         group_=x;
579         signal_added_to_group()(group_);
580 }
581
582 void
583 Layer::remove_from_group(const String&x)
584 {
585         if(group_==x)
586                 remove_from_all_groups();
587 }
588
589 void
590 Layer::remove_from_all_groups()
591 {
592         if(group_.empty())
593                 return;
594         signal_removed_from_group()(group_);
595         group_.clear();
596 }
597
598 String
599 Layer::get_group()const
600 {
601         return group_;
602 }
603
604 const String
605 Layer::get_param_local_name(const String &param_name)const
606 {
607         ParamVocab vocab = get_param_vocab();
608         // loop to find the parameter in the parameter vocab - this gives us its local name
609         for (ParamVocab::iterator iter = vocab.begin(); iter != vocab.end(); iter++)
610                 if (iter->get_name() == param_name)
611                         return iter->get_local_name();
612         return String();
613 }