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