Use a map of static values instead of hard coded names.
[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         //z_depth_static(false)
141 {
142         _LayerCounter::counter++;
143         Vocab vocab=get_param_vocab();
144         Vocab::const_iterator viter;
145         for(viter=vocab.begin();viter!=vocab.end();viter++)
146         {
147                 static_params.insert(make_pair(viter->get_name(),false));
148         }
149 }
150
151 Layer::LooseHandle
152 synfig::Layer::create(const String &name)
153 {
154         if(!book().count(name))
155         {
156                 return Layer::LooseHandle(new Layer_Mime(name));
157         }
158
159         Layer* layer(book()[name].factory());
160         return Layer::LooseHandle(layer);
161 }
162
163 synfig::Layer::~Layer()
164 {
165         _LayerCounter::counter--;
166         while(!dynamic_param_list_.empty())
167         {
168                 remove_child(dynamic_param_list_.begin()->second.get());
169                 dynamic_param_list_.erase(dynamic_param_list_.begin());
170         }
171
172         remove_from_all_groups();
173
174         parent_death_connect_.disconnect();
175         begin_delete();
176 }
177
178 void
179 synfig::Layer::set_canvas(etl::loose_handle<Canvas> x)
180 {
181         if(canvas_!=x)
182         {
183                 parent_death_connect_.disconnect();
184                 canvas_=x;
185                 if(x)
186                 {
187                         parent_death_connect_=x->signal_deleted().connect(
188                                 sigc::bind(
189                                         sigc::mem_fun(
190                                                 *this,
191                                                 &Layer::set_canvas
192                                         ),
193                                         etl::loose_handle<synfig::Canvas>(0)
194                                 )
195                         );
196                 }
197                 on_canvas_set();
198         }
199 }
200
201 void
202 synfig::Layer::on_canvas_set()
203 {
204 }
205
206 etl::loose_handle<synfig::Canvas>
207 synfig::Layer::get_canvas()const
208 {
209         return canvas_;
210 }
211
212 int
213 Layer::get_depth()const
214 {
215         if(!get_canvas())
216                 return -1;
217         return get_canvas()->get_depth(const_cast<synfig::Layer*>(this));
218 }
219
220 void
221 Layer::set_active(bool x)
222 {
223         if(active_!=x)
224         {
225                 active_=x;
226
227                 Node::on_changed();
228                 signal_status_changed_();
229         }
230 }
231
232 void
233 Layer::set_description(const String& x)
234 {
235         if(description_!=x)
236         {
237                 description_=x;
238                 signal_description_changed_();
239         }
240 }
241
242 bool
243 Layer::connect_dynamic_param(const String& param, etl::loose_handle<ValueNode> value_node)
244 {
245         ValueNode::Handle previous(dynamic_param_list_[param]);
246
247         if(previous==value_node)
248                 return true;
249
250         dynamic_param_list_[param]=ValueNode::Handle(value_node);
251
252         if(previous)
253                 remove_child(previous.get());
254
255         add_child(value_node.get());
256
257         if(!value_node->is_exported() && get_canvas())
258         {
259                 value_node->set_parent_canvas(get_canvas());
260         }
261
262         changed();
263         return true;
264 }
265
266 bool
267 Layer::disconnect_dynamic_param(const String& param)
268 {
269         ValueNode::Handle previous(dynamic_param_list_[param]);
270
271         if(previous)
272         {
273                 dynamic_param_list_.erase(param);
274
275                 // fix 2353284: if two parameters in the same layer are
276                 // connected to the same valuenode and we disconnect one of
277                 // them, the parent-child relationship for the remaining
278                 // connection was being deleted.  now we search the parameter
279                 // list to see if another parameter uses the same valuenode
280                 DynamicParamList::const_iterator iter;
281                 for (iter = dynamic_param_list().begin(); iter != dynamic_param_list().end(); iter++)
282                         if (iter->second == previous)
283                                 break;
284                 if (iter == dynamic_param_list().end())
285                         remove_child(previous.get());
286
287                 changed();
288         }
289         return true;
290 }
291
292 void
293 Layer::on_changed()
294 {
295         dirty_time_=Time::end();
296         Node::on_changed();
297 }
298
299 bool
300 Layer::set_param(const String &param, const ValueBase &value)
301 {
302         IMPORT(z_depth)
303         return false;
304 }
305
306 bool
307 Layer::set_param_static(const String &param, const bool x)
308 {
309         Sparams::iterator iter;
310
311         for(iter=static_params.begin();iter!=static_params.end();iter++)
312         {
313                 if(iter->first == param)
314                 {
315                         iter->second = x;
316                         return true;
317                 }
318         }
319         //SET_STATIC(z_depth,x)
320
321         return false;
322 }
323
324
325 bool
326 Layer::get_param_static(const String &param) const
327 {
328
329         Sparams::const_iterator iter;
330
331         for(iter=static_params.begin();iter!=static_params.end();iter++)
332         {
333                 if(iter->first == param)
334                 {
335                         return iter->second;
336                 }
337         }
338         //GET_STATIC(z_depth);
339
340         return false;
341 }
342
343
344 etl::handle<Transform>
345 Layer::get_transform()const
346 {
347         return 0;
348 }
349
350 float
351 Layer::get_z_depth(const synfig::Time& t)const
352 {
353         if(!dynamic_param_list().count("z_depth"))
354                 return z_depth;
355         return (*dynamic_param_list().find("z_depth")->second)(t).get(Real());
356 }
357
358 Layer::Handle
359 Layer::simple_clone()const
360 {
361         if(!book().count(get_name())) return 0;
362         Handle ret = create(get_name()).get();
363         ret->group_=group_;
364         //ret->set_canvas(get_canvas());
365         ret->set_description(get_description());
366         ret->set_active(active());
367         ret->set_param_list(get_param_list());
368         for(DynamicParamList::const_iterator iter=dynamic_param_list().begin();iter!=dynamic_param_list().end();++iter)
369                 ret->connect_dynamic_param(iter->first, iter->second);
370         return ret;
371 }
372
373 Layer::Handle
374 Layer::clone(const GUID& deriv_guid) const
375 {
376         if(!book().count(get_name())) return 0;
377
378         //Layer *ret = book()[get_name()].factory();//create(get_name()).get();
379         Handle ret = create(get_name()).get();
380
381         ret->group_=group_;
382         //ret->set_canvas(get_canvas());
383         ret->set_description(get_description());
384         ret->set_active(active());
385         ret->set_guid(get_guid()^deriv_guid);
386
387         //ret->set_param_list(get_param_list());
388         // Process the parameter list so that
389         // we can duplicate any inline canvases
390         ParamList param_list(get_param_list());
391         for(ParamList::const_iterator iter(param_list.begin()); iter != param_list.end(); ++iter)
392         {
393                 if(dynamic_param_list().count(iter->first)==0 && iter->second.get_type()==ValueBase::TYPE_CANVAS)
394                 {
395                         // This parameter is a canvas.  We need a close look.
396                         Canvas::Handle canvas(iter->second.get(Canvas::Handle()));
397                         if(canvas && canvas->is_inline())
398                         {
399                                 // This parameter is an inline canvas! we need to clone it
400                                 // before we set it as a parameter.
401                                 Canvas::Handle new_canvas(canvas->clone(deriv_guid));
402                                 ValueBase value(new_canvas);
403                                 ret->set_param(iter->first, value);
404                                 continue;
405                         }
406                 }
407
408                 // This is a normal parameter,go ahead and set it.
409                 ret->set_param(iter->first, iter->second);
410         }
411
412         // Duplicate the dynamic paramlist, but only the exported data nodes
413         DynamicParamList::const_iterator iter;
414         for(iter=dynamic_param_list().begin();iter!=dynamic_param_list().end();++iter)
415         {
416                 // Make sure we clone inline canvases
417                 if(iter->second->get_type()==ValueBase::TYPE_CANVAS)
418                 {
419                         Canvas::Handle canvas((*iter->second)(0).get(Canvas::Handle()));
420                         if(canvas->is_inline())
421                         {
422                                 Canvas::Handle new_canvas(canvas->clone(deriv_guid));
423                                 ValueBase value(new_canvas);
424                                 ret->connect_dynamic_param(iter->first,ValueNode_Const::create(value));
425                                 continue;
426                         }
427                 }
428
429                 if(iter->second->is_exported())
430                         ret->connect_dynamic_param(iter->first,iter->second);
431                 else
432                         ret->connect_dynamic_param(iter->first,iter->second->clone(deriv_guid));
433         }
434
435         //ret->set_canvas(0);
436
437         return ret;
438 }
439
440 bool
441 Layer::reads_context() const
442 {
443         return false;
444 }
445
446 Rect
447 Layer::get_full_bounding_rect(Context context)const
448 {
449         if(active())
450                 return context.get_full_bounding_rect()|get_bounding_rect();
451         return context.get_full_bounding_rect();
452 }
453
454 Rect
455 Layer::get_bounding_rect()const
456 {
457         return Rect::full_plane();
458 }
459
460 bool
461 Layer::set_param_list(const ParamList &list)
462 {
463         bool ret=true;
464         if(!list.size())
465                 return false;
466         ParamList::const_iterator iter(list.begin());
467         for(;iter!=list.end();++iter)
468         {
469                 if(!set_param(iter->first, iter->second))ret=false;
470         }
471         return ret;
472 }
473
474 Layer::ParamList
475 Layer::get_param_list()const
476 {
477         ParamList ret;
478
479         Vocab vocab(get_param_vocab());
480
481         Vocab::const_iterator iter=vocab.begin();
482         for(;iter!=vocab.end();++iter)
483         {
484                 ret[iter->get_name()]=get_param(iter->get_name());
485         }
486         return ret;
487 }
488
489 ValueBase
490 Layer::get_param(const String & param)const
491 {
492         if(param=="z_depth")
493         {
494                 synfig::ValueBase ret(get_z_depth());
495                 ret.set_static(get_param_static(param));
496                 return ret;
497         }
498         return ValueBase();
499 }
500
501 String
502 Layer::get_version()const
503 {
504         return get_param("version__").get(String());
505 }
506
507 bool
508 Layer::set_version(const String &/*ver*/)
509 {
510         return false;
511 }
512
513 void
514 Layer::reset_version()
515 {
516 }
517
518
519 void
520 Layer::set_time(Context context, Time time)const
521 {
522         context.set_time(time);
523         dirty_time_=time;
524 }
525
526 void
527 Layer::set_time(Context context, Time time, const Point &pos)const
528 {
529         context.set_time(time,pos);
530         dirty_time_=time;
531 }
532
533 Color
534 Layer::get_color(Context context, const Point &pos)const
535 {
536         return context.get_color(pos);
537 }
538
539 synfig::Layer::Handle
540 Layer::hit_check(synfig::Context context, const synfig::Point &pos)const
541 {
542         return context.hit_check(pos);
543 }
544
545 /*      The default accelerated renderer
546 **      is anything but accelerated...
547 */
548 bool
549 Layer::accelerated_render(Context context,Surface *surface,int /*quality*/, const RendDesc &renddesc, ProgressCallback *cb)  const
550 {
551         handle<Target> target=surface_target(surface);
552         if(!target)
553         {
554                 if(cb)cb->error(_("Unable to create surface target"));
555                 return false;
556         }
557         RendDesc desc=renddesc;
558         target->set_rend_desc(&desc);
559
560         // When we render, we want to
561         // make sure that we are rendered too...
562         // Since the context iterator is for
563         // the layer after us, we need to back up.
564         // This could be considered a hack, as
565         // it is a possibility that we are indeed
566         // not the previous layer.
567         --context;
568
569         return render(context,target,desc,cb);
570         //return render_threaded(context,target,desc,cb,2);
571 }
572
573 String
574 Layer::get_name()const
575 {
576         return get_param("name__").get(String());
577 }
578
579 String
580 Layer::get_local_name()const
581 {
582         return get_param("local_name__").get(String());
583 }
584
585
586 Layer::Vocab
587 Layer::get_param_vocab()const
588 {
589         Layer::Vocab ret;
590
591         ret.push_back(ParamDesc(z_depth,"z_depth")
592                 .set_local_name(_("Z Depth"))
593                 .set_animation_only(true)
594         );
595
596         return ret;
597 }
598
599 void
600 Layer::get_times_vfunc(Node::time_set &set) const
601 {
602         DynamicParamList::const_iterator        i = dynamic_param_list_.begin(),
603                                                                                 end = dynamic_param_list_.end();
604
605         for(; i != end; ++i)
606         {
607                 const Node::time_set &tset = i->second->get_times();
608                 set.insert(tset.begin(),tset.end());
609         }
610 }
611
612
613 void
614 Layer::add_to_group(const String&x)
615 {
616         if(x==group_)
617                 return;
618         if(!group_.empty())
619                 remove_from_all_groups();
620         group_=x;
621         signal_added_to_group()(group_);
622 }
623
624 void
625 Layer::remove_from_group(const String&x)
626 {
627         if(group_==x)
628                 remove_from_all_groups();
629 }
630
631 void
632 Layer::remove_from_all_groups()
633 {
634         if(group_.empty())
635                 return;
636         signal_removed_from_group()(group_);
637         group_.clear();
638 }
639
640 String
641 Layer::get_group()const
642 {
643         return group_;
644 }
645
646 const String
647 Layer::get_param_local_name(const String &param_name)const
648 {
649         ParamVocab vocab = get_param_vocab();
650         // loop to find the parameter in the parameter vocab - this gives us its local name
651         for (ParamVocab::iterator iter = vocab.begin(); iter != vocab.end(); iter++)
652                 if (iter->get_name() == param_name)
653                         return iter->get_local_name();
654         return String();
655 }