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