1 /* === S Y N F I G ========================================================= */
2 /*! \file childrentreestore.cpp
3 ** \brief Template File
5 ** $Id: layerparamtreestore.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
8 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
10 ** This software and associated documentation
11 ** are CONFIDENTIAL and PROPRIETARY property of
12 ** the above-mentioned copyright holder.
14 ** You may not copy, print, publish, or in any
15 ** other way distribute this software without
16 ** a prior written agreement with
17 ** the copyright holder.
20 /* ========================================================================= */
22 /* === H E A D E R S ======================================================= */
31 #include "layerparamtreestore.h"
32 #include "iconcontroler.h"
33 #include <gtkmm/button.h>
34 #include <synfig/paramdesc.h>
35 #include "layertree.h"
36 #include <synfigapp/action_system.h>
37 #include <synfigapp/instance.h>
43 /* === U S I N G =========================================================== */
47 using namespace synfig;
48 using namespace studio;
50 /* === M A C R O S ========================================================= */
52 class Profiler : private etl::clock
54 const std::string name;
56 Profiler(const std::string& name):name(name) { reset(); }
57 ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
60 /* === G L O B A L S ======================================================= */
62 /* === P R O C E D U R E S ================================================= */
64 /* === M E T H O D S ======================================================= */
66 static LayerParamTreeStore::Model& ModelHack()
68 static LayerParamTreeStore::Model* model(0);
69 if(!model)model=new LayerParamTreeStore::Model;
73 LayerParamTreeStore::LayerParamTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_,LayerTree* layer_tree):
74 Gtk::TreeStore (ModelHack()),
75 CanvasTreeStore (canvas_interface_),
76 layer_tree (layer_tree)
79 // Connect all the signals
80 canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_changed));
81 canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_added));
82 canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_deleted));
83 canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_replaced));
84 canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_layer_param_changed));
86 canvas_interface()->signal_value_node_child_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_added));
87 canvas_interface()->signal_value_node_child_removed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_removed));
90 layer_tree->get_selection()->signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_rebuild));
92 signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_refresh));
96 LayerParamTreeStore::~LayerParamTreeStore()
98 while(!changed_connection_list.empty())
100 changed_connection_list.back().disconnect();
101 changed_connection_list.pop_back();
103 synfig::info("LayerParamTreeStore::~LayerParamTreeStore(): Deleted");
106 Glib::RefPtr<LayerParamTreeStore>
107 LayerParamTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree)
109 return Glib::RefPtr<LayerParamTreeStore>(new LayerParamTreeStore(canvas_interface_,layer_tree));
115 LayerParamTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
119 synfig::error("LayerParamTreeStore::get_value_vfunc(): Bad column!");
123 /* if(column==model.label.index())
125 synfig::Layer::Handle layer((*iter)[model.layer]);
129 Glib::Value<Glib::ustring> x;
130 g_value_init(x.gobj(),x.value_type());
133 if(!layer->get_description().empty())
134 x.set(layer->get_description());
136 x.set(layer->get_local_name());
138 g_value_init(value.gobj(),x.value_type());
139 g_value_copy(x.gobj(),value.gobj());
143 if(column==model.label.index())
145 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
148 if(!(*iter)[model.is_toplevel])
149 return CanvasTreeStore::get_value_vfunc(iter,column,value);
150 synfig::ParamDesc param_desc((*iter)[model.param_desc]);
151 label=param_desc.get_local_name();
153 if(!(*iter)[model.is_inconsistent])
154 if(value_desc.is_value_node() && value_desc.get_value_node()->is_exported())
156 label+=strprintf(" (%s)",value_desc.get_value_node()->get_id().c_str());
159 Glib::Value<Glib::ustring> x;
160 g_value_init(x.gobj(),x.value_type());
164 g_value_init(value.gobj(),x.value_type());
165 g_value_copy(x.gobj(),value.gobj());
168 if(column==model.is_toplevel.index())
171 g_value_init(x.gobj(),x.value_type());
173 TreeModel::Path path(get_path(iter));
175 x.set(path.get_depth()<=1);
177 g_value_init(value.gobj(),x.value_type());
178 g_value_copy(x.gobj(),value.gobj());
181 if(column==model.is_inconsistent.index())
183 if((*iter)[model.is_toplevel])
185 CanvasTreeStore::get_value_vfunc(iter,column,value);
190 g_value_init(x.gobj(),x.value_type());
194 g_value_init(value.gobj(),x.value_type());
195 g_value_copy(x.gobj(),value.gobj());
198 CanvasTreeStore::get_value_vfunc(iter,column,value);
204 LayerParamTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
206 //if(!iterator_sane(row))
209 if(column>=get_n_columns_vfunc())
211 g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
215 if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
217 g_warning("LayerTreeStore::set_value_impl: Bad value type");
223 if(column==model.value.index())
225 Glib::Value<synfig::ValueBase> x;
226 g_value_init(x.gobj(),model.value.type());
227 g_value_copy(value.gobj(),x.gobj());
229 if((bool)(*iter)[model.is_toplevel])
231 synfigapp::Action::PassiveGrouper group(canvas_interface()->get_instance().get(),_("Set Layer Params"));
233 synfig::ParamDesc param_desc((*iter)[model.param_desc]);
235 LayerList::iterator iter2(layer_list.begin());
237 for(;iter2!=layer_list.end();++iter2)
239 if(!canvas_interface()->change_value(synfigapp::ValueDesc(*iter2,param_desc.get_name()),x.get()))
243 App::dialog_error_blocking(_("Error"),_("Unable to set all layer parameters."));
251 canvas_interface()->change_value((*iter)[model.value_desc],x.get());
257 if(column==model.active.index())
259 synfig::Layer::Handle layer((*iter)[model.layer]);
264 g_value_init(x.gobj(),model.active.type());
265 g_value_copy(value.gobj(),x.gobj());
267 synfigapp::Action::Handle action(synfigapp::Action::create("layer_activate"));
272 action->set_param("canvas",canvas_interface()->get_canvas());
273 action->set_param("canvas_interface",canvas_interface());
274 action->set_param("layer",layer);
275 action->set_param("new_status",bool(x.get()));
277 canvas_interface()->get_instance()->perform_action(action);
282 CanvasTreeStore::set_value_impl(iter,column, value);
284 catch(std::exception x)
300 LayerParamTreeStore::rebuild()
302 Profiler profiler("LayerParamTreeStore::rebuild()");
303 if(queued)queued=false;
305 layer_list=layer_tree->get_selected_layers();
307 if(layer_list.size()<=0)
310 // Get rid of all the connections,
311 // and clear the connection map.
312 //while(!connection_map.empty())connection_map.begin()->second.disconnect(),connection_map.erase(connection_map.begin());
313 while(!changed_connection_list.empty())
315 changed_connection_list.back().disconnect();
316 changed_connection_list.pop_back();
319 struct REBUILD_HELPER
323 static ParamVocab::iterator find_param_desc(ParamVocab& vocab, const synfig::String& x)
325 ParamVocab::iterator iter;
327 for(iter=vocab.begin();iter!=vocab.end();++iter)
328 if(iter->get_name()==x)
333 void process_vocab(ParamVocab x)
335 ParamVocab::iterator iter;
337 for(iter=vocab.begin();iter!=vocab.end();++iter)
339 ParamVocab::iterator iter2(find_param_desc(x,iter->get_name()));
342 // remove it and start over
355 LayerList::iterator iter(layer_list.begin());
356 rebuild_helper.vocab=(*iter)->get_param_vocab();
358 for(++iter;iter!=layer_list.end();++iter)
360 rebuild_helper.process_vocab((*iter)->get_param_vocab());
361 changed_connection_list.push_back(
362 (*iter)->signal_changed().connect(
365 &LayerParamTreeStore::changed
372 ParamVocab::iterator iter;
373 for(iter=rebuild_helper.vocab.begin();iter!=rebuild_helper.vocab.end();++iter)
375 if(iter->get_hidden())
379 if(iter->get_animation_only())
381 int length(layer_list.front()->get_canvas()->rend_desc().get_frame_end()-layer_list.front()->get_canvas()->rend_desc().get_frame_start());
386 Gtk::TreeRow row(*(append()));
387 synfigapp::ValueDesc value_desc(layer_list.front(),iter->get_name());
388 CanvasTreeStore::set_row(row,value_desc);
389 if(value_desc.is_value_node())
391 changed_connection_list.push_back(
392 value_desc.get_value_node()->signal_changed().connect(
395 &LayerParamTreeStore::changed
400 if(value_desc.get_value_type()==ValueBase::TYPE_CANVAS)
402 changed_connection_list.push_back(
403 value_desc.get_value().get(Canvas::Handle())->signal_changed().connect(
406 &LayerParamTreeStore::changed
411 //row[model.label] = iter->get_local_name();
412 row[model.param_desc] = *iter;
413 row[model.canvas] = layer_list.front()->get_canvas();
414 row[model.is_inconsistent] = false;
415 //row[model.is_toplevel] = true;
418 LayerList::iterator iter2(layer_list.begin());
419 ValueBase value((*iter2)->get_param(iter->get_name()));
420 for(++iter2;iter2!=layer_list.end();++iter2)
422 if(value!=((*iter2)->get_param(iter->get_name())))
424 row[model.is_inconsistent] = true;
425 while(!row.children().empty() && erase(row.children().begin()));
433 LayerParamTreeStore::queue_refresh()
438 queue_connection.disconnect();
439 queue_connection=Glib::signal_timeout().connect(
441 sigc::mem_fun(*this,&LayerParamTreeStore::refresh),
449 LayerParamTreeStore::queue_rebuild()
454 queue_connection.disconnect();
455 queue_connection=Glib::signal_timeout().connect(
457 sigc::mem_fun(*this,&LayerParamTreeStore::rebuild),
465 LayerParamTreeStore::refresh()
467 if(queued)queued=false;
469 Gtk::TreeModel::Children children_(children());
471 Gtk::TreeModel::Children::iterator iter;
473 if(!children_.empty())
474 for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
476 Gtk::TreeRow row=*iter;
482 LayerParamTreeStore::refresh_row(Gtk::TreeModel::Row &row)
484 if(row[model.is_toplevel])
486 row[model.is_inconsistent] = false;
487 ParamDesc param_desc(row[model.param_desc]);
489 LayerList::iterator iter2(layer_list.begin());
490 ValueBase value((*iter2)->get_param(param_desc.get_name()));
491 for(++iter2;iter2!=layer_list.end();++iter2)
493 if(value!=((*iter2)->get_param(param_desc.get_name())))
495 row[model.is_inconsistent] = true;
496 while(!row.children().empty() && erase(row.children().begin()));
502 //handle<ValueNode> value_node=row[model.value_node];
505 CanvasTreeStore::refresh_row(row);
511 LayerParamTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc)
513 Gtk::TreeModel::Children children = row.children();
514 while(!children.empty() && erase(children.begin()));
516 CanvasTreeStore::set_row(row,value_desc);
520 LayerParamTreeStore::on_value_node_added(ValueNode::Handle value_node)
526 LayerParamTreeStore::on_value_node_deleted(etl::handle<ValueNode> value_node)
532 LayerParamTreeStore::on_value_node_child_added(synfig::ValueNode::Handle value_node,synfig::ValueNode::Handle child)
538 LayerParamTreeStore::on_value_node_child_removed(synfig::ValueNode::Handle value_node,synfig::ValueNode::Handle child)
544 LayerParamTreeStore::on_value_node_changed(etl::handle<ValueNode> value_node)
550 LayerParamTreeStore::on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node)
556 LayerParamTreeStore::on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name)