1 /* === S Y N F I G ========================================================= */
3 ** \brief Layer class implementation
5 ** $Id: layer.cpp,v 1.2 2005/01/24 03:08:17 darco Exp $
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
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.
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.
21 /* ========================================================================= */
23 /* === H E A D E R S ======================================================= */
25 #define SYNFIG_NO_ANGLE
38 #include "layer_bitmap.h"
39 #include "layer_mime.h"
41 #include "paramdesc.h"
43 #include "layer_solidcolor.h"
44 #include "layer_polygon.h"
45 #include "layer_pastecanvas.h"
46 #include "layer_motionblur.h"
48 #include "valuenode_const.h"
50 #include "transform.h"
54 #include <sigc++/adaptors/bind.h>
57 /* === U S I N G =========================================================== */
61 using namespace synfig;
63 /* === G L O B A L S ======================================================= */
65 static Layer::Book* _layer_book;
73 synfig::error("%d layers not yet deleted!",counter);
77 int _LayerCounter::counter(0);
79 /* === P R O C E D U R E S ================================================= */
88 Layer::register_in_book(const BookEntry &entry)
90 book()[entry.name]=entry;
96 _layer_book=new Book();
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__);
101 INCLUDE_LAYER(Layer_SolidColor);
102 INCLUDE_LAYER(Layer_PasteCanvas);
103 INCLUDE_LAYER(Layer_Polygon);
104 LAYER_ALIAS(Layer_Polygon,"Polygon");
105 INCLUDE_LAYER(Layer_MotionBlur);
119 /* === M E T H O D S ======================================================= */
124 dirty_time_(Time::end())
126 _LayerCounter::counter++;
130 synfig::Layer::create(const String &name)
132 if(!book().count(name))
134 return Layer::LooseHandle(new Layer_Mime(name));
137 Layer* layer(book()[name].factory());
138 return Layer::LooseHandle(layer);
141 synfig::Layer::~Layer()
143 _LayerCounter::counter--;
144 while(!dynamic_param_list_.empty())
146 remove_child(dynamic_param_list_.begin()->second.get());
147 dynamic_param_list_.erase(dynamic_param_list_.begin());
150 remove_from_all_groups();
152 parent_death_connect_.disconnect();
157 synfig::Layer::set_canvas(etl::loose_handle<synfig::Canvas> x)
161 parent_death_connect_.disconnect();
165 parent_death_connect_=x->signal_deleted().connect(
171 etl::loose_handle<synfig::Canvas>(0)
180 synfig::Layer::on_canvas_set()
184 etl::loose_handle<synfig::Canvas>
185 synfig::Layer::get_canvas()const
191 Layer::get_depth()const
195 return get_canvas()->get_depth(const_cast<synfig::Layer*>(this));
199 Layer::set_active(bool x)
206 signal_status_changed_();
211 Layer::set_description(const String& x)
216 signal_description_changed_();
221 Layer::connect_dynamic_param(const String& param, etl::loose_handle<ValueNode> value_node)
223 ValueNode::Handle previous(dynamic_param_list_[param]);
225 if(previous==value_node)
228 dynamic_param_list_[param]=ValueNode::Handle(value_node);
231 remove_child(previous.get());
233 add_child(value_node.get());
235 if(!value_node->is_exported() && get_canvas())
237 value_node->set_parent_canvas(get_canvas());
245 Layer::disconnect_dynamic_param(const String& param)
247 ValueNode::Handle previous(dynamic_param_list_[param]);
251 dynamic_param_list_.erase(param);
252 remove_child(previous.get());
261 dirty_time_=Time::end();
267 Layer::set_param(const String ¶m, const ValueBase &value)
269 if(param=="z_depth" && value.same_as(z_depth_))
271 z_depth_=value.get(z_depth_);
277 etl::handle<Transform>
278 Layer::get_transform()const
284 Layer::get_z_depth(const synfig::Time& t)const
286 if(!dynamic_param_list().count("z_depth"))
288 return (*dynamic_param_list().find("z_depth")->second)(t).get(Real());
292 Layer::simple_clone()const
294 if(!book().count(get_name())) return 0;
295 Layer *ret = create(get_name()).get();
296 ret->set_canvas(get_canvas());
297 ret->set_description(get_description());
298 ret->set_param_list(get_param_list());
303 Layer::clone(const GUID& deriv_guid) const
305 if(!book().count(get_name())) return 0;
307 //Layer *ret = book()[get_name()].factory();//create(get_name()).get();
308 Handle ret = create(get_name()).get();
311 //ret->set_canvas(get_canvas());
312 ret->set_description(get_description());
313 ret->set_active(active());
314 ret->set_guid(get_guid()^deriv_guid);
316 //ret->set_param_list(get_param_list());
317 // Process the parameter list sothat
318 // we can duplicate any inlinecanvases
319 ParamList param_list(get_param_list());
320 for(ParamList::const_iterator iter(param_list.begin()); iter != param_list.end(); ++iter)
322 if(dynamic_param_list().count(iter->first)==0 && iter->second.get_type()==ValueBase::TYPE_CANVAS)
325 // This parameter is a canvas. We need a close look.
326 Canvas::Handle canvas(iter->second.get(Canvas::Handle()));
327 if(canvas->is_inline())
329 // This parameter is an inlinecanvas! we need to clone it
330 // before we set it as aparameter.
331 Canvas::Handle new_canvas(canvas->clone(deriv_guid));
332 ValueBase value(new_canvas);
333 ret->set_param(iter->first, value);
338 // This is a normal parameter,go ahead and set it.
339 ret->set_param(iter->first, iter->second);
342 // Duplicate the dynamic paramlist, but only the exported data nodes
343 DynamicParamList::const_iterator iter;
344 for(iter=dynamic_param_list().begin();iter!=dynamic_param_list().end();++iter)
346 // Make sure we clone inlinecanvases
347 if(iter->second->get_type()==ValueBase::TYPE_CANVAS)
349 Canvas::Handle canvas((*iter->second)(0).get(Canvas::Handle()));
350 if(canvas->is_inline())
352 Canvas::Handle new_canvas(canvas->clone(deriv_guid));
353 ValueBase value(new_canvas);
354 ret->connect_dynamic_param(iter->first,ValueNode_Const::create(value));
359 if(iter->second->is_exported())
360 ret->connect_dynamic_param(iter->first,iter->second);
362 ret->connect_dynamic_param(iter->first,iter->second->clone(deriv_guid));
365 //ret->set_canvas(0);
371 Layer::get_full_bounding_rect(Context context)const
374 return context.get_full_bounding_rect()|get_bounding_rect();
375 return context.get_full_bounding_rect();
379 Layer::get_bounding_rect()const
381 return Rect::full_plane();
385 Layer::set_param_list(const ParamList &list)
390 ParamList::const_iterator iter(list.begin());
391 for(;iter!=list.end();++iter)
393 if(!set_param(iter->first, iter->second))ret=false;
399 Layer::get_param_list()const
403 Vocab vocab(get_param_vocab());
405 Vocab::const_iterator iter=vocab.begin();
406 for(;iter!=vocab.end();++iter)
408 ret[iter->get_name()]=get_param(iter->get_name());
414 Layer::get_param(const String & param)const
417 return get_z_depth();
423 Layer::get_version()const
425 return get_param("version__").get(String());
429 Layer::set_version(const String &ver)
435 Layer::reset_version()
441 Layer::set_time(Context context, Time time)const
443 context.set_time(time);
448 Layer::set_time(Context context, Time time, const Point &pos)const
450 context.set_time(time,pos);
455 Layer::get_color(Context context, const Point &pos)const
457 return context.get_color(pos);
460 synfig::Layer::Handle
461 Layer::hit_check(synfig::Context context, const synfig::Point &pos)const
463 return context.hit_check(pos);
466 /* The default accelerated renderer
467 ** is anything but accelerated...
470 Layer::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb) const
472 handle<Target> target=surface_target(surface);
475 if(cb)cb->error(_("Unable to create surface target"));
478 RendDesc desc=renddesc;
479 target->set_rend_desc(&desc);
481 // When we render, we want to
482 // make sure that we are rendered too...
483 // Since the context iterator is for
484 // the layer after us, we need to back up.
485 // This could be considered a hack, as
486 // it is a possibility that we are indeed
487 // not the previous layer.
490 return render(context,target,desc,cb);
491 //return render_threaded(context,target,desc,cb,2);
495 Layer::get_name()const
497 return get_param("name__").get(String());
501 Layer::get_local_name()const
503 return get_param("local_name__").get(String());
508 Layer::get_param_vocab()const
512 ret.push_back(ParamDesc(z_depth_,"z_depth")
513 .set_local_name(_("Z Depth"))
514 .set_animation_only(true)
521 Layer::get_times_vfunc(Node::time_set &set) const
523 DynamicParamList::const_iterator i = dynamic_param_list_.begin(),
524 end = dynamic_param_list_.end();
528 const Node::time_set &tset = i->second->get_times();
529 set.insert(tset.begin(),tset.end());
535 Layer::add_to_group(const String&x)
540 remove_from_all_groups();
542 signal_added_to_group()(group_);
546 Layer::remove_from_group(const String&x)
549 remove_from_all_groups();
553 Layer::remove_from_all_groups()
557 signal_removed_from_group()(group_);
562 Layer::get_group()const