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