1 /* === S Y N F I G ========================================================= */
2 /*! \file childrentreestore.cpp
3 ** \brief Template File
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007 Chris Moore
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.
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.
22 /* ========================================================================= */
24 /* === H E A D E R S ======================================================= */
33 #include "childrentreestore.h"
34 #include "iconcontroller.h"
35 #include <gtkmm/button.h>
36 #include <synfig/paramdesc.h>
41 class Profiler : private etl::clock
43 const std::string name;
45 Profiler(const std::string& name):name(name) { reset(); }
46 ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
51 /* === U S I N G =========================================================== */
55 using namespace synfig;
56 using namespace studio;
58 /* === M A C R O S ========================================================= */
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 ChildrenTreeStore::Model& ModelHack()
68 static ChildrenTreeStore::Model* model(0);
69 if(!model)model=new ChildrenTreeStore::Model;
73 ChildrenTreeStore::ChildrenTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
74 Gtk::TreeStore (ModelHack()),
75 CanvasTreeStore (canvas_interface_)
78 canvas_row[model.label]=_("Canvases");
79 canvas_row[model.is_canvas] = false;
80 canvas_row[model.is_value_node] = false;
82 value_node_row=*append();
83 value_node_row[model.label]=_("ValueBase Nodes");
84 value_node_row[model.is_canvas] = false;
85 value_node_row[model.is_value_node] = false;
87 // Connect all the signals
88 canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_changed));
89 canvas_interface()->signal_value_node_renamed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_renamed));
90 canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_added));
91 canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_deleted));
92 canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_replaced));
93 canvas_interface()->signal_canvas_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_added));
94 canvas_interface()->signal_canvas_removed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_removed));
99 ChildrenTreeStore::~ChildrenTreeStore()
103 Glib::RefPtr<ChildrenTreeStore>
104 ChildrenTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
106 return Glib::RefPtr<ChildrenTreeStore>(new ChildrenTreeStore(canvas_interface_));
110 ChildrenTreeStore::rebuild()
112 // Profiler profiler("ChildrenTreeStore::rebuild()");
113 rebuild_value_nodes();
118 ChildrenTreeStore::refresh()
120 // Profiler profiler("ChildrenTreeStore::refresh()");
121 refresh_value_nodes();
126 ChildrenTreeStore::rebuild_value_nodes()
128 Gtk::TreeModel::Children children(value_node_row.children());
130 while(!children.empty())erase(children.begin());
132 clear_changed_queue();
135 canvas_interface()->get_canvas()->value_node_list().rbegin(), canvas_interface()->get_canvas()->value_node_list().rend(),
136 sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_value_node_added)
141 ChildrenTreeStore::refresh_value_nodes()
143 Gtk::TreeModel::Children children(value_node_row.children());
145 Gtk::TreeModel::Children::iterator iter;
147 if(!children.empty())
148 for(iter = children.begin(); iter != children.end(); ++iter)
150 Gtk::TreeRow row=*iter;
156 ChildrenTreeStore::rebuild_canvases()
158 Gtk::TreeModel::Children children(canvas_row.children());
160 while(!children.empty())erase(children.begin());
163 canvas_interface()->get_canvas()->children().rbegin(), canvas_interface()->get_canvas()->children().rend(),
164 sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_canvas_added)
169 ChildrenTreeStore::refresh_canvases()
175 ChildrenTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool /*do_children*/)
177 CanvasTreeStore::refresh_row(row,false);
179 if((bool)row[model.is_value_node])
181 changed_set_.erase(row[model.value_node]);
187 ChildrenTreeStore::on_canvas_added(synfig::Canvas::Handle canvas)
189 Gtk::TreeRow row = *(prepend(canvas_row.children()));
191 row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("synfig-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
192 row[model.id] = canvas->get_id();
193 row[model.name] = canvas->get_name();
195 if(!canvas->get_id().empty())
196 row[model.label] = canvas->get_id();
198 if(!canvas->get_name().empty())
199 row[model.label] = canvas->get_name();
201 row[model.label] = _("[Unnamed]");
203 row[model.canvas] = canvas;
204 row[model.type] = _("Canvas");
205 //row[model.is_canvas] = true;
206 //row[model.is_value_node] = false;
210 ChildrenTreeStore::on_canvas_removed(synfig::Canvas::Handle /*canvas*/)
216 ChildrenTreeStore::on_value_node_added(synfig::ValueNode::Handle value_node)
218 // if(value_node->get_id().find("Unnamed")!=String::npos)
221 Gtk::TreeRow row = *prepend(value_node_row.children());
223 set_row(row,synfigapp::ValueDesc(canvas_interface()->get_canvas(),value_node->get_id()),false);
227 ChildrenTreeStore::on_value_node_deleted(synfig::ValueNode::Handle value_node)
232 if(find_first_value_node(value_node,iter))
236 //rebuild_value_nodes();
240 ChildrenTreeStore::execute_changed_value_nodes()
242 // Profiler profiler("ChildrenTreeStore::execute_changed_value_nodes()");
243 if(!replaced_set_.empty())
244 rebuild_value_nodes();
249 while(!changed_set_.empty())
251 ValueNode::Handle value_node(*changed_set_.begin());
252 changed_set_.erase(value_node);
261 if(!value_node->is_exported() && find_first_value_node(value_node,iter))
263 rebuild_value_nodes();
267 if(value_node->is_exported() && find_first_value_node(value_node,iter)) do
269 Gtk::TreeRow row(*iter);
272 }while(find_next_value_node(value_node,iter));
276 refresh_value_nodes();
283 rebuild_value_nodes();
287 // If we are taking too long...
290 refresh_value_nodes();
299 ChildrenTreeStore::on_value_node_changed(synfig::ValueNode::Handle value_node)
302 if(!value_node->is_exported())
304 changed_connection.disconnect();
305 // if(!execute_changed_queued())
306 // changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
307 changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
309 changed_set_.insert(value_node);
315 while(find_next_value_node(value_node,iter))
317 Gtk::TreeRow row(*iter);
323 refresh_value_nodes();
328 rebuild_value_nodes();
334 ChildrenTreeStore::on_value_node_renamed(synfig::ValueNode::Handle value_node __attribute__ ((unused)))
336 rebuild_value_nodes();
340 ChildrenTreeStore::on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle /*new_value_node*/)
342 changed_connection.disconnect();
343 //if(!execute_changed_queued())
344 // changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
345 changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
347 replaced_set_.insert(replaced_value_node);
351 ChildrenTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
353 if(column>=get_n_columns_vfunc())
355 g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
359 if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
361 g_warning("LayerTreeStore::set_value_impl: Bad value type");
367 if(column==model.value.index())
369 Glib::Value<synfig::ValueBase> x;
370 g_value_init(x.gobj(),model.value.type());
371 g_value_copy(value.gobj(),x.gobj());
373 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
376 canvas_interface()->change_value(value_desc,x.get());
377 row_changed(get_path(*iter),*iter);
383 CanvasTreeStore::set_value_impl(iter,column, value);
385 catch(std::exception x)