1 /* === S Y N F I G ========================================================= */
2 /*! \file layerparamtreestore.cpp
3 ** \brief Template File
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 ======================================================= */
32 #include "layerparamtreestore.h"
33 #include "iconcontroller.h"
34 #include <gtkmm/button.h>
35 #include <synfig/paramdesc.h>
36 #include "layertree.h"
37 #include <synfigapp/action_system.h>
38 #include <synfigapp/instance.h>
46 /* === U S I N G =========================================================== */
50 using namespace synfig;
51 using namespace studio;
53 /* === M A C R O S ========================================================= */
55 class Profiler : private etl::clock
57 const std::string name;
59 Profiler(const std::string& name):name(name) { reset(); }
60 ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
63 /* === G L O B A L S ======================================================= */
65 /* === P R O C E D U R E S ================================================= */
67 /* === M E T H O D S ======================================================= */
69 static LayerParamTreeStore::Model& ModelHack()
71 static LayerParamTreeStore::Model* model(0);
72 if(!model)model=new LayerParamTreeStore::Model;
76 LayerParamTreeStore::LayerParamTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_,LayerTree* layer_tree):
77 Gtk::TreeStore (ModelHack()),
78 CanvasTreeStore (canvas_interface_),
79 layer_tree (layer_tree)
82 // Connect all the signals
83 canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_changed));
84 canvas_interface()->signal_value_node_renamed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_renamed));
85 canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_added));
86 canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_deleted));
87 canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_replaced));
88 canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_layer_param_changed));
90 canvas_interface()->signal_value_node_child_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_added));
91 canvas_interface()->signal_value_node_child_removed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_removed));
94 layer_tree->get_selection()->signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_rebuild));
96 signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_refresh));
100 LayerParamTreeStore::~LayerParamTreeStore()
102 while(!changed_connection_list.empty())
104 changed_connection_list.back().disconnect();
105 changed_connection_list.pop_back();
107 synfig::info("LayerParamTreeStore::~LayerParamTreeStore(): Deleted");
110 Glib::RefPtr<LayerParamTreeStore>
111 LayerParamTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree)
113 return Glib::RefPtr<LayerParamTreeStore>(new LayerParamTreeStore(canvas_interface_,layer_tree));
119 LayerParamTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
123 synfig::error("LayerParamTreeStore::get_value_vfunc(): Bad column!");
127 /* if(column==model.label.index())
129 synfig::Layer::Handle layer((*iter)[model.layer]);
133 Glib::Value<Glib::ustring> x;
134 g_value_init(x.gobj(),x.value_type());
137 if(!layer->get_description().empty())
138 x.set(layer->get_description());
140 x.set(layer->get_local_name());
142 g_value_init(value.gobj(),x.value_type());
143 g_value_copy(x.gobj(),value.gobj());
147 if(column==model.label.index())
149 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
152 if(!(*iter)[model.is_toplevel])
153 return CanvasTreeStore::get_value_vfunc(iter,column,value);
154 synfig::ParamDesc param_desc((*iter)[model.param_desc]);
155 label=param_desc.get_local_name();
157 if(!(*iter)[model.is_inconsistent])
158 if(value_desc.is_value_node() && value_desc.get_value_node()->is_exported())
160 label+=strprintf(" (%s)",value_desc.get_value_node()->get_id().c_str());
163 Glib::Value<Glib::ustring> x;
164 g_value_init(x.gobj(),x.value_type());
168 g_value_init(value.gobj(),x.value_type());
169 g_value_copy(x.gobj(),value.gobj());
172 if(column==model.is_toplevel.index())
175 g_value_init(x.gobj(),x.value_type());
177 TreeModel::Path path(get_path(iter));
179 x.set(path.get_depth()<=1);
181 g_value_init(value.gobj(),x.value_type());
182 g_value_copy(x.gobj(),value.gobj());
185 if(column==model.is_inconsistent.index())
187 if((*iter)[model.is_toplevel])
189 CanvasTreeStore::get_value_vfunc(iter,column,value);
194 g_value_init(x.gobj(),x.value_type());
198 g_value_init(value.gobj(),x.value_type());
199 g_value_copy(x.gobj(),value.gobj());
202 CanvasTreeStore::get_value_vfunc(iter,column,value);
208 LayerParamTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
210 //if(!iterator_sane(row))
213 if(column>=get_n_columns_vfunc())
215 g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
219 if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
221 g_warning("LayerTreeStore::set_value_impl: Bad value type");
227 if(column==model.value.index())
229 Glib::Value<synfig::ValueBase> x;
230 g_value_init(x.gobj(),model.value.type());
231 g_value_copy(value.gobj(),x.gobj());
233 if((bool)(*iter)[model.is_toplevel])
235 synfigapp::Action::PassiveGrouper group(canvas_interface()->get_instance().get(),_("Set Layer Params"));
237 synfig::ParamDesc param_desc((*iter)[model.param_desc]);
239 LayerList::iterator iter2(layer_list.begin());
241 for(;iter2!=layer_list.end();++iter2)
243 if(!canvas_interface()->change_value(synfigapp::ValueDesc(*iter2,param_desc.get_name()),x.get()))
247 App::dialog_error_blocking(_("Error"),_("Unable to set all layer parameters."));
255 canvas_interface()->change_value((*iter)[model.value_desc],x.get());
261 if(column==model.active.index())
263 synfig::Layer::Handle layer((*iter)[model.layer]);
268 g_value_init(x.gobj(),model.active.type());
269 g_value_copy(value.gobj(),x.gobj());
271 synfigapp::Action::Handle action(synfigapp::Action::create("layer_activate"));
276 action->set_param("canvas",canvas_interface()->get_canvas());
277 action->set_param("canvas_interface",canvas_interface());
278 action->set_param("layer",layer);
279 action->set_param("new_status",bool(x.get()));
281 canvas_interface()->get_instance()->perform_action(action);
286 CanvasTreeStore::set_value_impl(iter,column, value);
288 catch(std::exception x)
304 LayerParamTreeStore::rebuild()
306 Profiler profiler("LayerParamTreeStore::rebuild()");
307 if(queued)queued=false;
309 layer_list=layer_tree->get_selected_layers();
311 if(layer_list.size()<=0)
314 // Get rid of all the connections,
315 // and clear the connection map.
316 //while(!connection_map.empty())connection_map.begin()->second.disconnect(),connection_map.erase(connection_map.begin());
317 while(!changed_connection_list.empty())
319 changed_connection_list.back().disconnect();
320 changed_connection_list.pop_back();
323 struct REBUILD_HELPER
327 static ParamVocab::iterator find_param_desc(ParamVocab& vocab, const synfig::String& x)
329 ParamVocab::iterator iter;
331 for(iter=vocab.begin();iter!=vocab.end();++iter)
332 if(iter->get_name()==x)
337 void process_vocab(ParamVocab x)
339 ParamVocab::iterator iter;
341 for(iter=vocab.begin();iter!=vocab.end();++iter)
343 ParamVocab::iterator iter2(find_param_desc(x,iter->get_name()));
346 // remove it and start over
359 LayerList::iterator iter(layer_list.begin());
360 rebuild_helper.vocab=(*iter)->get_param_vocab();
362 for(++iter;iter!=layer_list.end();++iter)
364 rebuild_helper.process_vocab((*iter)->get_param_vocab());
365 changed_connection_list.push_back(
366 (*iter)->signal_changed().connect(
369 &LayerParamTreeStore::changed
376 ParamVocab::iterator iter;
377 for(iter=rebuild_helper.vocab.begin();iter!=rebuild_helper.vocab.end();++iter)
379 if(iter->get_hidden())
383 if(iter->get_animation_only())
385 int length(layer_list.front()->get_canvas()->rend_desc().get_frame_end()-layer_list.front()->get_canvas()->rend_desc().get_frame_start());
390 Gtk::TreeRow row(*(append()));
391 synfigapp::ValueDesc value_desc(layer_list.front(),iter->get_name());
392 CanvasTreeStore::set_row(row,value_desc);
393 if(value_desc.is_value_node())
395 changed_connection_list.push_back(
396 value_desc.get_value_node()->signal_changed().connect(
399 &LayerParamTreeStore::changed
404 if(value_desc.get_value_type()==ValueBase::TYPE_CANVAS)
406 Canvas::Handle canvas_handle = value_desc.get_value().get(Canvas::Handle());
407 if(canvas_handle) changed_connection_list.push_back(
408 canvas_handle->signal_changed().connect(
411 &LayerParamTreeStore::changed
416 //row[model.label] = iter->get_local_name();
417 row[model.param_desc] = *iter;
418 row[model.canvas] = layer_list.front()->get_canvas();
419 row[model.is_inconsistent] = false;
420 //row[model.is_toplevel] = true;
423 LayerList::iterator iter2(layer_list.begin());
424 ValueBase value((*iter2)->get_param(iter->get_name()));
425 for(++iter2;iter2!=layer_list.end();++iter2)
427 if(value!=((*iter2)->get_param(iter->get_name())))
429 row[model.is_inconsistent] = true;
430 while(!row.children().empty() && erase(row.children().begin()));
438 LayerParamTreeStore::queue_refresh()
443 queue_connection.disconnect();
444 queue_connection=Glib::signal_timeout().connect(
446 sigc::mem_fun(*this,&LayerParamTreeStore::refresh),
454 LayerParamTreeStore::queue_rebuild()
459 queue_connection.disconnect();
460 queue_connection=Glib::signal_timeout().connect(
462 sigc::mem_fun(*this,&LayerParamTreeStore::rebuild),
470 LayerParamTreeStore::refresh()
472 if(queued)queued=false;
474 Gtk::TreeModel::Children children_(children());
476 Gtk::TreeModel::Children::iterator iter;
478 if(!children_.empty())
479 for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
481 Gtk::TreeRow row=*iter;
487 LayerParamTreeStore::refresh_row(Gtk::TreeModel::Row &row)
489 if(row[model.is_toplevel])
491 row[model.is_inconsistent] = false;
492 ParamDesc param_desc(row[model.param_desc]);
494 LayerList::iterator iter2(layer_list.begin());
495 ValueBase value((*iter2)->get_param(param_desc.get_name()));
496 for(++iter2;iter2!=layer_list.end();++iter2)
498 if(value!=((*iter2)->get_param(param_desc.get_name())))
500 row[model.is_inconsistent] = true;
501 while(!row.children().empty() && erase(row.children().begin()));
507 //handle<ValueNode> value_node=row[model.value_node];
510 CanvasTreeStore::refresh_row(row);
516 LayerParamTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc)
518 Gtk::TreeModel::Children children = row.children();
519 while(!children.empty() && erase(children.begin()));
521 CanvasTreeStore::set_row(row,value_desc);
525 LayerParamTreeStore::on_value_node_added(synfig::ValueNode::Handle /*value_node*/)
531 LayerParamTreeStore::on_value_node_deleted(synfig::ValueNode::Handle /*value_node*/)
537 LayerParamTreeStore::on_value_node_child_added(synfig::ValueNode::Handle /*value_node*/,synfig::ValueNode::Handle /*child*/)
543 LayerParamTreeStore::on_value_node_child_removed(synfig::ValueNode::Handle /*value_node*/,synfig::ValueNode::Handle /*child*/)
549 LayerParamTreeStore::on_value_node_changed(synfig::ValueNode::Handle /*value_node*/)
555 LayerParamTreeStore::on_value_node_renamed(synfig::ValueNode::Handle /*value_node*/)
561 LayerParamTreeStore::on_value_node_replaced(synfig::ValueNode::Handle /*replaced_value_node*/,synfig::ValueNode::Handle /*new_value_node*/)
567 LayerParamTreeStore::on_layer_param_changed(synfig::Layer::Handle /*handle*/,synfig::String /*param_name*/)