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