TREEVIEW_HH = \
- childrentree.h \
- keyframetree.h \
- layergrouptree.h \
- layertree.h
+ trees/childrentree.h \
+ trees/keyframetree.h \
+ trees/layergrouptree.h \
+ trees/layertree.h
TREEVIEW_CC = \
- childrentree.cpp \
- keyframetree.cpp \
- layergrouptree.cpp \
- layertree.cpp
+ trees/childrentree.cpp \
+ trees/keyframetree.cpp \
+ trees/layergrouptree.cpp \
+ trees/layertree.cpp
TREESTORE_HH = \
- canvastreestore.h \
- childrentreestore.h \
- historytreestore.h \
- keyframetreestore.h \
- layergrouptreestore.h \
- layerparamtreestore.h \
- layertreestore.h \
- metadatatreestore.h
+ trees/canvastreestore.h \
+ trees/childrentreestore.h \
+ trees/historytreestore.h \
+ trees/keyframetreestore.h \
+ trees/layergrouptreestore.h \
+ trees/layerparamtreestore.h \
+ trees/layertreestore.h \
+ trees/metadatatreestore.h
TREESTORE_CC = \
- canvastreestore.cpp \
- childrentreestore.cpp \
- historytreestore.cpp \
- keyframetreestore.cpp \
- layergrouptreestore.cpp \
- layerparamtreestore.cpp \
- layertreestore.cpp \
- metadatatreestore.cpp
+ trees/canvastreestore.cpp \
+ trees/childrentreestore.cpp \
+ trees/historytreestore.cpp \
+ trees/keyframetreestore.cpp \
+ trees/layergrouptreestore.cpp \
+ trees/layerparamtreestore.cpp \
+ trees/layertreestore.cpp \
+ trees/metadatatreestore.cpp
DUCKTRANSFORM_HH = \
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file canvastreestore.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "canvastreestore.h"
-#include <synfig/valuenode.h>
-#include "iconcontroller.h"
-#include <synfig/valuenode_timedswap.h>
-#include <synfig/valuenode_animated.h>
-#include <gtkmm/button.h>
-#include <synfigapp/instance.h>
-#include "cellrenderer_value.h"
-#include "cellrenderer_timetrack.h"
-#include <ETL/clock>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static CanvasTreeStore::Model& ModelHack()
-{
- static CanvasTreeStore::Model* model(0);
- if(!model)model=new CanvasTreeStore::Model;
- return *model;
-}
-
-CanvasTreeStore::CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
- Gtk::TreeStore(ModelHack()),
- canvas_interface_ (canvas_interface_)
-{
-}
-
-CanvasTreeStore::~CanvasTreeStore()
-{
-}
-
-void
-CanvasTreeStore::get_value_vfunc(const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
-{
- if(column==model.value.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
- Glib::Value<synfig::ValueBase> x;
- g_value_init(x.gobj(),x.value_type());
-
- if(!value_desc)
- {
- x.set(ValueBase());
- }
- else
- if(value_desc.is_const())
- x.set(value_desc.get_value());
- else
- if(value_desc.is_value_node())
- x.set((*value_desc.get_value_node())(canvas_interface()->get_time()));
- else
- {
- synfig::error(__FILE__":%d: Unable to figure out value",__LINE__);
- return;
- }
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.is_value_node.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
- Glib::Value<bool> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(value_desc && value_desc.is_value_node());
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.is_shared.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
- Glib::Value<bool> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(value_desc.is_value_node() && value_desc.get_value_node()->rcount()>1);
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.is_exported.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
- Glib::Value<bool> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(value_desc.is_value_node() && value_desc.get_value_node()->is_exported());
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.is_canvas.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
- Glib::Value<bool> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(!value_desc && (Canvas::Handle)(*iter)[model.canvas]);
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.id.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
-
- if(value_desc && value_desc.is_value_node())
- x.set(value_desc.get_value_node()->get_id());
- else if(!value_desc && Canvas::Handle((*iter)[model.canvas]))
- x.set(Canvas::Handle((*iter)[model.canvas])->get_id());
- else
- return Gtk::TreeStore::get_value_vfunc(iter,column,value);
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.is_editable.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
- Glib::Value<bool> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(!value_desc.is_value_node() || synfigapp::is_editable(value_desc.get_value_node()));
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.type.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
-
- // Set the type
- if(!value_desc)
- {
- if((*iter)[model.is_canvas])
- x.set(_("Canvas"));
- }
- else
- {
- if(!value_desc.is_value_node() || value_desc.get_value_node()->get_name()=="constant")
- {
- x.set(ValueBase::type_local_name(value_desc.get_value_type()));
- }
- else
- {
- x.set(value_desc.get_value_node()->get_local_name());
- }
- }
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.label.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
-
- // Set the type
- if(!value_desc)
- {
- Canvas::Handle canvas((*iter)[model.canvas]);
- if(canvas)
- {
- if(!canvas->get_id().empty())
- x.set(canvas->get_id());
- else
- if(!canvas->get_name().empty())
- x.set(canvas->get_name());
- else
- x.set(_("[Unnamed]"));
- x.set(_("Canvas"));
- }
- return Gtk::TreeStore::get_value_vfunc(iter,column,value);
- }
- else
- {
- ValueNode::Handle value_node=value_desc.get_value_node();
-
- // Setup the row's label
- if(value_node->get_id().empty())
- x.set(Glib::ustring((*iter)[model.name]));
- else if(Glib::ustring((*iter)[model.name]).empty())
- x.set(value_node->get_id());
- else
- x.set(Glib::ustring((*iter)[model.name])+" ("+value_node->get_id()+')');
- }
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.icon.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
- if(!value_desc)
- return Gtk::TreeStore::get_value_vfunc(iter,column,value);
-
- Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(get_tree_pixbuf(value_desc.get_value_type()));
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- Gtk::TreeStore::get_value_vfunc(iter,column,value);
-}
-
-bool
-CanvasTreeStore::find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
-{
- iter=children().begin();
- while(iter && value_desc!=(*iter)[model.value_desc])
- {
- if(!iter->children().empty())
- {
- Gtk::TreeIter iter2(iter->children().begin());
- //! \todo confirm that the && should be done before the ||
- if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
- {
- iter=iter2;
- return true;
- }
- }
- Gtk::TreeIter iter2(++iter);
- if(!iter2)
- iter==iter->parent();
- else
- iter=iter2;
- }
- return (bool)iter && value_desc==(*iter)[model.value_desc];
-}
-
-bool
-CanvasTreeStore::find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
-{
- if(!iter) return find_first_value_desc(value_desc,iter);
-
- if(iter) do {
- if(!iter->children().empty())
- {
- Gtk::TreeIter iter2(iter->children().begin());
- //! \todo confirm that the && should be done before the ||
- if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
- {
- iter=iter2;
- return true;
- }
- }
- Gtk::TreeIter iter2(++iter);
- if(!iter2)
- {
- iter==iter->parent();
- if(iter)++iter;
- }
- else
- iter=iter2;
- } while(iter && value_desc!=(*iter)[model.value_desc]);
- return (bool)iter && value_desc==(*iter)[model.value_desc];
-}
-
-bool
-CanvasTreeStore::find_first_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
-{
- iter=children().begin();
- while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node])
- {
- if(!iter->children().empty())
- {
- Gtk::TreeIter iter2(iter->children().begin());
- //! \todo confirm that the && should be done before the ||
- if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
- {
- iter=iter2;
- return true;
- }
- }
- Gtk::TreeIter iter2(++iter);
- if(!iter2)
- iter==iter->parent();
- else
- iter=iter2;
- }
- return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
-}
-
-bool
-CanvasTreeStore::find_next_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
-{
- if(!iter) return find_first_value_node(value_node,iter);
-
- if(iter) do {
- if(!iter->children().empty())
- {
- Gtk::TreeIter iter2(iter->children().begin());
- //! \todo confirm that the && should be done before the ||
- if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
- {
- iter=iter2;
- return true;
- }
- }
- Gtk::TreeIter iter2(++iter);
- if(!iter2)
- {
- iter==iter->parent();
- if(iter)++iter;
- }
- else
- iter=iter2;
- } while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node]);
- return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
-}
-
-void
-CanvasTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children)
-{
- Gtk::TreeModel::Children children = row.children();
- while(!children.empty() && erase(children.begin()))
- ;
-
- row[model.value_desc]=value_desc;
- try
- {
- //row[model.icon] = get_tree_pixbuf(value_desc.get_value_type());
-
- if(value_desc.is_value_node())
- {
- ValueNode::Handle value_node=value_desc.get_value_node();
-
- assert(value_node);
-
- row[model.value_node] = value_node;
- //row[model.is_canvas] = false;
- //row[model.is_value_node] = true;
- //row[model.is_editable] = synfigapp::is_editable(value_node);
- //row[model.id]=value_node->get_id();
-
- // Set the canvas
- if(value_desc.parent_is_canvas())
- row[model.canvas]=value_desc.get_canvas();
- else
- row[model.canvas]=canvas_interface()->get_canvas();
-
- LinkableValueNode::Handle linkable;
- linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
-
- if(linkable && do_children)
- {
- row[model.link_count] = linkable->link_count();
- for(int i=0;i<linkable->link_count();i++)
- {
- Gtk::TreeRow child_row=*(append(row.children()));
- child_row[model.link_id] = i;
- child_row[model.canvas] = static_cast<Canvas::Handle>(row[model.canvas]);
- child_row[model.name] = linkable->link_local_name(i);
- set_row(child_row,synfigapp::ValueDesc(linkable,i));
- }
- }
- return;
- }
- else
- {
- //row[model.is_value_node] = false;
- //row[model.is_editable] = true;
- //row[model.label] = Glib::ustring(row[model.name]);
- return;
- }
- }
- catch(synfig::Exception::IDNotFound x)
- {
- synfig::error(__FILE__":%d: IDNotFound thrown",__LINE__);
- erase(row);
- return;
- }
-
- // We should never get to this point
- assert(0);
-}
-
-void
-CanvasTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool do_children)
-{
- synfigapp::ValueDesc value_desc=row[model.value_desc];
-
- if(value_desc)
- {
- if((bool)row[model.is_value_node] != value_desc.is_value_node() ||
- (!bool(row[model.is_value_node]) && row[model.link_count]!=0))
- {
- set_row(row,value_desc,do_children);
- return;
- }
-
- if(row[model.is_value_node])
- {
- ValueNode::Handle value_node(value_desc.get_value_node());
-
- if(ValueNode::Handle(row[model.value_node])!=value_node)
- {
- rebuild_row(row,do_children);
- return;
- }
-
- //row[model.id]=value_node->get_id();
-
- // Setup the row's label
- /*
- if(value_node->get_id().empty())
- row[model.label] = Glib::ustring(row[model.name]);
- else if(Glib::ustring(row[model.name]).empty())
- row[model.label] = value_node->get_id();
- else
- row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
- */
-
- LinkableValueNode::Handle linkable;
- linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
- if(do_children && linkable && ((int)row[model.link_count] != linkable->link_count()))
- {
- // Gtk::TreeModel::Children children = row.children();
- // while(!children.empty() && erase(children.begin()));
-
- set_row(row,value_desc);
- return;
- }
- }
- else
- {
- //row[model.label] = Glib::ustring(row[model.name]);
- //row[model.is_value_node] = false;
- //row[model.is_editable] = true;
- }
- }
- if(!do_children)
- return;
-
- Gtk::TreeModel::Children children = row.children();
- Gtk::TreeModel::Children::iterator iter;
-
- if(!children.empty())
- for(iter = children.begin(); iter != children.end(); ++iter)
- {
- Gtk::TreeRow row=*iter;
- refresh_row(row);
- }
-}
-
-void
-CanvasTreeStore::rebuild_row(Gtk::TreeModel::Row &row, bool do_children)
-{
- synfigapp::ValueDesc value_desc=(synfigapp::ValueDesc)row[model.value_desc];
-
- if(value_desc && value_desc.get_value_node())
- {
- ValueNode::Handle value_node;
- value_node=value_desc.get_value_node();
-
- assert(value_node);if(!value_node)return;
-
- if(value_node && value_node!=(ValueNode::Handle)row[model.value_node])
- {
-// Gtk::TreeModel::Children children = row.children();
-// while(!children.empty() && erase(children.begin()));
-
- set_row(row,value_desc,do_children);
- return;
- }
-
- LinkableValueNode::Handle linkable;
- linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
-
- if( do_children && linkable && (int)row[model.link_count] != linkable->link_count())
- {
-// Gtk::TreeModel::Children children = row.children();
-// while(!children.empty() && erase(children.begin()));
-
- set_row(row,value_desc);
- return;
- }
-
- //if(!value_node)
- // value_node=row[model.value_node];
-
- row[model.id]=value_node->get_id();
-
- // Setup the row's label
- if(value_node->get_id().empty())
- row[model.label] = Glib::ustring(row[model.name]);
- else if(Glib::ustring(row[model.name]).empty())
- row[model.label] = value_node->get_id();
- else
- row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
- }
- else
- {
- row[model.label] = Glib::ustring(row[model.name]);
- row[model.is_value_node] = false;
- row[model.is_editable] = true;
- Gtk::TreeModel::Children children = row.children();
- while(!children.empty() && erase(children.begin()))
- ;
- }
- if(!do_children)
- return;
-
- Gtk::TreeModel::Children children = row.children();
- Gtk::TreeModel::Children::iterator iter;
- if(!children.empty())
- for(iter = children.begin(); iter != children.end(); ++iter)
- {
- Gtk::TreeRow row=*iter;
- rebuild_row(row);
- }
-}
-
-CellRenderer_ValueBase*
-CanvasTreeStore::add_cell_renderer_value(Gtk::TreeView::Column* column)
-{
- const CanvasTreeStore::Model model;
-
- CellRenderer_ValueBase* ret;
-
- ret=Gtk::manage( new CellRenderer_ValueBase() );
-
- column->pack_start(*ret,true);
- column->add_attribute(ret->property_value(), model.value);
- column->add_attribute(ret->property_editable(), model.is_editable);
- column->add_attribute(ret->property_canvas(), model.canvas);
-
- return ret;
-}
-
-CellRenderer_TimeTrack*
-CanvasTreeStore::add_cell_renderer_value_node(Gtk::TreeView::Column* column)
-{
- const CanvasTreeStore::Model model;
-
- CellRenderer_TimeTrack* ret;
-
- ret = Gtk::manage( new CellRenderer_TimeTrack() );
-
- column->pack_start(*ret,true);
- //column->add_attribute(ret->property_visible(), model.is_value_node);
- column->add_attribute(ret->property_value_desc(), model.value_desc);
- column->add_attribute(ret->property_canvas(), model.canvas);
-
-
- return ret;
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file canvastreestore.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_CANVASTREESTORE_H
-#define __SYNFIG_STUDIO_CANVASTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <gdkmm/pixbuf.h>
-#include <synfigapp/value_desc.h>
-#include <gtkmm/treeview.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class CellRenderer_TimeTrack;
-class CellRenderer_ValueBase;
-
- enum ColumnID
- {
- COLUMNID_ID,
- COLUMNID_VALUE,
- COLUMNID_TIME_TRACK,
- COLUMNID_TYPE,
-
- COLUMNID_END //!< \internal
- };
-#define COLUMNID_NAME COLUMNID_ID
-
-class CanvasTreeStore : virtual public Gtk::TreeStore
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
-
- class Model : public Gtk::TreeModel::ColumnRecord
- {
- public:
- Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
- Gtk::TreeModelColumn<Glib::ustring> label;
- Gtk::TreeModelColumn<Glib::ustring> name;
- Gtk::TreeModelColumn<Glib::ustring> id;
-
- Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
- Gtk::TreeModelColumn<bool> is_canvas;
-
- Gtk::TreeModelColumn<synfig::ValueNode::Handle> value_node;
- Gtk::TreeModelColumn<bool> is_value_node;
- Gtk::TreeModelColumn<synfig::ValueBase> value;
- Gtk::TreeModelColumn<Glib::ustring> type;
- Gtk::TreeModelColumn<int> link_id;
- Gtk::TreeModelColumn<int> link_count;
-
- Gtk::TreeModelColumn<bool> is_editable;
-
- Gtk::TreeModelColumn<bool> is_shared;
- Gtk::TreeModelColumn<bool> is_exported;
-
- Gtk::TreeModelColumn<synfigapp::ValueDesc> value_desc;
-
- Gtk::TreeModelColumn<Glib::ustring> tooltip;
-
- Model()
- {
- add(value);
- add(name);
- add(label);
- add(icon);
- add(type);
- add(id);
- add(canvas);
- add(value_node);
- add(is_canvas);
- add(is_value_node);
-
- add(is_shared);
- add(is_exported);
- add(is_editable);
- add(value_desc);
- add(link_count);
- add(link_id);
-
- add(tooltip);
- }
- };
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- const Model model;
-
- //std::multimap<etl::handle<ValueNode>, sigc::connection> connection_map;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
-protected:
- virtual void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
- ~CanvasTreeStore();
-
- etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
- etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
-
- virtual void rebuild_row(Gtk::TreeModel::Row &row, bool do_children=true);
-
- virtual void refresh_row(Gtk::TreeModel::Row &row, bool do_children=true);
-
- virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children=true);
-
- bool find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter);
- bool find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter);
-
- bool find_first_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter);
- bool find_next_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter);
-
-
- static CellRenderer_ValueBase* add_cell_renderer_value(Gtk::TreeView::Column* column);
-
- static CellRenderer_TimeTrack* add_cell_renderer_value_node(Gtk::TreeView::Column* column);
-
- etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
-
- virtual void on_value_node_changed(synfig::ValueNode::Handle value_node)=0;
-
- /*
- -- ** -- P R O T E C T E D M E T H O D S -----------------------------------
- */
-
-public:
-
-}; // END of class CanvasTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
#include "cellrenderer_timetrack.h"
#include "app.h"
-#include "layertreestore.h"
-#include "layertree.h"
-#include "childrentreestore.h"
-#include "childrentree.h"
-#include "keyframetreestore.h"
-#include "keyframetree.h"
+#include "trees/layertreestore.h"
+#include "trees/layertree.h"
+#include "trees/childrentreestore.h"
+#include "trees/childrentree.h"
+#include "trees/keyframetreestore.h"
+#include "trees/keyframetree.h"
#include "dialogs/dialog_waypoint.h"
#include "dialogs/dialog_keyframe.h"
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file childrentree.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "childrentree.h"
-#include "cellrenderer_value.h"
-#include "cellrenderer_timetrack.h"
-#include <synfigapp/action.h>
-#include <synfigapp/instance.h>
-#include <gtkmm/scrolledwindow.h>
-#include <synfig/timepointcollect.h>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-#ifndef SMALL_BUTTON
-#define SMALL_BUTTON(button,stockid,tooltip) \
- button = manage(new class Gtk::Button()); \
- icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize)); \
- button->add(*icon); \
- tooltips_.set_tip(*button,tooltip); \
- icon->set_padding(0,0);\
- icon->show(); \
- button->set_relief(Gtk::RELIEF_NONE); \
- button->show()
-#endif
-
-#ifndef NORMAL_BUTTON
-#define NORMAL_BUTTON(button,stockid,tooltip) \
- button = manage(new class Gtk::Button()); \
- icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON)); \
- button->add(*icon); \
- tooltips_.set_tip(*button,tooltip); \
- icon->set_padding(0,0);\
- icon->show(); \
- /*button->set_relief(Gtk::RELIEF_NONE);*/ \
- button->show()
-#endif
-
-#define NEW_SMALL_BUTTON(x,y,z) Gtk::Button *SMALL_BUTTON(x,y,z)
-
-#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-ChildrenTree::ChildrenTree()
-{
- const ChildrenTreeStore::Model model;
-
- { // --- N A M E --------------------------------------------------------
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ID")) );
-
- // Set up the icon cell-renderer
- Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
- column->pack_start(*icon_cellrenderer,false);
- column->add_attribute(icon_cellrenderer->property_pixbuf(), model.icon);
-
- // Pack the label into the column
- column->pack_start(model.label,true);
-
- // Finish setting up the column
- column->set_reorderable();
- column->set_resizable();
- column->set_clickable();
- column->set_min_width(150);
- column->set_sort_column(model.label);
- tree_view.append_column(*column);
-
- }
- { // --- T Y P E --------------------------------------------------------
- int cols_count = tree_view.append_column(_("Type"),model.type);
- Gtk::TreeViewColumn* column = tree_view.get_column(cols_count-1);
- if(column)
- {
- column->set_reorderable();
- column->set_resizable();
- column->set_clickable();
- column->set_sort_column(model.type);
- }
- }
- { // --- V A L U E -----------------------------------------------------
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ValueBase")) );
-
- // Set up the value cell-renderer
- cellrenderer_value=ChildrenTreeStore::add_cell_renderer_value(column);
- cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_edited_value));
- cellrenderer_value->property_value()=synfig::ValueBase();
-
- // Finish setting up the column
- tree_view.append_column(*column);
- column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
- column->set_min_width(150);
- column->set_reorderable();
- column->set_resizable();
- column->set_clickable(false);
- }
- { // --- T I M E T R A C K --------------------------------------------
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
- column_time_track=column;
-
- // Set up the value-node cell-renderer
- cellrenderer_time_track=ChildrenTreeStore::add_cell_renderer_value_node(column);
- cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
- cellrenderer_time_track->signal_waypoint_clicked_cellrenderer().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_waypoint_clicked_childrentree) );
- column->add_attribute(cellrenderer_time_track->property_value_desc(), model.value_desc);
- column->add_attribute(cellrenderer_time_track->property_canvas(), model.canvas);
-
- //column->pack_start(*cellrenderer_time_track);
-
- // Finish setting up the column
- column->set_reorderable();
- column->set_resizable();
- tree_view.append_column(*column);
- }
-
- // This makes things easier to read.
- tree_view.set_rules_hint();
-
- // Make us more sensitive to several events
- tree_view.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
-
- tree_view.signal_event().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_tree_event));
-
- // Create a scrolled window for that tree
- Gtk::ScrolledWindow *scroll_children_tree = manage(new class Gtk::ScrolledWindow());
- scroll_children_tree->set_flags(Gtk::CAN_FOCUS);
- scroll_children_tree->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- scroll_children_tree->add(tree_view);
- scroll_children_tree->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
- scroll_children_tree->show();
-
- attach(*scroll_children_tree, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
-
- hbox=manage(new Gtk::HBox());
-
- attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-
- tree_view.set_enable_search(true);
- tree_view.set_search_column(model.label);
-
-/* // Buttons to raise/lower/duplicate/delete children valuenodes
- // Commented out because these functions are not implemented
- // and children sort themselves alphabetically
-
- Gtk::Image *icon;
- //Gtk::IconSize iconsize(Gtk::IconSize::from_name("synfig-small_icon"));
- Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
-
- SMALL_BUTTON(button_raise,"gtk-go-up",_("Raise"));
- SMALL_BUTTON(button_lower,"gtk-go-down",_("Lower"));
- SMALL_BUTTON(button_duplicate,"synfig-duplicate",_("Duplicate"));
- SMALL_BUTTON(button_delete,"gtk-delete",_("Delete"));
-
- hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
- hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
- hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
- hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
-
- button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_raise_pressed));
- button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_lower_pressed));
- button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_duplicate_pressed));
- button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_delete_pressed));
-
- button_raise->set_sensitive(false);
- button_lower->set_sensitive(false);
- button_duplicate->set_sensitive(false);
- button_delete->set_sensitive(false);
-*/
-
- get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_selection_changed));
-
- tree_view.set_reorderable(true);
-
- hbox->show();
- tree_view.show();
-
- tooltips_.enable();
-
- //get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
-}
-
-ChildrenTree::~ChildrenTree()
-{
-}
-
-void
-ChildrenTree::set_show_timetrack(bool x)
-{
- column_time_track->set_visible(x);
-}
-
-void
-ChildrenTree::set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store)
-{
- children_tree_store_=children_tree_store;
- tree_view.set_model(children_tree_store_);
- cellrenderer_time_track->set_canvas_interface(children_tree_store_->canvas_interface()); // am I smart people? (cellrenderer_timetrack.h:176)
- children_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::ChildrenTree::on_dirty_preview));
-}
-
-void
-ChildrenTree::set_time_adjustment(Gtk::Adjustment &adjustment)
-{
- cellrenderer_time_track->set_adjustment(adjustment);
-}
-
-void
-ChildrenTree::on_dirty_preview()
-{
-}
-
-void
-ChildrenTree::on_selection_changed()
-{
- if(0)
- {
- button_raise->set_sensitive(false);
- button_lower->set_sensitive(false);
- button_duplicate->set_sensitive(false);
- button_delete->set_sensitive(false);
- return;
- }
-}
-
-void
-ChildrenTree::on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value)
-{
- Gtk::TreePath path(path_string);
-
- const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
-
- row[model.value]=value;
-// signal_edited_value()(row[model.value_desc],value);
-}
-
-void
-ChildrenTree::on_waypoint_clicked_childrentree(const etl::handle<synfig::Node>& node __attribute__ ((unused)),
- const synfig::Time& time __attribute__ ((unused)),
- const synfig::Time& time_offset __attribute__ ((unused)),
- int button __attribute__ ((unused)))
-{
- std::set<synfig::Waypoint, std::less<UniqueID> > waypoint_set;
- synfig::waypoint_collect(waypoint_set,time,node);
-
- synfigapp::ValueDesc value_desc;
-
- if (waypoint_set.size() == 1)
- {
- ValueNode::Handle value_node(waypoint_set.begin()->get_parent_value_node());
- assert(value_node);
-
- Gtk::TreeRow row;
- if (children_tree_store_->find_first_value_node(value_node, row) && row)
- value_desc = static_cast<synfigapp::ValueDesc>(row[model.value_desc]);
- }
-
- if (!waypoint_set.empty())
- signal_waypoint_clicked_childrentree()(value_desc,waypoint_set,button);
-}
-
-bool
-ChildrenTree::on_tree_event(GdkEvent *event)
-{
- switch(event->type)
- {
- case GDK_BUTTON_PRESS:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!tree_view.get_path_at_pos(
- int(event->button.x),int(event->button.y), // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
- const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
-
- if(column->get_first_cell_renderer()==cellrenderer_time_track)
- {
- Gdk::Rectangle rect;
- tree_view.get_cell_area(path,*column,rect);
- cellrenderer_time_track->property_value_desc()=row[model.value_desc];
- cellrenderer_time_track->property_canvas()=row[model.canvas];
- cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
- queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
- return true;
- }
- else if(column->get_first_cell_renderer()==cellrenderer_value)
- return signal_user_click()(event->button.button,row,COLUMNID_VALUE);
- else
- return signal_user_click()(event->button.button,row,COLUMNID_ID);
-
- }
- break;
-
- case GDK_MOTION_NOTIFY:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!tree_view.get_path_at_pos(
- (int)event->button.x,(int)event->button.y, // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
-
- if(!tree_view.get_model()->get_iter(path))
- break;
-
- Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
-
- if(cellrenderer_time_track==column->get_first_cell_renderer())
- {
- // Movement on TimeLine
- Gdk::Rectangle rect;
- tree_view.get_cell_area(path,*column,rect);
- cellrenderer_time_track->property_value_desc()=row[model.value_desc];
- cellrenderer_time_track->property_canvas()=row[model.canvas];
- cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
- queue_draw();
- //queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
- return true;
- }
- else
- if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
- {
- tooltips_.unset_tip(*this);
- Glib::ustring tooltips_string(row[model.tooltip]);
- last_tooltip_path=path;
- if(!tooltips_string.empty())
- {
- tooltips_.set_tip(*this,tooltips_string);
- tooltips_.force_window();
- }
- }
- }
- break;
- case GDK_BUTTON_RELEASE:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!tree_view.get_path_at_pos(
- (int)event->button.x,(int)event->button.y, // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
-
- if(!tree_view.get_model()->get_iter(path))
- break;
-
- Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
-
- if(column && cellrenderer_time_track == column->get_first_cell_renderer())
- {
- Gdk::Rectangle rect;
- tree_view.get_cell_area(path,*column,rect);
- cellrenderer_time_track->property_value_desc()=row[model.value_desc];
- cellrenderer_time_track->property_canvas()=row[model.canvas];
- cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
- queue_draw();
- queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
- return true;
- }
- }
- break;
- default:
- break;
- }
- return false;
-}
-
-void
-ChildrenTree::on_raise_pressed()
-{
-}
-
-void
-ChildrenTree::on_lower_pressed()
-{
-}
-
-void
-ChildrenTree::on_duplicate_pressed()
-{
-}
-
-void
-ChildrenTree::on_delete_pressed()
-{
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file childrentree.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_CHILDRENTREE_H
-#define __SYNFIG_STUDIO_CHILDRENTREE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treeview.h>
-#include <gtkmm/treestore.h>
-#include <gtkmm/tooltips.h>
-#include <gtkmm/table.h>
-#include <gtkmm/box.h>
-#include <gtkmm/adjustment.h>
-#include <gtkmm/scale.h>
-#include <gtkmm/button.h>
-
-#include <synfigapp/canvasinterface.h>
-#include <synfigapp/value_desc.h>
-#include "childrentreestore.h"
-#include <synfig/valuenode_animated.h>
-
-#include "widgets/widget_value.h"
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class CellRenderer_TimeTrack;
-class CellRenderer_ValueBase;
-
-class ChildrenTree : public Gtk::Table
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
-
- typedef studio::ColumnID ColumnID;
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- ChildrenTreeStore::Model model;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- Gtk::Tooltips tooltips_;
-
- Gtk::TreePath last_tooltip_path;
-
- Gtk::TreeView tree_view;
-
- Gtk::HBox *hbox;
-
- Glib::RefPtr<ChildrenTreeStore> children_tree_store_;
-
- CellRenderer_TimeTrack *cellrenderer_time_track;
-
- Gtk::TreeView::Column* column_time_track;
-
- CellRenderer_ValueBase *cellrenderer_value;
-
- sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase> signal_edited_value_;
-
- sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_user_click_;
-
- sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int> signal_waypoint_clicked_childrentree_;
-
- Gtk::Button *button_raise;
- Gtk::Button *button_lower;
- Gtk::Button *button_duplicate;
- Gtk::Button *button_delete;
-
- Widget_ValueBase blend_method_widget;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- void on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value);
-
- void on_waypoint_clicked_childrentree(const etl::handle<synfig::Node>& node,const synfig::Time&,const synfig::Time&,int button);
-
- bool on_tree_event(GdkEvent *event);
-
- void on_selection_changed();
-
- void on_dirty_preview();
-
- //! \todo Implement raise/lower/duplicate/delete functions
- void on_raise_pressed();
-
- void on_lower_pressed();
-
- void on_duplicate_pressed();
-
- void on_delete_pressed();
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- Gtk::HBox& get_hbox() { return *hbox; }
-
- Gtk::TreeView& get_tree_view() { return tree_view; }
-
- Glib::RefPtr<Gtk::TreeSelection> get_selection() { return tree_view.get_selection(); }
- Glib::SignalProxy1< bool,GdkEvent* > signal_event () { return tree_view.signal_event(); }
-
- ChildrenTree();
- ~ChildrenTree();
-
- void set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store_);
-
- void set_time_adjustment(Gtk::Adjustment &adjustment);
-
- void set_show_timetrack(bool x=true);
-
- //! Signal called with a value has been edited.
- sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase>& signal_edited_value() { return signal_edited_value_; }
-
- sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_user_click() { return signal_user_click_; }
-
- sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int>& signal_waypoint_clicked_childrentree() { return signal_waypoint_clicked_childrentree_; }
-
- etl::handle<synfigapp::SelectionManager> get_selection_manager() { return children_tree_store_->canvas_interface()->get_selection_manager(); }
-
-}; // END of ChildrenTree
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file childrentreestore.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2007 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "childrentreestore.h"
-#include "iconcontroller.h"
-#include <gtkmm/button.h>
-#include <synfig/paramdesc.h>
-#include <ETL/clock>
-
-#include "general.h"
-
-class Profiler : private etl::clock
-{
- const std::string name;
-public:
- Profiler(const std::string& name):name(name) { reset(); }
- ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
-};
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static ChildrenTreeStore::Model& ModelHack()
-{
- static ChildrenTreeStore::Model* model(0);
- if(!model)model=new ChildrenTreeStore::Model;
- return *model;
-}
-
-ChildrenTreeStore::ChildrenTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
- Gtk::TreeStore (ModelHack()),
- CanvasTreeStore (canvas_interface_)
-{
- canvas_row=*append();
- canvas_row[model.label]=_("Canvases");
- canvas_row[model.is_canvas] = false;
- canvas_row[model.is_value_node] = false;
-
- value_node_row=*append();
- value_node_row[model.label]=_("ValueBase Nodes");
- value_node_row[model.is_canvas] = false;
- value_node_row[model.is_value_node] = false;
-
- // Connect all the signals
- canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_changed));
- canvas_interface()->signal_value_node_renamed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_renamed));
- canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_added));
- canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_deleted));
- canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_replaced));
- canvas_interface()->signal_canvas_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_added));
- canvas_interface()->signal_canvas_removed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_removed));
-
- rebuild();
-}
-
-ChildrenTreeStore::~ChildrenTreeStore()
-{
-}
-
-Glib::RefPtr<ChildrenTreeStore>
-ChildrenTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
-{
- return Glib::RefPtr<ChildrenTreeStore>(new ChildrenTreeStore(canvas_interface_));
-}
-
-void
-ChildrenTreeStore::rebuild()
-{
- // Profiler profiler("ChildrenTreeStore::rebuild()");
- rebuild_value_nodes();
- rebuild_canvases();
-}
-
-void
-ChildrenTreeStore::refresh()
-{
- // Profiler profiler("ChildrenTreeStore::refresh()");
- refresh_value_nodes();
- refresh_canvases();
-}
-
-void
-ChildrenTreeStore::rebuild_value_nodes()
-{
- Gtk::TreeModel::Children children(value_node_row.children());
-
- while(!children.empty())erase(children.begin());
-
- clear_changed_queue();
-
- std::for_each(
- canvas_interface()->get_canvas()->value_node_list().rbegin(), canvas_interface()->get_canvas()->value_node_list().rend(),
- sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_value_node_added)
- );
-}
-
-void
-ChildrenTreeStore::refresh_value_nodes()
-{
- Gtk::TreeModel::Children children(value_node_row.children());
-
- Gtk::TreeModel::Children::iterator iter;
-
- if(!children.empty())
- for(iter = children.begin(); iter != children.end(); ++iter)
- {
- Gtk::TreeRow row=*iter;
- refresh_row(row);
- }
-}
-
-void
-ChildrenTreeStore::rebuild_canvases()
-{
- Gtk::TreeModel::Children children(canvas_row.children());
-
- while(!children.empty())erase(children.begin());
-
- std::for_each(
- canvas_interface()->get_canvas()->children().rbegin(), canvas_interface()->get_canvas()->children().rend(),
- sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_canvas_added)
- );
-}
-
-void
-ChildrenTreeStore::refresh_canvases()
-{
- rebuild_canvases();
-}
-
-void
-ChildrenTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool /*do_children*/)
-{
- CanvasTreeStore::refresh_row(row,false);
-
- if((bool)row[model.is_value_node])
- {
- changed_set_.erase(row[model.value_node]);
- }
-
-}
-
-void
-ChildrenTreeStore::on_canvas_added(synfig::Canvas::Handle canvas)
-{
- Gtk::TreeRow row = *(prepend(canvas_row.children()));
-
- row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("synfig-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
- row[model.id] = canvas->get_id();
- row[model.name] = canvas->get_name();
-
- if(!canvas->get_id().empty())
- row[model.label] = canvas->get_id();
- else
- if(!canvas->get_name().empty())
- row[model.label] = canvas->get_name();
- else
- row[model.label] = _("[Unnamed]");
-
- row[model.canvas] = canvas;
- row[model.type] = _("Canvas");
- //row[model.is_canvas] = true;
- //row[model.is_value_node] = false;
-}
-
-void
-ChildrenTreeStore::on_canvas_removed(synfig::Canvas::Handle /*canvas*/)
-{
- rebuild_canvases();
-}
-
-void
-ChildrenTreeStore::on_value_node_added(synfig::ValueNode::Handle value_node)
-{
-// if(value_node->get_id().find("Unnamed")!=String::npos)
-// return;
-
- Gtk::TreeRow row = *prepend(value_node_row.children());
-
- set_row(row,synfigapp::ValueDesc(canvas_interface()->get_canvas(),value_node->get_id()),false);
-}
-
-void
-ChildrenTreeStore::on_value_node_deleted(synfig::ValueNode::Handle value_node)
-{
- Gtk::TreeIter iter;
- //int i(0);
-
- if(find_first_value_node(value_node,iter))
- {
- erase(iter);
- }
- //rebuild_value_nodes();
-}
-
-bool
-ChildrenTreeStore::execute_changed_value_nodes()
-{
- // Profiler profiler("ChildrenTreeStore::execute_changed_value_nodes()");
- if(!replaced_set_.empty())
- rebuild_value_nodes();
-
- etl::clock timer;
- timer.reset();
-
- while(!changed_set_.empty())
- {
- ValueNode::Handle value_node(*changed_set_.begin());
- changed_set_.erase(value_node);
-
- Gtk::TreeIter iter;
-
- try
- {
- Gtk::TreeIter iter;
- int i(0);
-
- if(!value_node->is_exported() && find_first_value_node(value_node,iter))
- {
- rebuild_value_nodes();
- continue;
- }
-
- if(value_node->is_exported() && find_first_value_node(value_node,iter)) do
- {
- Gtk::TreeRow row(*iter);
- i++;
- refresh_row(row);
- }while(find_next_value_node(value_node,iter));
-
- if(!i)
- {
- refresh_value_nodes();
- return false;
- }
-
- }
- catch(...)
- {
- rebuild_value_nodes();
- return false;
- }
-
- // If we are taking too long...
- if(timer()>4)
- {
- refresh_value_nodes();
- return false;
- }
- }
-
- return false;
-}
-
-void
-ChildrenTreeStore::on_value_node_changed(synfig::ValueNode::Handle value_node)
-{
-
- if(!value_node->is_exported())
- return;
- changed_connection.disconnect();
-// if(!execute_changed_queued())
-// changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
- changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
-
- changed_set_.insert(value_node);
- /*
- try
- {
- Gtk::TreeIter iter;
- int i(0);
- while(find_next_value_node(value_node,iter))
- {
- Gtk::TreeRow row(*iter);
- i++;
- refresh_row(row);
- }
- if(!i)
- {
- refresh_value_nodes();
- }
- }
- catch(...)
- {
- rebuild_value_nodes();
- }
- */
-}
-
-void
-ChildrenTreeStore::on_value_node_renamed(synfig::ValueNode::Handle value_node __attribute__ ((unused)))
-{
- rebuild_value_nodes();
-}
-
-void
-ChildrenTreeStore::on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle /*new_value_node*/)
-{
- changed_connection.disconnect();
- //if(!execute_changed_queued())
-// changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
- changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
-
- replaced_set_.insert(replaced_value_node);
-}
-
-void
-ChildrenTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
-{
- if(column>=get_n_columns_vfunc())
- {
- g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
- return;
- }
-
- if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
- {
- g_warning("LayerTreeStore::set_value_impl: Bad value type");
- return;
- }
-
- try
- {
- if(column==model.value.index())
- {
- Glib::Value<synfig::ValueBase> x;
- g_value_init(x.gobj(),model.value.type());
- g_value_copy(value.gobj(),x.gobj());
-
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
- if(value_desc)
- {
- canvas_interface()->change_value(value_desc,x.get());
- row_changed(get_path(*iter),*iter);
- }
-
- return;
- }
- else
- CanvasTreeStore::set_value_impl(iter,column, value);
- }
- catch(std::exception x)
- {
- g_warning("%s", x.what());
- }
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file childrentreestore.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2007 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_CHILDRENTREESTORE_H
-#define __SYNFIG_STUDIO_CHILDRENTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include "canvastreestore.h"
-#include <synfig/value.h>
-#include <synfig/valuenode.h>
-#include <set>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class ChildrenTreeStore : public CanvasTreeStore
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- //! TreeModel for the layers
- const Model model;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- Gtk::TreeModel::Row value_node_row;
- Gtk::TreeModel::Row canvas_row;
-
- std::set<synfig::ValueNode::Handle> changed_set_;
-
- std::set<synfig::ValueNode::Handle> replaced_set_;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
- sigc::connection changed_connection;
- bool execute_changed_queued()const { return !changed_set_.empty() || !replaced_set_.empty(); }
- bool execute_changed_value_nodes();
- void clear_changed_queue() { changed_set_.clear(); replaced_set_.clear(); }
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- void on_value_node_added(synfig::ValueNode::Handle value_node);
- void on_value_node_deleted(synfig::ValueNode::Handle value_node);
- void on_value_node_changed(synfig::ValueNode::Handle value_node);
- void on_value_node_renamed(synfig::ValueNode::Handle value_node);
- void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
- void on_canvas_added(synfig::Canvas::Handle canvas);
- void on_canvas_removed(synfig::Canvas::Handle canvas);
-
- void set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value);
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- ChildrenTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
- ~ChildrenTreeStore();
-
- void rebuild();
-
- void refresh();
-
- void rebuild_value_nodes();
-
- void refresh_value_nodes();
-
- void rebuild_canvases();
-
- void refresh_canvases();
-
- void refresh_row(Gtk::TreeModel::Row &row, bool do_children=false);
-
- Gtk::TreeModel::Row get_canvas_row()const { return canvas_row; }
-
- Gtk::TreeModel::Row get_value_node_row()const { return value_node_row; }
-
- /*
- -- ** -- S T A T I C P U B L I C M E T H O D S ---------------------------
- */
-
-public:
-
- static Glib::RefPtr<ChildrenTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-}; // END of class ChildrenTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
#include <gtkmm/label.h>
#include <gtkmm/alignment.h>
#include <synfigapp/canvasinterface.h>
-#include "metadatatreestore.h"
+#include "trees/metadatatreestore.h"
#include <gtkmm/treeview.h>
#include <gtkmm/scrolledwindow.h>
#include "app.h"
#include <sigc++/adaptors/hide.h>
//#include <sigc++/hide.h>
#include <sigc++/slot.h>
-#include "metadatatreestore.h"
#include "canvasview.h"
#include <ETL/clock>
#include <sigc++/hide.h>
#include <sigc++/retype_return.h>
#include <sigc++/slot.h>
-#include "childrentreestore.h"
-#include "childrentree.h"
+#include "trees/childrentreestore.h"
+#include "trees/childrentree.h"
#include "canvasview.h"
#include "general.h"
#include <sigc++/hide.h>
#include <sigc++/slot.h>
#include "canvasview.h"
-#include "layerparamtreestore.h"
+#include "trees/layerparamtreestore.h"
#include "workarea.h"
#include "widgets/widget_curves.h"
-#include "layerparamtreestore.h"
#include <gtkmm/table.h>
#include <gtkmm/scrollbar.h>
#include "widgets/widget_timeslider.h"
#include <sigc++/hide.h>
#include <sigc++/slot.h>
#include <synfigapp/action.h>
-#include "historytreestore.h"
+#include "trees/historytreestore.h"
#include "general.h"
#include <sigc++/signal.h>
#include <sigc++/hide.h>
#include <sigc++/slot.h>
-#include "keyframetreestore.h"
-#include "keyframetree.h"
+#include "trees/keyframetreestore.h"
+#include "trees/keyframetree.h"
#include "canvasview.h"
#include "keyframeactionmanager.h"
#include <sigc++/slot.h>
#include "canvasview.h"
-#include "layergrouptreestore.h"
-#include "layergrouptree.h"
+#include "trees/layergrouptreestore.h"
+#include "trees/layergrouptree.h"
#include "groupactionmanager.h"
#include "general.h"
#include <sigc++/hide.h>
#include <sigc++/retype_return.h>
#include <sigc++/slot.h>
-#include "layertreestore.h"
-#include "layertree.h"
+#include "trees/layertreestore.h"
+#include "trees/layertree.h"
#include "canvasview.h"
#include "layeractionmanager.h"
//#include <ETL/ref_count>
#include <sigc++/signal.h>
#include <sigc++/hide.h>
#include <sigc++/slot.h>
-#include "metadatatreestore.h"
+#include "trees/metadatatreestore.h"
#include "canvasview.h"
#include "general.h"
#include <sigc++/hide.h>
#include <sigc++/slot.h>
#include "canvasview.h"
-#include "layerparamtreestore.h"
+#include "trees/layerparamtreestore.h"
#include "workarea.h"
#include "general.h"
#include <sigc++/hide.h>
#include <sigc++/slot.h>
#include "canvasview.h"
-#include "layerparamtreestore.h"
+#include "trees/layerparamtreestore.h"
#include "workarea.h"
#include "widgets/widget_timeslider.h"
#include "widgets/widget_keyframe_list.h"
-#include "layerparamtreestore.h"
#include "general.h"
#include <synfig/timepointcollect.h>
#endif
#include "groupactionmanager.h"
-#include "layergrouptree.h"
+#include "trees/layergrouptree.h"
#include <synfigapp/action_param.h>
#include "instance.h"
#include <gtkmm/stock.h>
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file historytreestore.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "historytreestore.h"
-#include <synfig/valuenode.h>
-#include "iconcontroller.h"
-#include <synfig/valuenode_timedswap.h>
-#include <gtkmm/button.h>
-#include <synfigapp/action.h>
-#include "instance.h"
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static HistoryTreeStore::Model& ModelHack()
-{
- static HistoryTreeStore::Model* model(0);
- if(!model)model=new HistoryTreeStore::Model;
- return *model;
-}
-
-HistoryTreeStore::HistoryTreeStore(etl::loose_handle<studio::Instance> instance_):
- Gtk::TreeStore (ModelHack()),
- instance_ (instance_)
-{
- instance_->signal_undo().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_undo));
- instance_->signal_redo().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_redo));
- instance_->signal_undo_stack_cleared().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_undo_stack_cleared));
- instance_->signal_redo_stack_cleared().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_redo_stack_cleared));
- instance_->signal_new_action().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_new_action));
- instance_->signal_action_status_changed().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_action_status_changed));
-}
-
-HistoryTreeStore::~HistoryTreeStore()
-{
- if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
- synfig::info("HistoryTreeStore::~HistoryTreeStore(): Deleted");
-}
-
-Glib::RefPtr<HistoryTreeStore>
-HistoryTreeStore::create(etl::loose_handle<studio::Instance> instance_)
-{
- return Glib::RefPtr<HistoryTreeStore>(new HistoryTreeStore(instance_));
-}
-
-void
-HistoryTreeStore::rebuild()
-{
- synfigapp::Action::Stack::const_iterator iter;
-
- clear();
-
- for(iter=instance()->undo_action_stack().begin();iter!=instance()->undo_action_stack().end();++iter)
- {
- insert_action(*(prepend()),*iter,true,true,false);
- }
- curr_row=*children().end();
- for(iter=instance()->redo_action_stack().begin();iter!=instance()->redo_action_stack().end();++iter)
- {
- insert_action(*(append()),*iter,true,false,true);
- }
-
- signal_undo_tree_changed()();
-}
-
-void
-HistoryTreeStore::insert_action(Gtk::TreeRow row,etl::handle<synfigapp::Action::Undoable> action, bool /*is_active*/, bool is_undo, bool is_redo)
-{
- assert(action);
-
- row[model.action] = action;
- row[model.name] = static_cast<Glib::ustring>(action->get_local_name());
- row[model.is_active] = action->is_active();
- row[model.is_undo] = is_undo;
- row[model.is_redo] = is_redo;
-
- synfigapp::Action::CanvasSpecific *specific_action;
- specific_action=dynamic_cast<synfigapp::Action::CanvasSpecific*>(action.get());
- if(specific_action)
- {
- row[model.canvas] = specific_action->get_canvas();
- row[model.canvas_id] = specific_action->get_canvas()->get_id();
- }
-
- etl::handle<synfigapp::Action::Group> group;
- group=etl::handle<synfigapp::Action::Group>::cast_dynamic(action);
- if(group)
- {
- synfigapp::Action::ActionList::const_iterator iter;
- for(iter=group->action_list().begin();iter!=group->action_list().end();++iter)
- {
- Gtk::TreeRow child_row = *(append(row.children()));
- insert_action(child_row,*iter,true,is_undo,is_redo);
- }
- }
-
- //row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("synfig-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
-}
-
-
-void
-HistoryTreeStore::on_undo()
-{
- refresh();
-}
-
-void
-HistoryTreeStore::on_redo()
-{
- refresh();
-}
-
-void
-HistoryTreeStore::on_undo_stack_cleared()
-{
- Gtk::TreeModel::Children::iterator iter,next;
- Gtk::TreeModel::Children children_(children());
-
- for(next=children_.begin(),iter=next++; iter != children_.end(); iter=(next!=children_.end())?next++:next)
- {
- Gtk::TreeModel::Row row = *iter;
- if(row[model.is_undo])
- erase(iter);
- }
-}
-
-void
-HistoryTreeStore::on_redo_stack_cleared()
-{
- Gtk::TreeModel::Children::iterator iter,next;
- Gtk::TreeModel::Children children_(children());
-
- for(next=children_.begin(),iter=next++; iter != children_.end(); iter=(next!=children_.end())?next++:next)
- {
- Gtk::TreeModel::Row row = *iter;
- if(row[model.is_redo])
- erase(iter);
- }
-}
-
-void
-HistoryTreeStore::on_new_action(etl::handle<synfigapp::Action::Undoable> action)
-{
-// Gtk::TreeRow row = *(append());
- Gtk::TreeRow row;
- Gtk::TreeModel::Children::iterator iter;
- for(iter=children().begin(); iter != children().end(); ++iter)
- {
- Gtk::TreeModel::Row row = *iter;
- if(row[model.is_redo])
- {
- break;
- }
- }
-
- row=*insert(iter);
-
- insert_action(row,action);
-
- signal_undo_tree_changed()();
-}
-
-void
-HistoryTreeStore::on_action_status_changed(etl::handle<synfigapp::Action::Undoable> action)
-{
- Gtk::TreeModel::Children::iterator iter;
- Gtk::TreeModel::Children children_(children());
-
- for(iter=children_.begin(); iter != children_.end(); ++iter)
- {
- Gtk::TreeModel::Row row = *iter;
- if(action == (etl::handle<synfigapp::Action::Undoable>)row[model.action])
- {
- row[model.is_active]=action->is_active();
- return;
- }
- }
-}
-
-bool
-HistoryTreeStore::search_func(const Glib::RefPtr<Gtk::TreeModel>&,int,const Glib::ustring& x,const Gtk::TreeModel::iterator& iter)
-{
- const Model model;
-
- Glib::ustring substr(x.uppercase());
- Glib::ustring name((*iter)[model.name]);
- name=name.uppercase();
-
- return name.find(substr)==Glib::ustring::npos;
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file historytreestore.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_HISTORYTREESTORE_H
-#define __SYNFIG_STUDIO_HISTORYTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <gdkmm/pixbuf.h>
-#include <synfigapp/action.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class Instance;
-
-class HistoryTreeStore : virtual public Gtk::TreeStore
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
-
- class Model : public Gtk::TreeModel::ColumnRecord
- {
- public:
- public:
- Gtk::TreeModelColumn<etl::handle<synfigapp::Action::Undoable> > action;
- Gtk::TreeModelColumn<Glib::ustring> name;
- Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
- Gtk::TreeModelColumn<bool> is_active;
- Gtk::TreeModelColumn<bool> is_undo;
- Gtk::TreeModelColumn<bool> is_redo;
-
- Gtk::TreeModelColumn<Glib::ustring> canvas_id;
- Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
-
- Model()
- {
- add(action);
- add(name);
- add(icon);
- add(is_active);
- add(is_undo);
- add(is_redo);
- add(canvas_id);
- add(canvas);
- }
- };
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- const Model model;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- etl::loose_handle<studio::Instance> instance_;
- Gtk::TreeIter curr_row;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- sigc::signal<void> signal_undo_tree_changed_;
-
- /*
- -- ** -- S I G N A L I N T E R F A C E S -----------------------------------
- */
-
-public:
-
- sigc::signal<void>& signal_undo_tree_changed() { return signal_undo_tree_changed_; }
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- void on_undo();
-
- void on_redo();
-
- void on_undo_stack_cleared();
-
- void on_redo_stack_cleared();
-
- void on_new_action(etl::handle<synfigapp::Action::Undoable> action);
-
- void on_action_status_changed(etl::handle<synfigapp::Action::Undoable> action);
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- HistoryTreeStore(etl::loose_handle<studio::Instance> instance_);
- ~HistoryTreeStore();
-
- etl::loose_handle<studio::Instance> instance() { return instance_; }
- etl::loose_handle<const studio::Instance> instance()const { return instance_; }
-
- void rebuild();
-
- void refresh() { rebuild(); }
-
- void insert_action(Gtk::TreeRow row,etl::handle<synfigapp::Action::Undoable> action, bool is_active=true, bool is_undo=true, bool is_redo=false);
-
- static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
-
- /*
- -- ** -- P R O T E C T E D M E T H O D S -----------------------------------
- */
-
-public:
-
- static Glib::RefPtr<HistoryTreeStore> create(etl::loose_handle<studio::Instance> instance);
-
-}; // END of class HistoryTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
#include <synfigapp/instance.h>
#include <sigc++/object.h>
#include <synfigapp/value_desc.h>
-#include "historytreestore.h"
+#include "trees/historytreestore.h"
#include <synfig/canvas.h>
/* === M A C R O S ========================================================= */
#endif
#include "keyframeactionmanager.h"
-#include "keyframetree.h"
+#include "trees/keyframetree.h"
#include <synfigapp/action_param.h>
#include "instance.h"
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file keyframetree.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "keyframetree.h"
-#include "cellrenderer_time.h"
-#include <gtkmm/treemodelsort.h>
-#include <ETL/misc>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-KeyframeTree::KeyframeTree()
-{
- const KeyframeTreeStore::Model model;
-
- {
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time")) );
-
- cell_renderer_time = Gtk::manage( new CellRenderer_Time() );
- column->pack_start(*cell_renderer_time,true);
- column->add_attribute(cell_renderer_time->property_time(), model.time);
- cell_renderer_time->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_time));
-
- column->set_reorderable();
- column->set_resizable();
- column->set_clickable();
- column->set_sort_column(model.time);
-
- append_column(*column);
- }
- {
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Length")) );
-
- cell_renderer_time_delta = Gtk::manage( new CellRenderer_Time() );
- column->pack_start(*cell_renderer_time_delta,true);
- column->add_attribute(cell_renderer_time_delta->property_time(), model.time_delta);
- cell_renderer_time_delta->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_time_delta));
-
- column->set_reorderable();
- column->set_resizable();
- column->set_clickable(false);
- // column->set_sort_column(model.time_delta);
-
- append_column(*column);
- }
- {
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Jump")) );
-
- Gtk::CellRendererText* cell_renderer_jump=Gtk::manage(new Gtk::CellRendererText());
- column->pack_start(*cell_renderer_jump,true);
- cell_renderer_jump->property_text()=_("(JMP)");
- cell_renderer_jump->property_foreground()="#003a7f";
-
- column->set_reorderable();
- column->set_resizable();
- column->set_clickable(false);
- column->set_sort_column(COLUMNID_JUMP); // without this, (JMP) needs a double click?!
-
- append_column(*column);
- }
- {
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Description")) );
-
- cell_renderer_description=Gtk::manage(new Gtk::CellRendererText());
- column->pack_start(*cell_renderer_description,true);
- column->add_attribute(cell_renderer_description->property_text(), model.description);
- cell_renderer_description->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_description));
-
- column->set_reorderable();
- column->set_resizable();
- column->set_clickable();
- column->set_sort_column(model.description);
-
- append_column(*column);
- }
-
- set_enable_search(true);
- set_search_column(model.description);
-
- // This makes things easier to read.
- set_rules_hint();
-
- // Make us more sensitive to several events
- add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
-}
-
-KeyframeTree::~KeyframeTree()
-{
- if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
- synfig::info("KeyframeTree::~KeyframeTree(): Deleted");
-}
-
-void
-KeyframeTree::on_rend_desc_changed()
-{
- cell_renderer_time->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
- queue_draw();
-}
-
-void
-KeyframeTree::set_model(Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store)
-{
- keyframe_tree_store_=keyframe_tree_store;
- KeyframeTreeStore::Model model;
-
- if(true)
- {
- Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(keyframe_tree_store_));
- sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::KeyframeTreeStore::time_sorter));
- sorted_store->set_sort_func(model.time, sigc::ptr_fun(&studio::KeyframeTreeStore::time_sorter));
- sorted_store->set_sort_func(model.description, sigc::ptr_fun(&studio::KeyframeTreeStore::description_sorter));
- Gtk::TreeView::set_model(sorted_store);
- }
- else
- Gtk::TreeView::set_model(keyframe_tree_store);
-
- keyframe_tree_store_->canvas_interface()->signal_rend_desc_changed().connect(
- sigc::mem_fun(
- *this,
- &studio::KeyframeTree::on_rend_desc_changed
- )
- );
- cell_renderer_time->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
- cell_renderer_time_delta->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
-}
-
-void
-KeyframeTree::set_editable(bool x)
-{
- editable_=x;
-
- if(editable_)
- {
- cell_renderer_time->property_editable()=true;
- cell_renderer_time_delta->property_editable()=true;
- cell_renderer_description->property_editable()=true;
- }
- else
- {
- cell_renderer_time->property_editable()=false;
- cell_renderer_time_delta->property_editable()=false;
- cell_renderer_description->property_editable()=false;
- }
-}
-
-void
-KeyframeTree::on_edited_time(const Glib::ustring&path_string,synfig::Time time)
-{
- Gtk::TreePath path(path_string);
-
- const Gtk::TreeRow row(*(get_model()->get_iter(path)));
-
- synfig::Keyframe keyframe(row[model.keyframe]);
- if(time!=keyframe.get_time())
- {
- row[model.time]=time;
- //keyframe.set_time(time);
- //signal_edited_time()(keyframe,time);
- //signal_edited()(keyframe);
- }
-}
-
-void
-KeyframeTree::on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time)
-{
- Gtk::TreePath path(path_string);
-
- const Gtk::TreeRow row(*(get_model()->get_iter(path)));
-
- if(row)row[model.time_delta]=time;
-}
-
-void
-KeyframeTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
-{
- Gtk::TreePath path(path_string);
-
- const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
- const synfig::String description(desc);
- synfig::Keyframe keyframe(row[model.keyframe]);
- if(description!=keyframe.get_description())
- {
- row[model.description]=desc;
- keyframe.set_description(description);
- signal_edited_description()(keyframe,description);
- signal_edited()(keyframe);
- }
-}
-
-bool
-KeyframeTree::on_event(GdkEvent *event)
-{
- switch(event->type)
- {
- case GDK_BUTTON_PRESS:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
- //tree_to_widget_coords (,, wx, wy);
- if(!get_path_at_pos(
- wx,wy, // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
- const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
- signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
- if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
- {
- keyframe_tree_store_->canvas_interface()->set_time(row[model.time]);
- }
- }
- break;
- case GDK_2BUTTON_PRESS:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!get_path_at_pos(
- int(event->button.x),int(event->button.y), // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
- const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
- {
- keyframe_tree_store_->canvas_interface()->set_time(row[model.time]);
- return true;
- }
- }
- break;
-
- case GDK_BUTTON_RELEASE:
- break;
- default:
- break;
- }
- return false;
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file keyframetree.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_KEYFRAMETREE_H
-#define __SYNFIG_STUDIO_KEYFRAMETREE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treeview.h>
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <synfigapp/value_desc.h>
-#include "keyframetreestore.h"
-#include <synfig/keyframe.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class CellRenderer_Time;
-
-class KeyframeTree : public Gtk::TreeView
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
-
- enum ColumnID
- {
- COLUMNID_TIME,
- COLUMNID_DESCRIPTION,
- COLUMNID_JUMP,
-
- COLUMNID_END //!< \internal
- };
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- KeyframeTreeStore::Model model;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_;
-
- CellRenderer_Time *cell_renderer_time;
-
- CellRenderer_Time *cell_renderer_time_delta;
-
- Gtk::CellRendererText *cell_renderer_description;
-
- sigc::signal<void,synfig::Keyframe> signal_edited_;
-
- sigc::signal<void,synfig::Keyframe,synfig::Time> signal_edited_time_;
-
- sigc::signal<void,synfig::Keyframe,synfig::String> signal_edited_description_;
-
- sigc::signal<void, int, Gtk::TreeRow, ColumnID> signal_user_click_;
-
- bool editable_;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- void on_edited_time(const Glib::ustring&path_string,synfig::Time time);
-
- void on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time);
-
- void on_edited_description(const Glib::ustring&path_string,const Glib::ustring &description);
-
- bool on_event(GdkEvent *event);
-
- void on_rend_desc_changed();
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- KeyframeTree();
- ~KeyframeTree();
-
- void set_model(Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_);
-
- void set_editable(bool x=true);
-
- bool get_editable()const { return editable_; }
-
- //! Signal called when a keyframe has been edited in any way
- sigc::signal<void,synfig::Keyframe>& signal_edited() { return signal_edited_; }
-
- //! Signal called when a time has been edited.
- sigc::signal<void,synfig::Keyframe,synfig::Time>& signal_edited_time() { return signal_edited_time_; }
-
- //! Signal called when a description has been edited.
- sigc::signal<void,synfig::Keyframe,synfig::String>& signal_edited_description() { return signal_edited_description_; }
-
- sigc::signal<void,int, Gtk::TreeRow, ColumnID>& signal_user_click() { return signal_user_click_; }
-}; // END of KeyframeTree
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file keyframetreestore.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2007, 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "keyframetreestore.h"
-#include <synfig/valuenode.h>
-#include "iconcontroller.h"
-#include <synfig/valuenode_timedswap.h>
-#include <gtkmm/button.h>
-#include <gtkmm/treerowreference.h>
-#include <synfig/canvas.h>
-#include <synfig/keyframe.h>
-#include <time.h>
-#include <cstdlib>
-#include <ETL/smart_ptr>
-#include <synfigapp/action.h>
-#include <synfigapp/instance.h>
-#include "onemoment.h"
-#include <synfig/exception.h>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-// KeyframeTreeStore_Class KeyframeTreeStore::keyframe_tree_store_class_;
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-struct _keyframe_iterator
-{
- synfig::KeyframeList::iterator iter;
- int ref_count;
- int index;
-};
-
-/*
-Gtk::TreeModel::iterator keyframe_iter_2_model_iter(synfig::KeyframeList::iterator iter,int index)
-{
- Gtk::TreeModel::iterator ret;
-
- _keyframe_iterator*& data(static_cast<_keyframe_iterator*&>(ret->gobj()->user_data));
- data=new _keyframe_iterator();
- data->ref_count=1;
- data->iter=iter;
- data->index=index;
-
- return ret;
-}
-*/
-
-synfig::KeyframeList::iterator model_iter_2_keyframe_iter(Gtk::TreeModel::iterator iter)
-{
- _keyframe_iterator* data(static_cast<_keyframe_iterator*>(iter->gobj()->user_data));
- if(!data)
- throw std::runtime_error("bad data");
- return data->iter;
-}
-
-int get_index_from_model_iter(Gtk::TreeModel::iterator iter)
-{
- _keyframe_iterator* data(static_cast<_keyframe_iterator*>(iter->gobj()->user_data));
- if(!data)
- throw std::runtime_error("bad data");
- return data->index;
-}
-
-
-/*
-#ifndef TreeRowReferenceHack
-class TreeRowReferenceHack
-{
- GtkTreeRowReference *gobject_;
-public:
- TreeRowReferenceHack():
- gobject_(0)
- {
- }
-
- TreeRowReferenceHack(const Glib::RefPtr<Gtk::TreeModel>& model, const Gtk::TreeModel::Path& path):
- gobject_ ( gtk_tree_row_reference_new(model->gobj(), const_cast<GtkTreePath*>(path.gobj())) )
- {
- }
-
- TreeRowReferenceHack(const TreeRowReferenceHack &x):
- gobject_ ( x.gobject_?gtk_tree_row_reference_copy(x.gobject_):0 )
- {
-
- }
-
- void swap(TreeRowReferenceHack & other)
- {
- GtkTreeRowReference *const temp = gobject_;
- gobject_ = other.gobject_;
- other.gobject_ = temp;
- }
-
- const TreeRowReferenceHack &
- operator=(const TreeRowReferenceHack &rhs)
- {
- TreeRowReferenceHack temp (rhs);
- swap(temp);
- return *this;
- }
-
- ~TreeRowReferenceHack()
- {
- if(gobject_)
- gtk_tree_row_reference_free(gobject_);
- }
-
- Gtk::TreeModel::Path get_path() { return Gtk::TreeModel::Path(gtk_tree_row_reference_get_path(gobject_),false); }
- GtkTreeRowReference *gobj() { return gobject_; }
-};
-#endif
-*/
-
-/* === P R O C E D U R E S ================================================= */
-
-void clear_iterator(GtkTreeIter* iter)
-{
- iter->stamp=0;
- iter->user_data=iter->user_data2=iter->user_data3=0;
-}
-
-/* === M E T H O D S ======================================================= */
-
-const Glib::Class&
-KeyframeTreeStore_Class::init()
-{
- if(!gtype_)
- {
- class_init_func_ = &KeyframeTreeStore_Class::class_init_function;
-
- const GTypeInfo derived_info =
- {
- sizeof(GObjectClass),
- NULL,
- NULL,
- class_init_func_,
- NULL,
- NULL,
- sizeof(GObject),
- 0,
- 0,
- NULL
- };
-
- gtype_ = g_type_register_static(G_TYPE_OBJECT, "KeyframeTreeStore", &derived_info, GTypeFlags(0));
- Gtk::TreeModel::add_interface(get_type());
- }
- return *this;
-}
-
-void
-KeyframeTreeStore_Class::class_init_function(gpointer /*g_class*/, gpointer /*class_data*/)
-{
- // ???
-}
-
-KeyframeTreeStore::KeyframeTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
- Glib::ObjectBase ("KeyframeTreeStore"),
- //! \todo what is going on here? why the need for this KeyframeTreeStore_Class at all?
- // Glib::Object (Glib::ConstructParams(keyframe_tree_store_class_.init(), (char*) 0, (char*) 0)),
- canvas_interface_ (canvas_interface_)
-{
- reset_stamp();
- //reset_path_table();
-
- canvas_interface()->signal_keyframe_added().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::add_keyframe));
- canvas_interface()->signal_keyframe_removed().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::remove_keyframe));
- canvas_interface()->signal_keyframe_changed().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::change_keyframe));
-}
-
-KeyframeTreeStore::~KeyframeTreeStore()
-{
- if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
- synfig::info("KeyframeTreeStore::~KeyframeTreeStore(): Deleted");
-}
-
-Glib::RefPtr<KeyframeTreeStore>
-KeyframeTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
-{
- KeyframeTreeStore *store(new KeyframeTreeStore(canvas_interface_));
- Glib::RefPtr<KeyframeTreeStore> ret(store);
- assert(ret);
- return ret;
-}
-
-void
-KeyframeTreeStore::reset_stamp()
-{
- stamp_=time(0)+reinterpret_cast<long>(this);
-}
-
-/*
-void
-KeyframeTreeStore::reset_path_table()
-{
- Gtk::TreeModel::Children::iterator iter;
- const Gtk::TreeModel::Children children(children());
- path_table_.clear();
- for(iter = children.begin(); iter != children.end(); ++iter)
- {
- Gtk::TreeModel::Row row(*iter);
- path_table_[(Keyframe)row[model.keyframe]]=TreeRowReferenceHack(Glib::RefPtr<KeyframeTreeStore>(this),Gtk::TreePath(row));
- }
-}
-*/
-
-
-inline bool
-KeyframeTreeStore::iterator_sane(const GtkTreeIter* iter)const
-{
- if(iter && iter->stamp==stamp_)
- return true;
- g_warning("KeyframeTreeStore::iterator_sane(): Bad iterator stamp");
- return false;
-}
-
-inline bool
-KeyframeTreeStore::iterator_sane(const Gtk::TreeModel::iterator& iter)const
-{
- return iterator_sane(iter->gobj());
-}
-
-inline void
-KeyframeTreeStore::dump_iterator(const GtkTreeIter* /*gtk_iter*/, const Glib::ustring &/*name*/)const
-{
-#if 0
- if(!gtk_iter)
- {
- g_warning("KeyframeTreeStore::dump_iterator: \"%s\" is NULL (Root?)",name.c_str());
- return;
- }
-
- _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
-
- if(gtk_iter->stamp!=stamp_ || !iter)
- {
- g_warning("KeyframeTreeStore::dump_iterator: \"%s\" is INVALID",name.c_str());
- return;
- }
-
- if((unsigned)iter->index>=canvas_interface()->get_canvas()->keyframe_list().size())
- g_warning("KeyframeTreeStore::dump_iterator: \"%s\"(%p) has bad index(index:%d)",name.c_str(),gtk_iter,iter->index);
-
- g_warning("KeyframeTreeStore::dump_iterator: \"%s\"(%p) ref:%d, index:%d, time:%s",name.c_str(),gtk_iter,iter->ref_count,iter->index,iter->iter->get_time().get_string().c_str());
-#endif
-}
-
-inline void
-KeyframeTreeStore::dump_iterator(const Gtk::TreeModel::iterator& iter, const Glib::ustring &name)const
-{
- dump_iterator(iter->gobj(),name);
-}
-
-int
-KeyframeTreeStore::time_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
-{
- const Model model;
-
- _keyframe_iterator *rhs_iter(static_cast<_keyframe_iterator*>(rhs->gobj()->user_data));
- _keyframe_iterator *lhs_iter(static_cast<_keyframe_iterator*>(lhs->gobj()->user_data));
-
- Time diff(rhs_iter->iter->get_time()-lhs_iter->iter->get_time());
- if(diff<0)
- return -1;
- if(diff>0)
- return 1;
- return 0;
-}
-
-int
-KeyframeTreeStore::description_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
-{
- const Model model;
-
- _keyframe_iterator *rhs_iter(static_cast<_keyframe_iterator*>(rhs->gobj()->user_data));
- _keyframe_iterator *lhs_iter(static_cast<_keyframe_iterator*>(lhs->gobj()->user_data));
-
- int comp = rhs_iter->iter->get_description().compare(lhs_iter->iter->get_description());
- if (comp > 0) return 1;
- if (comp < 0) return -1;
- return 0;
-}
-
-void
-KeyframeTreeStore::set_value_impl(const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value)
-{
- if(!iterator_sane(row))
- return;
-
- if(column>=get_n_columns_vfunc())
- {
- g_warning("KeyframeTreeStore::set_value_impl: Bad column (%d)",column);
- return;
- }
-
- if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
- {
- g_warning("KeyframeTreeStore::set_value_impl: Bad value type");
- return;
- }
-
- _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(row.gobj()->user_data));
-
- try
- {
- if(column==model.time_delta.index())
- {
- Glib::Value<synfig::Time> x;
- g_value_init(x.gobj(),model.time.type());
- g_value_copy(value.gobj(),x.gobj());
-
- Time new_delta(x.get());
- if(new_delta<=Time::zero()+Time::epsilon())
- {
- // Bad value
- return;
- }
-
- Time old_delta((*row)[model.time_delta]);
- if(old_delta<=Time::zero()+Time::epsilon())
- {
- // Bad old delta
- return;
- }
- // row(row) on the next line is bad - don't use it, because it leaves 'row' uninitialized
- //Gtk::TreeModel::iterator row(row);
- //row++;
- //if(!row)return;
-
- Time change_delta(new_delta-old_delta);
-
- if(change_delta<=Time::zero()+Time::epsilon() &&change_delta>=Time::zero()-Time::epsilon())
- {
- // Not an error, just no change
- return;
- }
-
- {
- Keyframe keyframe((*row)[model.keyframe]);
- synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSetDelta"));
-
- if(!action)return;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("keyframe",keyframe);
- action->set_param("delta",change_delta);
-
- canvas_interface()->get_instance()->perform_action(action);
- }
-
- return;
- }
- else
- if(column==model.time.index())
- {
- OneMoment one_moment;
-
- Glib::Value<synfig::Time> x;
- g_value_init(x.gobj(),model.time.type());
- g_value_copy(value.gobj(),x.gobj());
- synfig::Keyframe keyframe(*iter->iter);
-
- synfig::info("KeyframeTreeStore::set_value_impl():old_time=%s",keyframe.get_time().get_string().c_str());
- keyframe.set_time(x.get());
- synfig::info("KeyframeTreeStore::set_value_impl():new_time=%s",keyframe.get_time().get_string().c_str());
-
- synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSet"));
-
- if(!action)
- return;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("keyframe",keyframe);
-
- canvas_interface()->get_instance()->perform_action(action);
- }
- else if(column==model.description.index())
- {
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),model.description.type());
- g_value_copy(value.gobj(),x.gobj());
- synfig::Keyframe keyframe(*iter->iter);
- keyframe.set_description(x.get());
-
- synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSet"));
-
- if(!action)
- return;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("keyframe",keyframe);
-
- canvas_interface()->get_instance()->perform_action(action);
- }
- else if(column==model.keyframe.index())
- {
- g_warning("KeyframeTreeStore::set_value_impl: This column is read-only");
- }
- else
- {
- assert(0);
- }
- }
- catch(std::exception x)
- {
- g_warning("%s", x.what());
- }
-}
-
-Gtk::TreeModelFlags
-KeyframeTreeStore::get_flags_vfunc ()
-{
- return Gtk::TREE_MODEL_LIST_ONLY;
-}
-
-int
-KeyframeTreeStore::get_n_columns_vfunc ()
-{
- return model.size();
-}
-
-GType
-KeyframeTreeStore::get_column_type_vfunc (int index)
-{
- return model.types()[index];
-}
-
-bool
-KeyframeTreeStore::iter_next_vfunc (const iterator& xiter, iterator& iter_next) const
-{
- if(!iterator_sane(xiter)) return false;
-
- _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(xiter.gobj()->user_data));
-
- if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
- return false;
-
- _keyframe_iterator *next(new _keyframe_iterator());
- iter_next.gobj()->user_data=static_cast<gpointer>(next);
- next->ref_count=1;
- next->index=iter->index+1;
- next->iter=iter->iter;
- ++next->iter;
-
- if(next->iter==canvas_interface()->get_canvas()->keyframe_list().end())
- return false;
-
- iter_next.gobj()->stamp=stamp_;
-
- return true;
-}
-
-/*
-bool
-KeyframeTreeStore::iter_next_vfunc (GtkTreeIter* gtk_iter)
-{
- if(!iterator_sane(gtk_iter)) return false;
-
- _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
-
- // If we are already at the end, then we are very invalid
- if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
- return false;
-
- ++(iter->iter);
-
- if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
- {
- --(iter->iter);
- return false;
- }
- (iter->index)++;
- return true;
-}
-
-bool
-KeyframeTreeStore::iter_children_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* parent)
-{
- dump_iterator(gtk_iter,"gtk_iter");
- dump_iterator(parent,"parent");
-
- if(!parent || !iterator_sane(parent))
- {
- clear_iterator(gtk_iter);
- return false;
- }
-
- _keyframe_iterator *iter(new _keyframe_iterator());
- iter->ref_count=1;
- iter->index=0;
- iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
-
- gtk_iter->user_data=static_cast<gpointer>(iter);
- gtk_iter->stamp=stamp_;
-
- return true;
-}
-
-bool
-KeyframeTreeStore::iter_has_child_vfunc (const GtkTreeIter*parent)
-{
- dump_iterator(parent,"parent");
-
- if(parent)
- return false;
-
- return true;
-}
-
-int
-KeyframeTreeStore::iter_n_children_vfunc (const GtkTreeIter* parent)
-{
- dump_iterator(parent,"parent");
-
- if(parent)
- return 0;
-
- return canvas_interface()->get_canvas()->keyframe_list().size();
-}
-*/
-
-int
-KeyframeTreeStore::iter_n_root_children_vfunc () const
-{
- return canvas_interface()->get_canvas()->keyframe_list().size();
-}
-
-bool
-KeyframeTreeStore::iter_nth_root_child_vfunc (int n, iterator& xiter)const
-{
- if(canvas_interface()->get_canvas()->keyframe_list().size()==0)
- {
- return false;
- }
-
- if(n<0)
- {
- g_warning("KeyframeTreeStore::iter_nth_root_child_vfunc: Out of range (negative index)");
- return false;
- }
- if(n && (unsigned)n>=canvas_interface()->get_canvas()->keyframe_list().size())
- {
- g_warning("KeyframeTreeStore::iter_nth_child_vfunc: Out of range (large index)");
- return false;
- }
-
- _keyframe_iterator *iter(new _keyframe_iterator());
- iter->ref_count=1;
- iter->index=n;
- iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
- while(n--)
- {
- if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
- {
- g_warning("KeyframeTreeStore::iter_nth_child_vfunc: >>>BUG<<< in %s on line %d",__FILE__,__LINE__);
- delete iter;
- return false;
- }
- ++iter->iter;
- }
- xiter.gobj()->user_data=static_cast<gpointer>(iter);
- xiter.gobj()->stamp=stamp_;
- return true;
-}
-
-/*
-bool
-KeyframeTreeStore::iter_nth_child_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* parent, int n)
-{
- dump_iterator(parent,"parent");
-
- if(parent)
- {
- g_warning("KeyframeTreeStore::iter_nth_child_vfunc: I am a list");
- clear_iterator(gtk_iter);
- return false;
- }
-
-
-
- _keyframe_iterator *iter(new _keyframe_iterator());
- iter->ref_count=1;
- iter->index=n;
- iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
- while(n--)
- {
- if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
- {
- g_warning("KeyframeTreeStore::iter_nth_child_vfunc: >>>BUG<<< in %s on line %d",__FILE__,__LINE__);
- delete iter;
- clear_iterator(gtk_iter);
- return false;
- }
- ++iter->iter;
- }
-
- gtk_iter->user_data=static_cast<gpointer>(iter);
- gtk_iter->stamp=stamp_;
- return true;
-}
-
-bool
-KeyframeTreeStore::iter_parent_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* child)
-{
- dump_iterator(child,"child");
- iterator_sane(child);
- clear_iterator(gtk_iter);
- return false;
-}
-*/
-
-void
-KeyframeTreeStore::ref_node_vfunc (iterator& xiter)const
-{
- GtkTreeIter* gtk_iter(xiter.gobj());
- if(!gtk_iter || !iterator_sane(gtk_iter)) return;
-
- _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
- iter->ref_count++;
-}
-
-void
-KeyframeTreeStore::unref_node_vfunc (iterator& xiter)const
-{
- GtkTreeIter* gtk_iter(xiter.gobj());
- if(!gtk_iter || !iterator_sane(gtk_iter)) return;
-
- _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
- iter->ref_count--;
- if(!iter->ref_count)
- {
- delete iter;
-
- // Make this iterator invalid
- gtk_iter->stamp=0;
- }
-}
-
-Gtk::TreeModel::Path
-KeyframeTreeStore::get_path_vfunc (const iterator& gtk_iter)const
-{
- Gtk::TreeModel::Path path;
-
- // If this is the root node, then return
- // a root path
- if(!iterator_sane(gtk_iter))
- return path;
-
- _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->gobj()->user_data));
-
- path.append_index(iter->index);
-
- return path;
-}
-
-bool
-KeyframeTreeStore::get_iter_vfunc (const Gtk::TreeModel::Path& path, iterator& iter)const
-{
- if(path.get_depth()>=1)
- return iter_nth_root_child_vfunc(path.front(),iter);
-
- // Error case
- g_warning("KeyframeTreeStore::get_iter_vfunc(): Bad path \"%s\"",path.to_string().c_str());
- //clear_iterator(iter);
- return false;
-}
-
-bool
-KeyframeTreeStore::iter_is_valid (const iterator& iter) const
-{
- return iterator_sane(iter);
-}
-
-void
-KeyframeTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& gtk_iter, int column, Glib::ValueBase& value)const
-{
- dump_iterator(gtk_iter,"gtk_iter");
- if(!iterator_sane(gtk_iter))
- return;
-
- _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->gobj()->user_data));
-
- switch(column)
- {
- case 0: // Time
- {
- Glib::Value<synfig::Time> x;
- g_value_init(x.gobj(),x.value_type());
- x.set(iter->iter->get_time());
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- return;
- }
- case 3: // Time Delta
- {
- Glib::Value<synfig::Time> x;
- g_value_init(x.gobj(),x.value_type());
-
- synfig::Keyframe prev_keyframe(*iter->iter);
- synfig::Keyframe keyframe;
- {
- KeyframeList::iterator tmp(iter->iter);
- tmp++;
- if(tmp==get_canvas()->keyframe_list().end())
- {
- x.set(Time(0));
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- return;
- }
- keyframe=*tmp;
- }
-
- Time delta(0);
- try {
- delta=keyframe.get_time()-prev_keyframe.get_time();
- }catch(...) { }
- x.set(delta);
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- return;
- }
- case 1: // Description
- {
- g_value_init(value.gobj(),G_TYPE_STRING);
- g_value_set_string(value.gobj(),iter->iter->get_description().c_str());
- return;
- }
- case 2: // Keyframe
- {
- Glib::Value<synfig::Keyframe> x;
- g_value_init(x.gobj(),x.value_type());
- x.set(*iter->iter);
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- return;
- }
- default:
- break;
- }
-}
-
-Gtk::TreeModel::Row
-KeyframeTreeStore::find_row(const synfig::Keyframe &keyframe)
-{
- Gtk::TreeModel::Row row(*(children().begin()));
- dump_iterator(row,"find_row,begin");
- const GtkTreeIter *gtk_iter(row.gobj());
- if(!iterator_sane(gtk_iter))
- throw std::runtime_error(_("Unable to find Keyframe in table"));
-
- _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
-
- synfig::KeyframeList &keyframe_list(canvas_interface()->get_canvas()->keyframe_list());
- if(keyframe_list.empty())
- throw std::runtime_error(_("There are no keyframes n this canvas"));
-
- iter->index=0;
-
- for(iter->iter=keyframe_list.begin();iter->iter!=keyframe_list.end() && *iter->iter!=keyframe;++iter->iter)
- {
- iter->index++;
- }
- if(iter->iter==keyframe_list.end())
- throw std::runtime_error(_("Unable to find Keyframe in table"));
- return row;
-}
-
-void
-KeyframeTreeStore::add_keyframe(synfig::Keyframe keyframe)
-{
- try
- {
- Gtk::TreeRow row(find_row(keyframe));
- dump_iterator(row.gobj(),"add_keyframe,row");
- Gtk::TreePath path(get_path(row));
-
- row_inserted(path,row);
-
- old_keyframe_list=get_canvas()->keyframe_list();
- //old_keyframe_list.add(keyframe);
- //old_keyframe_list.sort();
- }
- catch(std::exception x)
- {
- g_warning("%s", x.what());
- }
-}
-
-void
-KeyframeTreeStore::remove_keyframe(synfig::Keyframe keyframe)
-{
- try
- {
- if(1)
- {
- Gtk::TreeRow row(find_row(keyframe));
- dump_iterator(row,"remove_keyframe,row");
- Gtk::TreePath path(get_path(row));
- row_deleted(path);
-
- old_keyframe_list.erase(keyframe);
- }
- else
- {
- g_warning("KeyframeTreeStore::remove_keyframe: Keyframe not in table");
- }
- }
- catch(std::exception x)
- {
- g_warning("%s", x.what());
- }
-}
-
-void
-KeyframeTreeStore::change_keyframe(synfig::Keyframe keyframe)
-{
- try
- {
- Gtk::TreeRow row(find_row(keyframe));
-
- unsigned int new_index(get_index_from_model_iter(row));
- unsigned int old_index(0);
- synfig::KeyframeList::iterator iter;
- for(old_index=0,iter=old_keyframe_list.begin();iter!=old_keyframe_list.end() && (UniqueID)*iter!=(UniqueID)keyframe;++iter,old_index++)
- ;
-
- if(iter!=old_keyframe_list.end() && new_index!=old_index)
- {
- std::vector<int> new_order;
- for(unsigned int i=0;i<old_keyframe_list.size();i++)
- {
- new_order.push_back(i);
- }
- if(new_order.size()>new_index)
- {
- new_order.erase(new_order.begin()+new_index);
- new_order.insert(new_order.begin()+old_index,new_index);
-
- //new_order[old_index]=
-
- rows_reordered (Path(), iterator(), &new_order[0]);
- }
- old_keyframe_list=get_canvas()->keyframe_list();
-
- row=find_row(keyframe);
- }
-
- dump_iterator(row,"change_keyframe,row");
- row_changed(get_path(row),row);
- }
- catch(std::exception x)
- {
- g_warning("%s", x.what());
- }
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file keyframetreestore.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_KEYFRAMETREESTORE_H
-#define __SYNFIG_STUDIO_KEYFRAMETREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/liststore.h>
-#include <synfigapp/canvasinterface.h>
-#include <gdkmm/pixbuf.h>
-#include <synfig/keyframe.h>
-#include <map>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-//class TreeRowReferenceHack;
-//#define TreeRowReferenceHack Gtk::TreeRowReference
-
-namespace studio {
-
-class KeyframeTreeStore_Class;
-
-class KeyframeTreeStore :
- public Glib::Object,
- public Gtk::TreeModel,
- public Gtk::TreeDragSource,
- public Gtk::TreeDragDest
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
-
- class Model : public Gtk::TreeModel::ColumnRecord
- {
- public:
- Gtk::TreeModelColumn<synfig::Time> time;
- Gtk::TreeModelColumn<Glib::ustring> description;
- Gtk::TreeModelColumn<synfig::Keyframe> keyframe;
- Gtk::TreeModelColumn<synfig::Time> time_delta;
-
- Model()
- {
- add(time);
- add(description);
- add(keyframe);
- add(time_delta);
- }
- };
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- const Model model;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
-
- //! Unique stamp for this TreeModel.
- int stamp_;
-
- static KeyframeTreeStore_Class keyframe_tree_store_class_;
-
- //std::map<synfig::Keyframe,TreeRowReferenceHack> path_table_;
-
- synfig::KeyframeList old_keyframe_list;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
- void add_keyframe(synfig::Keyframe);
-
- void remove_keyframe(synfig::Keyframe);
-
- void change_keyframe(synfig::Keyframe);
-
- static int sorter(const Gtk::TreeModel::iterator &,const Gtk::TreeModel::iterator &);
-
- bool iterator_sane(const GtkTreeIter* iter)const;
-
- bool iterator_sane(const Gtk::TreeModel::iterator& iter)const;
-
- void dump_iterator(const GtkTreeIter* iter, const Glib::ustring &name)const;
-
- void dump_iterator(const Gtk::TreeModel::iterator& iter, const Glib::ustring &name)const;
-
- //! Resets the iterator stamp for this model.
- /*! This should be called whenever the class is
- ** constructed or when large numbers of
- ** iterators become invalid. */
- void reset_stamp();
-
- //void reset_path_table();
-
- /*
- -- ** -- V I R T U A L F U N C T I O N S -----------------------------------
- */
-
-protected:
-
- virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
- virtual Gtk::TreeModelFlags get_flags_vfunc ();
- virtual int get_n_columns_vfunc ();
- virtual GType get_column_type_vfunc (int index);
- virtual bool iter_next_vfunc (const iterator& iter, iterator& iter_next) const;
- virtual bool get_iter_vfunc (const Gtk::TreeModel::Path& path, iterator& iter_next)const;
- virtual bool iter_nth_root_child_vfunc (int n, iterator& iter)const;
- virtual Gtk::TreeModel::Path get_path_vfunc (const iterator& iter)const;
- virtual void ref_node_vfunc (iterator& iter)const;
- virtual void unref_node_vfunc (iterator& iter)const;
- virtual void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
- virtual bool iter_is_valid (const iterator& iter) const;
- virtual int iter_n_root_children_vfunc () const;
-
- //virtual bool iter_nth_child_vfunc (GtkTreeIter* iter, const GtkTreeIter* parent, int n);
- //virtual bool iter_children_vfunc (GtkTreeIter* iter, const GtkTreeIter* parent);
- //virtual bool iter_has_child_vfunc (const GtkTreeIter* iter);
- //virtual int iter_n_children_vfunc (const GtkTreeIter* iter);
- //virtual bool iter_parent_vfunc (GtkTreeIter* iter, const GtkTreeIter* child);
-
- /*
- virtual bool get_sort_column_id_vfunc (int* sort_column_id, Gtk::SortType* order);
- virtual void set_sort_column_id_vfunc (int sort_column_id, Gtk::SortType order);
- virtual void set_sort_func_vfunc (int sort_column_id, GtkTreeIterCompareFunc func, void* data, GtkDestroyNotify destroy);
- virtual void set_default_sort_func_vfunc (GtkTreeIterCompareFunc func, void* data, GtkDestroyNotify destroy);
- virtual bool has_default_sort_func_vfunc ();
- */
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- KeyframeTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
- ~KeyframeTreeStore();
-
- etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
- etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
-
- synfig::Canvas::Handle get_canvas() { return canvas_interface()->get_canvas(); }
- synfig::Canvas::Handle get_canvas()const { return canvas_interface()->get_canvas(); }
-
- Gtk::TreeModel::Row find_row(const synfig::Keyframe &keyframe);
-
- /*
- -- ** -- S T A T I C M E T H O D S ------------------------------------------
- */
-
-public:
-
- static Glib::RefPtr<KeyframeTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-
- static int time_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
- static int description_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
-
-}; // END of class KeyframeTreeStore
-
-//! \internal
-class KeyframeTreeStore_Class : public Glib::Class
-{
-public:
- struct KeyframeTreeStoreClass
- {
- GObjectClass parent_class;
- };
-
- friend class KeyframeTreeStore;
-
- const Glib::Class& init();
-
- static void class_init_function(gpointer g_blass, gpointer class_data);
-}; // END of CustomTreeStore_Class
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
#endif
#include "layeractionmanager.h"
-#include "layertree.h"
+#include "trees/layertree.h"
#include <synfig/context.h>
#include <synfig/layer_pastecanvas.h>
#include <synfigapp/action_param.h>
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file layergrouptree.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <synfig/layer.h>
-#include "layergrouptree.h"
-#include <gtkmm/treemodelsort.h>
-#include <ETL/misc>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-LayerGroupTree::LayerGroupTree()
-{
- const LayerGroupTreeStore::Model model;
-
-
- { // --- O N / O F F ----------------------------------------------------
- int index;
- index=append_column_editable(_(" "),model.active);
- //Gtk::TreeView::Column* column = get_column(index-1);
- }
- { // --- I C O N --------------------------------------------------------
- int index;
- index=append_column(_(" "),model.icon);
- Gtk::TreeView::Column* column = get_column(index-1);
- set_expander_column(*column);
- }
- { // --- N A M E --------------------------------------------------------
- int index;
- index=append_column_editable(_("Name"),model.label);
- label_column = get_column(index-1);
-
- //column->set_sort_column(layer_model.index);
-
- //set_expander_column(*column);
- //column->set_reorderable();
- //column->set_resizable();
- //column->set_clickable(false);
-
- //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
- //column->pack_start(*icon_cellrenderer,false);
- //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
- }
-
- set_enable_search(true);
- set_search_column(model.label);
- set_search_equal_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::search_func));
-
- // This makes things easier to read.
- set_rules_hint();
-
- // Make us more sensitive to several events
- add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
-
- set_reorderable(true);
-
- get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
-
- //set_flags(get_flags()|Gtk::RECEIVES_DEFAULT|Gtk::HAS_GRAB);
-
- //std::list<Gtk::TargetEntry> listTargets;
- //listTargets.push_back( Gtk::TargetEntry("LAYER") );
- //listTargets.push_back( Gtk::TargetEntry("GROUP") );
- //drag_dest_set(listTargets);
-}
-
-LayerGroupTree::~LayerGroupTree()
-{
- if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
- synfig::info("LayerGroupTree::~LayerGroupTree(): Deleted");
-}
-
-void
-LayerGroupTree::set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store)
-{
- layer_group_tree_store_=layer_group_tree_store;
- LayerGroupTreeStore::Model model;
-
-#if 0
- {
- Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(layer_group_tree_store_));
- sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
- sorted_store->set_sort_func(model.time.index(),sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
- sorted_store->set_sort_column(model.time.index(), Gtk::SORT_ASCENDING);
- Gtk::TreeView::set_model(sorted_store);
- }
-#else
- Gtk::TreeView::set_model(layer_group_tree_store);
-#endif
-}
-
-void
-LayerGroupTree::set_editable(bool x)
-{
- editable_=x;
-/*
- if(editable_)
- {
- cell_renderer_time->property_editable()=true;
- cell_renderer_time_delta->property_editable()=true;
- cell_renderer_description->property_editable()=true;
- }
- else
- {
- cell_renderer_time->property_editable()=false;
- cell_renderer_time_delta->property_editable()=false;
- cell_renderer_description->property_editable()=false;
- }
-*/
-}
-/*
-void
-LayerGroupTree::on_edited_time(const Glib::ustring&path_string,synfig::Time time)
-{
- Gtk::TreePath path(path_string);
-
- const Gtk::TreeRow row(*(get_model()->get_iter(path)));
-
- synfig::Keyframe keyframe(row[model.keyframe]);
- if(time!=keyframe.get_time())
- {
- row[model.time]=time;
- //keyframe.set_time(time);
- //signal_edited_time()(keyframe,time);
- //signal_edited()(keyframe);
- }
-}
-
-void
-LayerGroupTree::on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time)
-{
- Gtk::TreePath path(path_string);
-
- const Gtk::TreeRow row(*(get_model()->get_iter(path)));
-
- if(row)row[model.time_delta]=time;
-}
-
-void
-LayerGroupTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
-{
- Gtk::TreePath path(path_string);
-
- const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
- const synfig::String description(desc);
- synfig::Keyframe keyframe(row[model.keyframe]);
- if(description!=keyframe.get_description())
- {
- row[model.description]=desc;
- keyframe.set_description(description);
- signal_edited_description()(keyframe,description);
- signal_edited()(keyframe);
- }
-}
-*/
-
-bool
-LayerGroupTree::on_event(GdkEvent *event)
-{
- switch(event->type)
- {
- case GDK_BUTTON_PRESS:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
- //tree_to_widget_coords (,, wx, wy);
- if(!get_path_at_pos(
- wx,wy, // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
- const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
- if(row[model.is_layer] && event->button.button==3)
- {
- signal_popup_layer_menu()((Layer::Handle)row[model.layer]);
- return true;
- }
-
- /*signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
- if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
- {
- layer_group_tree_store_->canvas_interface()->set_time(row[model.time]);
- }*/
- }
- break;
- case GDK_2BUTTON_PRESS:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!get_path_at_pos(
- int(event->button.x),int(event->button.y), // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
- const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
- LayerList layer_list(row[model.all_layers]);
- if(!layer_list.empty())
- {
- if(!(event->button.state&GDK_CONTROL_MASK))
- {
- layer_group_tree_store_->canvas_interface()->get_selection_manager()->clear_selected_layers();
- }
- layer_group_tree_store_->canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
- return true;
- }
- }
- break;
- case GDK_BUTTON_RELEASE:
- break;
- default:
- break;
- }
- return Gtk::TreeView::on_event(event);
- //return false;
-}
-
-static inline void __group_grabber(const Gtk::TreeModel::iterator& iter, std::list<synfig::String>* ret)
-{
- const LayerGroupTreeStore::Model model;
- if((bool)(*iter)[model.is_group])
- ret->push_back((Glib::ustring)(*iter)[model.group_name]);
-}
-
-std::list<synfig::String>
-LayerGroupTree::get_selected_groups()const
-{
- Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
-
- if(!selection)
- return std::list<synfig::String>();
-
- std::list<synfig::String> ret;
-
- selection->selected_foreach_iter(
- sigc::bind(
- sigc::ptr_fun(
- &__group_grabber
- ),
- &ret
- )
- );
-
- return ret;
-}
-
-static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerGroupTree::LayerList* ret)
-{
- const LayerGroupTreeStore::Model model;
- if((bool)(*iter)[model.is_layer])
- ret->push_back((Layer::Handle)(*iter)[model.layer]);
-}
-
-LayerGroupTree::LayerList
-LayerGroupTree::get_selected_layers()const
-{
- Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
-
- if(!selection)
- return LayerList();
-
- LayerList ret;
-
- selection->selected_foreach_iter(
- sigc::bind(
- sigc::ptr_fun(
- &__layer_grabber
- ),
- &ret
- )
- );
-
- return ret;
-}
-
-void
-LayerGroupTree::set_cursor(const Gtk::TreeModel::Path& path, bool start_editing)
-{
- Gtk::TreeView::set_cursor(path, *label_column, start_editing);
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file layergrouptree.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_LAYERGROUPTREE_H
-#define __SYNFIG_STUDIO_LAYERGROUPTREE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treeview.h>
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <synfigapp/value_desc.h>
-#include "layergrouptreestore.h"
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace synfig { class Layer; }
-
-namespace studio {
-
-class LayerGroupTree : public Gtk::TreeView
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
-
- typedef std::list<synfig::Layer::Handle> LayerList;
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- LayerGroupTreeStore::Model model;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store_;
-
- Gtk::CellRendererText *cell_renderer_description;
-
- bool editable_;
-
-
- sigc::signal<void,etl::handle<synfig::Layer> > signal_popup_layer_menu_;
-
-// sigc::signal<void,LayerList> signal_select_layers_;
- Gtk::TreeView::Column* label_column;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- bool on_event(GdkEvent *event);
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- LayerGroupTree();
- ~LayerGroupTree();
- void set_cursor(const Gtk::TreeModel::Path& path, bool start_editing=false);
-
- Glib::RefPtr<LayerGroupTreeStore> get_model() { return layer_group_tree_store_; }
-
- sigc::signal<void,etl::handle<synfig::Layer> >& signal_popup_layer_menu() { return signal_popup_layer_menu_; }
-
-// sigc::signal<void,LayerList>& signal_select_layers() { return signal_select_layers_; }
-
- void set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store_);
-
- void set_editable(bool x=true);
-
- bool get_editable()const { return editable_; }
-
- std::list<synfig::String> get_selected_groups()const;
-
- LayerList get_selected_layers()const;
-}; // END of LayerGroupTree
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file layergrouptreestore.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "layergrouptreestore.h"
-#include "iconcontroller.h"
-#include <gtkmm/button.h>
-#include <synfig/paramdesc.h>
-#include <synfigapp/action.h>
-#include <synfigapp/instance.h>
-#include "app.h"
-#include "instance.h"
-#include <synfigapp/action_system.h>
-#include "docks/dockmanager.h"
-#include "docks/dockable.h"
-
-#include <gtk/gtkversion.h>
-#include <ETL/clock>
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-#define GROUP_NEST_CHAR '.'
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static LayerGroupTreeStore::Model& ModelHack()
-{
- static LayerGroupTreeStore::Model* model(0);
- if(!model)model=new LayerGroupTreeStore::Model;
- return *model;
-}
-
-LayerGroupTreeStore::LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
- Gtk::TreeStore (ModelHack()),
- canvas_interface_ (canvas_interface_)
-{
- layer_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
- group_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-group"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
-
- // Connect Signals to Terminals
- canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_status_changed));
- canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_new_description));
-
- canvas_interface()->get_canvas()->signal_group_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_added)));
- canvas_interface()->get_canvas()->signal_group_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_removed)));
- canvas_interface()->get_canvas()->signal_group_changed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_changed)));
-
- canvas_interface()->get_canvas()->signal_group_pair_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_added)));
- canvas_interface()->get_canvas()->signal_group_pair_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_removed)));
-
- rebuild();
-}
-
-LayerGroupTreeStore::~LayerGroupTreeStore()
-{
- //clear();
-
- if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
- synfig::info("LayerGroupTreeStore::~LayerGroupTreeStore(): Deleted");
-}
-
-bool
-LayerGroupTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
-{
- const Model model;
-
- Glib::ustring substr(x.uppercase());
- Glib::ustring label((*iter)[model.label]);
- label=label.uppercase();
-
- return label.find(substr)==Glib::ustring::npos;
-}
-
-
-Glib::RefPtr<LayerGroupTreeStore>
-LayerGroupTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
-{
- return Glib::RefPtr<LayerGroupTreeStore>(new LayerGroupTreeStore(canvas_interface_));
-}
-
-void
-LayerGroupTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
-{
- if(column==model.child_layers.index())
- {
- Glib::Value<LayerList> x;
- g_value_init(x.gobj(),x.value_type());
-
- if((bool)(*iter)[model.is_group])
- {
- set<Layer::Handle> layer_set(canvas_interface()->get_canvas()->get_layers_in_group((Glib::ustring)(*iter)[model.group_name]));
-
- x.set(LayerList(layer_set.begin(),layer_set.end()));
- }
- else if((bool)(*iter)[model.is_layer])
- {
- LayerList layer_list;
- layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
- x.set(layer_list);
- }
-
- g_value_init(value.gobj(),x.value_type());
- value=x;
- }
- else if(column==model.all_layers.index())
- {
- Glib::Value<LayerList> x;
- g_value_init(x.gobj(),x.value_type());
-
- if((bool)(*iter)[model.is_group])
- {
- LayerList layer_list;
- Gtk::TreeModel::iterator child_iter(iter->children().begin());
- for(;child_iter;++child_iter)
- {
- LayerList layer_list2((LayerList)(*child_iter)[model.all_layers]);
- for(;layer_list2.size();layer_list2.pop_front())
- layer_list.push_back(layer_list2.front());
- }
- x.set(layer_list);
- }
- else if((bool)(*iter)[model.is_layer])
- {
- LayerList layer_list;
- layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
- x.set(layer_list);
- }
-
- g_value_init(value.gobj(),x.value_type());
- value=x;
- }
- else if(column==model.group_name.index())
- {
- if((bool)(*iter)[model.is_group])
- return Gtk::TreeStore::get_value_vfunc(iter,column,value);
- return get_value_vfunc(iter->parent(),column,value);
- }
- else if(column==model.parent_group_name.index())
- {
- if(iter->parent())
- return get_value_vfunc(iter->parent(),model.group_name.index(),value);
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
- x.set(Glib::ustring());
- g_value_init(value.gobj(),x.value_type());
- value=x;
- }
- else if(column==model.label.index())
- {
- if((bool)(*iter)[model.is_group])
- {
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
-
- Glib::ustring group_name((*iter)[model.group_name]);
-
- // Get rid of any parent group crap
- while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
- group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
-
- x.set(group_name);
-
- g_value_init(value.gobj(),x.value_type());
-
- value=x;
- }
- else if((bool)(*iter)[model.is_layer])
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(layer->get_non_empty_description());
-
- g_value_init(value.gobj(),x.value_type());
- //g_value_copy(x.gobj(),value.gobj());
- value=x;
- }
- }
- else
- if(column==model.tooltip.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
-
-
- x.set(layer->get_local_name());
-
- g_value_init(value.gobj(),x.value_type());
- //g_value_copy(x.gobj(),value.gobj());
- value=x;
- }
- else
- if(column==model.canvas.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<Canvas::Handle> x;
- g_value_init(x.gobj(),x.value_type());
-
-
- x.set(layer->get_canvas());
-
- g_value_init(value.gobj(),x.value_type());
- //g_value_copy(x.gobj(),value.gobj());
- value=x;
- }
- else
- if(column==model.active.index())
- {
- Glib::Value<bool> x;
- g_value_init(x.gobj(),x.value_type());
-
- if((bool)(*iter)[model.is_layer])
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
- x.set(layer->active());
- }
- else if((bool)(*iter)[model.is_group])
- {
- int activecount(0),total(0);
- Gtk::TreeModel::iterator child_iter(iter->children().begin());
- for(;child_iter;++child_iter)
- {
- total++;
- if((*child_iter)[model.active])
- activecount++;
- }
- x.set(activecount>total/2);
- }
- else
- x.set(false);
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.icon.index())
- {
- Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
- g_value_init(x.gobj(),x.value_type());
-
- if((bool)(*iter)[model.is_layer])
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
- if(!layer)return;
- //x.set(layer_icon);
- x.set(get_tree_pixbuf_layer(layer->get_name()));
- }
- if((bool)(*iter)[model.is_group])
- x.set(group_icon);
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- Gtk::TreeStore::get_value_vfunc(iter,column,value);
-}
-
-void
-LayerGroupTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
-{
- //if(!iterator_sane(row))
- // return;
-
- if(column>=get_n_columns_vfunc())
- {
- g_warning("LayerGroupTreeStore::set_value_impl: Bad column (%d)",column);
- return;
- }
-
- if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
- {
- g_warning("LayerGroupTreeStore::set_value_impl: Bad value type");
- return;
- }
-
- try
- {
- if(column==model.label.index())
- {
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),model.label.type());
- g_value_copy(value.gobj(),x.gobj());
-
- if((bool)(*iter)[model.is_layer])
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
- if(!layer)
- return;
- synfig::String new_desc(x.get());
-
- if(new_desc==layer->get_local_name())
- new_desc=synfig::String();
-
- if(new_desc==layer->get_description())
- return;
-
- synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetDesc"));
-
- if(!action)
- return;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("layer",layer);
- action->set_param("new_description",synfig::String(x.get()));
-
- canvas_interface()->get_instance()->perform_action(action);
- return;
- }
- else if((bool)(*iter)[model.is_group])
- {
- synfig::String group((Glib::ustring)(*iter)[model.label]);
- synfig::String new_group(x.get());
-
- if(x.get()==group)
- return;
-
- Glib::ustring group_name((*iter)[model.group_name]);
- group=group_name;
- new_group.clear();
-
- // Get rid of any parent group crap
- while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
- {
- new_group+=Glib::ustring(group_name,0,group_name.find(GROUP_NEST_CHAR)+1);
- group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
- }
- new_group+=x.get();
-
- synfig::info("Renaming group \"%s\" to \"%s\"...",group.c_str(),new_group.c_str());
-
- // Check to see if this group is real or not.
- // If it isn't real, then renaming it is a cinch.
- // We know it isn't real if it doesn't have any
- // children yet.
- if(iter->children().empty())
- {
- (*iter)[model.group_name]=new_group;
- }
- else
- {
- synfigapp::Action::Handle action(synfigapp::Action::create("GroupRename"));
-
- if(!action)
- return;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("group",group);
- action->set_param("new_group",new_group);
-
- canvas_interface()->get_instance()->perform_action(action);
- }
- return;
- }
- return;
- }
- else
- if(column==model.active.index())
- {
- Glib::Value<bool> x;
- g_value_init(x.gobj(),model.active.type());
- g_value_copy(value.gobj(),x.gobj());
-
- if((bool)(*iter)[model.is_layer])
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
- if(!layer)return;
-
- synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
-
- if(!action)
- return;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("layer",layer);
- action->set_param("new_status",bool(x.get()));
-
-
- canvas_interface()->get_instance()->perform_action(action);
- return;
- }
- else if(!iter->children().empty())
- {
- synfigapp::Action::PassiveGrouper group(
- get_canvas_interface()->get_instance().get(),
- String(
- x.get()?_("Activate "):_("Deactivate ")
- )+(Glib::ustring)(*iter)[model.label]
- );
-
- Gtk::TreeModel::iterator child_iter(iter->children().begin());
-
- for(;child_iter;++child_iter)
- (*child_iter)[model.active]=x.get();
-
- Gtk::TreeStore::set_value_impl(iter,column, value);
- }
- }
- else
- Gtk::TreeStore::set_value_impl(iter,column, value);
-
- }
- catch(std::exception x)
- {
- g_warning("%s", x.what());
- }
-}
-
-
-
-
-bool
-LayerGroupTreeStore::row_draggable_vfunc (const TreeModel::Path& /*path*/)const
-{
- //if(!get_iter(path)) return false;
-// Gtk::TreeModel::Row row(*get_iter(path));
-
- return true;
-}
-
-bool
-LayerGroupTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
-{
- if(!const_cast<LayerGroupTreeStore*>(this)->get_iter(path)) return false;
- //synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
- //synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
- //synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
-
- Gtk::TreeModel::Row row(*const_cast<LayerGroupTreeStore*>(this)->get_iter(path));
-
- if((bool)row[model.is_layer])
- {
- Layer* layer(((Layer::Handle)row[model.layer]).get());
- assert(layer);
-
- std::vector<Layer*> layers;
-
- layers.push_back(layer);
-
- selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
-
- return true;
- }
- else if((bool)row[model.is_group])
- {
- synfig::String group((Glib::ustring)row[model.group_name]);
- if(group.empty())
- return false;
-
- selection_data.set("GROUP", 8, reinterpret_cast<const guchar*>(&*group.begin()), sizeof(void*)*group.size());
-
- return true;
- }
-
- return false;
-}
-
-bool
-LayerGroupTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
-{
- return true;
-}
-
-bool
-LayerGroupTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
-{
- Gtk::TreeIter iter(const_cast<LayerGroupTreeStore*>(this)->get_iter(dest));
- if(!iter) return false;
-
- if(synfig::String(selection_data.get_data_type())=="LAYER")
- return true;
-
- if(synfig::String(selection_data.get_data_type())=="GROUP")
- {
- synfig::String dest_group((Glib::ustring)(*iter)[model.group_name]);
- synfig::String src_group(reinterpret_cast<const gchar*>(selection_data.get_data()));
- //synfig::String src_group(const_cast<gchar*>(selection_data.get_data()));
-
- // Avoid putting a group inside of itself
- if(dest_group.size()>src_group.size() && src_group==String(dest_group,0,src_group.size()))
- return false;
- return true;
- }
-
- return false;
- //synfig::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
- //synfig::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
- //synfig::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
-
- //Gtk::TreeModel::Row row(*get_iter(dest));
-
-/* if(synfig::String(selection_data.get_data_type())=="LAYER" && (bool)true)
- return true;
-*/
- return false;
-}
-
-bool
-LayerGroupTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
-{
- if(!get_iter(dest)) return false;
-// bool ret=false;
- //int i(0);
-
- Gtk::TreeModel::Row row(*get_iter(dest));
-
- //synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
- //synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
- //synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
- synfigapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Regroup"));
-
- if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
- {
- synfig::String dest_group;
-
- dest_group=(Glib::ustring)row[model.group_name];
-
- if(dest_group.empty())
- return false;
-
- if(synfig::String(selection_data.get_data_type())=="LAYER")
- {
- synfigapp::Action::Handle action(synfigapp::Action::create("GroupAddLayers"));
-
- if(!action)
- return false;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("group",dest_group);
-
- for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
- {
- Layer::Handle layer(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
- assert(layer);
-
- action->set_param("layer",layer);
- }
- if(!canvas_interface()->get_instance()->perform_action(action))
- {
- passive_grouper.cancel();
- return false;
- }
- return true;
- }
- if(synfig::String(selection_data.get_data_type())=="GROUP")
- {
- synfig::String src_group(reinterpret_cast<const gchar*>(selection_data.get_data()));
- synfig::String group(src_group);
-
- // Get rid of any parent group crap
- while(group.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
- group=Glib::ustring(group,group.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
-
- group=dest_group+GROUP_NEST_CHAR+group;
-
- synfigapp::Action::Handle action(synfigapp::Action::create("GroupRename"));
-
- if(!action)
- return false;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("group",src_group);
- action->set_param("new_group",group);
-
- if(!canvas_interface()->get_instance()->perform_action(action))
- {
- passive_grouper.cancel();
- return false;
- }
- return true;
- }
- }
-/* // Save the selection data
- synfigapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
-
- if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
- {
- Canvas::Handle dest_canvas;
- Layer::Handle dest_layer;
-
- dest_canvas=(Canvas::Handle)(row[model.canvas]);
- dest_layer=(Layer::Handle)(row[model.layer]);
- assert(dest_canvas);
-
- if(!dest_layer)
- return false;
-
- int dest_layer_depth=dest_layer->get_depth();
-
- if(synfig::String(selection_data.get_data_type())=="LAYER")for(i=0;i<selection_data.get_length()/sizeof(void*);i++)
- {
- //synfig::info("dest_layer_depth=%d",dest_layer_depth);
-
- Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
- assert(src);
- if(dest_layer==src)
- continue;
-
- // In this case, we are just moving.
-// if(dest_canvas==src->get_canvas())
- {
- if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
- dest_layer_depth--;
- if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
- continue;
-
- synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
- action->set_param("canvas",dest_canvas);
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("layer",src);
- action->set_param("new_index",dest_layer_depth);
- action->set_param("dest_canvas",dest_canvas);
- if(canvas_interface()->get_instance()->perform_action(action))
- {
- ret=true;
- }
- else
- {
- passive_grouper.cancel();
- return false;
- }
- continue;
- }
- }
- }
- synfig::info("I supposedly moved %d layers",i);
-
- // Reselect the previously selected layers
- canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
-
- return ret;
- */
- return false;
-}
-
-
-
-
-
-
-
-void
-LayerGroupTreeStore::rebuild()
-{
- rebuilding=true;
- // etl::clock timer;timer.reset();
- try {
-
- // Clear out the current list
- clear();
- Canvas::Handle canvas(canvas_interface()->get_canvas());
- std::set<String> groups(canvas->get_groups());
- for(;groups.size();groups.erase(groups.begin()))
- {
- String group(*groups.begin());
- Gtk::TreeRow row(on_group_added(group));
- std::set<Layer::Handle> layers(canvas->get_layers_in_group(group));
-
- for(;layers.size();layers.erase(layers.begin()))
- {
- Gtk::TreeRow layer_row(*(prepend(row.children())));
- Layer::Handle layer(*layers.begin());
- set_row_layer(layer_row,layer);
- }
- }
-
- // Go ahead and add all the layers
- /*std::for_each(
- canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
- sigc::mem_fun(*this, &studio::LayerGroupTreeStore::on_layer_added)
- );*/
- }
- catch(...)
- {
- rebuilding=false;
- throw;
- }
- rebuilding=false;
- // synfig::info("LayerGroupTreeStore::rebuild() took %f seconds",float(timer()));
-}
-
-void
-LayerGroupTreeStore::refresh()
-{
- rebuild();
-}
-
-void
-LayerGroupTreeStore::refresh_row(Gtk::TreeModel::Row &row)
-{
- if((bool)row[model.is_layer])
- {
- Layer::Handle layer=row[model.layer];
-
-
- //if(layer->dynamic_param_list().count("z_depth"))
- // row[model.z_depth]=Time::begin();
- }
-
- Gtk::TreeModel::Children children = row.children();
- Gtk::TreeModel::Children::iterator iter;
-
- if(!children.empty())
- for(iter = children.begin(); iter && iter != children.end(); ++iter)
- {
- Gtk::TreeRow row=*iter;
- refresh_row(row);
- }
-}
-
-
-void
-LayerGroupTreeStore::set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle)
-{
- row[model.is_layer] = true;
- row[model.is_group] = false;
- row[model.layer] = handle;
-}
-
-Gtk::TreeRow
-LayerGroupTreeStore::on_group_added(synfig::String group)
-{
- // Check to see if this group perhaps already
- // exists
- {
- Gtk::TreeModel::Children::iterator iter;
- if(find_group_row(group, iter))
- return *iter;
- }
-
- if(group.find(GROUP_NEST_CHAR)!=String::npos)
- {
- Gtk::TreeModel::Children::iterator iter;
- String parent_name;
- do
- {
- if(parent_name.size())
- parent_name+=GROUP_NEST_CHAR;
- parent_name+=string(group,0,group.find(GROUP_NEST_CHAR));
-
- if(!find_group_row(parent_name, iter))
- iter=on_group_added(parent_name);
-
- group=String(group,group.find(GROUP_NEST_CHAR)+1,String::npos);
- }while(group.find(GROUP_NEST_CHAR)!=String::npos);
-
- if(parent_name.size())
- parent_name+=GROUP_NEST_CHAR;
- parent_name+=group;
-
- if(iter)
- {
- Gtk::TreeRow row(*(prepend(iter->children())));
- row[model.group_name]=parent_name;
- row[model.is_layer]=false;
- row[model.is_group]=true;
- on_activity();
- return row;
- }
- }
-
- Gtk::TreeRow row(*(append()));
- row[model.group_name]=group;
- row[model.is_layer]=false;
- row[model.is_group]=true;
- on_activity();
- return row;
-}
-
-bool
-LayerGroupTreeStore::on_group_removed(synfig::String group)
-{
- Gtk::TreeModel::Children::iterator iter;
- if(find_group_row(group,iter) && iter->children().size()==0)
- erase(iter);
- else
- return false;
-
- return true;
-}
-
-bool
-LayerGroupTreeStore::on_group_changed(synfig::String /*group*/)
-{
- return true;
-}
-
-void
-LayerGroupTreeStore::on_group_pair_added(synfig::String group, etl::handle<synfig::Layer> layer)
-{
- if(!layer->get_canvas())
- return;
- Gtk::TreeModel::Children::iterator iter;
- if(!find_group_row(group, iter))
- iter=on_group_added(group);
-
- Gtk::TreeRow layer_row(*(append(iter->children())));
- set_row_layer(layer_row,layer);
- on_activity();
-}
-
-void
-LayerGroupTreeStore::on_group_pair_removed(synfig::String group, etl::handle<synfig::Layer> layer)
-{
- if(!layer->get_canvas())
- return;
- Gtk::TreeModel::Children::iterator iter;
- if(!find_group_row(group, iter))
- return;
-
- Gtk::TreeModel::Children::iterator prev,layer_iter;
-
- if(!find_layer_row_(layer, layer->get_canvas(), iter->children(), layer_iter, prev))
- return;
-
- erase(layer_iter);
-
- on_activity();
-}
-
-void
-LayerGroupTreeStore::on_activity()
-{
- // If we aren't rebuilding and the last action
- // had something to do with groups, then go
- // a head and present the groups dialog.
- if(!rebuilding && canvas_interface()->get_instance()->get_most_recent_action() && canvas_interface()->get_instance()->get_most_recent_action()->get_name().find("Group")!=String::npos)
- try
- {
- App::dock_manager->find_dockable("groups").present();
- }
- catch(...) { }
-}
-
-void
-LayerGroupTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
-{
- Gtk::TreeModel::Children::iterator iter;
- if(find_layer_row(handle,iter))
- (*iter)[model.layer]=handle;
- else
- {
- // Not need to send a warning when a layer changes its status and
- // it is not found in any group.
- //synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
- rebuild();
- }
-}
-
-
-void
-LayerGroupTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
-{
- Gtk::TreeModel::Children::iterator iter;
- if(find_layer_row(handle,iter))
- {
- Gtk::TreeRow row(*iter);
-
- Layer::Handle layer(row[model.layer]);
-
- if(desc.empty())
- {
- //row[model.label]=layer->get_local_name();
- row[model.tooltip]=Glib::ustring(_("Layer"));
- }
- else
- //row[model.label]=layer->get_description();
- row[model.tooltip]=layer->get_local_name();
- }
- else
- {
- rebuild();
- }
-}
-
-bool
-LayerGroupTreeStore::find_layer_row_(const synfig::Layer::Handle &layer, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
-{
- assert(layer);
-
- //if(layer->get_canvas()==canvas)
- {
- for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
- {
- Gtk::TreeModel::Row row = *iter;
- if((bool)row[model.is_layer] && layer==(synfig::Layer::Handle)row[model.layer])
- return true;
- }
-
- iter=children().end();
- //return false;
- }
-
- Gtk::TreeModel::Children::iterator iter2;
-
- for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
- {
- Gtk::TreeModel::Row row = *iter2;
- assert((bool)true);
-
- if(row.children().empty())
- continue;
-
- /*Canvas::Handle canvas((*row.children().begin())[model.canvas]);
- if(!canvas)
- continue;
- */
-
- if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
- return true;
- }
-
- iter=children().end();
- return false;
-}
-
-bool
-LayerGroupTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
-{
- Gtk::TreeModel::Children::iterator prev;
- return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
-}
-
-bool
-LayerGroupTreeStore::find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter)
-{
- Gtk::TreeModel::Children::iterator prev;
- return find_group_row_(group,children(),iter,prev);
-}
-
-bool
-LayerGroupTreeStore::find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
-{
- //if(layer->get_canvas()==canvas)
- {
- for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
- {
- Gtk::TreeModel::Row row = *iter;
- if((bool)row[model.is_group] && group==(Glib::ustring)row[model.group_name])
- return true;
- }
-
- iter=children().end();
- //return false;
- }
-
- Gtk::TreeModel::Children::iterator iter2;
-
- for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
- {
- Gtk::TreeModel::Row row = *iter2;
- assert((bool)true);
-
- if(row.children().empty())
- continue;
-
- if(find_group_row_(group,iter2->children(),iter,prev))
- return true;
- }
-
- iter=children().end();
- return false;
-}
-
-bool
-LayerGroupTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
-{
- Gtk::TreeModel::Children::iterator iter;
- if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
- return false;
- if(iter==children().begin())
- return false;
- return true;
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file layergrouptreestore.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_LAYERGROUPTREESTORE_H
-#define __SYNFIG_STUDIO_LAYERGROUPTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <synfig/value.h>
-#include <synfig/valuenode.h>
-#include <gtkmm/treeview.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class LayerGroupTreeStore : public Gtk::TreeStore
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
- typedef std::list<synfig::Layer::Handle> LayerList;
-
- class Model : public Gtk::TreeModel::ColumnRecord
- {
- public:
- Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
- Gtk::TreeModelColumn<Glib::ustring> label;
- Gtk::TreeModelColumn<Glib::ustring> tooltip;
-
- Gtk::TreeModelColumn<Glib::ustring> group_name;
- Gtk::TreeModelColumn<Glib::ustring> parent_group_name;
-
- Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
-
- Gtk::TreeModelColumn<bool> active;
- Gtk::TreeModelColumn<bool> is_layer;
- Gtk::TreeModelColumn<bool> is_group;
- Gtk::TreeModelColumn<synfig::Layer::Handle> layer;
-
- Gtk::TreeModelColumn<LayerList> all_layers;
- Gtk::TreeModelColumn<LayerList> child_layers;
-
- Model()
- {
- add(icon);
- add(label);
- add(group_name);
- add(parent_group_name);
- add(canvas);
- add(tooltip);
- add(active);
- add(layer);
- add(is_layer);
- add(is_group);
- add(all_layers);
- add(child_layers);
- }
- };
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- //! TreeModel for the layers
- const Model model;
-
- bool rebuilding;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
-
- Glib::RefPtr<Gdk::Pixbuf> layer_icon;
- Glib::RefPtr<Gdk::Pixbuf> group_icon;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
- /*
- -- ** -- P R O T E C T E D M E T H O D S -----------------------------------
- */
-
-private:
-
- virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
- virtual void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
-
- virtual bool row_draggable_vfunc (const TreeModel::Path& path)const;
- virtual bool drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
- virtual bool drag_data_delete_vfunc (const TreeModel::Path& path);
- virtual bool drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
- virtual bool row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;
-
-
- void on_group_pair_added(synfig::String group, etl::handle<synfig::Layer> layer);
- void on_group_pair_removed(synfig::String group, etl::handle<synfig::Layer> layer);
-
- void on_activity();
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- bool on_layer_tree_event(GdkEvent *event);
-
- void on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc);
-
- void on_layer_status_changed(synfig::Layer::Handle handle,bool);
-
- bool find_layer_row_(const synfig::Layer::Handle &handle, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
-
- bool find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
-
- bool on_group_removed(synfig::String group);
- bool on_group_changed(synfig::String group);
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
- ~LayerGroupTreeStore();
-
- Gtk::TreeRow on_group_added(synfig::String group);
- etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
- etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
- etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
-
- bool find_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
-
- bool find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter);
-
- bool find_prev_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
-
- void rebuild();
-
- void refresh();
-
- void refresh_row(Gtk::TreeModel::Row &row);
-
- void set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle);
-
- static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
-
- /*
- -- ** -- S T A T I C P U B L I C M E T H O D S ---------------------------
- */
-
-public:
-
- static Glib::RefPtr<LayerGroupTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-
-}; // END of class LayerGroupTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file layerparamtreestore.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2007, 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "layerparamtreestore.h"
-#include "iconcontroller.h"
-#include <gtkmm/button.h>
-#include <synfig/paramdesc.h>
-#include "layertree.h"
-#include <synfigapp/action_system.h>
-#include <synfigapp/instance.h>
-#include "app.h"
-#include <ETL/clock>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-class Profiler : private etl::clock
-{
- const std::string name;
-public:
- Profiler(const std::string& name):name(name) { reset(); }
- ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
-};
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static LayerParamTreeStore::Model& ModelHack()
-{
- static LayerParamTreeStore::Model* model(0);
- if(!model)model=new LayerParamTreeStore::Model;
- return *model;
-}
-
-LayerParamTreeStore::LayerParamTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_,LayerTree* layer_tree):
- Gtk::TreeStore (ModelHack()),
- CanvasTreeStore (canvas_interface_),
- layer_tree (layer_tree)
-{
- queued=0;
- // Connect all the signals
- canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_changed));
- canvas_interface()->signal_value_node_renamed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_renamed));
- canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_added));
- canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_deleted));
- canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_replaced));
- canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_layer_param_changed));
-
- canvas_interface()->signal_value_node_child_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_added));
- canvas_interface()->signal_value_node_child_removed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_removed));
-
-
- layer_tree->get_selection()->signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_rebuild));
-
- signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_refresh));
- rebuild();
-}
-
-LayerParamTreeStore::~LayerParamTreeStore()
-{
- while(!changed_connection_list.empty())
- {
- changed_connection_list.back().disconnect();
- changed_connection_list.pop_back();
- }
-
- if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
- synfig::info("LayerParamTreeStore::~LayerParamTreeStore(): Deleted");
-}
-
-Glib::RefPtr<LayerParamTreeStore>
-LayerParamTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree)
-{
- return Glib::RefPtr<LayerParamTreeStore>(new LayerParamTreeStore(canvas_interface_,layer_tree));
-}
-
-
-
-void
-LayerParamTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
-{
- if(column<0)
- {
- synfig::error("LayerParamTreeStore::get_value_vfunc(): Bad column!");
- return;
- }
-
-/* if(column==model.label.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(layer->get_non_empty_description());
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
-*/
- if(column==model.label.index())
- {
- synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
- Glib::ustring label;
-
- if(!(*iter)[model.is_toplevel])
- return CanvasTreeStore::get_value_vfunc(iter,column,value);
- synfig::ParamDesc param_desc((*iter)[model.param_desc]);
- label=param_desc.get_local_name();
-
- if(!(*iter)[model.is_inconsistent])
- if(value_desc.is_value_node() && value_desc.get_value_node()->is_exported())
- {
- label+=strprintf(" (%s)",value_desc.get_value_node()->get_id().c_str());
- }
-
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(label);
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.is_toplevel.index())
- {
- Glib::Value<bool> x;
- g_value_init(x.gobj(),x.value_type());
-
- TreeModel::Path path(get_path(iter));
-
- x.set(path.get_depth()<=1);
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- if(column==model.is_inconsistent.index())
- {
- if((*iter)[model.is_toplevel])
- {
- CanvasTreeStore::get_value_vfunc(iter,column,value);
- return;
- }
-
- Glib::Value<bool> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(false);
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- CanvasTreeStore::get_value_vfunc(iter,column,value);
-}
-
-
-
-void
-LayerParamTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
-{
- //if(!iterator_sane(row))
- // return;
-
- if(column>=get_n_columns_vfunc())
- {
- g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
- return;
- }
-
- if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
- {
- g_warning("LayerTreeStore::set_value_impl: Bad value type");
- return;
- }
-
- try
- {
- if(column==model.value.index())
- {
- Glib::Value<synfig::ValueBase> x;
- g_value_init(x.gobj(),model.value.type());
- g_value_copy(value.gobj(),x.gobj());
-
- if((bool)(*iter)[model.is_toplevel])
- {
- synfigapp::Action::PassiveGrouper group(canvas_interface()->get_instance().get(),_("Set Layer Params"));
-
- synfig::ParamDesc param_desc((*iter)[model.param_desc]);
-
- LayerList::iterator iter2(layer_list.begin());
-
- for(;iter2!=layer_list.end();++iter2)
- {
- if(!canvas_interface()->change_value(synfigapp::ValueDesc(*iter2,param_desc.get_name()),x.get()))
- {
- // ERROR!
- group.cancel();
- App::dialog_error_blocking(_("Error"),_("Unable to set all layer parameters."));
-
- return;
- }
- }
- }
- else
- {
- canvas_interface()->change_value((*iter)[model.value_desc],x.get());
- }
- return;
- }
- else
-/*
- if(column==model.active.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<bool> x;
- g_value_init(x.gobj(),model.active.type());
- g_value_copy(value.gobj(),x.gobj());
-
- synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
-
- if(!action)
- return;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("layer",layer);
- action->set_param("new_status",bool(x.get()));
-
- canvas_interface()->get_instance()->perform_action(action);
- return;
- }
- else
-*/
- CanvasTreeStore::set_value_impl(iter,column, value);
- }
- catch(std::exception x)
- {
- g_warning("%s", x.what());
- }
-}
-
-
-
-
-
-
-
-
-
-
-void
-LayerParamTreeStore::rebuild()
-{
- // Profiler profiler("LayerParamTreeStore::rebuild()");
- if(queued)queued=0;
- clear();
- layer_list=layer_tree->get_selected_layers();
-
- if(layer_list.size()<=0)
- return;
-
- // Get rid of all the connections,
- // and clear the connection map.
- //while(!connection_map.empty())connection_map.begin()->second.disconnect(),connection_map.erase(connection_map.begin());
- while(!changed_connection_list.empty())
- {
- changed_connection_list.back().disconnect();
- changed_connection_list.pop_back();
- }
-
- struct REBUILD_HELPER
- {
- ParamVocab vocab;
- Layer::Handle layer_0;
-
- static ParamVocab::iterator find_param_desc(ParamVocab& vocab, const synfig::String& x)
- {
- ParamVocab::iterator iter;
-
- for(iter=vocab.begin();iter!=vocab.end();++iter)
- if(iter->get_name()==x)
- break;
- return iter;
- }
-
- void process_vocab(synfig::Layer::Handle layer_n)
- {
- ParamVocab x = layer_n->get_param_vocab();
- ParamVocab::iterator iter;
-
- for(iter=vocab.begin();iter!=vocab.end();++iter)
- {
- String name(iter->get_name());
- ParamVocab::iterator iter2(find_param_desc(x,name));
- if(iter2==x.end() ||
- layer_0->get_param(name).get_type() != layer_n->get_param(name).get_type())
- {
- // remove it and start over
- vocab.erase(iter);
- iter=vocab.begin();
- iter--;
- continue;
- }
- }
- }
-
- } rebuild_helper;
-
-
- {
- LayerList::iterator iter(layer_list.begin());
- rebuild_helper.vocab=(*iter)->get_param_vocab();
- rebuild_helper.layer_0=*iter;
-
- for(++iter;iter!=layer_list.end();++iter)
- {
- rebuild_helper.process_vocab(*iter);
- changed_connection_list.push_back(
- (*iter)->signal_changed().connect(
- sigc::mem_fun(
- *this,
- &LayerParamTreeStore::changed
- )
- )
- );
- }
- }
-
- ParamVocab::iterator iter;
- for(iter=rebuild_helper.vocab.begin();iter!=rebuild_helper.vocab.end();++iter)
- {
- if(iter->get_hidden())
- continue;
-
- /*
- if(iter->get_animation_only())
- {
- int length(layer_list.front()->get_canvas()->rend_desc().get_frame_end()-layer_list.front()->get_canvas()->rend_desc().get_frame_start());
- if(!length)
- continue;
- }
- */
- Gtk::TreeRow row(*(append()));
- synfigapp::ValueDesc value_desc(layer_list.front(),iter->get_name());
- CanvasTreeStore::set_row(row,value_desc);
- if(value_desc.is_value_node())
- {
- changed_connection_list.push_back(
- value_desc.get_value_node()->signal_changed().connect(
- sigc::mem_fun(
- this,
- &LayerParamTreeStore::changed
- )
- )
- );
- }
- if(value_desc.get_value_type()==ValueBase::TYPE_CANVAS)
- {
- Canvas::Handle canvas_handle = value_desc.get_value().get(Canvas::Handle());
- if(canvas_handle) changed_connection_list.push_back(
- canvas_handle->signal_changed().connect(
- sigc::mem_fun(
- this,
- &LayerParamTreeStore::changed
- )
- )
- );
- }
- //row[model.label] = iter->get_local_name();
- row[model.param_desc] = *iter;
- row[model.canvas] = layer_list.front()->get_canvas();
- row[model.is_inconsistent] = false;
- //row[model.is_toplevel] = true;
-
-
- LayerList::iterator iter2(layer_list.begin());
- ValueBase value((*iter2)->get_param(iter->get_name()));
- for(++iter2;iter2!=layer_list.end();++iter2)
- {
- if(value!=((*iter2)->get_param(iter->get_name())))
- {
- row[model.is_inconsistent] = true;
- while(!row.children().empty() && erase(row.children().begin()))
- ;
- break;
- }
- }
- }
-}
-
-void
-LayerParamTreeStore::queue_refresh()
-{
- if(queued)
- return;
- queued=1;
- queue_connection.disconnect();
- queue_connection=Glib::signal_timeout().connect(
- sigc::bind_return(
- sigc::mem_fun(*this,&LayerParamTreeStore::refresh),
- false
- )
- ,150);
-
-}
-
-void
-LayerParamTreeStore::queue_rebuild()
-{
- if(queued==2)
- return;
- queued=2;
- queue_connection.disconnect();
- queue_connection=Glib::signal_timeout().connect(
- sigc::bind_return(
- sigc::mem_fun(*this,&LayerParamTreeStore::rebuild),
- false
- )
- ,150);
-
-}
-
-void
-LayerParamTreeStore::refresh()
-{
- if(queued)queued=0;
-
- Gtk::TreeModel::Children children_(children());
-
- Gtk::TreeModel::Children::iterator iter;
-
- if(!children_.empty())
- for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
- {
- Gtk::TreeRow row=*iter;
- refresh_row(row);
- }
-}
-
-void
-LayerParamTreeStore::refresh_row(Gtk::TreeModel::Row &row)
-{
- if(row[model.is_toplevel])
- {
- row[model.is_inconsistent] = false;
- ParamDesc param_desc(row[model.param_desc]);
-
- LayerList::iterator iter2(layer_list.begin());
- ValueBase value((*iter2)->get_param(param_desc.get_name()));
- for(++iter2;iter2!=layer_list.end();++iter2)
- {
- if(value!=((*iter2)->get_param(param_desc.get_name())))
- {
- row[model.is_inconsistent] = true;
- while(!row.children().empty() && erase(row.children().begin()))
- ;
- return;
- }
- }
- }
-
- //handle<ValueNode> value_node=row[model.value_node];
- //if(value_node)
- {
- CanvasTreeStore::refresh_row(row);
- return;
- }
-}
-
-void
-LayerParamTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc)
-{
- Gtk::TreeModel::Children children = row.children();
- while(!children.empty() && erase(children.begin()))
- ;
-
- CanvasTreeStore::set_row(row,value_desc);
-}
-
-void
-LayerParamTreeStore::on_value_node_added(synfig::ValueNode::Handle /*value_node*/)
-{
-// queue_refresh();
-}
-
-void
-LayerParamTreeStore::on_value_node_deleted(synfig::ValueNode::Handle /*value_node*/)
-{
-// queue_refresh();
-}
-
-void
-LayerParamTreeStore::on_value_node_child_added(synfig::ValueNode::Handle /*value_node*/,synfig::ValueNode::Handle /*child*/)
-{
- queue_rebuild();
-}
-
-void
-LayerParamTreeStore::on_value_node_child_removed(synfig::ValueNode::Handle /*value_node*/,synfig::ValueNode::Handle /*child*/)
-{
- rebuild();
-}
-
-void
-LayerParamTreeStore::on_value_node_changed(synfig::ValueNode::Handle /*value_node*/)
-{
- queue_refresh();
-}
-
-void
-LayerParamTreeStore::on_value_node_renamed(synfig::ValueNode::Handle /*value_node*/)
-{
- rebuild();
-}
-
-void
-LayerParamTreeStore::on_value_node_replaced(synfig::ValueNode::Handle /*replaced_value_node*/,synfig::ValueNode::Handle /*new_value_node*/)
-{
- queue_rebuild();
-}
-
-void
-LayerParamTreeStore::on_layer_param_changed(synfig::Layer::Handle /*handle*/,synfig::String /*param_name*/)
-{
- queue_refresh();
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file layerparamtreestore.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2007 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_LAYERPARAMTREESTORE_H
-#define __SYNFIG_STUDIO_LAYERPARAMTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include "canvastreestore.h"
-#include <synfig/value.h>
-#include <synfig/valuenode.h>
-#include <synfig/paramdesc.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class LayerTree;
-
-class LayerParamTreeStore : public CanvasTreeStore
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
- typedef std::list<synfig::Layer::Handle> LayerList;
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- //! TreeModel for the layer parameters
- class Model : public CanvasTreeStore::Model
- {
- public:
-
- Gtk::TreeModelColumn<synfig::ParamDesc> param_desc;
-
- Gtk::TreeModelColumn<bool> is_inconsistent;
- Gtk::TreeModelColumn<bool> is_toplevel;
-
- Model()
- {
- add(param_desc);
- add(is_inconsistent);
- add(is_toplevel);
- }
- };
-
- Model model;
-
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- int queued;
-
- LayerTree* layer_tree;
-
- LayerList layer_list;
-
- sigc::connection queue_connection;
-
- std::list<sigc::connection> changed_connection_list;
-
- sigc::signal<void> signal_changed_;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
-protected:
- virtual void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
- virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
- virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc);
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- void on_value_node_child_added(synfig::ValueNode::Handle value_node,synfig::ValueNode::Handle child);
- void on_value_node_child_removed(synfig::ValueNode::Handle value_node,synfig::ValueNode::Handle child);
-
- void on_value_node_added(synfig::ValueNode::Handle value_node);
- void on_value_node_deleted(synfig::ValueNode::Handle value_node);
- virtual void on_value_node_changed(synfig::ValueNode::Handle value_node);
- virtual void on_value_node_renamed(synfig::ValueNode::Handle value_node);
- void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
- void on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name);
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- LayerParamTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_,
- LayerTree* layer_tree);
- ~LayerParamTreeStore();
-
- void rebuild();
-
- void refresh();
-
- void queue_refresh();
-
- void queue_rebuild();
-
- void refresh_row(Gtk::TreeModel::Row &row);
-
- sigc::signal<void>& signal_changed() { return signal_changed_; }
-
- void changed() { signal_changed_(); }
-
- /*
- -- ** -- S T A T I C P U B L I C M E T H O D S ---------------------------
- */
-
-public:
-
- static Glib::RefPtr<LayerParamTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree);
-}; // END of class LayerParamTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file layertree.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2007, 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "layertree.h"
-#include "layerparamtreestore.h"
-#include "cellrenderer_value.h"
-#include "cellrenderer_timetrack.h"
-#include <synfigapp/action.h>
-#include <synfigapp/instance.h>
-#include <gtkmm/scrolledwindow.h>
-#include <gtkmm/paned.h>
-#include "app.h"
-#include "instance.h"
-#include <gtkmm/treemodelsort.h>
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-# include <synfig/timepointcollect.h>
-#endif // TIMETRACK_IN_PARAMS_PANEL
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-#ifndef SMALL_BUTTON
-#define SMALL_BUTTON(button,stockid,tooltip) \
- button = manage(new class Gtk::Button()); \
- icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize)); \
- button->add(*icon); \
- tooltips_.set_tip(*button,tooltip); \
- icon->set_padding(0,0);\
- icon->show(); \
- button->set_relief(Gtk::RELIEF_NONE); \
- button->show()
-#endif
-
-#ifndef NORMAL_BUTTON
-#define NORMAL_BUTTON(button,stockid,tooltip) \
- button = manage(new class Gtk::Button()); \
- icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON)); \
- button->add(*icon); \
- tooltips_.set_tip(*button,tooltip); \
- icon->set_padding(0,0);\
- icon->show(); \
- /*button->set_relief(Gtk::RELIEF_NONE);*/ \
- button->show()
-#endif
-
-#define NEW_SMALL_BUTTON(x,y,z) Gtk::Button *SMALL_BUTTON(x,y,z)
-
-#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-LayerTree::LayerTree():
- layer_amount_adjustment_(1,0,1,0.01,0.01,0)
-{
- param_tree_view_=new Gtk::TreeView;
- layer_tree_view_=new Gtk::TreeView;
-
- //Gtk::HPaned* hpaned(manage(new Gtk::HPaned()));
- //hpaned->show();
- //attach(*hpaned, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
- //attach(*create_layer_tree(), 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
-
- create_layer_tree();
- create_param_tree();
-
- //hpaned->pack1(*create_layer_tree(),false,false);
- //hpaned->pack2(*create_param_tree(),true,false);
- //hpaned->set_position(200);
- hbox=manage(new Gtk::HBox());
-
- attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
- attach(blend_method_widget, 2, 3, 1, 2,Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-
- layer_amount_hscale=manage(new Gtk::HScale(layer_amount_adjustment_));
- layer_amount_hscale->set_digits(2);
- layer_amount_hscale->set_value_pos(Gtk::POS_LEFT);
- layer_amount_hscale->set_sensitive(false);
- layer_amount_hscale->set_update_policy( Gtk::UPDATE_DISCONTINUOUS);
- attach(*layer_amount_hscale, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 1, 1);
- layer_amount_adjustment_.signal_value_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_amount_value_changed));
-
- Gtk::Image *icon;
- //Gtk::IconSize iconsize(Gtk::IconSize::from_name("synfig-small_icon"));
- Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
-
- SMALL_BUTTON(button_raise,"gtk-go-up","Raise");
- SMALL_BUTTON(button_lower,"gtk-go-down","Lower");
- SMALL_BUTTON(button_duplicate,"synfig-duplicate","Duplicate");
- SMALL_BUTTON(button_encapsulate,"synfig-encapsulate","Encapsulate");
- SMALL_BUTTON(button_delete,"gtk-delete","Delete");
-
- hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
- hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
- hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
- hbox->pack_start(*button_encapsulate,Gtk::PACK_SHRINK);
- hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
-
- // button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_raise_pressed));
- // button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_lower_pressed));
- // button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_duplicate_pressed));
- // button_encapsulate->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_encapsulate_pressed));
- // button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_delete_pressed));
-
- button_raise->set_sensitive(false);
- button_lower->set_sensitive(false);
- button_duplicate->set_sensitive(false);
- button_encapsulate->set_sensitive(false);
- button_delete->set_sensitive(false);
-
- get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_selection_changed));
-
- get_layer_tree_view().set_reorderable(true);
- get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
- //get_param_tree_view().get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
- get_layer_tree_view().show();
- get_param_tree_view().show();
-
- hbox->show();
- layer_amount_hscale->show();
- blend_method_widget.show();
-
- tooltips_.enable();
- disable_amount_changed_signal=false;
-
- blend_method_widget.set_param_desc(ParamDesc(Color::BlendMethod(),"blend_method"));
-
- blend_method_widget.set_value((int)Color::BLEND_COMPOSITE);
- blend_method_widget.set_size_request(150,-1);
- blend_method_widget.set_sensitive(false);
- blend_method_widget.signal_activate().connect(sigc::mem_fun(*this, &studio::LayerTree::on_blend_method_changed));
-}
-
-LayerTree::~LayerTree()
-{
- if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
- synfig::info("LayerTree::~LayerTree(): Deleted");
-}
-
-Gtk::Widget*
-LayerTree::create_layer_tree()
-{
- const LayerTreeStore::Model model;
-
- { // --- O N / O F F ----------------------------------------------------
- //int index;
- //index=get_layer_tree_view().append_column_editable(_(" "),layer_model.active);
- //Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
-
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_(" ")) );
-
- // Set up the icon cell-renderer
- Gtk::CellRendererToggle* cellrenderer = Gtk::manage( new Gtk::CellRendererToggle() );
- cellrenderer->signal_toggled().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_toggle));
-
- column->pack_start(*cellrenderer,false);
- column->add_attribute(cellrenderer->property_active(), layer_model.active);
- get_layer_tree_view().append_column(*column);
- }
-
- { // --- I C O N --------------------------------------------------------
- int index;
- index=get_layer_tree_view().append_column(_("Z"),layer_model.icon);
- Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
- get_layer_tree_view().set_expander_column(*column);
-
- column->set_sort_column(layer_model.z_depth);
- //column->set_reorderable();
- //column->set_resizable();
- //column->set_clickable();
-
- //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
- //column->pack_start(*icon_cellrenderer,false);
- //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
- }
- //get_layer_tree_view().append_column(_("Z"),layer_model.z_depth);
- { // --- N A M E --------------------------------------------------------
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Name")) );
-
- // Set up the icon cell-renderer
- Gtk::CellRendererText* cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
- column->pack_start(*cellrenderer,false);
- column->add_attribute(cellrenderer->property_text(), layer_model.label);
- cellrenderer->signal_edited().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_renamed));
- cellrenderer->property_editable()=true;
-
- column->set_reorderable();
- // column->set_resizable();
- column->set_clickable(true);
- column->set_sort_column(layer_model.label);
-
- get_layer_tree_view().append_column(*column);
-
- // int index;
-// index=get_layer_tree_view().append_column_editable(_("Layer"),layer_model.label);
- //Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
-
- //get_layer_tree_view().set_expander_column(*column);
-
- //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
- //column->pack_start(*icon_cellrenderer,false);
- //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
- }
- { // --- Z D E P T H ----------------------------------------------------
- int index;
- index=get_layer_tree_view().append_column(_("Z"),layer_model.z_depth);
- column_z_depth=get_layer_tree_view().get_column(index-1);
-
- column_z_depth->set_reorderable();
- column_z_depth->set_resizable();
- column_z_depth->set_clickable();
-
- column_z_depth->set_sort_column(layer_model.z_depth);
- }
-
- get_layer_tree_view().set_enable_search(true);
- get_layer_tree_view().set_search_column(layer_model.label);
- get_layer_tree_view().set_search_equal_func(sigc::ptr_fun(&studio::LayerTreeStore::search_func));
-
- std::list<Gtk::TargetEntry> listTargets;
- listTargets.push_back( Gtk::TargetEntry("LAYER") );
- get_layer_tree_view().drag_dest_set(listTargets);
-
- // This makes things easier to read.
- get_layer_tree_view().set_rules_hint();
-
- // Make us more sensitive to several events
- //get_layer_tree_view().add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
-
- get_layer_tree_view().signal_event().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_tree_event));
- get_layer_tree_view().show();
-
- Gtk::ScrolledWindow *scroll = manage(new class Gtk::ScrolledWindow());
- scroll->set_flags(Gtk::CAN_FOCUS);
- scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- //scroll->add(get_layer_tree_view());
- scroll->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
- scroll->show();
-
- return scroll;
-}
-
-Gtk::Widget*
-LayerTree::create_param_tree()
-{
- Pango::AttrList attr_list;
- {
- Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*8));
- pango_size.set_start_index(0);
- pango_size.set_end_index(64);
- attr_list.change(pango_size);
- }
-
- Gtk::IconSize icon_size(Gtk::ICON_SIZE_SMALL_TOOLBAR);
-
- { // --- N A M E --------------------------------------------------------
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Name")) );
-
- // Set up the icon cell-renderer
- Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
- column->pack_start(*icon_cellrenderer,false);
- column->add_attribute(icon_cellrenderer->property_pixbuf(), param_model.icon);
-
- // Pack the label into the column
- //column->pack_start(layer_model.label,true);
- Gtk::CellRendererText* text_cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
- column->pack_start(*text_cellrenderer,false);
- column->add_attribute(text_cellrenderer->property_text(), param_model.label);
- text_cellrenderer->property_attributes()=attr_list;
-
- text_cellrenderer->property_foreground()=Glib::ustring("#7f7f7f");
- column->add_attribute(text_cellrenderer->property_foreground_set(),param_model.is_inconsistent);
-
- // Pack the label into the column
- //column->pack_start(param_model.label,true);
-
- // Set up the value-node icon cell-renderer to be on the far right
- Gtk::CellRendererPixbuf* valuenode_icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
- column->pack_end(*valuenode_icon_cellrenderer,false);
- valuenode_icon_cellrenderer->property_pixbuf()=Gtk::Button().render_icon(Gtk::StockID("synfig-value_node"),icon_size);
- column->add_attribute(valuenode_icon_cellrenderer->property_visible(), param_model.is_shared);
-
- // Finish setting up the column
- column->set_reorderable();
- column->set_resizable();
- column->set_clickable();
-
- get_param_tree_view().append_column(*column);
- }
- { // --- V A L U E -----------------------------------------------------
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Value")) );
-
- // Set up the value cell-renderer
- cellrenderer_value=LayerParamTreeStore::add_cell_renderer_value(column);
- cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::LayerTree::on_edited_value));
- cellrenderer_value->property_value()=synfig::ValueBase();
- column->add_attribute(cellrenderer_value->property_param_desc(), param_model.param_desc);
- column->add_attribute(cellrenderer_value->property_inconsistent(),param_model.is_inconsistent);
- //cellrenderer_value->property_canvas()=canvas_interface->get_canvas(); // Is this line necessary?
- cellrenderer_value->property_attributes()=attr_list;
-
- // Finish setting up the column
- get_param_tree_view().append_column(*column);
- column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
- column->set_clickable();
- column->set_min_width(120);
- column->set_reorderable();
- column->set_resizable();
- }
- { // --- T Y P E --------------------------------------------------------
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Type")) );
- Gtk::CellRendererText* text_cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
- column->pack_start(*text_cellrenderer,false);
- column->add_attribute(text_cellrenderer->property_text(), param_model.type);
- text_cellrenderer->property_attributes()=attr_list;
- get_param_tree_view().append_column(*column);
- column->set_reorderable();
- column->set_resizable();
- column->set_clickable();
- column->set_sort_column(param_model.type);
- }
-#ifdef TIMETRACK_IN_PARAMS_PANEL
- { // --- T I M E T R A C K --------------------------------------------
- Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
- column_time_track=column;
-
- // Set up the value-node cell-renderer
- cellrenderer_time_track=LayerParamTreeStore::add_cell_renderer_value_node(column);
- cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
- cellrenderer_time_track->signal_waypoint_clicked_cellrenderer().connect(sigc::mem_fun(*this, &studio::LayerTree::on_waypoint_clicked_layertree) );
- cellrenderer_time_track->signal_waypoint_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_waypoint_changed) );
- column->add_attribute(cellrenderer_time_track->property_value_desc(), param_model.value_desc);
- column->add_attribute(cellrenderer_time_track->property_canvas(), param_model.canvas);
- column->add_attribute(cellrenderer_time_track->property_visible(), param_model.is_value_node);
-
- // Finish setting up the column
- column->set_reorderable();
- column->set_resizable();
- column->set_min_width(200);
-
- if (!getenv("SYNFIG_DISABLE_PARAMS_PANEL_TIMETRACK"))
- get_param_tree_view().append_column(*column);
- }
-#endif // TIMETRACK_IN_PARAMS_PANEL
-
- // This makes things easier to read.
- get_param_tree_view().set_rules_hint();
-
- // Make us more sensitive to several events
- get_param_tree_view().add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
-
- get_param_tree_view().signal_event().connect(sigc::mem_fun(*this, &studio::LayerTree::on_param_tree_event));
- get_param_tree_view().show();
-
- Gtk::ScrolledWindow *scroll = manage(new class Gtk::ScrolledWindow());
- scroll->set_flags(Gtk::CAN_FOCUS);
- scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- //scroll->add(get_param_tree_view());
- scroll->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
- scroll->show();
-
- //column_time_track->set_visible(false);
-
- return scroll;
-}
-
-void
-LayerTree::on_waypoint_changed( synfig::Waypoint waypoint , synfig::ValueNode::Handle value_node)
-{
- synfigapp::Action::ParamList param_list;
- param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
- param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
- param_list.add("value_node",value_node);
- param_list.add("waypoint",waypoint);
-// param_list.add("time",canvas_interface()->get_time());
-
- etl::handle<studio::Instance>::cast_static(layer_tree_store_->canvas_interface()->get_instance())->process_action("WaypointSetSmart", param_list);
-}
-
-void
-LayerTree::select_layer(synfig::Layer::Handle layer)
-{
- Gtk::TreeModel::Children::iterator iter;
- if(layer_tree_store_->find_layer_row(layer,iter))
- {
- if(sorted_layer_tree_store_)
- iter=sorted_layer_tree_store_->convert_child_iter_to_iter(iter);
-
- Gtk::TreePath path(iter);
- for(int i=path.get_depth();i;i--)
- {
- int j;
- path=Gtk::TreePath(iter);
- for(j=i;j;j--)
- path.up();
- get_layer_tree_view().expand_row(path,false);
- }
- get_layer_tree_view().scroll_to_row(Gtk::TreePath(iter));
- get_layer_tree_view().get_selection()->select(iter);
- }
-}
-
-void
-LayerTree::select_all_children(Gtk::TreeModel::Children::iterator iter)
-{
- get_layer_tree_view().get_selection()->select(iter);
- if((bool)(*iter)[layer_model.children_lock])
- return;
- get_layer_tree_view().expand_row(layer_tree_store_->get_path(iter),false);
- Gtk::TreeModel::Children children(iter->children());
- for(iter=children.begin();iter!=children.end();++iter)
- select_all_children(iter);
-}
-
-void
-LayerTree::select_all_children_layers(synfig::Layer::Handle layer)
-{
- Gtk::TreeModel::Children::iterator iter;
- if(layer_tree_store_->find_layer_row(layer,iter))
- select_all_children(iter);
-}
-
-void
-LayerTree::select_layers(const LayerList &layer_list)
-{
- LayerList::const_iterator iter;
- for(iter = layer_list.begin(); iter != layer_list.end(); ++iter)
- select_layer(*iter);
-}
-
-static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerTree::LayerList* ret)
-{
- const LayerTreeStore::Model layer_tree_model;
- ret->push_back((Layer::Handle)(*iter)[layer_tree_model.layer]);
-}
-
-LayerTree::LayerList
-LayerTree::get_selected_layers()const
-{
- Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<Gtk::TreeView&>(get_layer_tree_view()).get_selection();
-
- if(!selection)
- return LayerList();
-
- LayerList ret;
-
- selection->selected_foreach_iter(
- sigc::bind(
- sigc::ptr_fun(
- &__layer_grabber
- ),
- &ret
- )
- );
-
- return ret;
-}
-
-synfig::Layer::Handle
-LayerTree::get_selected_layer()const
-{
- LayerList layers(get_selected_layers());
-
- if(layers.empty())
- return 0;
-
- return *layers.begin();
-}
-
-void
-LayerTree::clear_selected_layers()
-{
- get_layer_tree_view().get_selection()->unselect_all();
-}
-
-void
-LayerTree::set_show_timetrack(bool x)
-{
- //column_time_track->set_visible(x);
-// column_time_track->set_visible(false);
- column_z_depth->set_visible(x);
-}
-
-void
-LayerTree::set_model(Glib::RefPtr<LayerTreeStore> layer_tree_store)
-{
- layer_tree_store_=layer_tree_store;
-
- if(false)
- {
- sorted_layer_tree_store_=Gtk::TreeModelSort::create(layer_tree_store);
-
- sorted_layer_tree_store_->set_default_sort_func(sigc::ptr_fun(&studio::LayerTreeStore::z_sorter));
-
- //sorted_store->set_sort_func(model.time.index(),sigc::mem_fun(&studio::KeyframeTreeStore::time_sorter));
- //sorted_store->set_sort_column(model.time.index(), Gtk::SORT_ASCENDING);
-
- get_layer_tree_view().set_model(sorted_layer_tree_store_);
- }
- else
- get_layer_tree_view().set_model(layer_tree_store_);
-
- layer_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::LayerTree::on_dirty_preview));
-
- //layer_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::LayerTree::on_dirty_preview));
-
- layer_tree_store_->canvas_interface()->signal_time_changed().connect(
- sigc::mem_fun(
- &get_param_tree_view(),
- &Gtk::Widget::queue_draw
- )
- );
- if(!param_tree_store_)
- {
- param_tree_store_=LayerParamTreeStore::create(layer_tree_store_->canvas_interface(), this);
- get_param_tree_view().set_model(param_tree_store_);
- }
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
- if(cellrenderer_time_track && layer_tree_store_ && layer_tree_store_->canvas_interface())
- cellrenderer_time_track->set_canvas_interface(layer_tree_store_->canvas_interface());
-#endif // TIMETRACK_IN_PARAMS_PANEL
-}
-
-void
-LayerTree::set_time_adjustment(Gtk::Adjustment &adjustment)
-{
-#ifdef TIMETRACK_IN_PARAMS_PANEL
- cellrenderer_time_track->set_adjustment(adjustment);
-#endif // TIMETRACK_IN_PARAMS_PANEL
- adjustment.signal_value_changed().connect(sigc::mem_fun(get_param_tree_view(),&Gtk::TreeView::queue_draw));
- adjustment.signal_changed().connect(sigc::mem_fun(get_param_tree_view(),&Gtk::TreeView::queue_draw));
-}
-
-void
-LayerTree::on_dirty_preview()
-{
-/*
- if(quick_layer && !disable_amount_changed_signal)
- {
- layer_amount_hscale->set_sensitive(true);
- disable_amount_changed_signal=true;
- layer_amount_adjustment_.set_value(quick_layer->get_param("amount").get(Real()));
- disable_amount_changed_signal=false;
- if(quick_layer->get_param("blend_method").is_valid())
- {
- blend_method_widget.set_sensitive(true);
- disable_amount_changed_signal=true;
- blend_method_widget.set_value(quick_layer->get_param("blend_method"));
- disable_amount_changed_signal=false;
- }
- }
-*/
-}
-
-void
-LayerTree::on_selection_changed()
-{
- synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-
- Gtk::TreeIter iter;
- if(last_top_selected_layer && !layer_tree_store_->find_layer_row(last_top_selected_layer,iter))
- {
- if(layer_list.empty())
- {
- last_top_selected_layer=0;
- layer_tree_view_->get_selection()->select(last_top_selected_path);
- return;
- }
- }
-
- {
- if(!layer_list.empty())
- {
- last_top_selected_layer=layer_list.front();
- last_top_selected_path=*layer_tree_view_->get_selection()->get_selected_rows().begin();
- }
- else
- {
- last_top_selected_layer=0;
- }
- }
-
- if(layer_list.empty())
- {
- button_raise->set_sensitive(false);
- button_lower->set_sensitive(false);
- button_duplicate->set_sensitive(false);
- button_encapsulate->set_sensitive(false);
- button_delete->set_sensitive(false);
- layer_amount_hscale->set_sensitive(false);
- blend_method_widget.set_sensitive(false);
- return;
- }
-
- button_raise->set_sensitive(true);
- button_lower->set_sensitive(true);
- button_duplicate->set_sensitive(true);
- button_encapsulate->set_sensitive(true);
- button_delete->set_sensitive(true);
-
- if(layer_list.size()==1 && (*layer_list.begin())->get_param("amount").is_valid()&& (*layer_list.begin())->get_param("amount").same_type_as(Real()))
- {
- quick_layer=*layer_list.begin();
- }
- else
- quick_layer=0;
-
- if(quick_layer)
- {
- layer_amount_hscale->set_sensitive(true);
- disable_amount_changed_signal=true;
- layer_amount_adjustment_.set_value(quick_layer->get_param("amount").get(Real()));
- disable_amount_changed_signal=false;
- if(quick_layer->get_param("blend_method").is_valid())
- {
- blend_method_widget.set_sensitive(true);
- disable_amount_changed_signal=true;
- blend_method_widget.set_value(quick_layer->get_param("blend_method"));
- disable_amount_changed_signal=false;
- }
- else
- blend_method_widget.set_sensitive(false);
- }
- else
- {
- layer_amount_hscale->set_sensitive(false);
- blend_method_widget.set_sensitive(false);
- }
-}
-
-void
-LayerTree::on_blend_method_changed()
-{
- if(disable_amount_changed_signal)
- return;
- if(!quick_layer)
- return;
-
- if(quick_layer->get_param("blend_method").is_valid())
- {
- disable_amount_changed_signal=true;
- signal_edited_value()(synfigapp::ValueDesc(quick_layer,"blend_method"),blend_method_widget.get_value());
- disable_amount_changed_signal=false;
- }
-}
-
-void
-LayerTree::on_amount_value_changed()
-{
- if(disable_amount_changed_signal)
- return;
- if(!quick_layer)
- return;
-
- disable_amount_changed_signal=true;
- signal_edited_value()(synfigapp::ValueDesc(quick_layer,"amount"),synfig::ValueBase(layer_amount_adjustment_.get_value()));
- disable_amount_changed_signal=false;
-}
-
-void
-LayerTree::on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value)
-{
- Gtk::TreePath path(path_string);
-
- const Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
- if(!row)
- return;
- row[param_model.value]=value;
- //signal_edited_value()(row[param_model.value_desc],value);
-}
-
-void
-LayerTree::on_layer_renamed(const Glib::ustring&path_string,const Glib::ustring& value)
-{
- Gtk::TreePath path(path_string);
-
- const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
- if(!row)
- return;
- row[layer_model.label]=value;
- get_layer_tree_view().columns_autosize();
-}
-
-void
-LayerTree::on_layer_toggle(const Glib::ustring& path_string)
-{
- Gtk::TreePath path(path_string);
-
- const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
- bool active=static_cast<bool>(row[layer_model.active]);
- row[layer_model.active]=!active;
-}
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-void
-LayerTree::on_waypoint_clicked_layertree(const etl::handle<synfig::Node>& node __attribute__ ((unused)),
- const synfig::Time& time __attribute__ ((unused)),
- const synfig::Time& time_offset __attribute__ ((unused)),
- int button __attribute__ ((unused)))
-{
- std::set<synfig::Waypoint, std::less<UniqueID> > waypoint_set;
- synfig::waypoint_collect(waypoint_set,time,node);
-
- synfigapp::ValueDesc value_desc;
-
- if (waypoint_set.size() == 1)
- {
- ValueNode::Handle value_node(waypoint_set.begin()->get_parent_value_node());
- assert(value_node);
-
- Gtk::TreeRow row;
- if (param_tree_store_->find_first_value_node(value_node, row) && row)
- value_desc = static_cast<synfigapp::ValueDesc>(row[param_tree_store_->model.value_desc]);
- }
-
- if (!waypoint_set.empty())
- signal_waypoint_clicked_layertree()(value_desc,waypoint_set,button);
-}
-#endif // TIMETRACK_IN_PARAMS_PANEL
-
-bool
-LayerTree::on_layer_tree_event(GdkEvent *event)
-{
- switch(event->type)
- {
- case GDK_BUTTON_PRESS:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!get_layer_tree_view().get_path_at_pos(
- int(event->button.x),int(event->button.y), // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
- const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
- if(column->get_first_cell_renderer()==cellrenderer_time_track)
- return signal_layer_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
- else
-#endif // TIMETRACK_IN_PARAMS_PANEL
- if(column->get_first_cell_renderer()==cellrenderer_value)
- return signal_layer_user_click()(event->button.button,row,COLUMNID_VALUE);
- else
- return signal_layer_user_click()(event->button.button,row,COLUMNID_NAME);
-
- }
- break;
-
- case GDK_MOTION_NOTIFY:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!get_layer_tree_view().get_path_at_pos(
- (int)event->button.x,(int)event->button.y, // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
-
- if(!get_layer_tree_view().get_model()->get_iter(path))
- break;
-
- Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
- if(cellrenderer_time_track==column->get_first_cell_renderer())
- // Movement on TimeLine
- return true;
- else
-#endif // TIMETRACK_IN_PARAMS_PANEL
- if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
- {
- tooltips_.unset_tip(*this);
- Glib::ustring tooltips_string(row[layer_model.tooltip]);
- last_tooltip_path=path;
- if(!tooltips_string.empty())
- {
- tooltips_.set_tip(*this,tooltips_string);
- tooltips_.force_window();
- }
- }
- }
- break;
- case GDK_BUTTON_RELEASE:
- break;
- default:
- break;
- }
- return false;
-}
-
-bool
-LayerTree::on_param_tree_event(GdkEvent *event)
-{
- switch(event->type)
- {
- case GDK_BUTTON_PRESS:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!get_param_tree_view().get_path_at_pos(
- int(event->button.x),int(event->button.y), // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
- const Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
- if(column && column->get_first_cell_renderer()==cellrenderer_time_track)
- {
- Gdk::Rectangle rect;
- get_param_tree_view().get_cell_area(path,*column,rect);
- cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
- cellrenderer_time_track->property_canvas()=row[param_model.canvas];
- cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
- get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
- return true;
- //return signal_param_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
- }
- else
-#endif // TIMETRACK_IN_PARAMS_PANEL
- {
- if(event->button.button==3)
- {
- LayerList layer_list(get_selected_layers());
- if(layer_list.size()<=1)
- {
- synfigapp::ValueDesc value_desc(row[param_model.value_desc]);
- Gtk::Menu* menu(manage(new Gtk::Menu()));
- menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), menu));
- App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc,0.5f);
- menu->popup(event->button.button,gtk_get_current_event_time());
- return true;
- }
- Gtk::Menu* menu(manage(new Gtk::Menu()));
- menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), menu));
- std::list<synfigapp::ValueDesc> value_desc_list;
- ParamDesc param_desc(row[param_model.param_desc]);
- for(;!layer_list.empty();layer_list.pop_back())
- value_desc_list.push_back(synfigapp::ValueDesc(layer_list.back(),param_desc.get_name()));
- App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc_list);
- menu->popup(event->button.button,gtk_get_current_event_time());
- return true;
- }
- else
- {
- if(column->get_first_cell_renderer()==cellrenderer_value)
- return signal_param_user_click()(event->button.button,row,COLUMNID_VALUE);
- else
- return signal_param_user_click()(event->button.button,row,COLUMNID_NAME);
- }
- }
- }
- break;
-
- case GDK_MOTION_NOTIFY:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!get_param_tree_view().get_path_at_pos(
- (int)event->motion.x,(int)event->motion.y, // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
-
- if(!get_param_tree_view().get_model()->get_iter(path))
- break;
-
- Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
- if((event->motion.state&GDK_BUTTON1_MASK ||event->motion.state&GDK_BUTTON3_MASK) && column && cellrenderer_time_track==column->get_first_cell_renderer())
- {
- Gdk::Rectangle rect;
- get_param_tree_view().get_cell_area(path,*column,rect);
- cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
- cellrenderer_time_track->property_canvas()=row[param_model.canvas];
- cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
- get_param_tree_view().queue_draw();
- //get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
- return true;
- }
- else
-#endif // TIMETRACK_IN_PARAMS_PANEL
- if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
- {
- tooltips_.unset_tip(*this);
- Glib::ustring tooltips_string(row[layer_model.tooltip]);
- last_tooltip_path=path;
- if(!tooltips_string.empty())
- {
- tooltips_.set_tip(*this,tooltips_string);
- tooltips_.force_window();
- }
- }
- }
- break;
- case GDK_BUTTON_RELEASE:
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!get_param_tree_view().get_path_at_pos(
- (int)event->button.x,(int)event->button.y, // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- ) break;
-
- if(!get_param_tree_view().get_model()->get_iter(path))
- break;
-
- Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
- if(column && cellrenderer_time_track==column->get_first_cell_renderer())
- {
- Gdk::Rectangle rect;
- get_param_tree_view().get_cell_area(path,*column,rect);
- cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
- cellrenderer_time_track->property_canvas()=row[param_model.canvas];
- cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
- get_param_tree_view().queue_draw();
- get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
- return true;
-
- }
-#endif // TIMETRACK_IN_PARAMS_PANEL
- }
- break;
- default:
- break;
- }
- return false;
-}
-
-// void
-// LayerTree::on_raise_pressed()
-// {
-// synfigapp::Action::ParamList param_list;
-// param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
-// param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-// param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-//
-// {
-// synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-// synfigapp::SelectionManager::LayerList::iterator iter;
-//
-// for(iter=layer_list.begin();iter!=layer_list.end();++iter)
-// param_list.add("layer",Layer::Handle(*iter));
-// }
-// synfigapp::Action::Handle action(synfigapp::Action::create("LayerRaise"));
-// action->set_param_list(param_list);
-// layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
-// }
-
-// void
-// LayerTree::on_lower_pressed()
-// {
-// synfigapp::Action::ParamList param_list;
-// param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
-// param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-// param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-//
-// {
-// synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-// synfigapp::SelectionManager::LayerList::iterator iter;
-//
-// for(iter=layer_list.begin();iter!=layer_list.end();++iter)
-// param_list.add("layer",Layer::Handle(*iter));
-// }
-//
-// synfigapp::Action::Handle action(synfigapp::Action::create("LayerLower"));
-// action->set_param_list(param_list);
-// layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
-// }
-
-// void
-// LayerTree::on_duplicate_pressed()
-// {
-// synfigapp::Action::ParamList param_list;
-// param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
-// param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-// param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-//
-// {
-// synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-// synfigapp::SelectionManager::LayerList::iterator iter;
-//
-// for(iter=layer_list.begin();iter!=layer_list.end();++iter)
-// param_list.add("layer",Layer::Handle(*iter));
-// }
-//
-// synfigapp::Action::Handle action(synfigapp::Action::create("LayerDuplicate"));
-// action->set_param_list(param_list);
-// layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
-// }
-
-// void
-// LayerTree::on_encapsulate_pressed()
-// {
-// synfigapp::Action::ParamList param_list;
-// param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
-// param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-// param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-//
-// {
-// synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-// synfigapp::SelectionManager::LayerList::iterator iter;
-//
-// for(iter=layer_list.begin();iter!=layer_list.end();++iter)
-// param_list.add("layer",Layer::Handle(*iter));
-// }
-//
-// synfigapp::Action::Handle action(synfigapp::Action::create("LayerEncapsulate"));
-// action->set_param_list(param_list);
-// layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
-// }
-
-// void
-// LayerTree::on_delete_pressed()
-// {
-// synfigapp::Action::ParamList param_list;
-// param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
-// param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-// param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-//
-// {
-// synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-// synfigapp::SelectionManager::LayerList::iterator iter;
-//
-// for(iter=layer_list.begin();iter!=layer_list.end();++iter)
-// param_list.add("layer",Layer::Handle(*iter));
-// }
-//
-// synfigapp::Action::Handle action(synfigapp::Action::create("LayerRemove"));
-// action->set_param_list(param_list);
-// layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
-// }
-
-/*
-void
-LayerTree::on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&context, Gtk::SelectionData& selection_data, guint info, guint time)
-{
- synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
- synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
- synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
-
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(get_selection()
- Gtk::TreeRow row = *(get_selection()->get_selected());
-
- if(synfig::String(gdk_atom_name(selection_data->target))=="LAYER" && (bool)row[model.is_layer])
- {
- Layer* layer(((Layer::Handle)row[model.layer]).get());
- assert(layer);
- selection_data.set(8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
- return;
- }
-}
-
-void
-LayerTree::on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, Gtk::SelectionData& selection_data, guint info, guint time)
-{
- synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
- synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
- synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
- synfig::info("Dropped x=%d, y=%d",x,y);
- bool success=false;
- bool dropped_on_specific_row=false;
-
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!get_path_at_pos(
- x,y, // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- )
- {
- dropped_on_specific_row=false;
- }
- else
- dropped_on_specific_row=true;
-
- Gtk::TreeRow row = *(get_model()->get_iter(path));
-
- if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
- {
- if(synfig::String(selection_data.get_data_type())=="LAYER")do
- {
- Layer::Handle src(*reinterpret_cast<Layer**>(selection_data.get_data()));
- assert(src);
-
- Canvas::Handle dest_canvas;
- Layer::Handle dest_layer;
-
- if(dropped_on_specific_row)
- {
- dest_canvas=(Canvas::Handle)(row[model.canvas]);
- dest_layer=(Layer::Handle)(row[model.layer]);
- assert(dest_canvas);
- }
- else
- dest_canvas=layer_tree_store_->canvas_interface()->get_canvas();
-
- // In this case, we are just moving.
- if(dest_canvas==src->get_canvas())
- {
- if(!dest_layer || dest_layer==src)
- break;
-
- synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
- action->set_param("canvas",dest_canvas);
- action->set_param("canvas_interface",layer_tree_store_->canvas_interface());
- action->set_param("layer",src);
- action->set_param("new_index",dest_canvas->get_depth(dest_layer));
- if(layer_tree_store_->canvas_interface()->get_instance()->perform_action(action))
- success=true;
- else
- success=false;
- break;
- }
- }while(0);
- }
-
- // Finish the drag
- context->drag_finish(success, false, time);
-}
-*/
-
-/*bool
-LayerTree::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& context,int x, int y, guint time)
-{
- return get_layer_tree_view().on_drag_motion(context,x,y,time);
-}
-
-void
-LayerTree::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, Gtk::SelectionData& selection_data, guint info, guint time)
-{
- get_layer_tree_view().on_drag_data_received(context,x,y,selection_data,info,time);
-*/
-/*
- if(context->gobj()->source_window==context->gobj()->dest_window)
- {
- Gtk::TreeView::on_drag_data_received(context,x,y,selection_data,info,time);
- return;
- }
-
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn *column;
- int cell_x, cell_y;
- if(!get_path_at_pos(
- x,y, // x, y
- path, // TreeModel::Path&
- column, //TreeViewColumn*&
- cell_x,cell_y //int&cell_x,int&cell_y
- )
- )
- {
- context->drag_finish(false, false, time);
- }
-
- if(layer_tree_store_->row_drop_possible(path,selection_data))
- {
- if(layer_tree_store_->drag_data_received(path,selection_data))
- context->drag_finish(true, false, time);
- }
- context->drag_finish(false, false, time);
-}
-*/
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file layertree.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_LAYERTREE_H
-#define __SYNFIG_STUDIO_LAYERTREE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treeview.h>
-#include <gtkmm/treestore.h>
-#include <gtkmm/tooltips.h>
-#include <gtkmm/table.h>
-#include <gtkmm/box.h>
-#include <gtkmm/adjustment.h>
-#include <gtkmm/scale.h>
-#include <gtkmm/button.h>
-
-#include <synfigapp/canvasinterface.h>
-#include <synfigapp/value_desc.h>
-#include "layertreestore.h"
-#include "layerparamtreestore.h"
-#include <synfig/valuenode_animated.h>
-
-#include "widgets/widget_value.h"
-
-/* === M A C R O S ========================================================= */
-
-// comment this out if you don't want the params dialog to have a 'timetrack' column
-// (alternatively, export SYNFIG_DISABLE_PARAMS_PANEL_TIMETRACK=1 in environment at runtime)
-#define TIMETRACK_IN_PARAMS_PANEL
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace Gtk { class TreeModelSort; };
-
-namespace studio {
-
-class CellRenderer_TimeTrack;
-class CellRenderer_ValueBase;
-
-class LayerTree : public Gtk::Table
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
-
- typedef studio::ColumnID ColumnID;
-/* enum ColumnID
- {
- COLUMNID_NAME,
- COLUMNID_VALUE,
- COLUMNID_TIME_TRACK,
-
- COLUMNID_END //!< \internal
- };
-*/
- typedef std::list<synfig::Layer::Handle> LayerList;
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- //LayerTreeStore::Model model;
-
- LayerTreeStore::Model layer_model;
- LayerParamTreeStore::Model param_model;
-
- synfig::Layer::Handle last_top_selected_layer;
- Gtk::TreePath last_top_selected_path;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- Gtk::Tooltips tooltips_;
- Gtk::TreePath last_tooltip_path;
-
- Gtk::TreeView* layer_tree_view_;
-
- Gtk::TreeView* param_tree_view_;
-
- Gtk::HBox *hbox;
-
- Gtk::Adjustment layer_amount_adjustment_;
-
- Gtk::HScale *layer_amount_hscale;
-
- synfig::Layer::Handle quick_layer;
-
- Glib::RefPtr<LayerTreeStore> layer_tree_store_;
-
- Glib::RefPtr<LayerParamTreeStore> param_tree_store_;
-
- Glib::RefPtr<Gtk::TreeModelSort> sorted_layer_tree_store_;
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
- CellRenderer_TimeTrack *cellrenderer_time_track;
-#endif // TIMETRACK_IN_PARAMS_PANEL
-
- Gtk::TreeView::Column* column_time_track;
-
- Gtk::TreeView::Column* column_z_depth;
-
- CellRenderer_ValueBase *cellrenderer_value;
-
- sigc::signal<void,synfig::Layer::Handle> signal_layer_toggle_;
-
- sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase> signal_edited_value_;
-
- sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_layer_user_click_;
-
- sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_param_user_click_;
-
- sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int> signal_waypoint_clicked_layertree_;
-
- bool disable_amount_changed_signal;
-
- Gtk::Button *button_raise;
- Gtk::Button *button_lower;
- Gtk::Button *button_duplicate;
- Gtk::Button *button_encapsulate;
- Gtk::Button *button_delete;
-
- Widget_ValueBase blend_method_widget;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
- Gtk::Widget* create_layer_tree();
- Gtk::Widget* create_param_tree();
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- void on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value);
-
- void on_layer_renamed(const Glib::ustring&path_string,const Glib::ustring& value);
-
- void on_layer_toggle(const Glib::ustring& path_string);
-
- void on_waypoint_clicked_layertree(const etl::handle<synfig::Node>& node, const synfig::Time&, const synfig::Time&, int button);
-
- void on_waypoint_changed( synfig::Waypoint waypoint , synfig::ValueNode::Handle value_node);
-
- bool on_layer_tree_event(GdkEvent *event);
-
- bool on_param_tree_event(GdkEvent *event);
-
- void on_selection_changed();
-
- void on_dirty_preview();
-
- void on_amount_value_changed();
-
- void on_blend_method_changed();
-
-public:
-
- // void on_raise_pressed();
-
- // void on_lower_pressed();
-
- // void on_duplicate_pressed();
-
- // void on_encapsulate_pressed();
-
- // void on_delete_pressed();
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- //Gtk::TreeView* get_param_tree_view() { return param_tree_view_; }
- //Gtk::TreeView& param_tree_view() { return *param_tree_view_; }
- Gtk::HBox& get_hbox() { return *hbox; }
-
- Gtk::TreeView& get_layer_tree_view() { return *layer_tree_view_; }
- Gtk::TreeView& get_param_tree_view() { return *param_tree_view_; }
-
- const Gtk::TreeView& get_layer_tree_view()const { return *layer_tree_view_; }
- const Gtk::TreeView& get_param_tree_view()const { return *param_tree_view_; }
-
- Glib::RefPtr<Gtk::TreeSelection> get_selection() { return get_layer_tree_view().get_selection(); }
- Glib::SignalProxy1< bool,GdkEvent* > signal_event () { return get_layer_tree_view().signal_event(); }
-
- LayerTree();
- ~LayerTree();
-
- void set_model(Glib::RefPtr<LayerTreeStore> layer_tree_store_);
-
- void set_time_adjustment(Gtk::Adjustment &adjustment);
-
- void set_show_timetrack(bool x=true);
-
- //! Signal called when layer is toggled.
- sigc::signal<void,synfig::Layer::Handle>& signal_layer_toggle() { return signal_layer_toggle_; }
-
- //! Signal called with a value has been edited.
- sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase>& signal_edited_value() { return signal_edited_value_; }
-
- sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_layer_user_click() { return signal_layer_user_click_; }
-
- sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_param_user_click() { return signal_param_user_click_; }
-
- sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int>& signal_waypoint_clicked_layertree() { return signal_waypoint_clicked_layertree_; }
-
- etl::handle<synfigapp::SelectionManager> get_selection_manager() { return layer_tree_store_->canvas_interface()->get_selection_manager(); }
-
- void select_layer(synfig::Layer::Handle layer);
- void select_layers(const LayerList& layer_list);
- void select_all_children_layers(synfig::Layer::Handle layer);
- void select_all_children(Gtk::TreeModel::Children::iterator iter);
- LayerList get_selected_layers()const;
- synfig::Layer::Handle get_selected_layer()const;
- void clear_selected_layers();
-
-}; // END of LayerTree
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file layertreestore.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "layertreestore.h"
-#include "iconcontroller.h"
-#include <gtkmm/button.h>
-#include <synfig/paramdesc.h>
-#include <synfigapp/action.h>
-#include <synfigapp/instance.h>
-#include "app.h"
-#include "instance.h"
-#include <synfig/layer_pastecanvas.h>
-#include <synfigapp/action_system.h>
-
-#include <gtk/gtkversion.h>
-#include <ETL/clock>
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static LayerTreeStore::Model& ModelHack()
-{
- static LayerTreeStore::Model* model(0);
- if(!model)model=new LayerTreeStore::Model;
- return *model;
-}
-
-LayerTreeStore::LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
- Gtk::TreeStore (ModelHack()),
- queued (false),
- canvas_interface_ (canvas_interface_)
-{
- layer_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
-
- // Connect Signals to Terminals
- canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_status_changed));
- canvas_interface()->signal_layer_lowered().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_lowered));
- canvas_interface()->signal_layer_raised().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_raised));
- canvas_interface()->signal_layer_removed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_removed));
- canvas_interface()->signal_layer_inserted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_inserted));
- canvas_interface()->signal_layer_moved().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_moved));
- //canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_param_changed));
- canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_new_description));
-
- canvas_interface()->signal_time_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::refresh));
-
- //canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_changed));
- //canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_added));
- //canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_deleted));
- //canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_replaced));
-
- set_default_sort_func(sigc::ptr_fun(index_sorter));
-
-// rebuild();
-}
-
-LayerTreeStore::~LayerTreeStore()
-{
- if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
- synfig::info("LayerTreeStore::~LayerTreeStore(): Deleted");
-}
-
-int
-LayerTreeStore::z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
-{
- const Model model;
-
- float diff((float)(*rhs)[model.z_depth]-(float)(*lhs)[model.z_depth]);
-
- if(diff<0)
- return -1;
- if(diff>0)
- return 1;
- return 0;
-}
-
-int
-LayerTreeStore::index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
-{
- const Model model;
-
- return ((int)(*rhs)[model.index]-(int)(*lhs)[model.index]);
-}
-
-bool
-LayerTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
-{
- const Model model;
-
- Glib::ustring substr(x.uppercase());
- Glib::ustring label((*iter)[model.label]);
- label=label.uppercase();
-
- return label.find(substr)==Glib::ustring::npos;
-}
-
-
-Glib::RefPtr<LayerTreeStore>
-LayerTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
-{
- return Glib::RefPtr<LayerTreeStore>(new LayerTreeStore(canvas_interface_));
-}
-
-void
-LayerTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
-{
- if(column==model.index.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<int> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(layer->get_depth());
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else if(column==model.z_depth.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<float> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(layer->get_z_depth(canvas_interface()->get_time())*1.0001+layer->get_depth());
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else if(column==model.children_lock.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<bool> x;
- g_value_init(x.gobj(),x.value_type());
- x.set(false);
-
- ValueBase v(layer->get_param("children_lock"));
- if(v.same_type_as(bool()))
- x.set(v.get(bool()));
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else if(column==model.label.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(layer->get_non_empty_description());
-
- g_value_init(value.gobj(),x.value_type());
- //g_value_copy(x.gobj(),value.gobj());
- value=x;
- }
- else if(column==model.tooltip.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),x.value_type());
-
-
- x.set(layer->get_local_name());
-
- g_value_init(value.gobj(),x.value_type());
- //g_value_copy(x.gobj(),value.gobj());
- value=x;
- }
- else if(column==model.canvas.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<Canvas::Handle> x;
- g_value_init(x.gobj(),x.value_type());
-
-
- x.set(layer->get_canvas());
-
- g_value_init(value.gobj(),x.value_type());
- //g_value_copy(x.gobj(),value.gobj());
- value=x;
- }
- else if(column==model.active.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<bool> x;
- g_value_init(x.gobj(),x.value_type());
-
- x.set(layer->active());
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else if(column==model.icon.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
- if(!layer)return;
-
- Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
- g_value_init(x.gobj(),x.value_type());
-
- //x.set(layer_icon);
- x.set(get_tree_pixbuf_layer(layer->get_name()));
-
- g_value_init(value.gobj(),x.value_type());
- g_value_copy(x.gobj(),value.gobj());
- }
- else
- Gtk::TreeStore::get_value_vfunc(iter,column,value);
-}
-
-void
-LayerTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
-{
- //if(!iterator_sane(row))
- // return;
-
- if(column>=get_n_columns_vfunc())
- {
- g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
- return;
- }
-
- if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
- {
- g_warning("LayerTreeStore::set_value_impl: Bad value type");
- return;
- }
-
- try
- {
- if(column==model.label.index())
- {
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),model.label.type());
- g_value_copy(value.gobj(),x.gobj());
-
- synfig::Layer::Handle layer((*iter)[model.layer]);
- if(!layer)
- return;
- synfig::String new_desc(x.get());
-
- if(new_desc==layer->get_local_name())
- new_desc=synfig::String();
-
- if(new_desc==layer->get_description())
- return;
-
- synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetDesc"));
-
- if(!action)
- return;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("layer",layer);
- action->set_param("new_description",synfig::String(x.get()));
-
- canvas_interface()->get_instance()->perform_action(action);
- return;
- }
- else if(column==model.active.index())
- {
- synfig::Layer::Handle layer((*iter)[model.layer]);
-
- if(!layer)return;
-
- Glib::Value<bool> x;
- g_value_init(x.gobj(),model.active.type());
- g_value_copy(value.gobj(),x.gobj());
-
- synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
-
- if(!action)
- return;
-
- action->set_param("canvas",canvas_interface()->get_canvas());
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("layer",layer);
- action->set_param("new_status",bool(x.get()));
-
- canvas_interface()->get_instance()->perform_action(action);
- return;
- }
- else
- Gtk::TreeStore::set_value_impl(iter,column, value);
-
- }
- catch(std::exception x)
- {
- g_warning("%s", x.what());
- }
-}
-
-
-
-
-bool
-LayerTreeStore::row_draggable_vfunc (const TreeModel::Path& /*path*/)const
-{
- //if(!get_iter(path)) return false;
-// Gtk::TreeModel::Row row(*get_iter(path));
-
- return true;
-// return (bool)true;
-}
-
-bool
-LayerTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
-{
- if(!const_cast<LayerTreeStore*>(this)->get_iter(path)) return false;
- //synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
- //synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
- //synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
-
- Gtk::TreeModel::Row row(*const_cast<LayerTreeStore*>(this)->get_iter(path));
-
- if((bool)true)
- {
- Layer* layer(((Layer::Handle)row[model.layer]).get());
- assert(layer);
- bool included(false);
-
- //gtk_selection_data_set (selection_data, gdk_atom_intern("LAYER",false), 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
-
- std::vector<Layer*> layers;
- // The following is a hack for multiple row DND
- {
- synfigapp::SelectionManager::LayerList bleh(get_canvas_interface()->get_selection_manager()->get_selected_layers());
- if(bleh.empty())
- {
- selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
- return true;
- }
- while(!bleh.empty())
- {
- if(bleh.back().get()==layer)
- included=true;
- layers.push_back(bleh.back().get());
- bleh.pop_back();
- }
- }
- if(!included)
- layers.push_back(layer);
- selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
-
- return true;
- }
- return false;
-}
-
-bool
-LayerTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
-{
- return true;
-}
-
-bool
-LayerTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
-{
- //if(!const_cast<LayerTreeStore*>(this)->get_iter(dest)) return false;
-
- //synfig::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
- //synfig::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
- //synfig::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
-
- //Gtk::TreeModel::Row row(*get_iter(dest));
-
- if(synfig::String(selection_data.get_data_type())=="LAYER" && (bool)true)
- {
- //Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
- //assert(src);
-
- //return true;
- TreeModel::Path dest_parent(dest);
- if(!dest_parent.up() || dest.get_depth()==1)
- {
- //row=(*get_iter(dest));
- //dest_canvas=(Canvas::Handle)(row[model.canvas]);
- return true;
- }
- else if((bool)const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))
- return (bool)(Canvas::Handle)(*const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))[model.contained_canvas];
- }
- return false;
-}
-
-bool
-LayerTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
-{
-
- //if(!dest_parent.up() || !get_iter(dest)) return false;
-
- bool ret=false;
- int i(0);
-
-
- //synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
- //synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
- //synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
- synfigapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Move Layers"));
-
- // Save the selection data
- synfigapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
-
- if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
- {
- Gtk::TreeModel::Row row;
- Canvas::Handle dest_canvas;
-
- int dest_layer_depth=dest.back();
-
- TreeModel::Path dest_parent(dest);
- if(!dest_parent.up() || !get_iter(dest_parent))
- {
- TreeModel::Path dest_(dest);
- if(!get_iter(dest_))
- dest_.prev();
-
- if(!get_iter(dest_))
- return false;
-
- {
- row=(*get_iter(dest_));
- dest_canvas=(Canvas::Handle)(row[model.canvas]);
- }
- }
- else
- {
- row=(*get_iter(dest_parent));
- dest_canvas=row[model.contained_canvas];
- }
-
- assert(dest_canvas);
-
- Layer::Handle dest_layer(row[model.layer]);
-
- if(synfig::String(selection_data.get_data_type())=="LAYER")for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
- {
- //synfig::info("dest_layer_depth=%d",dest_layer_depth);
-
- Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
- assert(src);
- if(dest_layer==src)
- continue;
-
- if(dest_canvas==src->get_canvas() && src->get_depth()<dest_layer_depth)
- dest_layer_depth--;
-
- // In this case, we are just moving.
-// if(dest_canvas==src->get_canvas())
- {
- //if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
- // dest_layer_depth--;
- if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
- continue;
-
- synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
- action->set_param("canvas",dest_canvas);
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("layer",src);
- action->set_param("new_index",dest_layer_depth);
- action->set_param("dest_canvas",dest_canvas);
- if(canvas_interface()->get_instance()->perform_action(action))
- ret=true;
- else
- {
- passive_grouper.cancel();
- return false;
- }
- continue;
- }
- /*else // In this case we need to remove and then add
- {
-
- synfigapp::Action::Handle action;
- action=synfigapp::Action::create("LayerRemove");
- action->set_param("canvas",Canvas::Handle(src->get_canvas()));
- if(!action->set_param("canvas_interface",App::get_instance(src->get_canvas())->find_canvas_interface(src->get_canvas())))
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("layer",src);
- if(!canvas_interface()->get_instance()->perform_action(action))
- {
- passive_grouper.cancel();
- ret=false;
- return false;
- }
-
- action=synfigapp::Action::create("LayerAdd");
- action->set_param("canvas",dest_canvas);
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("new",src);
- if(!canvas_interface()->get_instance()->perform_action(action))
- {
- passive_grouper.cancel();
- ret=false;
- return false;
- }
-
- if(dest_layer_depth!=0)
- {
- action=synfigapp::Action::create("LayerMove");
- action->set_param("canvas",dest_canvas);
- action->set_param("canvas_interface",canvas_interface());
- action->set_param("layer",src);
- action->set_param("new_index",dest_layer_depth);
- if(!canvas_interface()->get_instance()->perform_action(action))
- {
- passive_grouper.cancel();
- ret=false;
- return false;
- }
- }
- ret=true;
- }
- */
- }
- }
- synfig::info("I supposedly moved %d layers",i);
-
- // Reselect the previously selected layers
- canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
-
- return ret;
-}
-
-void
-LayerTreeStore::queue_rebuild()
-{
- if (queued) return;
- queued = false;
- queue_connection.disconnect();
- queue_connection=Glib::signal_timeout().connect(
- sigc::bind_return(
- sigc::mem_fun(*this,&LayerTreeStore::rebuild),
- false
- )
- ,150);
-}
-
-void
-LayerTreeStore::rebuild()
-{
- if (queued) queued = false;
-
- // disconnect any subcanvas_changed connections
- std::map<synfig::Layer::Handle, sigc::connection>::iterator iter;
- for (iter = subcanvas_changed_connections.begin(); iter != subcanvas_changed_connections.end(); iter++)
- iter->second.disconnect();
- subcanvas_changed_connections.clear();
-
- //etl::clock timer;timer.reset();
-
- //synfig::warning("---------rebuilding layer table---------");
- // Save the selection data
- synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
-
- // Clear out the current list
- clear();
-
- // Go ahead and add all the layers
- std::for_each(
- canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
- sigc::mem_fun(*this, &studio::LayerTreeStore::on_layer_added)
- );
-
- // Reselect the previously selected layers
- if(!layer_list.empty())
- canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
-
- //synfig::info("LayerTreeStore::rebuild() took %f seconds",float(timer()));
-}
-
-void
-LayerTreeStore::refresh()
-{
- etl::clock timer;timer.reset();
-
- Gtk::TreeModel::Children children_(children());
-
- Gtk::TreeModel::Children::iterator iter;
-
- if(!children_.empty())
- for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
- {
- Gtk::TreeRow row=*iter;
- refresh_row(row);
- }
- //synfig::info("LayerTreeStore::refresh() took %f seconds",float(timer()));
-}
-
-void
-LayerTreeStore::refresh_row(Gtk::TreeModel::Row &row)
-{
- Layer::Handle layer=row[model.layer];
- /*
- {
- row[model.name] = layer->get_local_name();
- if(layer->get_description().empty())
- {
- row[model.label] = layer->get_local_name();
- row[model.tooltip] = Glib::ustring("Layer");
- }
- else
- {
- row[model.label] = layer->get_description();
- row[model.tooltip] = layer->get_local_name();
- }
- }
- */
-
- if(layer->dynamic_param_list().count("z_depth"))
- row[model.z_depth]=Time::begin();
- // row_changed(get_path(row),row);
-
- Gtk::TreeModel::Children children = row.children();
- Gtk::TreeModel::Children::iterator iter;
-
- if(!children.empty())
- for(iter = children.begin(); iter && iter != children.end(); ++iter)
- {
- Gtk::TreeRow row=*iter;
- refresh_row(row);
- }
-}
-
-
-void
-LayerTreeStore::set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle)
-{
- //row[model.id] = handle->get_name();
- //row[model.name] = handle->get_local_name();
- /*if(handle->get_description().empty())
- {
- //row[model.label] = handle->get_local_name();
- row[model.tooltip] = Glib::ustring("Layer");
- }
- else
- {
- //row[model.label] = handle->get_description();
- row[model.tooltip] = handle->get_local_name();
- }*/
-
- //row[model.active] = handle->active();
- row[model.layer] = handle;
- //row[model.canvas] = handle->get_canvas();
- //row[model.icon] = layer_icon;
-
- synfig::Layer::ParamList paramlist=handle->get_param_list();
-
- synfig::Layer::Vocab vocab=handle->get_param_vocab();
- synfig::Layer::Vocab::iterator iter;
-
- for(iter=vocab.begin();iter!=vocab.end();++iter)
- {
- if(iter->get_hidden())
- continue;
- if(handle->get_param(iter->get_name()).get_type()!=ValueBase::TYPE_CANVAS)
- continue;
-
- {
- Canvas::Handle canvas;
- canvas=handle->get_param(iter->get_name()).get(canvas);
- if(!canvas)
- continue;
-
- Canvas::reverse_iterator iter;
- row[model.contained_canvas]=canvas;
-
- for(iter=canvas->rbegin();iter!=canvas->rend();++iter)
- {
- Gtk::TreeRow row_(*(prepend(row.children())));
- set_row_layer(row_,*iter);
- }
- continue;
- }
-
- /*
- etl::handle<ValueNode> value_node;
- if(handle.constant()->dynamic_param_list().count(iter->get_name()))
- value_node=handle->dynamic_param_list()[iter->get_name()];
-
- Gtk::TreeRow child_row = *(append(row.children()));
- set_row_param(
- child_row,
- handle,
- iter->get_name(),
- iter->get_local_name(),
- paramlist[iter->get_name()],
- value_node,
- &*iter
- );
- */
- }
-}
-
-void
-LayerTreeStore::on_layer_added(synfig::Layer::Handle layer)
-{
- if (etl::handle<Layer_PasteCanvas>::cast_dynamic(layer))
- subcanvas_changed_connections[layer] =
- (etl::handle<Layer_PasteCanvas>::cast_dynamic(layer))->signal_subcanvas_changed().connect(
- sigc::mem_fun(*this,&studio::LayerTreeStore::queue_rebuild)
- );
-
- assert(layer);
- Gtk::TreeRow row;
- if(canvas_interface()->get_canvas()==layer->get_canvas())
- {
- row=*(prepend());
- }
- else
- {
- Gtk::TreeModel::Children::iterator iter;
- if(!find_canvas_row(layer->get_canvas(),iter))
- {
- rebuild();
- return;
- }
- row=*(prepend(iter->children()));
- }
- set_row_layer(row,layer);
-}
-
-void
-LayerTreeStore::on_layer_removed(synfig::Layer::Handle handle)
-{
- if (etl::handle<Layer_PasteCanvas>::cast_dynamic(handle))
- {
- subcanvas_changed_connections[handle].disconnect();
- subcanvas_changed_connections.erase(handle);
- }
- Gtk::TreeModel::Children::iterator iter;
- if(find_layer_row(handle,iter))
- erase(iter);
- else
- {
- synfig::error("LayerTreeStore::on_layer_removed():Unable to find layer to be removed, forced to rebuild...");
- rebuild();
- }
-}
-
-void
-LayerTreeStore::on_layer_inserted(synfig::Layer::Handle handle,int depth)
-{
- if(depth==0)
- {
- on_layer_added(handle);
- return;
- }
-
- Gtk::TreeModel::Children children_(children());
- if(canvas_interface()->get_canvas()!=handle->get_canvas())
- {
- Gtk::TreeModel::Children::iterator iter;
- if(!find_canvas_row(handle->get_canvas(),iter))
- {
- synfig::error("LayerTreeStore::on_layer_inserted():Unable to find canvas row, forced to rebuild...");
- rebuild();
- return;
- }
- children_=iter->children();
- }
-
- Gtk::TreeModel::Children::iterator iter(children_.begin());
- while(depth-- && iter)
- {
- ++iter;
- if(!iter || iter==children_.end())
- {
- synfig::error("LayerTreeStore::on_layer_inserted():Unable to achieve desired depth, forced to rebuild...");
- rebuild();
- return;
- }
- }
-
- Gtk::TreeModel::Row row(*insert(iter));
- set_row_layer(row,handle);
-}
-
-void
-LayerTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
-{
- Gtk::TreeModel::Children::iterator iter;
- if(find_layer_row(handle,iter))
- (*iter)[model.layer]=handle;
- else
- {
- synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
- rebuild();
- }
-}
-
-void
-LayerTreeStore::on_layer_lowered(synfig::Layer::Handle layer)
-{
- Gtk::TreeModel::Children::iterator iter, iter2;
- if(find_layer_row(layer,iter))
- {
- // Save the selection data
- //synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
- iter2=iter;
- iter2++;
- if(!iter2)
- {
- rebuild();
- return;
- }
-
- //Gtk::TreeModel::Row row(*iter);
- Gtk::TreeModel::Row row2 = *iter2;
- synfig::Layer::Handle layer2=row2[model.layer];
-
- erase(iter2);
- row2=*insert(iter);
- set_row_layer(row2,layer2);
-
- }
- else
- rebuild();
-}
-
-void
-LayerTreeStore::on_layer_raised(synfig::Layer::Handle layer)
-{
- Gtk::TreeModel::Children::iterator iter, iter2;
-
- Gtk::TreeModel::Children children_(children());
-
- if(find_layer_row_(layer, canvas_interface()->get_canvas(), children_, iter,iter2))
- {
- if(iter!=iter2)
- {
- //Gtk::TreeModel::Row row = *iter;
- Gtk::TreeModel::Row row2 = *iter2;
- synfig::Layer::Handle layer2=row2[model.layer];
-
- erase(iter2);
- iter++;
- row2=*insert(iter);
- set_row_layer(row2,layer2);
-
- return;
- }
- }
-
- rebuild();
-}
-
-void
-LayerTreeStore::on_layer_moved(synfig::Layer::Handle layer,int depth, synfig::Canvas::Handle /*canvas*/)
-{
- on_layer_removed(layer);
- on_layer_inserted(layer,depth);
-}
-
-void
-LayerTreeStore::on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name)
-{
- if(param_name=="z_depth")
- {
- Gtk::TreeModel::Children::iterator iter;
- if(find_layer_row(handle,iter))
- {
- (*iter)[model.z_depth]=Time::begin();
- }
- }
-
- /*
- Gtk::TreeModel::Children::iterator iter;
- if(find_layer_row(handle,iter))
- {
- Gtk::TreeModel::Children children(iter->children());
-
- for(iter = children.begin(); iter && iter != children.end(); ++iter)
- {
- if((Glib::ustring)(*iter)[model.param_name]==param_name)
- {
- Gtk::TreeRow row=*iter;
- refresh_row(row);
- return;
- }
- }
- }
- rebuild();
- */
-}
-
-void
-LayerTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
-{
- Gtk::TreeModel::Children::iterator iter;
- if(find_layer_row(handle,iter))
- {
- Gtk::TreeRow row(*iter);
-
- Layer::Handle layer(row[model.layer]);
-
- if(desc.empty())
- {
- //row[model.label]=layer->get_local_name();
- row[model.tooltip]=Glib::ustring(_("Layer"));
- }
- else
- //row[model.label]=layer->get_description();
- row[model.tooltip]=layer->get_local_name();
- }
- else
- {
- rebuild();
- }
-}
-
-bool
-LayerTreeStore::find_canvas_row_(synfig::Canvas::Handle canvas, synfig::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter)
-{
- if(canvas==parent)
- return false;
-
- {
- for(iter=layers.begin(); iter && iter != layers.end(); ++iter)
- {
- Gtk::TreeModel::Row row = *iter;
- if(canvas==(synfig::Canvas::Handle)row[model.contained_canvas])
- return true;
- }
-
- iter=children().end();
- //return false;
- }
-
- Gtk::TreeModel::Children::iterator iter2;
- //Gtk::TreeModel::Children::iterator iter3;
-
- for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
- {
- Gtk::TreeModel::Row row = *iter2;
- assert((bool)true);
-
- if(row.children().empty())
- continue;
-
- Canvas::Handle sub_canvas((*row.children().begin())[model.canvas]);
- if(!sub_canvas)
- continue;
-
- if(find_canvas_row_(canvas,sub_canvas,iter2->children(),iter))
- return true;
- }
-
- iter=children().end();
- return false;
-}
-
-bool
-LayerTreeStore::find_canvas_row(synfig::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter)
-{
- return find_canvas_row_(canvas,canvas_interface()->get_canvas(),children(),iter);
-}
-
-
-bool
-LayerTreeStore::find_layer_row_(const synfig::Layer::Handle &layer, synfig::Canvas::Handle /*canvas*/, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
-{
- assert(layer);
-
- //if(layer->get_canvas()==canvas)
- {
- for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
- {
- Gtk::TreeModel::Row row = *iter;
- if(layer==(synfig::Layer::Handle)row[model.layer])
- return true;
- }
-
- iter=children().end();
- //return false;
- }
-
- Gtk::TreeModel::Children::iterator iter2;
-
- for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
- {
- Gtk::TreeModel::Row row = *iter2;
- assert((bool)true);
-
- if(row.children().empty())
- continue;
-
- Canvas::Handle canvas((*row.children().begin())[model.canvas]);
- if(!canvas)
- continue;
-
- if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
- return true;
- }
-
- iter=children().end();
- return false;
-}
-
-bool
-LayerTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
-{
- Gtk::TreeModel::Children::iterator prev;
- return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
-}
-
-bool
-LayerTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
-{
- Gtk::TreeModel::Children::iterator iter;
- if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
- return false;
- if(iter==children().begin())
- return false;
- return true;
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file layertreestore.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_LAYERTREESTORE_H
-#define __SYNFIG_STUDIO_LAYERTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <synfig/value.h>
-#include <synfig/valuenode.h>
-#include <gtkmm/treeview.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class LayerTreeStore : virtual public Gtk::TreeStore
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
-
- class Model : public Gtk::TreeModel::ColumnRecord
- {
- public:
- Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
- Gtk::TreeModelColumn<Glib::ustring> label;
- Gtk::TreeModelColumn<Glib::ustring> name;
- Gtk::TreeModelColumn<Glib::ustring> id;
-
- Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
-
- Gtk::TreeModelColumn<Glib::ustring> tooltip;
-
-
- Gtk::TreeModelColumn<bool> active;
- Gtk::TreeModelColumn<synfig::Layer::Handle> layer;
- Gtk::TreeModelColumn<synfig::Canvas::Handle> contained_canvas;
-
- Gtk::TreeModelColumn<bool> children_lock;
-
- Gtk::TreeModelColumn<float> z_depth;
- Gtk::TreeModelColumn<int> index;
-
- Model()
- {
- add(icon);
- add(label);
- add(name);
- add(id);
- add(canvas);
- add(tooltip);
- add(active);
- add(layer);
- add(contained_canvas);
- add(z_depth);
- add(index);
- add(children_lock);
- }
- };
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- //! TreeModel for the layers
- const Model model;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- bool queued;
-
- sigc::connection queue_connection;
-
- std::map<synfig::Layer::Handle, sigc::connection> subcanvas_changed_connections;
-
- etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
-
- Glib::RefPtr<Gdk::Pixbuf> layer_icon;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
- /*
- -- ** -- P R O T E C T E D M E T H O D S -----------------------------------
- */
-
-private:
- virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
- virtual void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
-
- virtual bool row_draggable_vfunc (const TreeModel::Path& path)const;
- virtual bool drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
- virtual bool drag_data_delete_vfunc (const TreeModel::Path& path);
- virtual bool drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
- virtual bool row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- bool on_layer_tree_event(GdkEvent *event);
-
- void on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc);
-
- void on_layer_added(synfig::Layer::Handle handle);
-
- void on_layer_removed(synfig::Layer::Handle handle);
-
- void on_layer_inserted(synfig::Layer::Handle handle,int depth);
-
- void on_layer_moved(synfig::Layer::Handle handle,int depth, synfig::Canvas::Handle canvas);
-
- void on_layer_status_changed(synfig::Layer::Handle handle,bool);
-
- void on_layer_lowered(synfig::Layer::Handle handle);
-
- void on_layer_raised(synfig::Layer::Handle handle);
-
- void on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name);
-
- //void on_value_node_added(synfig::ValueNode::Handle value_node);
-
- //void on_value_node_deleted(synfig::ValueNode::Handle value_node);
-
- //void on_value_node_changed(synfig::ValueNode::Handle value_node);
-
- //void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
-
- bool find_layer_row_(const synfig::Layer::Handle &handle, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
-
- bool find_canvas_row_(synfig::Canvas::Handle canvas, synfig::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter);
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
- ~LayerTreeStore();
-
- etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
- etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
- etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
-
- bool find_canvas_row(synfig::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter);
-
- bool find_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
-
- bool find_prev_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
-
- void queue_rebuild();
-
- void rebuild();
-
- void refresh();
-
- void refresh_row(Gtk::TreeModel::Row &row);
-
- void set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle);
-
- static int z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
- static int index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
-
- //void set_row_param(Gtk::TreeRow &row,synfig::Layer::Handle &handle,const std::string& name, const std::string& local_name, const synfig::ValueBase &value, etl::handle<synfig::ValueNode> value_node,synfig::ParamDesc *param_desc);
-
- //virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc);
- static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
-
- /*
- -- ** -- S T A T I C P U B L I C M E T H O D S ---------------------------
- */
-
-public:
-
- static Glib::RefPtr<LayerTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-
-
-}; // END of class LayerTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file metadatatreestore.cpp
-** \brief Template File
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2008 Chris Moore
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "metadatatreestore.h"
-#include <synfigapp/canvasinterface.h>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static MetaDataTreeStore::Model& ModelHack()
-{
- static MetaDataTreeStore::Model* model(0);
- if(!model)model=new MetaDataTreeStore::Model;
- return *model;
-}
-
-MetaDataTreeStore::MetaDataTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
- Gtk::TreeStore (ModelHack()),
- canvas_interface_ (canvas_interface_)
-{
- // Connect the signal
- get_canvas()->signal_meta_data_changed().connect(sigc::mem_fun(*this,&MetaDataTreeStore::meta_data_changed));
-
- rebuild();
-}
-
-MetaDataTreeStore::~MetaDataTreeStore()
-{
- if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
- synfig::info("MetaDataTreeStore::~MetaDataTreeStore(): Deleted");
-}
-
-Glib::RefPtr<MetaDataTreeStore>
-MetaDataTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
-{
- return Glib::RefPtr<MetaDataTreeStore>(new MetaDataTreeStore(canvas_interface_));
-}
-
-void
-MetaDataTreeStore::meta_data_changed(synfig::String /*key*/)
-{
- rebuild();
-}
-
-void
-MetaDataTreeStore::rebuild()
-{
- clear();
-
- std::list<String> keys(get_canvas()->get_meta_data_keys());
-
- for(;!keys.empty();keys.pop_front())
- {
- Gtk::TreeRow row(*append());
- row[model.key]=keys.front();
- }
-}
-
-void
-MetaDataTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
-{
- if(column>=get_n_columns_vfunc())
- {
- g_warning("MetaDataTreeStore::set_value_impl: Bad column (%d)",column);
- return;
- }
-
- if(column==model.data.index())
- {
- synfig::String key((Glib::ustring)(*iter)[model.key]);
- g_value_init(value.gobj(),G_TYPE_STRING);
- g_value_set_string(value.gobj(),get_canvas()->get_meta_data(key).c_str());
- return;
- }
- else
- Gtk::TreeStore::get_value_vfunc(iter,column,value);
-}
-
-void
-MetaDataTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
-{
- if(column>=get_n_columns_vfunc())
- {
- g_warning("MetaDataTreeStore::set_value_impl: Bad column (%d)",column);
- return;
- }
-
- if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
- {
- g_warning("MetaDataTreeStore::set_value_impl: Bad value type");
- return;
- }
-
- if(column==model.data.index())
- {
- Glib::Value<Glib::ustring> x;
- g_value_init(x.gobj(),model.data.type());
- g_value_copy(value.gobj(),x.gobj());
-
- synfig::String key((Glib::ustring)(*iter)[model.key]);
- synfig::String new_data(x.get());
-
- get_canvas_interface()->set_meta_data(key,new_data);
- }
- else
- Gtk::TreeStore::set_value_impl(iter,column, value);
-}
+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file metadatatreestore.h
-** \brief Template Header
-**
-** $Id$
-**
-** \legal
-** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_METADATATREESTORE_H
-#define __SYNFIG_STUDIO_METADATATREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <gdkmm/pixbuf.h>
-#include <synfigapp/action.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace synfigapp { class CanvasInterface; }
-
-namespace studio {
-
-class MetaDataTreeStore : virtual public Gtk::TreeStore
-{
- /*
- -- ** -- P U B L I C T Y P E S ---------------------------------------------
- */
-
-public:
-
- class Model : public Gtk::TreeModel::ColumnRecord
- {
- public:
- public:
- Gtk::TreeModelColumn<Glib::ustring> key;
- Gtk::TreeModelColumn<Glib::ustring> data;
-
- Model()
- {
- add(key);
- add(data);
- }
- };
-
- /*
- -- ** -- P U B L I C D A T A ------------------------------------------------
- */
-
-public:
-
- const Model model;
-
- /*
- -- ** -- P R I V A T E D A T A ---------------------------------------------
- */
-
-private:
-
- etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
-
- /*
- -- ** -- P R I V A T E M E T H O D S ---------------------------------------
- */
-
-private:
-
- /*
- -- ** -- S I G N A L T E R M I N A L S -------------------------------------
- */
-
-private:
-
- void meta_data_changed(synfig::String key);
-
- /*
- -- ** -- P U B L I C M E T H O D S -----------------------------------------
- */
-
-public:
-
- ~MetaDataTreeStore();
-
- etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface() { return canvas_interface_; }
- etl::loose_handle<const synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
- synfig::Canvas::Handle get_canvas()const { return canvas_interface_->get_canvas(); }
- synfig::Canvas::Handle get_canvas() { return canvas_interface_->get_canvas(); }
-
- void rebuild();
-
- void refresh() { rebuild(); }
-
- /*
- -- ** -- P R O T E C T E D M E T H O D S -----------------------------------
- */
-
-protected:
- MetaDataTreeStore(etl::loose_handle<synfigapp::CanvasInterface>);
- void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
- void set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value);
-
-public:
-
- static Glib::RefPtr<MetaDataTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface>);
-
-}; // END of class MetaDataTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file canvastreestore.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trees/canvastreestore.h"
+#include <synfig/valuenode.h>
+#include "iconcontroller.h"
+#include <synfig/valuenode_timedswap.h>
+#include <synfig/valuenode_animated.h>
+#include <gtkmm/button.h>
+#include <synfigapp/instance.h>
+#include "cellrenderer_value.h"
+#include "cellrenderer_timetrack.h"
+#include <ETL/clock>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static CanvasTreeStore::Model& ModelHack()
+{
+ static CanvasTreeStore::Model* model(0);
+ if(!model)model=new CanvasTreeStore::Model;
+ return *model;
+}
+
+CanvasTreeStore::CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+ Gtk::TreeStore(ModelHack()),
+ canvas_interface_ (canvas_interface_)
+{
+}
+
+CanvasTreeStore::~CanvasTreeStore()
+{
+}
+
+void
+CanvasTreeStore::get_value_vfunc(const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+ if(column==model.value.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+ Glib::Value<synfig::ValueBase> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ if(!value_desc)
+ {
+ x.set(ValueBase());
+ }
+ else
+ if(value_desc.is_const())
+ x.set(value_desc.get_value());
+ else
+ if(value_desc.is_value_node())
+ x.set((*value_desc.get_value_node())(canvas_interface()->get_time()));
+ else
+ {
+ synfig::error(__FILE__":%d: Unable to figure out value",__LINE__);
+ return;
+ }
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.is_value_node.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(value_desc && value_desc.is_value_node());
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.is_shared.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(value_desc.is_value_node() && value_desc.get_value_node()->rcount()>1);
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.is_exported.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(value_desc.is_value_node() && value_desc.get_value_node()->is_exported());
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.is_canvas.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(!value_desc && (Canvas::Handle)(*iter)[model.canvas]);
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.id.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ if(value_desc && value_desc.is_value_node())
+ x.set(value_desc.get_value_node()->get_id());
+ else if(!value_desc && Canvas::Handle((*iter)[model.canvas]))
+ x.set(Canvas::Handle((*iter)[model.canvas])->get_id());
+ else
+ return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.is_editable.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(!value_desc.is_value_node() || synfigapp::is_editable(value_desc.get_value_node()));
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.type.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ // Set the type
+ if(!value_desc)
+ {
+ if((*iter)[model.is_canvas])
+ x.set(_("Canvas"));
+ }
+ else
+ {
+ if(!value_desc.is_value_node() || value_desc.get_value_node()->get_name()=="constant")
+ {
+ x.set(ValueBase::type_local_name(value_desc.get_value_type()));
+ }
+ else
+ {
+ x.set(value_desc.get_value_node()->get_local_name());
+ }
+ }
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.label.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ // Set the type
+ if(!value_desc)
+ {
+ Canvas::Handle canvas((*iter)[model.canvas]);
+ if(canvas)
+ {
+ if(!canvas->get_id().empty())
+ x.set(canvas->get_id());
+ else
+ if(!canvas->get_name().empty())
+ x.set(canvas->get_name());
+ else
+ x.set(_("[Unnamed]"));
+ x.set(_("Canvas"));
+ }
+ return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+ }
+ else
+ {
+ ValueNode::Handle value_node=value_desc.get_value_node();
+
+ // Setup the row's label
+ if(value_node->get_id().empty())
+ x.set(Glib::ustring((*iter)[model.name]));
+ else if(Glib::ustring((*iter)[model.name]).empty())
+ x.set(value_node->get_id());
+ else
+ x.set(Glib::ustring((*iter)[model.name])+" ("+value_node->get_id()+')');
+ }
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.icon.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+ if(!value_desc)
+ return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+
+ Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(get_tree_pixbuf(value_desc.get_value_type()));
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+bool
+CanvasTreeStore::find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
+{
+ iter=children().begin();
+ while(iter && value_desc!=(*iter)[model.value_desc])
+ {
+ if(!iter->children().empty())
+ {
+ Gtk::TreeIter iter2(iter->children().begin());
+ //! \todo confirm that the && should be done before the ||
+ if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
+ {
+ iter=iter2;
+ return true;
+ }
+ }
+ Gtk::TreeIter iter2(++iter);
+ if(!iter2)
+ iter==iter->parent();
+ else
+ iter=iter2;
+ }
+ return (bool)iter && value_desc==(*iter)[model.value_desc];
+}
+
+bool
+CanvasTreeStore::find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
+{
+ if(!iter) return find_first_value_desc(value_desc,iter);
+
+ if(iter) do {
+ if(!iter->children().empty())
+ {
+ Gtk::TreeIter iter2(iter->children().begin());
+ //! \todo confirm that the && should be done before the ||
+ if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
+ {
+ iter=iter2;
+ return true;
+ }
+ }
+ Gtk::TreeIter iter2(++iter);
+ if(!iter2)
+ {
+ iter==iter->parent();
+ if(iter)++iter;
+ }
+ else
+ iter=iter2;
+ } while(iter && value_desc!=(*iter)[model.value_desc]);
+ return (bool)iter && value_desc==(*iter)[model.value_desc];
+}
+
+bool
+CanvasTreeStore::find_first_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
+{
+ iter=children().begin();
+ while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node])
+ {
+ if(!iter->children().empty())
+ {
+ Gtk::TreeIter iter2(iter->children().begin());
+ //! \todo confirm that the && should be done before the ||
+ if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
+ {
+ iter=iter2;
+ return true;
+ }
+ }
+ Gtk::TreeIter iter2(++iter);
+ if(!iter2)
+ iter==iter->parent();
+ else
+ iter=iter2;
+ }
+ return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
+}
+
+bool
+CanvasTreeStore::find_next_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
+{
+ if(!iter) return find_first_value_node(value_node,iter);
+
+ if(iter) do {
+ if(!iter->children().empty())
+ {
+ Gtk::TreeIter iter2(iter->children().begin());
+ //! \todo confirm that the && should be done before the ||
+ if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
+ {
+ iter=iter2;
+ return true;
+ }
+ }
+ Gtk::TreeIter iter2(++iter);
+ if(!iter2)
+ {
+ iter==iter->parent();
+ if(iter)++iter;
+ }
+ else
+ iter=iter2;
+ } while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node]);
+ return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
+}
+
+void
+CanvasTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children)
+{
+ Gtk::TreeModel::Children children = row.children();
+ while(!children.empty() && erase(children.begin()))
+ ;
+
+ row[model.value_desc]=value_desc;
+ try
+ {
+ //row[model.icon] = get_tree_pixbuf(value_desc.get_value_type());
+
+ if(value_desc.is_value_node())
+ {
+ ValueNode::Handle value_node=value_desc.get_value_node();
+
+ assert(value_node);
+
+ row[model.value_node] = value_node;
+ //row[model.is_canvas] = false;
+ //row[model.is_value_node] = true;
+ //row[model.is_editable] = synfigapp::is_editable(value_node);
+ //row[model.id]=value_node->get_id();
+
+ // Set the canvas
+ if(value_desc.parent_is_canvas())
+ row[model.canvas]=value_desc.get_canvas();
+ else
+ row[model.canvas]=canvas_interface()->get_canvas();
+
+ LinkableValueNode::Handle linkable;
+ linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
+
+ if(linkable && do_children)
+ {
+ row[model.link_count] = linkable->link_count();
+ for(int i=0;i<linkable->link_count();i++)
+ {
+ Gtk::TreeRow child_row=*(append(row.children()));
+ child_row[model.link_id] = i;
+ child_row[model.canvas] = static_cast<Canvas::Handle>(row[model.canvas]);
+ child_row[model.name] = linkable->link_local_name(i);
+ set_row(child_row,synfigapp::ValueDesc(linkable,i));
+ }
+ }
+ return;
+ }
+ else
+ {
+ //row[model.is_value_node] = false;
+ //row[model.is_editable] = true;
+ //row[model.label] = Glib::ustring(row[model.name]);
+ return;
+ }
+ }
+ catch(synfig::Exception::IDNotFound x)
+ {
+ synfig::error(__FILE__":%d: IDNotFound thrown",__LINE__);
+ erase(row);
+ return;
+ }
+
+ // We should never get to this point
+ assert(0);
+}
+
+void
+CanvasTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool do_children)
+{
+ synfigapp::ValueDesc value_desc=row[model.value_desc];
+
+ if(value_desc)
+ {
+ if((bool)row[model.is_value_node] != value_desc.is_value_node() ||
+ (!bool(row[model.is_value_node]) && row[model.link_count]!=0))
+ {
+ set_row(row,value_desc,do_children);
+ return;
+ }
+
+ if(row[model.is_value_node])
+ {
+ ValueNode::Handle value_node(value_desc.get_value_node());
+
+ if(ValueNode::Handle(row[model.value_node])!=value_node)
+ {
+ rebuild_row(row,do_children);
+ return;
+ }
+
+ //row[model.id]=value_node->get_id();
+
+ // Setup the row's label
+ /*
+ if(value_node->get_id().empty())
+ row[model.label] = Glib::ustring(row[model.name]);
+ else if(Glib::ustring(row[model.name]).empty())
+ row[model.label] = value_node->get_id();
+ else
+ row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
+ */
+
+ LinkableValueNode::Handle linkable;
+ linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
+ if(do_children && linkable && ((int)row[model.link_count] != linkable->link_count()))
+ {
+ // Gtk::TreeModel::Children children = row.children();
+ // while(!children.empty() && erase(children.begin()));
+
+ set_row(row,value_desc);
+ return;
+ }
+ }
+ else
+ {
+ //row[model.label] = Glib::ustring(row[model.name]);
+ //row[model.is_value_node] = false;
+ //row[model.is_editable] = true;
+ }
+ }
+ if(!do_children)
+ return;
+
+ Gtk::TreeModel::Children children = row.children();
+ Gtk::TreeModel::Children::iterator iter;
+
+ if(!children.empty())
+ for(iter = children.begin(); iter != children.end(); ++iter)
+ {
+ Gtk::TreeRow row=*iter;
+ refresh_row(row);
+ }
+}
+
+void
+CanvasTreeStore::rebuild_row(Gtk::TreeModel::Row &row, bool do_children)
+{
+ synfigapp::ValueDesc value_desc=(synfigapp::ValueDesc)row[model.value_desc];
+
+ if(value_desc && value_desc.get_value_node())
+ {
+ ValueNode::Handle value_node;
+ value_node=value_desc.get_value_node();
+
+ assert(value_node);if(!value_node)return;
+
+ if(value_node && value_node!=(ValueNode::Handle)row[model.value_node])
+ {
+// Gtk::TreeModel::Children children = row.children();
+// while(!children.empty() && erase(children.begin()));
+
+ set_row(row,value_desc,do_children);
+ return;
+ }
+
+ LinkableValueNode::Handle linkable;
+ linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
+
+ if( do_children && linkable && (int)row[model.link_count] != linkable->link_count())
+ {
+// Gtk::TreeModel::Children children = row.children();
+// while(!children.empty() && erase(children.begin()));
+
+ set_row(row,value_desc);
+ return;
+ }
+
+ //if(!value_node)
+ // value_node=row[model.value_node];
+
+ row[model.id]=value_node->get_id();
+
+ // Setup the row's label
+ if(value_node->get_id().empty())
+ row[model.label] = Glib::ustring(row[model.name]);
+ else if(Glib::ustring(row[model.name]).empty())
+ row[model.label] = value_node->get_id();
+ else
+ row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
+ }
+ else
+ {
+ row[model.label] = Glib::ustring(row[model.name]);
+ row[model.is_value_node] = false;
+ row[model.is_editable] = true;
+ Gtk::TreeModel::Children children = row.children();
+ while(!children.empty() && erase(children.begin()))
+ ;
+ }
+ if(!do_children)
+ return;
+
+ Gtk::TreeModel::Children children = row.children();
+ Gtk::TreeModel::Children::iterator iter;
+ if(!children.empty())
+ for(iter = children.begin(); iter != children.end(); ++iter)
+ {
+ Gtk::TreeRow row=*iter;
+ rebuild_row(row);
+ }
+}
+
+CellRenderer_ValueBase*
+CanvasTreeStore::add_cell_renderer_value(Gtk::TreeView::Column* column)
+{
+ const CanvasTreeStore::Model model;
+
+ CellRenderer_ValueBase* ret;
+
+ ret=Gtk::manage( new CellRenderer_ValueBase() );
+
+ column->pack_start(*ret,true);
+ column->add_attribute(ret->property_value(), model.value);
+ column->add_attribute(ret->property_editable(), model.is_editable);
+ column->add_attribute(ret->property_canvas(), model.canvas);
+
+ return ret;
+}
+
+CellRenderer_TimeTrack*
+CanvasTreeStore::add_cell_renderer_value_node(Gtk::TreeView::Column* column)
+{
+ const CanvasTreeStore::Model model;
+
+ CellRenderer_TimeTrack* ret;
+
+ ret = Gtk::manage( new CellRenderer_TimeTrack() );
+
+ column->pack_start(*ret,true);
+ //column->add_attribute(ret->property_visible(), model.is_value_node);
+ column->add_attribute(ret->property_value_desc(), model.value_desc);
+ column->add_attribute(ret->property_canvas(), model.canvas);
+
+
+ return ret;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trees/canvastreestore.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_CANVASTREESTORE_H
+#define __SYNFIG_STUDIO_CANVASTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <synfigapp/value_desc.h>
+#include <gtkmm/treeview.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CellRenderer_TimeTrack;
+class CellRenderer_ValueBase;
+
+ enum ColumnID
+ {
+ COLUMNID_ID,
+ COLUMNID_VALUE,
+ COLUMNID_TIME_TRACK,
+ COLUMNID_TYPE,
+
+ COLUMNID_END //!< \internal
+ };
+#define COLUMNID_NAME COLUMNID_ID
+
+class CanvasTreeStore : virtual public Gtk::TreeStore
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+
+ class Model : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+ Gtk::TreeModelColumn<Glib::ustring> label;
+ Gtk::TreeModelColumn<Glib::ustring> name;
+ Gtk::TreeModelColumn<Glib::ustring> id;
+
+ Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
+ Gtk::TreeModelColumn<bool> is_canvas;
+
+ Gtk::TreeModelColumn<synfig::ValueNode::Handle> value_node;
+ Gtk::TreeModelColumn<bool> is_value_node;
+ Gtk::TreeModelColumn<synfig::ValueBase> value;
+ Gtk::TreeModelColumn<Glib::ustring> type;
+ Gtk::TreeModelColumn<int> link_id;
+ Gtk::TreeModelColumn<int> link_count;
+
+ Gtk::TreeModelColumn<bool> is_editable;
+
+ Gtk::TreeModelColumn<bool> is_shared;
+ Gtk::TreeModelColumn<bool> is_exported;
+
+ Gtk::TreeModelColumn<synfigapp::ValueDesc> value_desc;
+
+ Gtk::TreeModelColumn<Glib::ustring> tooltip;
+
+ Model()
+ {
+ add(value);
+ add(name);
+ add(label);
+ add(icon);
+ add(type);
+ add(id);
+ add(canvas);
+ add(value_node);
+ add(is_canvas);
+ add(is_value_node);
+
+ add(is_shared);
+ add(is_exported);
+ add(is_editable);
+ add(value_desc);
+ add(link_count);
+ add(link_id);
+
+ add(tooltip);
+ }
+ };
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ const Model model;
+
+ //std::multimap<etl::handle<ValueNode>, sigc::connection> connection_map;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+protected:
+ virtual void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+ ~CanvasTreeStore();
+
+ etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+ etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+
+ virtual void rebuild_row(Gtk::TreeModel::Row &row, bool do_children=true);
+
+ virtual void refresh_row(Gtk::TreeModel::Row &row, bool do_children=true);
+
+ virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children=true);
+
+ bool find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter);
+ bool find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter);
+
+ bool find_first_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter);
+ bool find_next_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter);
+
+
+ static CellRenderer_ValueBase* add_cell_renderer_value(Gtk::TreeView::Column* column);
+
+ static CellRenderer_TimeTrack* add_cell_renderer_value_node(Gtk::TreeView::Column* column);
+
+ etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+ virtual void on_value_node_changed(synfig::ValueNode::Handle value_node)=0;
+
+ /*
+ -- ** -- P R O T E C T E D M E T H O D S -----------------------------------
+ */
+
+public:
+
+}; // END of class CanvasTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file childrentree.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trees/childrentree.h"
+#include "cellrenderer_value.h"
+#include "cellrenderer_timetrack.h"
+#include <synfigapp/action.h>
+#include <synfigapp/instance.h>
+#include <gtkmm/scrolledwindow.h>
+#include <synfig/timepointcollect.h>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef SMALL_BUTTON
+#define SMALL_BUTTON(button,stockid,tooltip) \
+ button = manage(new class Gtk::Button()); \
+ icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize)); \
+ button->add(*icon); \
+ tooltips_.set_tip(*button,tooltip); \
+ icon->set_padding(0,0);\
+ icon->show(); \
+ button->set_relief(Gtk::RELIEF_NONE); \
+ button->show()
+#endif
+
+#ifndef NORMAL_BUTTON
+#define NORMAL_BUTTON(button,stockid,tooltip) \
+ button = manage(new class Gtk::Button()); \
+ icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON)); \
+ button->add(*icon); \
+ tooltips_.set_tip(*button,tooltip); \
+ icon->set_padding(0,0);\
+ icon->show(); \
+ /*button->set_relief(Gtk::RELIEF_NONE);*/ \
+ button->show()
+#endif
+
+#define NEW_SMALL_BUTTON(x,y,z) Gtk::Button *SMALL_BUTTON(x,y,z)
+
+#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ChildrenTree::ChildrenTree()
+{
+ const ChildrenTreeStore::Model model;
+
+ { // --- N A M E --------------------------------------------------------
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ID")) );
+
+ // Set up the icon cell-renderer
+ Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+ column->pack_start(*icon_cellrenderer,false);
+ column->add_attribute(icon_cellrenderer->property_pixbuf(), model.icon);
+
+ // Pack the label into the column
+ column->pack_start(model.label,true);
+
+ // Finish setting up the column
+ column->set_reorderable();
+ column->set_resizable();
+ column->set_clickable();
+ column->set_min_width(150);
+ column->set_sort_column(model.label);
+ tree_view.append_column(*column);
+
+ }
+ { // --- T Y P E --------------------------------------------------------
+ int cols_count = tree_view.append_column(_("Type"),model.type);
+ Gtk::TreeViewColumn* column = tree_view.get_column(cols_count-1);
+ if(column)
+ {
+ column->set_reorderable();
+ column->set_resizable();
+ column->set_clickable();
+ column->set_sort_column(model.type);
+ }
+ }
+ { // --- V A L U E -----------------------------------------------------
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ValueBase")) );
+
+ // Set up the value cell-renderer
+ cellrenderer_value=ChildrenTreeStore::add_cell_renderer_value(column);
+ cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_edited_value));
+ cellrenderer_value->property_value()=synfig::ValueBase();
+
+ // Finish setting up the column
+ tree_view.append_column(*column);
+ column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
+ column->set_min_width(150);
+ column->set_reorderable();
+ column->set_resizable();
+ column->set_clickable(false);
+ }
+ { // --- T I M E T R A C K --------------------------------------------
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
+ column_time_track=column;
+
+ // Set up the value-node cell-renderer
+ cellrenderer_time_track=ChildrenTreeStore::add_cell_renderer_value_node(column);
+ cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
+ cellrenderer_time_track->signal_waypoint_clicked_cellrenderer().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_waypoint_clicked_childrentree) );
+ column->add_attribute(cellrenderer_time_track->property_value_desc(), model.value_desc);
+ column->add_attribute(cellrenderer_time_track->property_canvas(), model.canvas);
+
+ //column->pack_start(*cellrenderer_time_track);
+
+ // Finish setting up the column
+ column->set_reorderable();
+ column->set_resizable();
+ tree_view.append_column(*column);
+ }
+
+ // This makes things easier to read.
+ tree_view.set_rules_hint();
+
+ // Make us more sensitive to several events
+ tree_view.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+
+ tree_view.signal_event().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_tree_event));
+
+ // Create a scrolled window for that tree
+ Gtk::ScrolledWindow *scroll_children_tree = manage(new class Gtk::ScrolledWindow());
+ scroll_children_tree->set_flags(Gtk::CAN_FOCUS);
+ scroll_children_tree->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ scroll_children_tree->add(tree_view);
+ scroll_children_tree->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+ scroll_children_tree->show();
+
+ attach(*scroll_children_tree, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+ hbox=manage(new Gtk::HBox());
+
+ attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+
+ tree_view.set_enable_search(true);
+ tree_view.set_search_column(model.label);
+
+/* // Buttons to raise/lower/duplicate/delete children valuenodes
+ // Commented out because these functions are not implemented
+ // and children sort themselves alphabetically
+
+ Gtk::Image *icon;
+ //Gtk::IconSize iconsize(Gtk::IconSize::from_name("synfig-small_icon"));
+ Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ SMALL_BUTTON(button_raise,"gtk-go-up",_("Raise"));
+ SMALL_BUTTON(button_lower,"gtk-go-down",_("Lower"));
+ SMALL_BUTTON(button_duplicate,"synfig-duplicate",_("Duplicate"));
+ SMALL_BUTTON(button_delete,"gtk-delete",_("Delete"));
+
+ hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
+ hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
+ hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
+ hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
+
+ button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_raise_pressed));
+ button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_lower_pressed));
+ button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_duplicate_pressed));
+ button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_delete_pressed));
+
+ button_raise->set_sensitive(false);
+ button_lower->set_sensitive(false);
+ button_duplicate->set_sensitive(false);
+ button_delete->set_sensitive(false);
+*/
+
+ get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_selection_changed));
+
+ tree_view.set_reorderable(true);
+
+ hbox->show();
+ tree_view.show();
+
+ tooltips_.enable();
+
+ //get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+}
+
+ChildrenTree::~ChildrenTree()
+{
+}
+
+void
+ChildrenTree::set_show_timetrack(bool x)
+{
+ column_time_track->set_visible(x);
+}
+
+void
+ChildrenTree::set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store)
+{
+ children_tree_store_=children_tree_store;
+ tree_view.set_model(children_tree_store_);
+ cellrenderer_time_track->set_canvas_interface(children_tree_store_->canvas_interface()); // am I smart people? (cellrenderer_timetrack.h:176)
+ children_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::ChildrenTree::on_dirty_preview));
+}
+
+void
+ChildrenTree::set_time_adjustment(Gtk::Adjustment &adjustment)
+{
+ cellrenderer_time_track->set_adjustment(adjustment);
+}
+
+void
+ChildrenTree::on_dirty_preview()
+{
+}
+
+void
+ChildrenTree::on_selection_changed()
+{
+ if(0)
+ {
+ button_raise->set_sensitive(false);
+ button_lower->set_sensitive(false);
+ button_duplicate->set_sensitive(false);
+ button_delete->set_sensitive(false);
+ return;
+ }
+}
+
+void
+ChildrenTree::on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value)
+{
+ Gtk::TreePath path(path_string);
+
+ const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+
+ row[model.value]=value;
+// signal_edited_value()(row[model.value_desc],value);
+}
+
+void
+ChildrenTree::on_waypoint_clicked_childrentree(const etl::handle<synfig::Node>& node __attribute__ ((unused)),
+ const synfig::Time& time __attribute__ ((unused)),
+ const synfig::Time& time_offset __attribute__ ((unused)),
+ int button __attribute__ ((unused)))
+{
+ std::set<synfig::Waypoint, std::less<UniqueID> > waypoint_set;
+ synfig::waypoint_collect(waypoint_set,time,node);
+
+ synfigapp::ValueDesc value_desc;
+
+ if (waypoint_set.size() == 1)
+ {
+ ValueNode::Handle value_node(waypoint_set.begin()->get_parent_value_node());
+ assert(value_node);
+
+ Gtk::TreeRow row;
+ if (children_tree_store_->find_first_value_node(value_node, row) && row)
+ value_desc = static_cast<synfigapp::ValueDesc>(row[model.value_desc]);
+ }
+
+ if (!waypoint_set.empty())
+ signal_waypoint_clicked_childrentree()(value_desc,waypoint_set,button);
+}
+
+bool
+ChildrenTree::on_tree_event(GdkEvent *event)
+{
+ switch(event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!tree_view.get_path_at_pos(
+ int(event->button.x),int(event->button.y), // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+ const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+
+ if(column->get_first_cell_renderer()==cellrenderer_time_track)
+ {
+ Gdk::Rectangle rect;
+ tree_view.get_cell_area(path,*column,rect);
+ cellrenderer_time_track->property_value_desc()=row[model.value_desc];
+ cellrenderer_time_track->property_canvas()=row[model.canvas];
+ cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+ queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+ return true;
+ }
+ else if(column->get_first_cell_renderer()==cellrenderer_value)
+ return signal_user_click()(event->button.button,row,COLUMNID_VALUE);
+ else
+ return signal_user_click()(event->button.button,row,COLUMNID_ID);
+
+ }
+ break;
+
+ case GDK_MOTION_NOTIFY:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!tree_view.get_path_at_pos(
+ (int)event->button.x,(int)event->button.y, // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+
+ if(!tree_view.get_model()->get_iter(path))
+ break;
+
+ Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+
+ if(cellrenderer_time_track==column->get_first_cell_renderer())
+ {
+ // Movement on TimeLine
+ Gdk::Rectangle rect;
+ tree_view.get_cell_area(path,*column,rect);
+ cellrenderer_time_track->property_value_desc()=row[model.value_desc];
+ cellrenderer_time_track->property_canvas()=row[model.canvas];
+ cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+ queue_draw();
+ //queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+ return true;
+ }
+ else
+ if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
+ {
+ tooltips_.unset_tip(*this);
+ Glib::ustring tooltips_string(row[model.tooltip]);
+ last_tooltip_path=path;
+ if(!tooltips_string.empty())
+ {
+ tooltips_.set_tip(*this,tooltips_string);
+ tooltips_.force_window();
+ }
+ }
+ }
+ break;
+ case GDK_BUTTON_RELEASE:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!tree_view.get_path_at_pos(
+ (int)event->button.x,(int)event->button.y, // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+
+ if(!tree_view.get_model()->get_iter(path))
+ break;
+
+ Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+
+ if(column && cellrenderer_time_track == column->get_first_cell_renderer())
+ {
+ Gdk::Rectangle rect;
+ tree_view.get_cell_area(path,*column,rect);
+ cellrenderer_time_track->property_value_desc()=row[model.value_desc];
+ cellrenderer_time_track->property_canvas()=row[model.canvas];
+ cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+ queue_draw();
+ queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+ return true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void
+ChildrenTree::on_raise_pressed()
+{
+}
+
+void
+ChildrenTree::on_lower_pressed()
+{
+}
+
+void
+ChildrenTree::on_duplicate_pressed()
+{
+}
+
+void
+ChildrenTree::on_delete_pressed()
+{
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trees/childrentree.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_CHILDRENTREE_H
+#define __SYNFIG_STUDIO_CHILDRENTREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/box.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/scale.h>
+#include <gtkmm/button.h>
+
+#include <synfigapp/canvasinterface.h>
+#include <synfigapp/value_desc.h>
+#include "trees/childrentreestore.h"
+#include <synfig/valuenode_animated.h>
+
+#include "widgets/widget_value.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CellRenderer_TimeTrack;
+class CellRenderer_ValueBase;
+
+class ChildrenTree : public Gtk::Table
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+
+ typedef studio::ColumnID ColumnID;
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ ChildrenTreeStore::Model model;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ Gtk::Tooltips tooltips_;
+
+ Gtk::TreePath last_tooltip_path;
+
+ Gtk::TreeView tree_view;
+
+ Gtk::HBox *hbox;
+
+ Glib::RefPtr<ChildrenTreeStore> children_tree_store_;
+
+ CellRenderer_TimeTrack *cellrenderer_time_track;
+
+ Gtk::TreeView::Column* column_time_track;
+
+ CellRenderer_ValueBase *cellrenderer_value;
+
+ sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase> signal_edited_value_;
+
+ sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_user_click_;
+
+ sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int> signal_waypoint_clicked_childrentree_;
+
+ Gtk::Button *button_raise;
+ Gtk::Button *button_lower;
+ Gtk::Button *button_duplicate;
+ Gtk::Button *button_delete;
+
+ Widget_ValueBase blend_method_widget;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ void on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value);
+
+ void on_waypoint_clicked_childrentree(const etl::handle<synfig::Node>& node,const synfig::Time&,const synfig::Time&,int button);
+
+ bool on_tree_event(GdkEvent *event);
+
+ void on_selection_changed();
+
+ void on_dirty_preview();
+
+ //! \todo Implement raise/lower/duplicate/delete functions
+ void on_raise_pressed();
+
+ void on_lower_pressed();
+
+ void on_duplicate_pressed();
+
+ void on_delete_pressed();
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ Gtk::HBox& get_hbox() { return *hbox; }
+
+ Gtk::TreeView& get_tree_view() { return tree_view; }
+
+ Glib::RefPtr<Gtk::TreeSelection> get_selection() { return tree_view.get_selection(); }
+ Glib::SignalProxy1< bool,GdkEvent* > signal_event () { return tree_view.signal_event(); }
+
+ ChildrenTree();
+ ~ChildrenTree();
+
+ void set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store_);
+
+ void set_time_adjustment(Gtk::Adjustment &adjustment);
+
+ void set_show_timetrack(bool x=true);
+
+ //! Signal called with a value has been edited.
+ sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase>& signal_edited_value() { return signal_edited_value_; }
+
+ sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_user_click() { return signal_user_click_; }
+
+ sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int>& signal_waypoint_clicked_childrentree() { return signal_waypoint_clicked_childrentree_; }
+
+ etl::handle<synfigapp::SelectionManager> get_selection_manager() { return children_tree_store_->canvas_interface()->get_selection_manager(); }
+
+}; // END of ChildrenTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file childrentreestore.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trees/childrentreestore.h"
+#include "iconcontroller.h"
+#include <gtkmm/button.h>
+#include <synfig/paramdesc.h>
+#include <ETL/clock>
+
+#include "general.h"
+
+class Profiler : private etl::clock
+{
+ const std::string name;
+public:
+ Profiler(const std::string& name):name(name) { reset(); }
+ ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
+};
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static ChildrenTreeStore::Model& ModelHack()
+{
+ static ChildrenTreeStore::Model* model(0);
+ if(!model)model=new ChildrenTreeStore::Model;
+ return *model;
+}
+
+ChildrenTreeStore::ChildrenTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+ Gtk::TreeStore (ModelHack()),
+ CanvasTreeStore (canvas_interface_)
+{
+ canvas_row=*append();
+ canvas_row[model.label]=_("Canvases");
+ canvas_row[model.is_canvas] = false;
+ canvas_row[model.is_value_node] = false;
+
+ value_node_row=*append();
+ value_node_row[model.label]=_("ValueBase Nodes");
+ value_node_row[model.is_canvas] = false;
+ value_node_row[model.is_value_node] = false;
+
+ // Connect all the signals
+ canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_changed));
+ canvas_interface()->signal_value_node_renamed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_renamed));
+ canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_added));
+ canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_deleted));
+ canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_replaced));
+ canvas_interface()->signal_canvas_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_added));
+ canvas_interface()->signal_canvas_removed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_removed));
+
+ rebuild();
+}
+
+ChildrenTreeStore::~ChildrenTreeStore()
+{
+}
+
+Glib::RefPtr<ChildrenTreeStore>
+ChildrenTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
+{
+ return Glib::RefPtr<ChildrenTreeStore>(new ChildrenTreeStore(canvas_interface_));
+}
+
+void
+ChildrenTreeStore::rebuild()
+{
+ // Profiler profiler("ChildrenTreeStore::rebuild()");
+ rebuild_value_nodes();
+ rebuild_canvases();
+}
+
+void
+ChildrenTreeStore::refresh()
+{
+ // Profiler profiler("ChildrenTreeStore::refresh()");
+ refresh_value_nodes();
+ refresh_canvases();
+}
+
+void
+ChildrenTreeStore::rebuild_value_nodes()
+{
+ Gtk::TreeModel::Children children(value_node_row.children());
+
+ while(!children.empty())erase(children.begin());
+
+ clear_changed_queue();
+
+ std::for_each(
+ canvas_interface()->get_canvas()->value_node_list().rbegin(), canvas_interface()->get_canvas()->value_node_list().rend(),
+ sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_value_node_added)
+ );
+}
+
+void
+ChildrenTreeStore::refresh_value_nodes()
+{
+ Gtk::TreeModel::Children children(value_node_row.children());
+
+ Gtk::TreeModel::Children::iterator iter;
+
+ if(!children.empty())
+ for(iter = children.begin(); iter != children.end(); ++iter)
+ {
+ Gtk::TreeRow row=*iter;
+ refresh_row(row);
+ }
+}
+
+void
+ChildrenTreeStore::rebuild_canvases()
+{
+ Gtk::TreeModel::Children children(canvas_row.children());
+
+ while(!children.empty())erase(children.begin());
+
+ std::for_each(
+ canvas_interface()->get_canvas()->children().rbegin(), canvas_interface()->get_canvas()->children().rend(),
+ sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_canvas_added)
+ );
+}
+
+void
+ChildrenTreeStore::refresh_canvases()
+{
+ rebuild_canvases();
+}
+
+void
+ChildrenTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool /*do_children*/)
+{
+ CanvasTreeStore::refresh_row(row,false);
+
+ if((bool)row[model.is_value_node])
+ {
+ changed_set_.erase(row[model.value_node]);
+ }
+
+}
+
+void
+ChildrenTreeStore::on_canvas_added(synfig::Canvas::Handle canvas)
+{
+ Gtk::TreeRow row = *(prepend(canvas_row.children()));
+
+ row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("synfig-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+ row[model.id] = canvas->get_id();
+ row[model.name] = canvas->get_name();
+
+ if(!canvas->get_id().empty())
+ row[model.label] = canvas->get_id();
+ else
+ if(!canvas->get_name().empty())
+ row[model.label] = canvas->get_name();
+ else
+ row[model.label] = _("[Unnamed]");
+
+ row[model.canvas] = canvas;
+ row[model.type] = _("Canvas");
+ //row[model.is_canvas] = true;
+ //row[model.is_value_node] = false;
+}
+
+void
+ChildrenTreeStore::on_canvas_removed(synfig::Canvas::Handle /*canvas*/)
+{
+ rebuild_canvases();
+}
+
+void
+ChildrenTreeStore::on_value_node_added(synfig::ValueNode::Handle value_node)
+{
+// if(value_node->get_id().find("Unnamed")!=String::npos)
+// return;
+
+ Gtk::TreeRow row = *prepend(value_node_row.children());
+
+ set_row(row,synfigapp::ValueDesc(canvas_interface()->get_canvas(),value_node->get_id()),false);
+}
+
+void
+ChildrenTreeStore::on_value_node_deleted(synfig::ValueNode::Handle value_node)
+{
+ Gtk::TreeIter iter;
+ //int i(0);
+
+ if(find_first_value_node(value_node,iter))
+ {
+ erase(iter);
+ }
+ //rebuild_value_nodes();
+}
+
+bool
+ChildrenTreeStore::execute_changed_value_nodes()
+{
+ // Profiler profiler("ChildrenTreeStore::execute_changed_value_nodes()");
+ if(!replaced_set_.empty())
+ rebuild_value_nodes();
+
+ etl::clock timer;
+ timer.reset();
+
+ while(!changed_set_.empty())
+ {
+ ValueNode::Handle value_node(*changed_set_.begin());
+ changed_set_.erase(value_node);
+
+ Gtk::TreeIter iter;
+
+ try
+ {
+ Gtk::TreeIter iter;
+ int i(0);
+
+ if(!value_node->is_exported() && find_first_value_node(value_node,iter))
+ {
+ rebuild_value_nodes();
+ continue;
+ }
+
+ if(value_node->is_exported() && find_first_value_node(value_node,iter)) do
+ {
+ Gtk::TreeRow row(*iter);
+ i++;
+ refresh_row(row);
+ }while(find_next_value_node(value_node,iter));
+
+ if(!i)
+ {
+ refresh_value_nodes();
+ return false;
+ }
+
+ }
+ catch(...)
+ {
+ rebuild_value_nodes();
+ return false;
+ }
+
+ // If we are taking too long...
+ if(timer()>4)
+ {
+ refresh_value_nodes();
+ return false;
+ }
+ }
+
+ return false;
+}
+
+void
+ChildrenTreeStore::on_value_node_changed(synfig::ValueNode::Handle value_node)
+{
+
+ if(!value_node->is_exported())
+ return;
+ changed_connection.disconnect();
+// if(!execute_changed_queued())
+// changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
+ changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
+
+ changed_set_.insert(value_node);
+ /*
+ try
+ {
+ Gtk::TreeIter iter;
+ int i(0);
+ while(find_next_value_node(value_node,iter))
+ {
+ Gtk::TreeRow row(*iter);
+ i++;
+ refresh_row(row);
+ }
+ if(!i)
+ {
+ refresh_value_nodes();
+ }
+ }
+ catch(...)
+ {
+ rebuild_value_nodes();
+ }
+ */
+}
+
+void
+ChildrenTreeStore::on_value_node_renamed(synfig::ValueNode::Handle value_node __attribute__ ((unused)))
+{
+ rebuild_value_nodes();
+}
+
+void
+ChildrenTreeStore::on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle /*new_value_node*/)
+{
+ changed_connection.disconnect();
+ //if(!execute_changed_queued())
+// changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
+ changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
+
+ replaced_set_.insert(replaced_value_node);
+}
+
+void
+ChildrenTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+ if(column>=get_n_columns_vfunc())
+ {
+ g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
+ return;
+ }
+
+ if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+ {
+ g_warning("LayerTreeStore::set_value_impl: Bad value type");
+ return;
+ }
+
+ try
+ {
+ if(column==model.value.index())
+ {
+ Glib::Value<synfig::ValueBase> x;
+ g_value_init(x.gobj(),model.value.type());
+ g_value_copy(value.gobj(),x.gobj());
+
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+ if(value_desc)
+ {
+ canvas_interface()->change_value(value_desc,x.get());
+ row_changed(get_path(*iter),*iter);
+ }
+
+ return;
+ }
+ else
+ CanvasTreeStore::set_value_impl(iter,column, value);
+ }
+ catch(std::exception x)
+ {
+ g_warning("%s", x.what());
+ }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trees/childrentreestore.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_CHILDRENTREESTORE_H
+#define __SYNFIG_STUDIO_CHILDRENTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include "trees/canvastreestore.h"
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class ChildrenTreeStore : public CanvasTreeStore
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ //! TreeModel for the layers
+ const Model model;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ Gtk::TreeModel::Row value_node_row;
+ Gtk::TreeModel::Row canvas_row;
+
+ std::set<synfig::ValueNode::Handle> changed_set_;
+
+ std::set<synfig::ValueNode::Handle> replaced_set_;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+ sigc::connection changed_connection;
+ bool execute_changed_queued()const { return !changed_set_.empty() || !replaced_set_.empty(); }
+ bool execute_changed_value_nodes();
+ void clear_changed_queue() { changed_set_.clear(); replaced_set_.clear(); }
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ void on_value_node_added(synfig::ValueNode::Handle value_node);
+ void on_value_node_deleted(synfig::ValueNode::Handle value_node);
+ void on_value_node_changed(synfig::ValueNode::Handle value_node);
+ void on_value_node_renamed(synfig::ValueNode::Handle value_node);
+ void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
+ void on_canvas_added(synfig::Canvas::Handle canvas);
+ void on_canvas_removed(synfig::Canvas::Handle canvas);
+
+ void set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value);
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ ChildrenTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+ ~ChildrenTreeStore();
+
+ void rebuild();
+
+ void refresh();
+
+ void rebuild_value_nodes();
+
+ void refresh_value_nodes();
+
+ void rebuild_canvases();
+
+ void refresh_canvases();
+
+ void refresh_row(Gtk::TreeModel::Row &row, bool do_children=false);
+
+ Gtk::TreeModel::Row get_canvas_row()const { return canvas_row; }
+
+ Gtk::TreeModel::Row get_value_node_row()const { return value_node_row; }
+
+ /*
+ -- ** -- S T A T I C P U B L I C M E T H O D S ---------------------------
+ */
+
+public:
+
+ static Glib::RefPtr<ChildrenTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+}; // END of class ChildrenTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file historytreestore.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trees/historytreestore.h"
+#include <synfig/valuenode.h>
+#include "iconcontroller.h"
+#include <synfig/valuenode_timedswap.h>
+#include <gtkmm/button.h>
+#include <synfigapp/action.h>
+#include "instance.h"
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static HistoryTreeStore::Model& ModelHack()
+{
+ static HistoryTreeStore::Model* model(0);
+ if(!model)model=new HistoryTreeStore::Model;
+ return *model;
+}
+
+HistoryTreeStore::HistoryTreeStore(etl::loose_handle<studio::Instance> instance_):
+ Gtk::TreeStore (ModelHack()),
+ instance_ (instance_)
+{
+ instance_->signal_undo().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_undo));
+ instance_->signal_redo().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_redo));
+ instance_->signal_undo_stack_cleared().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_undo_stack_cleared));
+ instance_->signal_redo_stack_cleared().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_redo_stack_cleared));
+ instance_->signal_new_action().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_new_action));
+ instance_->signal_action_status_changed().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_action_status_changed));
+}
+
+HistoryTreeStore::~HistoryTreeStore()
+{
+ if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+ synfig::info("HistoryTreeStore::~HistoryTreeStore(): Deleted");
+}
+
+Glib::RefPtr<HistoryTreeStore>
+HistoryTreeStore::create(etl::loose_handle<studio::Instance> instance_)
+{
+ return Glib::RefPtr<HistoryTreeStore>(new HistoryTreeStore(instance_));
+}
+
+void
+HistoryTreeStore::rebuild()
+{
+ synfigapp::Action::Stack::const_iterator iter;
+
+ clear();
+
+ for(iter=instance()->undo_action_stack().begin();iter!=instance()->undo_action_stack().end();++iter)
+ {
+ insert_action(*(prepend()),*iter,true,true,false);
+ }
+ curr_row=*children().end();
+ for(iter=instance()->redo_action_stack().begin();iter!=instance()->redo_action_stack().end();++iter)
+ {
+ insert_action(*(append()),*iter,true,false,true);
+ }
+
+ signal_undo_tree_changed()();
+}
+
+void
+HistoryTreeStore::insert_action(Gtk::TreeRow row,etl::handle<synfigapp::Action::Undoable> action, bool /*is_active*/, bool is_undo, bool is_redo)
+{
+ assert(action);
+
+ row[model.action] = action;
+ row[model.name] = static_cast<Glib::ustring>(action->get_local_name());
+ row[model.is_active] = action->is_active();
+ row[model.is_undo] = is_undo;
+ row[model.is_redo] = is_redo;
+
+ synfigapp::Action::CanvasSpecific *specific_action;
+ specific_action=dynamic_cast<synfigapp::Action::CanvasSpecific*>(action.get());
+ if(specific_action)
+ {
+ row[model.canvas] = specific_action->get_canvas();
+ row[model.canvas_id] = specific_action->get_canvas()->get_id();
+ }
+
+ etl::handle<synfigapp::Action::Group> group;
+ group=etl::handle<synfigapp::Action::Group>::cast_dynamic(action);
+ if(group)
+ {
+ synfigapp::Action::ActionList::const_iterator iter;
+ for(iter=group->action_list().begin();iter!=group->action_list().end();++iter)
+ {
+ Gtk::TreeRow child_row = *(append(row.children()));
+ insert_action(child_row,*iter,true,is_undo,is_redo);
+ }
+ }
+
+ //row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("synfig-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+}
+
+
+void
+HistoryTreeStore::on_undo()
+{
+ refresh();
+}
+
+void
+HistoryTreeStore::on_redo()
+{
+ refresh();
+}
+
+void
+HistoryTreeStore::on_undo_stack_cleared()
+{
+ Gtk::TreeModel::Children::iterator iter,next;
+ Gtk::TreeModel::Children children_(children());
+
+ for(next=children_.begin(),iter=next++; iter != children_.end(); iter=(next!=children_.end())?next++:next)
+ {
+ Gtk::TreeModel::Row row = *iter;
+ if(row[model.is_undo])
+ erase(iter);
+ }
+}
+
+void
+HistoryTreeStore::on_redo_stack_cleared()
+{
+ Gtk::TreeModel::Children::iterator iter,next;
+ Gtk::TreeModel::Children children_(children());
+
+ for(next=children_.begin(),iter=next++; iter != children_.end(); iter=(next!=children_.end())?next++:next)
+ {
+ Gtk::TreeModel::Row row = *iter;
+ if(row[model.is_redo])
+ erase(iter);
+ }
+}
+
+void
+HistoryTreeStore::on_new_action(etl::handle<synfigapp::Action::Undoable> action)
+{
+// Gtk::TreeRow row = *(append());
+ Gtk::TreeRow row;
+ Gtk::TreeModel::Children::iterator iter;
+ for(iter=children().begin(); iter != children().end(); ++iter)
+ {
+ Gtk::TreeModel::Row row = *iter;
+ if(row[model.is_redo])
+ {
+ break;
+ }
+ }
+
+ row=*insert(iter);
+
+ insert_action(row,action);
+
+ signal_undo_tree_changed()();
+}
+
+void
+HistoryTreeStore::on_action_status_changed(etl::handle<synfigapp::Action::Undoable> action)
+{
+ Gtk::TreeModel::Children::iterator iter;
+ Gtk::TreeModel::Children children_(children());
+
+ for(iter=children_.begin(); iter != children_.end(); ++iter)
+ {
+ Gtk::TreeModel::Row row = *iter;
+ if(action == (etl::handle<synfigapp::Action::Undoable>)row[model.action])
+ {
+ row[model.is_active]=action->is_active();
+ return;
+ }
+ }
+}
+
+bool
+HistoryTreeStore::search_func(const Glib::RefPtr<Gtk::TreeModel>&,int,const Glib::ustring& x,const Gtk::TreeModel::iterator& iter)
+{
+ const Model model;
+
+ Glib::ustring substr(x.uppercase());
+ Glib::ustring name((*iter)[model.name]);
+ name=name.uppercase();
+
+ return name.find(substr)==Glib::ustring::npos;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trees/historytreestore.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_HISTORYTREESTORE_H
+#define __SYNFIG_STUDIO_HISTORYTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <synfigapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Instance;
+
+class HistoryTreeStore : virtual public Gtk::TreeStore
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+
+ class Model : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ public:
+ Gtk::TreeModelColumn<etl::handle<synfigapp::Action::Undoable> > action;
+ Gtk::TreeModelColumn<Glib::ustring> name;
+ Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+ Gtk::TreeModelColumn<bool> is_active;
+ Gtk::TreeModelColumn<bool> is_undo;
+ Gtk::TreeModelColumn<bool> is_redo;
+
+ Gtk::TreeModelColumn<Glib::ustring> canvas_id;
+ Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
+
+ Model()
+ {
+ add(action);
+ add(name);
+ add(icon);
+ add(is_active);
+ add(is_undo);
+ add(is_redo);
+ add(canvas_id);
+ add(canvas);
+ }
+ };
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ const Model model;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ etl::loose_handle<studio::Instance> instance_;
+ Gtk::TreeIter curr_row;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ sigc::signal<void> signal_undo_tree_changed_;
+
+ /*
+ -- ** -- S I G N A L I N T E R F A C E S -----------------------------------
+ */
+
+public:
+
+ sigc::signal<void>& signal_undo_tree_changed() { return signal_undo_tree_changed_; }
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ void on_undo();
+
+ void on_redo();
+
+ void on_undo_stack_cleared();
+
+ void on_redo_stack_cleared();
+
+ void on_new_action(etl::handle<synfigapp::Action::Undoable> action);
+
+ void on_action_status_changed(etl::handle<synfigapp::Action::Undoable> action);
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ HistoryTreeStore(etl::loose_handle<studio::Instance> instance_);
+ ~HistoryTreeStore();
+
+ etl::loose_handle<studio::Instance> instance() { return instance_; }
+ etl::loose_handle<const studio::Instance> instance()const { return instance_; }
+
+ void rebuild();
+
+ void refresh() { rebuild(); }
+
+ void insert_action(Gtk::TreeRow row,etl::handle<synfigapp::Action::Undoable> action, bool is_active=true, bool is_undo=true, bool is_redo=false);
+
+ static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
+
+ /*
+ -- ** -- P R O T E C T E D M E T H O D S -----------------------------------
+ */
+
+public:
+
+ static Glib::RefPtr<HistoryTreeStore> create(etl::loose_handle<studio::Instance> instance);
+
+}; // END of class HistoryTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file keyframetree.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trees/keyframetree.h"
+#include "cellrenderer_time.h"
+#include <gtkmm/treemodelsort.h>
+#include <ETL/misc>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+KeyframeTree::KeyframeTree()
+{
+ const KeyframeTreeStore::Model model;
+
+ {
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time")) );
+
+ cell_renderer_time = Gtk::manage( new CellRenderer_Time() );
+ column->pack_start(*cell_renderer_time,true);
+ column->add_attribute(cell_renderer_time->property_time(), model.time);
+ cell_renderer_time->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_time));
+
+ column->set_reorderable();
+ column->set_resizable();
+ column->set_clickable();
+ column->set_sort_column(model.time);
+
+ append_column(*column);
+ }
+ {
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Length")) );
+
+ cell_renderer_time_delta = Gtk::manage( new CellRenderer_Time() );
+ column->pack_start(*cell_renderer_time_delta,true);
+ column->add_attribute(cell_renderer_time_delta->property_time(), model.time_delta);
+ cell_renderer_time_delta->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_time_delta));
+
+ column->set_reorderable();
+ column->set_resizable();
+ column->set_clickable(false);
+ // column->set_sort_column(model.time_delta);
+
+ append_column(*column);
+ }
+ {
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Jump")) );
+
+ Gtk::CellRendererText* cell_renderer_jump=Gtk::manage(new Gtk::CellRendererText());
+ column->pack_start(*cell_renderer_jump,true);
+ cell_renderer_jump->property_text()=_("(JMP)");
+ cell_renderer_jump->property_foreground()="#003a7f";
+
+ column->set_reorderable();
+ column->set_resizable();
+ column->set_clickable(false);
+ column->set_sort_column(COLUMNID_JUMP); // without this, (JMP) needs a double click?!
+
+ append_column(*column);
+ }
+ {
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Description")) );
+
+ cell_renderer_description=Gtk::manage(new Gtk::CellRendererText());
+ column->pack_start(*cell_renderer_description,true);
+ column->add_attribute(cell_renderer_description->property_text(), model.description);
+ cell_renderer_description->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_description));
+
+ column->set_reorderable();
+ column->set_resizable();
+ column->set_clickable();
+ column->set_sort_column(model.description);
+
+ append_column(*column);
+ }
+
+ set_enable_search(true);
+ set_search_column(model.description);
+
+ // This makes things easier to read.
+ set_rules_hint();
+
+ // Make us more sensitive to several events
+ add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+}
+
+KeyframeTree::~KeyframeTree()
+{
+ if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+ synfig::info("KeyframeTree::~KeyframeTree(): Deleted");
+}
+
+void
+KeyframeTree::on_rend_desc_changed()
+{
+ cell_renderer_time->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
+ queue_draw();
+}
+
+void
+KeyframeTree::set_model(Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store)
+{
+ keyframe_tree_store_=keyframe_tree_store;
+ KeyframeTreeStore::Model model;
+
+ if(true)
+ {
+ Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(keyframe_tree_store_));
+ sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::KeyframeTreeStore::time_sorter));
+ sorted_store->set_sort_func(model.time, sigc::ptr_fun(&studio::KeyframeTreeStore::time_sorter));
+ sorted_store->set_sort_func(model.description, sigc::ptr_fun(&studio::KeyframeTreeStore::description_sorter));
+ Gtk::TreeView::set_model(sorted_store);
+ }
+ else
+ Gtk::TreeView::set_model(keyframe_tree_store);
+
+ keyframe_tree_store_->canvas_interface()->signal_rend_desc_changed().connect(
+ sigc::mem_fun(
+ *this,
+ &studio::KeyframeTree::on_rend_desc_changed
+ )
+ );
+ cell_renderer_time->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
+ cell_renderer_time_delta->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
+}
+
+void
+KeyframeTree::set_editable(bool x)
+{
+ editable_=x;
+
+ if(editable_)
+ {
+ cell_renderer_time->property_editable()=true;
+ cell_renderer_time_delta->property_editable()=true;
+ cell_renderer_description->property_editable()=true;
+ }
+ else
+ {
+ cell_renderer_time->property_editable()=false;
+ cell_renderer_time_delta->property_editable()=false;
+ cell_renderer_description->property_editable()=false;
+ }
+}
+
+void
+KeyframeTree::on_edited_time(const Glib::ustring&path_string,synfig::Time time)
+{
+ Gtk::TreePath path(path_string);
+
+ const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+
+ synfig::Keyframe keyframe(row[model.keyframe]);
+ if(time!=keyframe.get_time())
+ {
+ row[model.time]=time;
+ //keyframe.set_time(time);
+ //signal_edited_time()(keyframe,time);
+ //signal_edited()(keyframe);
+ }
+}
+
+void
+KeyframeTree::on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time)
+{
+ Gtk::TreePath path(path_string);
+
+ const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+
+ if(row)row[model.time_delta]=time;
+}
+
+void
+KeyframeTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
+{
+ Gtk::TreePath path(path_string);
+
+ const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+ const synfig::String description(desc);
+ synfig::Keyframe keyframe(row[model.keyframe]);
+ if(description!=keyframe.get_description())
+ {
+ row[model.description]=desc;
+ keyframe.set_description(description);
+ signal_edited_description()(keyframe,description);
+ signal_edited()(keyframe);
+ }
+}
+
+bool
+KeyframeTree::on_event(GdkEvent *event)
+{
+ switch(event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
+ //tree_to_widget_coords (,, wx, wy);
+ if(!get_path_at_pos(
+ wx,wy, // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+ const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+ signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
+ if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
+ {
+ keyframe_tree_store_->canvas_interface()->set_time(row[model.time]);
+ }
+ }
+ break;
+ case GDK_2BUTTON_PRESS:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!get_path_at_pos(
+ int(event->button.x),int(event->button.y), // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+ const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+ {
+ keyframe_tree_store_->canvas_interface()->set_time(row[model.time]);
+ return true;
+ }
+ }
+ break;
+
+ case GDK_BUTTON_RELEASE:
+ break;
+ default:
+ break;
+ }
+ return false;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trees/keyframetree.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_KEYFRAMETREE_H
+#define __SYNFIG_STUDIO_KEYFRAMETREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <synfigapp/value_desc.h>
+#include "trees/keyframetreestore.h"
+#include <synfig/keyframe.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CellRenderer_Time;
+
+class KeyframeTree : public Gtk::TreeView
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+
+ enum ColumnID
+ {
+ COLUMNID_TIME,
+ COLUMNID_DESCRIPTION,
+ COLUMNID_JUMP,
+
+ COLUMNID_END //!< \internal
+ };
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ KeyframeTreeStore::Model model;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_;
+
+ CellRenderer_Time *cell_renderer_time;
+
+ CellRenderer_Time *cell_renderer_time_delta;
+
+ Gtk::CellRendererText *cell_renderer_description;
+
+ sigc::signal<void,synfig::Keyframe> signal_edited_;
+
+ sigc::signal<void,synfig::Keyframe,synfig::Time> signal_edited_time_;
+
+ sigc::signal<void,synfig::Keyframe,synfig::String> signal_edited_description_;
+
+ sigc::signal<void, int, Gtk::TreeRow, ColumnID> signal_user_click_;
+
+ bool editable_;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ void on_edited_time(const Glib::ustring&path_string,synfig::Time time);
+
+ void on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time);
+
+ void on_edited_description(const Glib::ustring&path_string,const Glib::ustring &description);
+
+ bool on_event(GdkEvent *event);
+
+ void on_rend_desc_changed();
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ KeyframeTree();
+ ~KeyframeTree();
+
+ void set_model(Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_);
+
+ void set_editable(bool x=true);
+
+ bool get_editable()const { return editable_; }
+
+ //! Signal called when a keyframe has been edited in any way
+ sigc::signal<void,synfig::Keyframe>& signal_edited() { return signal_edited_; }
+
+ //! Signal called when a time has been edited.
+ sigc::signal<void,synfig::Keyframe,synfig::Time>& signal_edited_time() { return signal_edited_time_; }
+
+ //! Signal called when a description has been edited.
+ sigc::signal<void,synfig::Keyframe,synfig::String>& signal_edited_description() { return signal_edited_description_; }
+
+ sigc::signal<void,int, Gtk::TreeRow, ColumnID>& signal_user_click() { return signal_user_click_; }
+}; // END of KeyframeTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file keyframetreestore.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007, 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trees/keyframetreestore.h"
+#include <synfig/valuenode.h>
+#include "iconcontroller.h"
+#include <synfig/valuenode_timedswap.h>
+#include <gtkmm/button.h>
+#include <gtkmm/treerowreference.h>
+#include <synfig/canvas.h>
+#include <synfig/keyframe.h>
+#include <time.h>
+#include <cstdlib>
+#include <ETL/smart_ptr>
+#include <synfigapp/action.h>
+#include <synfigapp/instance.h>
+#include "onemoment.h"
+#include <synfig/exception.h>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+// KeyframeTreeStore_Class KeyframeTreeStore::keyframe_tree_store_class_;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+struct _keyframe_iterator
+{
+ synfig::KeyframeList::iterator iter;
+ int ref_count;
+ int index;
+};
+
+/*
+Gtk::TreeModel::iterator keyframe_iter_2_model_iter(synfig::KeyframeList::iterator iter,int index)
+{
+ Gtk::TreeModel::iterator ret;
+
+ _keyframe_iterator*& data(static_cast<_keyframe_iterator*&>(ret->gobj()->user_data));
+ data=new _keyframe_iterator();
+ data->ref_count=1;
+ data->iter=iter;
+ data->index=index;
+
+ return ret;
+}
+*/
+
+synfig::KeyframeList::iterator model_iter_2_keyframe_iter(Gtk::TreeModel::iterator iter)
+{
+ _keyframe_iterator* data(static_cast<_keyframe_iterator*>(iter->gobj()->user_data));
+ if(!data)
+ throw std::runtime_error("bad data");
+ return data->iter;
+}
+
+int get_index_from_model_iter(Gtk::TreeModel::iterator iter)
+{
+ _keyframe_iterator* data(static_cast<_keyframe_iterator*>(iter->gobj()->user_data));
+ if(!data)
+ throw std::runtime_error("bad data");
+ return data->index;
+}
+
+
+/*
+#ifndef TreeRowReferenceHack
+class TreeRowReferenceHack
+{
+ GtkTreeRowReference *gobject_;
+public:
+ TreeRowReferenceHack():
+ gobject_(0)
+ {
+ }
+
+ TreeRowReferenceHack(const Glib::RefPtr<Gtk::TreeModel>& model, const Gtk::TreeModel::Path& path):
+ gobject_ ( gtk_tree_row_reference_new(model->gobj(), const_cast<GtkTreePath*>(path.gobj())) )
+ {
+ }
+
+ TreeRowReferenceHack(const TreeRowReferenceHack &x):
+ gobject_ ( x.gobject_?gtk_tree_row_reference_copy(x.gobject_):0 )
+ {
+
+ }
+
+ void swap(TreeRowReferenceHack & other)
+ {
+ GtkTreeRowReference *const temp = gobject_;
+ gobject_ = other.gobject_;
+ other.gobject_ = temp;
+ }
+
+ const TreeRowReferenceHack &
+ operator=(const TreeRowReferenceHack &rhs)
+ {
+ TreeRowReferenceHack temp (rhs);
+ swap(temp);
+ return *this;
+ }
+
+ ~TreeRowReferenceHack()
+ {
+ if(gobject_)
+ gtk_tree_row_reference_free(gobject_);
+ }
+
+ Gtk::TreeModel::Path get_path() { return Gtk::TreeModel::Path(gtk_tree_row_reference_get_path(gobject_),false); }
+ GtkTreeRowReference *gobj() { return gobject_; }
+};
+#endif
+*/
+
+/* === P R O C E D U R E S ================================================= */
+
+void clear_iterator(GtkTreeIter* iter)
+{
+ iter->stamp=0;
+ iter->user_data=iter->user_data2=iter->user_data3=0;
+}
+
+/* === M E T H O D S ======================================================= */
+
+const Glib::Class&
+KeyframeTreeStore_Class::init()
+{
+ if(!gtype_)
+ {
+ class_init_func_ = &KeyframeTreeStore_Class::class_init_function;
+
+ const GTypeInfo derived_info =
+ {
+ sizeof(GObjectClass),
+ NULL,
+ NULL,
+ class_init_func_,
+ NULL,
+ NULL,
+ sizeof(GObject),
+ 0,
+ 0,
+ NULL
+ };
+
+ gtype_ = g_type_register_static(G_TYPE_OBJECT, "KeyframeTreeStore", &derived_info, GTypeFlags(0));
+ Gtk::TreeModel::add_interface(get_type());
+ }
+ return *this;
+}
+
+void
+KeyframeTreeStore_Class::class_init_function(gpointer /*g_class*/, gpointer /*class_data*/)
+{
+ // ???
+}
+
+KeyframeTreeStore::KeyframeTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+ Glib::ObjectBase ("KeyframeTreeStore"),
+ //! \todo what is going on here? why the need for this KeyframeTreeStore_Class at all?
+ // Glib::Object (Glib::ConstructParams(keyframe_tree_store_class_.init(), (char*) 0, (char*) 0)),
+ canvas_interface_ (canvas_interface_)
+{
+ reset_stamp();
+ //reset_path_table();
+
+ canvas_interface()->signal_keyframe_added().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::add_keyframe));
+ canvas_interface()->signal_keyframe_removed().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::remove_keyframe));
+ canvas_interface()->signal_keyframe_changed().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::change_keyframe));
+}
+
+KeyframeTreeStore::~KeyframeTreeStore()
+{
+ if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+ synfig::info("KeyframeTreeStore::~KeyframeTreeStore(): Deleted");
+}
+
+Glib::RefPtr<KeyframeTreeStore>
+KeyframeTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
+{
+ KeyframeTreeStore *store(new KeyframeTreeStore(canvas_interface_));
+ Glib::RefPtr<KeyframeTreeStore> ret(store);
+ assert(ret);
+ return ret;
+}
+
+void
+KeyframeTreeStore::reset_stamp()
+{
+ stamp_=time(0)+reinterpret_cast<long>(this);
+}
+
+/*
+void
+KeyframeTreeStore::reset_path_table()
+{
+ Gtk::TreeModel::Children::iterator iter;
+ const Gtk::TreeModel::Children children(children());
+ path_table_.clear();
+ for(iter = children.begin(); iter != children.end(); ++iter)
+ {
+ Gtk::TreeModel::Row row(*iter);
+ path_table_[(Keyframe)row[model.keyframe]]=TreeRowReferenceHack(Glib::RefPtr<KeyframeTreeStore>(this),Gtk::TreePath(row));
+ }
+}
+*/
+
+
+inline bool
+KeyframeTreeStore::iterator_sane(const GtkTreeIter* iter)const
+{
+ if(iter && iter->stamp==stamp_)
+ return true;
+ g_warning("KeyframeTreeStore::iterator_sane(): Bad iterator stamp");
+ return false;
+}
+
+inline bool
+KeyframeTreeStore::iterator_sane(const Gtk::TreeModel::iterator& iter)const
+{
+ return iterator_sane(iter->gobj());
+}
+
+inline void
+KeyframeTreeStore::dump_iterator(const GtkTreeIter* /*gtk_iter*/, const Glib::ustring &/*name*/)const
+{
+#if 0
+ if(!gtk_iter)
+ {
+ g_warning("KeyframeTreeStore::dump_iterator: \"%s\" is NULL (Root?)",name.c_str());
+ return;
+ }
+
+ _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+
+ if(gtk_iter->stamp!=stamp_ || !iter)
+ {
+ g_warning("KeyframeTreeStore::dump_iterator: \"%s\" is INVALID",name.c_str());
+ return;
+ }
+
+ if((unsigned)iter->index>=canvas_interface()->get_canvas()->keyframe_list().size())
+ g_warning("KeyframeTreeStore::dump_iterator: \"%s\"(%p) has bad index(index:%d)",name.c_str(),gtk_iter,iter->index);
+
+ g_warning("KeyframeTreeStore::dump_iterator: \"%s\"(%p) ref:%d, index:%d, time:%s",name.c_str(),gtk_iter,iter->ref_count,iter->index,iter->iter->get_time().get_string().c_str());
+#endif
+}
+
+inline void
+KeyframeTreeStore::dump_iterator(const Gtk::TreeModel::iterator& iter, const Glib::ustring &name)const
+{
+ dump_iterator(iter->gobj(),name);
+}
+
+int
+KeyframeTreeStore::time_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+ const Model model;
+
+ _keyframe_iterator *rhs_iter(static_cast<_keyframe_iterator*>(rhs->gobj()->user_data));
+ _keyframe_iterator *lhs_iter(static_cast<_keyframe_iterator*>(lhs->gobj()->user_data));
+
+ Time diff(rhs_iter->iter->get_time()-lhs_iter->iter->get_time());
+ if(diff<0)
+ return -1;
+ if(diff>0)
+ return 1;
+ return 0;
+}
+
+int
+KeyframeTreeStore::description_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+ const Model model;
+
+ _keyframe_iterator *rhs_iter(static_cast<_keyframe_iterator*>(rhs->gobj()->user_data));
+ _keyframe_iterator *lhs_iter(static_cast<_keyframe_iterator*>(lhs->gobj()->user_data));
+
+ int comp = rhs_iter->iter->get_description().compare(lhs_iter->iter->get_description());
+ if (comp > 0) return 1;
+ if (comp < 0) return -1;
+ return 0;
+}
+
+void
+KeyframeTreeStore::set_value_impl(const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value)
+{
+ if(!iterator_sane(row))
+ return;
+
+ if(column>=get_n_columns_vfunc())
+ {
+ g_warning("KeyframeTreeStore::set_value_impl: Bad column (%d)",column);
+ return;
+ }
+
+ if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+ {
+ g_warning("KeyframeTreeStore::set_value_impl: Bad value type");
+ return;
+ }
+
+ _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(row.gobj()->user_data));
+
+ try
+ {
+ if(column==model.time_delta.index())
+ {
+ Glib::Value<synfig::Time> x;
+ g_value_init(x.gobj(),model.time.type());
+ g_value_copy(value.gobj(),x.gobj());
+
+ Time new_delta(x.get());
+ if(new_delta<=Time::zero()+Time::epsilon())
+ {
+ // Bad value
+ return;
+ }
+
+ Time old_delta((*row)[model.time_delta]);
+ if(old_delta<=Time::zero()+Time::epsilon())
+ {
+ // Bad old delta
+ return;
+ }
+ // row(row) on the next line is bad - don't use it, because it leaves 'row' uninitialized
+ //Gtk::TreeModel::iterator row(row);
+ //row++;
+ //if(!row)return;
+
+ Time change_delta(new_delta-old_delta);
+
+ if(change_delta<=Time::zero()+Time::epsilon() &&change_delta>=Time::zero()-Time::epsilon())
+ {
+ // Not an error, just no change
+ return;
+ }
+
+ {
+ Keyframe keyframe((*row)[model.keyframe]);
+ synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSetDelta"));
+
+ if(!action)return;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("keyframe",keyframe);
+ action->set_param("delta",change_delta);
+
+ canvas_interface()->get_instance()->perform_action(action);
+ }
+
+ return;
+ }
+ else
+ if(column==model.time.index())
+ {
+ OneMoment one_moment;
+
+ Glib::Value<synfig::Time> x;
+ g_value_init(x.gobj(),model.time.type());
+ g_value_copy(value.gobj(),x.gobj());
+ synfig::Keyframe keyframe(*iter->iter);
+
+ synfig::info("KeyframeTreeStore::set_value_impl():old_time=%s",keyframe.get_time().get_string().c_str());
+ keyframe.set_time(x.get());
+ synfig::info("KeyframeTreeStore::set_value_impl():new_time=%s",keyframe.get_time().get_string().c_str());
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSet"));
+
+ if(!action)
+ return;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("keyframe",keyframe);
+
+ canvas_interface()->get_instance()->perform_action(action);
+ }
+ else if(column==model.description.index())
+ {
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),model.description.type());
+ g_value_copy(value.gobj(),x.gobj());
+ synfig::Keyframe keyframe(*iter->iter);
+ keyframe.set_description(x.get());
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSet"));
+
+ if(!action)
+ return;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("keyframe",keyframe);
+
+ canvas_interface()->get_instance()->perform_action(action);
+ }
+ else if(column==model.keyframe.index())
+ {
+ g_warning("KeyframeTreeStore::set_value_impl: This column is read-only");
+ }
+ else
+ {
+ assert(0);
+ }
+ }
+ catch(std::exception x)
+ {
+ g_warning("%s", x.what());
+ }
+}
+
+Gtk::TreeModelFlags
+KeyframeTreeStore::get_flags_vfunc ()
+{
+ return Gtk::TREE_MODEL_LIST_ONLY;
+}
+
+int
+KeyframeTreeStore::get_n_columns_vfunc ()
+{
+ return model.size();
+}
+
+GType
+KeyframeTreeStore::get_column_type_vfunc (int index)
+{
+ return model.types()[index];
+}
+
+bool
+KeyframeTreeStore::iter_next_vfunc (const iterator& xiter, iterator& iter_next) const
+{
+ if(!iterator_sane(xiter)) return false;
+
+ _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(xiter.gobj()->user_data));
+
+ if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+ return false;
+
+ _keyframe_iterator *next(new _keyframe_iterator());
+ iter_next.gobj()->user_data=static_cast<gpointer>(next);
+ next->ref_count=1;
+ next->index=iter->index+1;
+ next->iter=iter->iter;
+ ++next->iter;
+
+ if(next->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+ return false;
+
+ iter_next.gobj()->stamp=stamp_;
+
+ return true;
+}
+
+/*
+bool
+KeyframeTreeStore::iter_next_vfunc (GtkTreeIter* gtk_iter)
+{
+ if(!iterator_sane(gtk_iter)) return false;
+
+ _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+
+ // If we are already at the end, then we are very invalid
+ if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+ return false;
+
+ ++(iter->iter);
+
+ if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+ {
+ --(iter->iter);
+ return false;
+ }
+ (iter->index)++;
+ return true;
+}
+
+bool
+KeyframeTreeStore::iter_children_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* parent)
+{
+ dump_iterator(gtk_iter,"gtk_iter");
+ dump_iterator(parent,"parent");
+
+ if(!parent || !iterator_sane(parent))
+ {
+ clear_iterator(gtk_iter);
+ return false;
+ }
+
+ _keyframe_iterator *iter(new _keyframe_iterator());
+ iter->ref_count=1;
+ iter->index=0;
+ iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
+
+ gtk_iter->user_data=static_cast<gpointer>(iter);
+ gtk_iter->stamp=stamp_;
+
+ return true;
+}
+
+bool
+KeyframeTreeStore::iter_has_child_vfunc (const GtkTreeIter*parent)
+{
+ dump_iterator(parent,"parent");
+
+ if(parent)
+ return false;
+
+ return true;
+}
+
+int
+KeyframeTreeStore::iter_n_children_vfunc (const GtkTreeIter* parent)
+{
+ dump_iterator(parent,"parent");
+
+ if(parent)
+ return 0;
+
+ return canvas_interface()->get_canvas()->keyframe_list().size();
+}
+*/
+
+int
+KeyframeTreeStore::iter_n_root_children_vfunc () const
+{
+ return canvas_interface()->get_canvas()->keyframe_list().size();
+}
+
+bool
+KeyframeTreeStore::iter_nth_root_child_vfunc (int n, iterator& xiter)const
+{
+ if(canvas_interface()->get_canvas()->keyframe_list().size()==0)
+ {
+ return false;
+ }
+
+ if(n<0)
+ {
+ g_warning("KeyframeTreeStore::iter_nth_root_child_vfunc: Out of range (negative index)");
+ return false;
+ }
+ if(n && (unsigned)n>=canvas_interface()->get_canvas()->keyframe_list().size())
+ {
+ g_warning("KeyframeTreeStore::iter_nth_child_vfunc: Out of range (large index)");
+ return false;
+ }
+
+ _keyframe_iterator *iter(new _keyframe_iterator());
+ iter->ref_count=1;
+ iter->index=n;
+ iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
+ while(n--)
+ {
+ if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+ {
+ g_warning("KeyframeTreeStore::iter_nth_child_vfunc: >>>BUG<<< in %s on line %d",__FILE__,__LINE__);
+ delete iter;
+ return false;
+ }
+ ++iter->iter;
+ }
+ xiter.gobj()->user_data=static_cast<gpointer>(iter);
+ xiter.gobj()->stamp=stamp_;
+ return true;
+}
+
+/*
+bool
+KeyframeTreeStore::iter_nth_child_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* parent, int n)
+{
+ dump_iterator(parent,"parent");
+
+ if(parent)
+ {
+ g_warning("KeyframeTreeStore::iter_nth_child_vfunc: I am a list");
+ clear_iterator(gtk_iter);
+ return false;
+ }
+
+
+
+ _keyframe_iterator *iter(new _keyframe_iterator());
+ iter->ref_count=1;
+ iter->index=n;
+ iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
+ while(n--)
+ {
+ if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+ {
+ g_warning("KeyframeTreeStore::iter_nth_child_vfunc: >>>BUG<<< in %s on line %d",__FILE__,__LINE__);
+ delete iter;
+ clear_iterator(gtk_iter);
+ return false;
+ }
+ ++iter->iter;
+ }
+
+ gtk_iter->user_data=static_cast<gpointer>(iter);
+ gtk_iter->stamp=stamp_;
+ return true;
+}
+
+bool
+KeyframeTreeStore::iter_parent_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* child)
+{
+ dump_iterator(child,"child");
+ iterator_sane(child);
+ clear_iterator(gtk_iter);
+ return false;
+}
+*/
+
+void
+KeyframeTreeStore::ref_node_vfunc (iterator& xiter)const
+{
+ GtkTreeIter* gtk_iter(xiter.gobj());
+ if(!gtk_iter || !iterator_sane(gtk_iter)) return;
+
+ _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+ iter->ref_count++;
+}
+
+void
+KeyframeTreeStore::unref_node_vfunc (iterator& xiter)const
+{
+ GtkTreeIter* gtk_iter(xiter.gobj());
+ if(!gtk_iter || !iterator_sane(gtk_iter)) return;
+
+ _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+ iter->ref_count--;
+ if(!iter->ref_count)
+ {
+ delete iter;
+
+ // Make this iterator invalid
+ gtk_iter->stamp=0;
+ }
+}
+
+Gtk::TreeModel::Path
+KeyframeTreeStore::get_path_vfunc (const iterator& gtk_iter)const
+{
+ Gtk::TreeModel::Path path;
+
+ // If this is the root node, then return
+ // a root path
+ if(!iterator_sane(gtk_iter))
+ return path;
+
+ _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->gobj()->user_data));
+
+ path.append_index(iter->index);
+
+ return path;
+}
+
+bool
+KeyframeTreeStore::get_iter_vfunc (const Gtk::TreeModel::Path& path, iterator& iter)const
+{
+ if(path.get_depth()>=1)
+ return iter_nth_root_child_vfunc(path.front(),iter);
+
+ // Error case
+ g_warning("KeyframeTreeStore::get_iter_vfunc(): Bad path \"%s\"",path.to_string().c_str());
+ //clear_iterator(iter);
+ return false;
+}
+
+bool
+KeyframeTreeStore::iter_is_valid (const iterator& iter) const
+{
+ return iterator_sane(iter);
+}
+
+void
+KeyframeTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& gtk_iter, int column, Glib::ValueBase& value)const
+{
+ dump_iterator(gtk_iter,"gtk_iter");
+ if(!iterator_sane(gtk_iter))
+ return;
+
+ _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->gobj()->user_data));
+
+ switch(column)
+ {
+ case 0: // Time
+ {
+ Glib::Value<synfig::Time> x;
+ g_value_init(x.gobj(),x.value_type());
+ x.set(iter->iter->get_time());
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ return;
+ }
+ case 3: // Time Delta
+ {
+ Glib::Value<synfig::Time> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ synfig::Keyframe prev_keyframe(*iter->iter);
+ synfig::Keyframe keyframe;
+ {
+ KeyframeList::iterator tmp(iter->iter);
+ tmp++;
+ if(tmp==get_canvas()->keyframe_list().end())
+ {
+ x.set(Time(0));
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ return;
+ }
+ keyframe=*tmp;
+ }
+
+ Time delta(0);
+ try {
+ delta=keyframe.get_time()-prev_keyframe.get_time();
+ }catch(...) { }
+ x.set(delta);
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ return;
+ }
+ case 1: // Description
+ {
+ g_value_init(value.gobj(),G_TYPE_STRING);
+ g_value_set_string(value.gobj(),iter->iter->get_description().c_str());
+ return;
+ }
+ case 2: // Keyframe
+ {
+ Glib::Value<synfig::Keyframe> x;
+ g_value_init(x.gobj(),x.value_type());
+ x.set(*iter->iter);
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ return;
+ }
+ default:
+ break;
+ }
+}
+
+Gtk::TreeModel::Row
+KeyframeTreeStore::find_row(const synfig::Keyframe &keyframe)
+{
+ Gtk::TreeModel::Row row(*(children().begin()));
+ dump_iterator(row,"find_row,begin");
+ const GtkTreeIter *gtk_iter(row.gobj());
+ if(!iterator_sane(gtk_iter))
+ throw std::runtime_error(_("Unable to find Keyframe in table"));
+
+ _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+
+ synfig::KeyframeList &keyframe_list(canvas_interface()->get_canvas()->keyframe_list());
+ if(keyframe_list.empty())
+ throw std::runtime_error(_("There are no keyframes n this canvas"));
+
+ iter->index=0;
+
+ for(iter->iter=keyframe_list.begin();iter->iter!=keyframe_list.end() && *iter->iter!=keyframe;++iter->iter)
+ {
+ iter->index++;
+ }
+ if(iter->iter==keyframe_list.end())
+ throw std::runtime_error(_("Unable to find Keyframe in table"));
+ return row;
+}
+
+void
+KeyframeTreeStore::add_keyframe(synfig::Keyframe keyframe)
+{
+ try
+ {
+ Gtk::TreeRow row(find_row(keyframe));
+ dump_iterator(row.gobj(),"add_keyframe,row");
+ Gtk::TreePath path(get_path(row));
+
+ row_inserted(path,row);
+
+ old_keyframe_list=get_canvas()->keyframe_list();
+ //old_keyframe_list.add(keyframe);
+ //old_keyframe_list.sort();
+ }
+ catch(std::exception x)
+ {
+ g_warning("%s", x.what());
+ }
+}
+
+void
+KeyframeTreeStore::remove_keyframe(synfig::Keyframe keyframe)
+{
+ try
+ {
+ if(1)
+ {
+ Gtk::TreeRow row(find_row(keyframe));
+ dump_iterator(row,"remove_keyframe,row");
+ Gtk::TreePath path(get_path(row));
+ row_deleted(path);
+
+ old_keyframe_list.erase(keyframe);
+ }
+ else
+ {
+ g_warning("KeyframeTreeStore::remove_keyframe: Keyframe not in table");
+ }
+ }
+ catch(std::exception x)
+ {
+ g_warning("%s", x.what());
+ }
+}
+
+void
+KeyframeTreeStore::change_keyframe(synfig::Keyframe keyframe)
+{
+ try
+ {
+ Gtk::TreeRow row(find_row(keyframe));
+
+ unsigned int new_index(get_index_from_model_iter(row));
+ unsigned int old_index(0);
+ synfig::KeyframeList::iterator iter;
+ for(old_index=0,iter=old_keyframe_list.begin();iter!=old_keyframe_list.end() && (UniqueID)*iter!=(UniqueID)keyframe;++iter,old_index++)
+ ;
+
+ if(iter!=old_keyframe_list.end() && new_index!=old_index)
+ {
+ std::vector<int> new_order;
+ for(unsigned int i=0;i<old_keyframe_list.size();i++)
+ {
+ new_order.push_back(i);
+ }
+ if(new_order.size()>new_index)
+ {
+ new_order.erase(new_order.begin()+new_index);
+ new_order.insert(new_order.begin()+old_index,new_index);
+
+ //new_order[old_index]=
+
+ rows_reordered (Path(), iterator(), &new_order[0]);
+ }
+ old_keyframe_list=get_canvas()->keyframe_list();
+
+ row=find_row(keyframe);
+ }
+
+ dump_iterator(row,"change_keyframe,row");
+ row_changed(get_path(row),row);
+ }
+ catch(std::exception x)
+ {
+ g_warning("%s", x.what());
+ }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trees/keyframetreestore.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_KEYFRAMETREESTORE_H
+#define __SYNFIG_STUDIO_KEYFRAMETREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/liststore.h>
+#include <synfigapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <synfig/keyframe.h>
+#include <map>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+//class TreeRowReferenceHack;
+//#define TreeRowReferenceHack Gtk::TreeRowReference
+
+namespace studio {
+
+class KeyframeTreeStore_Class;
+
+class KeyframeTreeStore :
+ public Glib::Object,
+ public Gtk::TreeModel,
+ public Gtk::TreeDragSource,
+ public Gtk::TreeDragDest
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+
+ class Model : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ Gtk::TreeModelColumn<synfig::Time> time;
+ Gtk::TreeModelColumn<Glib::ustring> description;
+ Gtk::TreeModelColumn<synfig::Keyframe> keyframe;
+ Gtk::TreeModelColumn<synfig::Time> time_delta;
+
+ Model()
+ {
+ add(time);
+ add(description);
+ add(keyframe);
+ add(time_delta);
+ }
+ };
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ const Model model;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
+
+ //! Unique stamp for this TreeModel.
+ int stamp_;
+
+ static KeyframeTreeStore_Class keyframe_tree_store_class_;
+
+ //std::map<synfig::Keyframe,TreeRowReferenceHack> path_table_;
+
+ synfig::KeyframeList old_keyframe_list;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+ void add_keyframe(synfig::Keyframe);
+
+ void remove_keyframe(synfig::Keyframe);
+
+ void change_keyframe(synfig::Keyframe);
+
+ static int sorter(const Gtk::TreeModel::iterator &,const Gtk::TreeModel::iterator &);
+
+ bool iterator_sane(const GtkTreeIter* iter)const;
+
+ bool iterator_sane(const Gtk::TreeModel::iterator& iter)const;
+
+ void dump_iterator(const GtkTreeIter* iter, const Glib::ustring &name)const;
+
+ void dump_iterator(const Gtk::TreeModel::iterator& iter, const Glib::ustring &name)const;
+
+ //! Resets the iterator stamp for this model.
+ /*! This should be called whenever the class is
+ ** constructed or when large numbers of
+ ** iterators become invalid. */
+ void reset_stamp();
+
+ //void reset_path_table();
+
+ /*
+ -- ** -- V I R T U A L F U N C T I O N S -----------------------------------
+ */
+
+protected:
+
+ virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+ virtual Gtk::TreeModelFlags get_flags_vfunc ();
+ virtual int get_n_columns_vfunc ();
+ virtual GType get_column_type_vfunc (int index);
+ virtual bool iter_next_vfunc (const iterator& iter, iterator& iter_next) const;
+ virtual bool get_iter_vfunc (const Gtk::TreeModel::Path& path, iterator& iter_next)const;
+ virtual bool iter_nth_root_child_vfunc (int n, iterator& iter)const;
+ virtual Gtk::TreeModel::Path get_path_vfunc (const iterator& iter)const;
+ virtual void ref_node_vfunc (iterator& iter)const;
+ virtual void unref_node_vfunc (iterator& iter)const;
+ virtual void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+ virtual bool iter_is_valid (const iterator& iter) const;
+ virtual int iter_n_root_children_vfunc () const;
+
+ //virtual bool iter_nth_child_vfunc (GtkTreeIter* iter, const GtkTreeIter* parent, int n);
+ //virtual bool iter_children_vfunc (GtkTreeIter* iter, const GtkTreeIter* parent);
+ //virtual bool iter_has_child_vfunc (const GtkTreeIter* iter);
+ //virtual int iter_n_children_vfunc (const GtkTreeIter* iter);
+ //virtual bool iter_parent_vfunc (GtkTreeIter* iter, const GtkTreeIter* child);
+
+ /*
+ virtual bool get_sort_column_id_vfunc (int* sort_column_id, Gtk::SortType* order);
+ virtual void set_sort_column_id_vfunc (int sort_column_id, Gtk::SortType order);
+ virtual void set_sort_func_vfunc (int sort_column_id, GtkTreeIterCompareFunc func, void* data, GtkDestroyNotify destroy);
+ virtual void set_default_sort_func_vfunc (GtkTreeIterCompareFunc func, void* data, GtkDestroyNotify destroy);
+ virtual bool has_default_sort_func_vfunc ();
+ */
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ KeyframeTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+ ~KeyframeTreeStore();
+
+ etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+ etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+
+ synfig::Canvas::Handle get_canvas() { return canvas_interface()->get_canvas(); }
+ synfig::Canvas::Handle get_canvas()const { return canvas_interface()->get_canvas(); }
+
+ Gtk::TreeModel::Row find_row(const synfig::Keyframe &keyframe);
+
+ /*
+ -- ** -- S T A T I C M E T H O D S ------------------------------------------
+ */
+
+public:
+
+ static Glib::RefPtr<KeyframeTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+
+ static int time_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+ static int description_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+
+}; // END of class KeyframeTreeStore
+
+//! \internal
+class KeyframeTreeStore_Class : public Glib::Class
+{
+public:
+ struct KeyframeTreeStoreClass
+ {
+ GObjectClass parent_class;
+ };
+
+ friend class KeyframeTreeStore;
+
+ const Glib::Class& init();
+
+ static void class_init_function(gpointer g_blass, gpointer class_data);
+}; // END of CustomTreeStore_Class
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layergrouptree.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/layer.h>
+#include "trees/layergrouptree.h"
+#include <gtkmm/treemodelsort.h>
+#include <ETL/misc>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+LayerGroupTree::LayerGroupTree()
+{
+ const LayerGroupTreeStore::Model model;
+
+
+ { // --- O N / O F F ----------------------------------------------------
+ int index;
+ index=append_column_editable(_(" "),model.active);
+ //Gtk::TreeView::Column* column = get_column(index-1);
+ }
+ { // --- I C O N --------------------------------------------------------
+ int index;
+ index=append_column(_(" "),model.icon);
+ Gtk::TreeView::Column* column = get_column(index-1);
+ set_expander_column(*column);
+ }
+ { // --- N A M E --------------------------------------------------------
+ int index;
+ index=append_column_editable(_("Name"),model.label);
+ label_column = get_column(index-1);
+
+ //column->set_sort_column(layer_model.index);
+
+ //set_expander_column(*column);
+ //column->set_reorderable();
+ //column->set_resizable();
+ //column->set_clickable(false);
+
+ //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+ //column->pack_start(*icon_cellrenderer,false);
+ //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
+ }
+
+ set_enable_search(true);
+ set_search_column(model.label);
+ set_search_equal_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::search_func));
+
+ // This makes things easier to read.
+ set_rules_hint();
+
+ // Make us more sensitive to several events
+ add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+
+ set_reorderable(true);
+
+ get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+
+ //set_flags(get_flags()|Gtk::RECEIVES_DEFAULT|Gtk::HAS_GRAB);
+
+ //std::list<Gtk::TargetEntry> listTargets;
+ //listTargets.push_back( Gtk::TargetEntry("LAYER") );
+ //listTargets.push_back( Gtk::TargetEntry("GROUP") );
+ //drag_dest_set(listTargets);
+}
+
+LayerGroupTree::~LayerGroupTree()
+{
+ if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+ synfig::info("LayerGroupTree::~LayerGroupTree(): Deleted");
+}
+
+void
+LayerGroupTree::set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store)
+{
+ layer_group_tree_store_=layer_group_tree_store;
+ LayerGroupTreeStore::Model model;
+
+#if 0
+ {
+ Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(layer_group_tree_store_));
+ sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
+ sorted_store->set_sort_func(model.time.index(),sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
+ sorted_store->set_sort_column(model.time.index(), Gtk::SORT_ASCENDING);
+ Gtk::TreeView::set_model(sorted_store);
+ }
+#else
+ Gtk::TreeView::set_model(layer_group_tree_store);
+#endif
+}
+
+void
+LayerGroupTree::set_editable(bool x)
+{
+ editable_=x;
+/*
+ if(editable_)
+ {
+ cell_renderer_time->property_editable()=true;
+ cell_renderer_time_delta->property_editable()=true;
+ cell_renderer_description->property_editable()=true;
+ }
+ else
+ {
+ cell_renderer_time->property_editable()=false;
+ cell_renderer_time_delta->property_editable()=false;
+ cell_renderer_description->property_editable()=false;
+ }
+*/
+}
+/*
+void
+LayerGroupTree::on_edited_time(const Glib::ustring&path_string,synfig::Time time)
+{
+ Gtk::TreePath path(path_string);
+
+ const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+
+ synfig::Keyframe keyframe(row[model.keyframe]);
+ if(time!=keyframe.get_time())
+ {
+ row[model.time]=time;
+ //keyframe.set_time(time);
+ //signal_edited_time()(keyframe,time);
+ //signal_edited()(keyframe);
+ }
+}
+
+void
+LayerGroupTree::on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time)
+{
+ Gtk::TreePath path(path_string);
+
+ const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+
+ if(row)row[model.time_delta]=time;
+}
+
+void
+LayerGroupTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
+{
+ Gtk::TreePath path(path_string);
+
+ const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+ const synfig::String description(desc);
+ synfig::Keyframe keyframe(row[model.keyframe]);
+ if(description!=keyframe.get_description())
+ {
+ row[model.description]=desc;
+ keyframe.set_description(description);
+ signal_edited_description()(keyframe,description);
+ signal_edited()(keyframe);
+ }
+}
+*/
+
+bool
+LayerGroupTree::on_event(GdkEvent *event)
+{
+ switch(event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
+ //tree_to_widget_coords (,, wx, wy);
+ if(!get_path_at_pos(
+ wx,wy, // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+ const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+ if(row[model.is_layer] && event->button.button==3)
+ {
+ signal_popup_layer_menu()((Layer::Handle)row[model.layer]);
+ return true;
+ }
+
+ /*signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
+ if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
+ {
+ layer_group_tree_store_->canvas_interface()->set_time(row[model.time]);
+ }*/
+ }
+ break;
+ case GDK_2BUTTON_PRESS:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!get_path_at_pos(
+ int(event->button.x),int(event->button.y), // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+ const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+ LayerList layer_list(row[model.all_layers]);
+ if(!layer_list.empty())
+ {
+ if(!(event->button.state&GDK_CONTROL_MASK))
+ {
+ layer_group_tree_store_->canvas_interface()->get_selection_manager()->clear_selected_layers();
+ }
+ layer_group_tree_store_->canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
+ return true;
+ }
+ }
+ break;
+ case GDK_BUTTON_RELEASE:
+ break;
+ default:
+ break;
+ }
+ return Gtk::TreeView::on_event(event);
+ //return false;
+}
+
+static inline void __group_grabber(const Gtk::TreeModel::iterator& iter, std::list<synfig::String>* ret)
+{
+ const LayerGroupTreeStore::Model model;
+ if((bool)(*iter)[model.is_group])
+ ret->push_back((Glib::ustring)(*iter)[model.group_name]);
+}
+
+std::list<synfig::String>
+LayerGroupTree::get_selected_groups()const
+{
+ Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
+
+ if(!selection)
+ return std::list<synfig::String>();
+
+ std::list<synfig::String> ret;
+
+ selection->selected_foreach_iter(
+ sigc::bind(
+ sigc::ptr_fun(
+ &__group_grabber
+ ),
+ &ret
+ )
+ );
+
+ return ret;
+}
+
+static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerGroupTree::LayerList* ret)
+{
+ const LayerGroupTreeStore::Model model;
+ if((bool)(*iter)[model.is_layer])
+ ret->push_back((Layer::Handle)(*iter)[model.layer]);
+}
+
+LayerGroupTree::LayerList
+LayerGroupTree::get_selected_layers()const
+{
+ Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
+
+ if(!selection)
+ return LayerList();
+
+ LayerList ret;
+
+ selection->selected_foreach_iter(
+ sigc::bind(
+ sigc::ptr_fun(
+ &__layer_grabber
+ ),
+ &ret
+ )
+ );
+
+ return ret;
+}
+
+void
+LayerGroupTree::set_cursor(const Gtk::TreeModel::Path& path, bool start_editing)
+{
+ Gtk::TreeView::set_cursor(path, *label_column, start_editing);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trees/layergrouptree.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_LAYERGROUPTREE_H
+#define __SYNFIG_STUDIO_LAYERGROUPTREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <synfigapp/value_desc.h>
+#include "trees/layergrouptreestore.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig { class Layer; }
+
+namespace studio {
+
+class LayerGroupTree : public Gtk::TreeView
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+
+ typedef std::list<synfig::Layer::Handle> LayerList;
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ LayerGroupTreeStore::Model model;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store_;
+
+ Gtk::CellRendererText *cell_renderer_description;
+
+ bool editable_;
+
+
+ sigc::signal<void,etl::handle<synfig::Layer> > signal_popup_layer_menu_;
+
+// sigc::signal<void,LayerList> signal_select_layers_;
+ Gtk::TreeView::Column* label_column;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ bool on_event(GdkEvent *event);
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ LayerGroupTree();
+ ~LayerGroupTree();
+ void set_cursor(const Gtk::TreeModel::Path& path, bool start_editing=false);
+
+ Glib::RefPtr<LayerGroupTreeStore> get_model() { return layer_group_tree_store_; }
+
+ sigc::signal<void,etl::handle<synfig::Layer> >& signal_popup_layer_menu() { return signal_popup_layer_menu_; }
+
+// sigc::signal<void,LayerList>& signal_select_layers() { return signal_select_layers_; }
+
+ void set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store_);
+
+ void set_editable(bool x=true);
+
+ bool get_editable()const { return editable_; }
+
+ std::list<synfig::String> get_selected_groups()const;
+
+ LayerList get_selected_layers()const;
+}; // END of LayerGroupTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layergrouptreestore.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trees/layergrouptreestore.h"
+#include "iconcontroller.h"
+#include <gtkmm/button.h>
+#include <synfig/paramdesc.h>
+#include <synfigapp/action.h>
+#include <synfigapp/instance.h>
+#include "app.h"
+#include "instance.h"
+#include <synfigapp/action_system.h>
+#include "docks/dockmanager.h"
+#include "docks/dockable.h"
+
+#include <gtk/gtkversion.h>
+#include <ETL/clock>
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define GROUP_NEST_CHAR '.'
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static LayerGroupTreeStore::Model& ModelHack()
+{
+ static LayerGroupTreeStore::Model* model(0);
+ if(!model)model=new LayerGroupTreeStore::Model;
+ return *model;
+}
+
+LayerGroupTreeStore::LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+ Gtk::TreeStore (ModelHack()),
+ canvas_interface_ (canvas_interface_)
+{
+ layer_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+ group_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-group"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ // Connect Signals to Terminals
+ canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_status_changed));
+ canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_new_description));
+
+ canvas_interface()->get_canvas()->signal_group_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_added)));
+ canvas_interface()->get_canvas()->signal_group_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_removed)));
+ canvas_interface()->get_canvas()->signal_group_changed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_changed)));
+
+ canvas_interface()->get_canvas()->signal_group_pair_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_added)));
+ canvas_interface()->get_canvas()->signal_group_pair_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_removed)));
+
+ rebuild();
+}
+
+LayerGroupTreeStore::~LayerGroupTreeStore()
+{
+ //clear();
+
+ if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+ synfig::info("LayerGroupTreeStore::~LayerGroupTreeStore(): Deleted");
+}
+
+bool
+LayerGroupTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
+{
+ const Model model;
+
+ Glib::ustring substr(x.uppercase());
+ Glib::ustring label((*iter)[model.label]);
+ label=label.uppercase();
+
+ return label.find(substr)==Glib::ustring::npos;
+}
+
+
+Glib::RefPtr<LayerGroupTreeStore>
+LayerGroupTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
+{
+ return Glib::RefPtr<LayerGroupTreeStore>(new LayerGroupTreeStore(canvas_interface_));
+}
+
+void
+LayerGroupTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+ if(column==model.child_layers.index())
+ {
+ Glib::Value<LayerList> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ if((bool)(*iter)[model.is_group])
+ {
+ set<Layer::Handle> layer_set(canvas_interface()->get_canvas()->get_layers_in_group((Glib::ustring)(*iter)[model.group_name]));
+
+ x.set(LayerList(layer_set.begin(),layer_set.end()));
+ }
+ else if((bool)(*iter)[model.is_layer])
+ {
+ LayerList layer_list;
+ layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
+ x.set(layer_list);
+ }
+
+ g_value_init(value.gobj(),x.value_type());
+ value=x;
+ }
+ else if(column==model.all_layers.index())
+ {
+ Glib::Value<LayerList> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ if((bool)(*iter)[model.is_group])
+ {
+ LayerList layer_list;
+ Gtk::TreeModel::iterator child_iter(iter->children().begin());
+ for(;child_iter;++child_iter)
+ {
+ LayerList layer_list2((LayerList)(*child_iter)[model.all_layers]);
+ for(;layer_list2.size();layer_list2.pop_front())
+ layer_list.push_back(layer_list2.front());
+ }
+ x.set(layer_list);
+ }
+ else if((bool)(*iter)[model.is_layer])
+ {
+ LayerList layer_list;
+ layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
+ x.set(layer_list);
+ }
+
+ g_value_init(value.gobj(),x.value_type());
+ value=x;
+ }
+ else if(column==model.group_name.index())
+ {
+ if((bool)(*iter)[model.is_group])
+ return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+ return get_value_vfunc(iter->parent(),column,value);
+ }
+ else if(column==model.parent_group_name.index())
+ {
+ if(iter->parent())
+ return get_value_vfunc(iter->parent(),model.group_name.index(),value);
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+ x.set(Glib::ustring());
+ g_value_init(value.gobj(),x.value_type());
+ value=x;
+ }
+ else if(column==model.label.index())
+ {
+ if((bool)(*iter)[model.is_group])
+ {
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ Glib::ustring group_name((*iter)[model.group_name]);
+
+ // Get rid of any parent group crap
+ while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
+ group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
+
+ x.set(group_name);
+
+ g_value_init(value.gobj(),x.value_type());
+
+ value=x;
+ }
+ else if((bool)(*iter)[model.is_layer])
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(layer->get_non_empty_description());
+
+ g_value_init(value.gobj(),x.value_type());
+ //g_value_copy(x.gobj(),value.gobj());
+ value=x;
+ }
+ }
+ else
+ if(column==model.tooltip.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+
+
+ x.set(layer->get_local_name());
+
+ g_value_init(value.gobj(),x.value_type());
+ //g_value_copy(x.gobj(),value.gobj());
+ value=x;
+ }
+ else
+ if(column==model.canvas.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<Canvas::Handle> x;
+ g_value_init(x.gobj(),x.value_type());
+
+
+ x.set(layer->get_canvas());
+
+ g_value_init(value.gobj(),x.value_type());
+ //g_value_copy(x.gobj(),value.gobj());
+ value=x;
+ }
+ else
+ if(column==model.active.index())
+ {
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ if((bool)(*iter)[model.is_layer])
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+ x.set(layer->active());
+ }
+ else if((bool)(*iter)[model.is_group])
+ {
+ int activecount(0),total(0);
+ Gtk::TreeModel::iterator child_iter(iter->children().begin());
+ for(;child_iter;++child_iter)
+ {
+ total++;
+ if((*child_iter)[model.active])
+ activecount++;
+ }
+ x.set(activecount>total/2);
+ }
+ else
+ x.set(false);
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.icon.index())
+ {
+ Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
+ g_value_init(x.gobj(),x.value_type());
+
+ if((bool)(*iter)[model.is_layer])
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+ if(!layer)return;
+ //x.set(layer_icon);
+ x.set(get_tree_pixbuf_layer(layer->get_name()));
+ }
+ if((bool)(*iter)[model.is_group])
+ x.set(group_icon);
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+void
+LayerGroupTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+ //if(!iterator_sane(row))
+ // return;
+
+ if(column>=get_n_columns_vfunc())
+ {
+ g_warning("LayerGroupTreeStore::set_value_impl: Bad column (%d)",column);
+ return;
+ }
+
+ if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+ {
+ g_warning("LayerGroupTreeStore::set_value_impl: Bad value type");
+ return;
+ }
+
+ try
+ {
+ if(column==model.label.index())
+ {
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),model.label.type());
+ g_value_copy(value.gobj(),x.gobj());
+
+ if((bool)(*iter)[model.is_layer])
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+ if(!layer)
+ return;
+ synfig::String new_desc(x.get());
+
+ if(new_desc==layer->get_local_name())
+ new_desc=synfig::String();
+
+ if(new_desc==layer->get_description())
+ return;
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetDesc"));
+
+ if(!action)
+ return;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("layer",layer);
+ action->set_param("new_description",synfig::String(x.get()));
+
+ canvas_interface()->get_instance()->perform_action(action);
+ return;
+ }
+ else if((bool)(*iter)[model.is_group])
+ {
+ synfig::String group((Glib::ustring)(*iter)[model.label]);
+ synfig::String new_group(x.get());
+
+ if(x.get()==group)
+ return;
+
+ Glib::ustring group_name((*iter)[model.group_name]);
+ group=group_name;
+ new_group.clear();
+
+ // Get rid of any parent group crap
+ while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
+ {
+ new_group+=Glib::ustring(group_name,0,group_name.find(GROUP_NEST_CHAR)+1);
+ group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
+ }
+ new_group+=x.get();
+
+ synfig::info("Renaming group \"%s\" to \"%s\"...",group.c_str(),new_group.c_str());
+
+ // Check to see if this group is real or not.
+ // If it isn't real, then renaming it is a cinch.
+ // We know it isn't real if it doesn't have any
+ // children yet.
+ if(iter->children().empty())
+ {
+ (*iter)[model.group_name]=new_group;
+ }
+ else
+ {
+ synfigapp::Action::Handle action(synfigapp::Action::create("GroupRename"));
+
+ if(!action)
+ return;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("group",group);
+ action->set_param("new_group",new_group);
+
+ canvas_interface()->get_instance()->perform_action(action);
+ }
+ return;
+ }
+ return;
+ }
+ else
+ if(column==model.active.index())
+ {
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),model.active.type());
+ g_value_copy(value.gobj(),x.gobj());
+
+ if((bool)(*iter)[model.is_layer])
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+ if(!layer)return;
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
+
+ if(!action)
+ return;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("layer",layer);
+ action->set_param("new_status",bool(x.get()));
+
+
+ canvas_interface()->get_instance()->perform_action(action);
+ return;
+ }
+ else if(!iter->children().empty())
+ {
+ synfigapp::Action::PassiveGrouper group(
+ get_canvas_interface()->get_instance().get(),
+ String(
+ x.get()?_("Activate "):_("Deactivate ")
+ )+(Glib::ustring)(*iter)[model.label]
+ );
+
+ Gtk::TreeModel::iterator child_iter(iter->children().begin());
+
+ for(;child_iter;++child_iter)
+ (*child_iter)[model.active]=x.get();
+
+ Gtk::TreeStore::set_value_impl(iter,column, value);
+ }
+ }
+ else
+ Gtk::TreeStore::set_value_impl(iter,column, value);
+
+ }
+ catch(std::exception x)
+ {
+ g_warning("%s", x.what());
+ }
+}
+
+
+
+
+bool
+LayerGroupTreeStore::row_draggable_vfunc (const TreeModel::Path& /*path*/)const
+{
+ //if(!get_iter(path)) return false;
+// Gtk::TreeModel::Row row(*get_iter(path));
+
+ return true;
+}
+
+bool
+LayerGroupTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
+{
+ if(!const_cast<LayerGroupTreeStore*>(this)->get_iter(path)) return false;
+ //synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
+ //synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
+ //synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+ Gtk::TreeModel::Row row(*const_cast<LayerGroupTreeStore*>(this)->get_iter(path));
+
+ if((bool)row[model.is_layer])
+ {
+ Layer* layer(((Layer::Handle)row[model.layer]).get());
+ assert(layer);
+
+ std::vector<Layer*> layers;
+
+ layers.push_back(layer);
+
+ selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
+
+ return true;
+ }
+ else if((bool)row[model.is_group])
+ {
+ synfig::String group((Glib::ustring)row[model.group_name]);
+ if(group.empty())
+ return false;
+
+ selection_data.set("GROUP", 8, reinterpret_cast<const guchar*>(&*group.begin()), sizeof(void*)*group.size());
+
+ return true;
+ }
+
+ return false;
+}
+
+bool
+LayerGroupTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
+{
+ return true;
+}
+
+bool
+LayerGroupTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
+{
+ Gtk::TreeIter iter(const_cast<LayerGroupTreeStore*>(this)->get_iter(dest));
+ if(!iter) return false;
+
+ if(synfig::String(selection_data.get_data_type())=="LAYER")
+ return true;
+
+ if(synfig::String(selection_data.get_data_type())=="GROUP")
+ {
+ synfig::String dest_group((Glib::ustring)(*iter)[model.group_name]);
+ synfig::String src_group(reinterpret_cast<const gchar*>(selection_data.get_data()));
+ //synfig::String src_group(const_cast<gchar*>(selection_data.get_data()));
+
+ // Avoid putting a group inside of itself
+ if(dest_group.size()>src_group.size() && src_group==String(dest_group,0,src_group.size()))
+ return false;
+ return true;
+ }
+
+ return false;
+ //synfig::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
+ //synfig::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
+ //synfig::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+ //Gtk::TreeModel::Row row(*get_iter(dest));
+
+/* if(synfig::String(selection_data.get_data_type())=="LAYER" && (bool)true)
+ return true;
+*/
+ return false;
+}
+
+bool
+LayerGroupTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
+{
+ if(!get_iter(dest)) return false;
+// bool ret=false;
+ //int i(0);
+
+ Gtk::TreeModel::Row row(*get_iter(dest));
+
+ //synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
+ //synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
+ //synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
+ synfigapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Regroup"));
+
+ if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+ {
+ synfig::String dest_group;
+
+ dest_group=(Glib::ustring)row[model.group_name];
+
+ if(dest_group.empty())
+ return false;
+
+ if(synfig::String(selection_data.get_data_type())=="LAYER")
+ {
+ synfigapp::Action::Handle action(synfigapp::Action::create("GroupAddLayers"));
+
+ if(!action)
+ return false;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("group",dest_group);
+
+ for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
+ {
+ Layer::Handle layer(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+ assert(layer);
+
+ action->set_param("layer",layer);
+ }
+ if(!canvas_interface()->get_instance()->perform_action(action))
+ {
+ passive_grouper.cancel();
+ return false;
+ }
+ return true;
+ }
+ if(synfig::String(selection_data.get_data_type())=="GROUP")
+ {
+ synfig::String src_group(reinterpret_cast<const gchar*>(selection_data.get_data()));
+ synfig::String group(src_group);
+
+ // Get rid of any parent group crap
+ while(group.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
+ group=Glib::ustring(group,group.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
+
+ group=dest_group+GROUP_NEST_CHAR+group;
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("GroupRename"));
+
+ if(!action)
+ return false;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("group",src_group);
+ action->set_param("new_group",group);
+
+ if(!canvas_interface()->get_instance()->perform_action(action))
+ {
+ passive_grouper.cancel();
+ return false;
+ }
+ return true;
+ }
+ }
+/* // Save the selection data
+ synfigapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+
+ if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+ {
+ Canvas::Handle dest_canvas;
+ Layer::Handle dest_layer;
+
+ dest_canvas=(Canvas::Handle)(row[model.canvas]);
+ dest_layer=(Layer::Handle)(row[model.layer]);
+ assert(dest_canvas);
+
+ if(!dest_layer)
+ return false;
+
+ int dest_layer_depth=dest_layer->get_depth();
+
+ if(synfig::String(selection_data.get_data_type())=="LAYER")for(i=0;i<selection_data.get_length()/sizeof(void*);i++)
+ {
+ //synfig::info("dest_layer_depth=%d",dest_layer_depth);
+
+ Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+ assert(src);
+ if(dest_layer==src)
+ continue;
+
+ // In this case, we are just moving.
+// if(dest_canvas==src->get_canvas())
+ {
+ if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
+ dest_layer_depth--;
+ if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
+ continue;
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
+ action->set_param("canvas",dest_canvas);
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("layer",src);
+ action->set_param("new_index",dest_layer_depth);
+ action->set_param("dest_canvas",dest_canvas);
+ if(canvas_interface()->get_instance()->perform_action(action))
+ {
+ ret=true;
+ }
+ else
+ {
+ passive_grouper.cancel();
+ return false;
+ }
+ continue;
+ }
+ }
+ }
+ synfig::info("I supposedly moved %d layers",i);
+
+ // Reselect the previously selected layers
+ canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
+
+ return ret;
+ */
+ return false;
+}
+
+
+
+
+
+
+
+void
+LayerGroupTreeStore::rebuild()
+{
+ rebuilding=true;
+ // etl::clock timer;timer.reset();
+ try {
+
+ // Clear out the current list
+ clear();
+ Canvas::Handle canvas(canvas_interface()->get_canvas());
+ std::set<String> groups(canvas->get_groups());
+ for(;groups.size();groups.erase(groups.begin()))
+ {
+ String group(*groups.begin());
+ Gtk::TreeRow row(on_group_added(group));
+ std::set<Layer::Handle> layers(canvas->get_layers_in_group(group));
+
+ for(;layers.size();layers.erase(layers.begin()))
+ {
+ Gtk::TreeRow layer_row(*(prepend(row.children())));
+ Layer::Handle layer(*layers.begin());
+ set_row_layer(layer_row,layer);
+ }
+ }
+
+ // Go ahead and add all the layers
+ /*std::for_each(
+ canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
+ sigc::mem_fun(*this, &studio::LayerGroupTreeStore::on_layer_added)
+ );*/
+ }
+ catch(...)
+ {
+ rebuilding=false;
+ throw;
+ }
+ rebuilding=false;
+ // synfig::info("LayerGroupTreeStore::rebuild() took %f seconds",float(timer()));
+}
+
+void
+LayerGroupTreeStore::refresh()
+{
+ rebuild();
+}
+
+void
+LayerGroupTreeStore::refresh_row(Gtk::TreeModel::Row &row)
+{
+ if((bool)row[model.is_layer])
+ {
+ Layer::Handle layer=row[model.layer];
+
+
+ //if(layer->dynamic_param_list().count("z_depth"))
+ // row[model.z_depth]=Time::begin();
+ }
+
+ Gtk::TreeModel::Children children = row.children();
+ Gtk::TreeModel::Children::iterator iter;
+
+ if(!children.empty())
+ for(iter = children.begin(); iter && iter != children.end(); ++iter)
+ {
+ Gtk::TreeRow row=*iter;
+ refresh_row(row);
+ }
+}
+
+
+void
+LayerGroupTreeStore::set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle)
+{
+ row[model.is_layer] = true;
+ row[model.is_group] = false;
+ row[model.layer] = handle;
+}
+
+Gtk::TreeRow
+LayerGroupTreeStore::on_group_added(synfig::String group)
+{
+ // Check to see if this group perhaps already
+ // exists
+ {
+ Gtk::TreeModel::Children::iterator iter;
+ if(find_group_row(group, iter))
+ return *iter;
+ }
+
+ if(group.find(GROUP_NEST_CHAR)!=String::npos)
+ {
+ Gtk::TreeModel::Children::iterator iter;
+ String parent_name;
+ do
+ {
+ if(parent_name.size())
+ parent_name+=GROUP_NEST_CHAR;
+ parent_name+=string(group,0,group.find(GROUP_NEST_CHAR));
+
+ if(!find_group_row(parent_name, iter))
+ iter=on_group_added(parent_name);
+
+ group=String(group,group.find(GROUP_NEST_CHAR)+1,String::npos);
+ }while(group.find(GROUP_NEST_CHAR)!=String::npos);
+
+ if(parent_name.size())
+ parent_name+=GROUP_NEST_CHAR;
+ parent_name+=group;
+
+ if(iter)
+ {
+ Gtk::TreeRow row(*(prepend(iter->children())));
+ row[model.group_name]=parent_name;
+ row[model.is_layer]=false;
+ row[model.is_group]=true;
+ on_activity();
+ return row;
+ }
+ }
+
+ Gtk::TreeRow row(*(append()));
+ row[model.group_name]=group;
+ row[model.is_layer]=false;
+ row[model.is_group]=true;
+ on_activity();
+ return row;
+}
+
+bool
+LayerGroupTreeStore::on_group_removed(synfig::String group)
+{
+ Gtk::TreeModel::Children::iterator iter;
+ if(find_group_row(group,iter) && iter->children().size()==0)
+ erase(iter);
+ else
+ return false;
+
+ return true;
+}
+
+bool
+LayerGroupTreeStore::on_group_changed(synfig::String /*group*/)
+{
+ return true;
+}
+
+void
+LayerGroupTreeStore::on_group_pair_added(synfig::String group, etl::handle<synfig::Layer> layer)
+{
+ if(!layer->get_canvas())
+ return;
+ Gtk::TreeModel::Children::iterator iter;
+ if(!find_group_row(group, iter))
+ iter=on_group_added(group);
+
+ Gtk::TreeRow layer_row(*(append(iter->children())));
+ set_row_layer(layer_row,layer);
+ on_activity();
+}
+
+void
+LayerGroupTreeStore::on_group_pair_removed(synfig::String group, etl::handle<synfig::Layer> layer)
+{
+ if(!layer->get_canvas())
+ return;
+ Gtk::TreeModel::Children::iterator iter;
+ if(!find_group_row(group, iter))
+ return;
+
+ Gtk::TreeModel::Children::iterator prev,layer_iter;
+
+ if(!find_layer_row_(layer, layer->get_canvas(), iter->children(), layer_iter, prev))
+ return;
+
+ erase(layer_iter);
+
+ on_activity();
+}
+
+void
+LayerGroupTreeStore::on_activity()
+{
+ // If we aren't rebuilding and the last action
+ // had something to do with groups, then go
+ // a head and present the groups dialog.
+ if(!rebuilding && canvas_interface()->get_instance()->get_most_recent_action() && canvas_interface()->get_instance()->get_most_recent_action()->get_name().find("Group")!=String::npos)
+ try
+ {
+ App::dock_manager->find_dockable("groups").present();
+ }
+ catch(...) { }
+}
+
+void
+LayerGroupTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
+{
+ Gtk::TreeModel::Children::iterator iter;
+ if(find_layer_row(handle,iter))
+ (*iter)[model.layer]=handle;
+ else
+ {
+ // Not need to send a warning when a layer changes its status and
+ // it is not found in any group.
+ //synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
+ rebuild();
+ }
+}
+
+
+void
+LayerGroupTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
+{
+ Gtk::TreeModel::Children::iterator iter;
+ if(find_layer_row(handle,iter))
+ {
+ Gtk::TreeRow row(*iter);
+
+ Layer::Handle layer(row[model.layer]);
+
+ if(desc.empty())
+ {
+ //row[model.label]=layer->get_local_name();
+ row[model.tooltip]=Glib::ustring(_("Layer"));
+ }
+ else
+ //row[model.label]=layer->get_description();
+ row[model.tooltip]=layer->get_local_name();
+ }
+ else
+ {
+ rebuild();
+ }
+}
+
+bool
+LayerGroupTreeStore::find_layer_row_(const synfig::Layer::Handle &layer, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
+{
+ assert(layer);
+
+ //if(layer->get_canvas()==canvas)
+ {
+ for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
+ {
+ Gtk::TreeModel::Row row = *iter;
+ if((bool)row[model.is_layer] && layer==(synfig::Layer::Handle)row[model.layer])
+ return true;
+ }
+
+ iter=children().end();
+ //return false;
+ }
+
+ Gtk::TreeModel::Children::iterator iter2;
+
+ for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+ {
+ Gtk::TreeModel::Row row = *iter2;
+ assert((bool)true);
+
+ if(row.children().empty())
+ continue;
+
+ /*Canvas::Handle canvas((*row.children().begin())[model.canvas]);
+ if(!canvas)
+ continue;
+ */
+
+ if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
+ return true;
+ }
+
+ iter=children().end();
+ return false;
+}
+
+bool
+LayerGroupTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
+{
+ Gtk::TreeModel::Children::iterator prev;
+ return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
+}
+
+bool
+LayerGroupTreeStore::find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter)
+{
+ Gtk::TreeModel::Children::iterator prev;
+ return find_group_row_(group,children(),iter,prev);
+}
+
+bool
+LayerGroupTreeStore::find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
+{
+ //if(layer->get_canvas()==canvas)
+ {
+ for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
+ {
+ Gtk::TreeModel::Row row = *iter;
+ if((bool)row[model.is_group] && group==(Glib::ustring)row[model.group_name])
+ return true;
+ }
+
+ iter=children().end();
+ //return false;
+ }
+
+ Gtk::TreeModel::Children::iterator iter2;
+
+ for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+ {
+ Gtk::TreeModel::Row row = *iter2;
+ assert((bool)true);
+
+ if(row.children().empty())
+ continue;
+
+ if(find_group_row_(group,iter2->children(),iter,prev))
+ return true;
+ }
+
+ iter=children().end();
+ return false;
+}
+
+bool
+LayerGroupTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
+{
+ Gtk::TreeModel::Children::iterator iter;
+ if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
+ return false;
+ if(iter==children().begin())
+ return false;
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trees/layergrouptreestore.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_LAYERGROUPTREESTORE_H
+#define __SYNFIG_STUDIO_LAYERGROUPTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <gtkmm/treeview.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerGroupTreeStore : public Gtk::TreeStore
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+ typedef std::list<synfig::Layer::Handle> LayerList;
+
+ class Model : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+ Gtk::TreeModelColumn<Glib::ustring> label;
+ Gtk::TreeModelColumn<Glib::ustring> tooltip;
+
+ Gtk::TreeModelColumn<Glib::ustring> group_name;
+ Gtk::TreeModelColumn<Glib::ustring> parent_group_name;
+
+ Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
+
+ Gtk::TreeModelColumn<bool> active;
+ Gtk::TreeModelColumn<bool> is_layer;
+ Gtk::TreeModelColumn<bool> is_group;
+ Gtk::TreeModelColumn<synfig::Layer::Handle> layer;
+
+ Gtk::TreeModelColumn<LayerList> all_layers;
+ Gtk::TreeModelColumn<LayerList> child_layers;
+
+ Model()
+ {
+ add(icon);
+ add(label);
+ add(group_name);
+ add(parent_group_name);
+ add(canvas);
+ add(tooltip);
+ add(active);
+ add(layer);
+ add(is_layer);
+ add(is_group);
+ add(all_layers);
+ add(child_layers);
+ }
+ };
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ //! TreeModel for the layers
+ const Model model;
+
+ bool rebuilding;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
+
+ Glib::RefPtr<Gdk::Pixbuf> layer_icon;
+ Glib::RefPtr<Gdk::Pixbuf> group_icon;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- P R O T E C T E D M E T H O D S -----------------------------------
+ */
+
+private:
+
+ virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+ virtual void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+
+ virtual bool row_draggable_vfunc (const TreeModel::Path& path)const;
+ virtual bool drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
+ virtual bool drag_data_delete_vfunc (const TreeModel::Path& path);
+ virtual bool drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
+ virtual bool row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;
+
+
+ void on_group_pair_added(synfig::String group, etl::handle<synfig::Layer> layer);
+ void on_group_pair_removed(synfig::String group, etl::handle<synfig::Layer> layer);
+
+ void on_activity();
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ bool on_layer_tree_event(GdkEvent *event);
+
+ void on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc);
+
+ void on_layer_status_changed(synfig::Layer::Handle handle,bool);
+
+ bool find_layer_row_(const synfig::Layer::Handle &handle, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
+
+ bool find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
+
+ bool on_group_removed(synfig::String group);
+ bool on_group_changed(synfig::String group);
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+ ~LayerGroupTreeStore();
+
+ Gtk::TreeRow on_group_added(synfig::String group);
+ etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+ etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+ etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+ bool find_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+ bool find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter);
+
+ bool find_prev_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+ void rebuild();
+
+ void refresh();
+
+ void refresh_row(Gtk::TreeModel::Row &row);
+
+ void set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle);
+
+ static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
+
+ /*
+ -- ** -- S T A T I C P U B L I C M E T H O D S ---------------------------
+ */
+
+public:
+
+ static Glib::RefPtr<LayerGroupTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+
+}; // END of class LayerGroupTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layerparamtreestore.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007, 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layerparamtreestore.h"
+#include "iconcontroller.h"
+#include <gtkmm/button.h>
+#include <synfig/paramdesc.h>
+#include "layertree.h"
+#include <synfigapp/action_system.h>
+#include <synfigapp/instance.h>
+#include "app.h"
+#include <ETL/clock>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+class Profiler : private etl::clock
+{
+ const std::string name;
+public:
+ Profiler(const std::string& name):name(name) { reset(); }
+ ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
+};
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static LayerParamTreeStore::Model& ModelHack()
+{
+ static LayerParamTreeStore::Model* model(0);
+ if(!model)model=new LayerParamTreeStore::Model;
+ return *model;
+}
+
+LayerParamTreeStore::LayerParamTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_,LayerTree* layer_tree):
+ Gtk::TreeStore (ModelHack()),
+ CanvasTreeStore (canvas_interface_),
+ layer_tree (layer_tree)
+{
+ queued=0;
+ // Connect all the signals
+ canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_changed));
+ canvas_interface()->signal_value_node_renamed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_renamed));
+ canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_added));
+ canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_deleted));
+ canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_replaced));
+ canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_layer_param_changed));
+
+ canvas_interface()->signal_value_node_child_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_added));
+ canvas_interface()->signal_value_node_child_removed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_removed));
+
+
+ layer_tree->get_selection()->signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_rebuild));
+
+ signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_refresh));
+ rebuild();
+}
+
+LayerParamTreeStore::~LayerParamTreeStore()
+{
+ while(!changed_connection_list.empty())
+ {
+ changed_connection_list.back().disconnect();
+ changed_connection_list.pop_back();
+ }
+
+ if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+ synfig::info("LayerParamTreeStore::~LayerParamTreeStore(): Deleted");
+}
+
+Glib::RefPtr<LayerParamTreeStore>
+LayerParamTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree)
+{
+ return Glib::RefPtr<LayerParamTreeStore>(new LayerParamTreeStore(canvas_interface_,layer_tree));
+}
+
+
+
+void
+LayerParamTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+ if(column<0)
+ {
+ synfig::error("LayerParamTreeStore::get_value_vfunc(): Bad column!");
+ return;
+ }
+
+/* if(column==model.label.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(layer->get_non_empty_description());
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+*/
+ if(column==model.label.index())
+ {
+ synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+ Glib::ustring label;
+
+ if(!(*iter)[model.is_toplevel])
+ return CanvasTreeStore::get_value_vfunc(iter,column,value);
+ synfig::ParamDesc param_desc((*iter)[model.param_desc]);
+ label=param_desc.get_local_name();
+
+ if(!(*iter)[model.is_inconsistent])
+ if(value_desc.is_value_node() && value_desc.get_value_node()->is_exported())
+ {
+ label+=strprintf(" (%s)",value_desc.get_value_node()->get_id().c_str());
+ }
+
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(label);
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.is_toplevel.index())
+ {
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ TreeModel::Path path(get_path(iter));
+
+ x.set(path.get_depth()<=1);
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ if(column==model.is_inconsistent.index())
+ {
+ if((*iter)[model.is_toplevel])
+ {
+ CanvasTreeStore::get_value_vfunc(iter,column,value);
+ return;
+ }
+
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(false);
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ CanvasTreeStore::get_value_vfunc(iter,column,value);
+}
+
+
+
+void
+LayerParamTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+ //if(!iterator_sane(row))
+ // return;
+
+ if(column>=get_n_columns_vfunc())
+ {
+ g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
+ return;
+ }
+
+ if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+ {
+ g_warning("LayerTreeStore::set_value_impl: Bad value type");
+ return;
+ }
+
+ try
+ {
+ if(column==model.value.index())
+ {
+ Glib::Value<synfig::ValueBase> x;
+ g_value_init(x.gobj(),model.value.type());
+ g_value_copy(value.gobj(),x.gobj());
+
+ if((bool)(*iter)[model.is_toplevel])
+ {
+ synfigapp::Action::PassiveGrouper group(canvas_interface()->get_instance().get(),_("Set Layer Params"));
+
+ synfig::ParamDesc param_desc((*iter)[model.param_desc]);
+
+ LayerList::iterator iter2(layer_list.begin());
+
+ for(;iter2!=layer_list.end();++iter2)
+ {
+ if(!canvas_interface()->change_value(synfigapp::ValueDesc(*iter2,param_desc.get_name()),x.get()))
+ {
+ // ERROR!
+ group.cancel();
+ App::dialog_error_blocking(_("Error"),_("Unable to set all layer parameters."));
+
+ return;
+ }
+ }
+ }
+ else
+ {
+ canvas_interface()->change_value((*iter)[model.value_desc],x.get());
+ }
+ return;
+ }
+ else
+/*
+ if(column==model.active.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),model.active.type());
+ g_value_copy(value.gobj(),x.gobj());
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
+
+ if(!action)
+ return;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("layer",layer);
+ action->set_param("new_status",bool(x.get()));
+
+ canvas_interface()->get_instance()->perform_action(action);
+ return;
+ }
+ else
+*/
+ CanvasTreeStore::set_value_impl(iter,column, value);
+ }
+ catch(std::exception x)
+ {
+ g_warning("%s", x.what());
+ }
+}
+
+
+
+
+
+
+
+
+
+
+void
+LayerParamTreeStore::rebuild()
+{
+ // Profiler profiler("LayerParamTreeStore::rebuild()");
+ if(queued)queued=0;
+ clear();
+ layer_list=layer_tree->get_selected_layers();
+
+ if(layer_list.size()<=0)
+ return;
+
+ // Get rid of all the connections,
+ // and clear the connection map.
+ //while(!connection_map.empty())connection_map.begin()->second.disconnect(),connection_map.erase(connection_map.begin());
+ while(!changed_connection_list.empty())
+ {
+ changed_connection_list.back().disconnect();
+ changed_connection_list.pop_back();
+ }
+
+ struct REBUILD_HELPER
+ {
+ ParamVocab vocab;
+ Layer::Handle layer_0;
+
+ static ParamVocab::iterator find_param_desc(ParamVocab& vocab, const synfig::String& x)
+ {
+ ParamVocab::iterator iter;
+
+ for(iter=vocab.begin();iter!=vocab.end();++iter)
+ if(iter->get_name()==x)
+ break;
+ return iter;
+ }
+
+ void process_vocab(synfig::Layer::Handle layer_n)
+ {
+ ParamVocab x = layer_n->get_param_vocab();
+ ParamVocab::iterator iter;
+
+ for(iter=vocab.begin();iter!=vocab.end();++iter)
+ {
+ String name(iter->get_name());
+ ParamVocab::iterator iter2(find_param_desc(x,name));
+ if(iter2==x.end() ||
+ layer_0->get_param(name).get_type() != layer_n->get_param(name).get_type())
+ {
+ // remove it and start over
+ vocab.erase(iter);
+ iter=vocab.begin();
+ iter--;
+ continue;
+ }
+ }
+ }
+
+ } rebuild_helper;
+
+
+ {
+ LayerList::iterator iter(layer_list.begin());
+ rebuild_helper.vocab=(*iter)->get_param_vocab();
+ rebuild_helper.layer_0=*iter;
+
+ for(++iter;iter!=layer_list.end();++iter)
+ {
+ rebuild_helper.process_vocab(*iter);
+ changed_connection_list.push_back(
+ (*iter)->signal_changed().connect(
+ sigc::mem_fun(
+ *this,
+ &LayerParamTreeStore::changed
+ )
+ )
+ );
+ }
+ }
+
+ ParamVocab::iterator iter;
+ for(iter=rebuild_helper.vocab.begin();iter!=rebuild_helper.vocab.end();++iter)
+ {
+ if(iter->get_hidden())
+ continue;
+
+ /*
+ if(iter->get_animation_only())
+ {
+ int length(layer_list.front()->get_canvas()->rend_desc().get_frame_end()-layer_list.front()->get_canvas()->rend_desc().get_frame_start());
+ if(!length)
+ continue;
+ }
+ */
+ Gtk::TreeRow row(*(append()));
+ synfigapp::ValueDesc value_desc(layer_list.front(),iter->get_name());
+ CanvasTreeStore::set_row(row,value_desc);
+ if(value_desc.is_value_node())
+ {
+ changed_connection_list.push_back(
+ value_desc.get_value_node()->signal_changed().connect(
+ sigc::mem_fun(
+ this,
+ &LayerParamTreeStore::changed
+ )
+ )
+ );
+ }
+ if(value_desc.get_value_type()==ValueBase::TYPE_CANVAS)
+ {
+ Canvas::Handle canvas_handle = value_desc.get_value().get(Canvas::Handle());
+ if(canvas_handle) changed_connection_list.push_back(
+ canvas_handle->signal_changed().connect(
+ sigc::mem_fun(
+ this,
+ &LayerParamTreeStore::changed
+ )
+ )
+ );
+ }
+ //row[model.label] = iter->get_local_name();
+ row[model.param_desc] = *iter;
+ row[model.canvas] = layer_list.front()->get_canvas();
+ row[model.is_inconsistent] = false;
+ //row[model.is_toplevel] = true;
+
+
+ LayerList::iterator iter2(layer_list.begin());
+ ValueBase value((*iter2)->get_param(iter->get_name()));
+ for(++iter2;iter2!=layer_list.end();++iter2)
+ {
+ if(value!=((*iter2)->get_param(iter->get_name())))
+ {
+ row[model.is_inconsistent] = true;
+ while(!row.children().empty() && erase(row.children().begin()))
+ ;
+ break;
+ }
+ }
+ }
+}
+
+void
+LayerParamTreeStore::queue_refresh()
+{
+ if(queued)
+ return;
+ queued=1;
+ queue_connection.disconnect();
+ queue_connection=Glib::signal_timeout().connect(
+ sigc::bind_return(
+ sigc::mem_fun(*this,&LayerParamTreeStore::refresh),
+ false
+ )
+ ,150);
+
+}
+
+void
+LayerParamTreeStore::queue_rebuild()
+{
+ if(queued==2)
+ return;
+ queued=2;
+ queue_connection.disconnect();
+ queue_connection=Glib::signal_timeout().connect(
+ sigc::bind_return(
+ sigc::mem_fun(*this,&LayerParamTreeStore::rebuild),
+ false
+ )
+ ,150);
+
+}
+
+void
+LayerParamTreeStore::refresh()
+{
+ if(queued)queued=0;
+
+ Gtk::TreeModel::Children children_(children());
+
+ Gtk::TreeModel::Children::iterator iter;
+
+ if(!children_.empty())
+ for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
+ {
+ Gtk::TreeRow row=*iter;
+ refresh_row(row);
+ }
+}
+
+void
+LayerParamTreeStore::refresh_row(Gtk::TreeModel::Row &row)
+{
+ if(row[model.is_toplevel])
+ {
+ row[model.is_inconsistent] = false;
+ ParamDesc param_desc(row[model.param_desc]);
+
+ LayerList::iterator iter2(layer_list.begin());
+ ValueBase value((*iter2)->get_param(param_desc.get_name()));
+ for(++iter2;iter2!=layer_list.end();++iter2)
+ {
+ if(value!=((*iter2)->get_param(param_desc.get_name())))
+ {
+ row[model.is_inconsistent] = true;
+ while(!row.children().empty() && erase(row.children().begin()))
+ ;
+ return;
+ }
+ }
+ }
+
+ //handle<ValueNode> value_node=row[model.value_node];
+ //if(value_node)
+ {
+ CanvasTreeStore::refresh_row(row);
+ return;
+ }
+}
+
+void
+LayerParamTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc)
+{
+ Gtk::TreeModel::Children children = row.children();
+ while(!children.empty() && erase(children.begin()))
+ ;
+
+ CanvasTreeStore::set_row(row,value_desc);
+}
+
+void
+LayerParamTreeStore::on_value_node_added(synfig::ValueNode::Handle /*value_node*/)
+{
+// queue_refresh();
+}
+
+void
+LayerParamTreeStore::on_value_node_deleted(synfig::ValueNode::Handle /*value_node*/)
+{
+// queue_refresh();
+}
+
+void
+LayerParamTreeStore::on_value_node_child_added(synfig::ValueNode::Handle /*value_node*/,synfig::ValueNode::Handle /*child*/)
+{
+ queue_rebuild();
+}
+
+void
+LayerParamTreeStore::on_value_node_child_removed(synfig::ValueNode::Handle /*value_node*/,synfig::ValueNode::Handle /*child*/)
+{
+ rebuild();
+}
+
+void
+LayerParamTreeStore::on_value_node_changed(synfig::ValueNode::Handle /*value_node*/)
+{
+ queue_refresh();
+}
+
+void
+LayerParamTreeStore::on_value_node_renamed(synfig::ValueNode::Handle /*value_node*/)
+{
+ rebuild();
+}
+
+void
+LayerParamTreeStore::on_value_node_replaced(synfig::ValueNode::Handle /*replaced_value_node*/,synfig::ValueNode::Handle /*new_value_node*/)
+{
+ queue_rebuild();
+}
+
+void
+LayerParamTreeStore::on_layer_param_changed(synfig::Layer::Handle /*handle*/,synfig::String /*param_name*/)
+{
+ queue_refresh();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layerparamtreestore.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_LAYERPARAMTREESTORE_H
+#define __SYNFIG_STUDIO_LAYERPARAMTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include "trees/canvastreestore.h"
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/paramdesc.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerTree;
+
+class LayerParamTreeStore : public CanvasTreeStore
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+ typedef std::list<synfig::Layer::Handle> LayerList;
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ //! TreeModel for the layer parameters
+ class Model : public CanvasTreeStore::Model
+ {
+ public:
+
+ Gtk::TreeModelColumn<synfig::ParamDesc> param_desc;
+
+ Gtk::TreeModelColumn<bool> is_inconsistent;
+ Gtk::TreeModelColumn<bool> is_toplevel;
+
+ Model()
+ {
+ add(param_desc);
+ add(is_inconsistent);
+ add(is_toplevel);
+ }
+ };
+
+ Model model;
+
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ int queued;
+
+ LayerTree* layer_tree;
+
+ LayerList layer_list;
+
+ sigc::connection queue_connection;
+
+ std::list<sigc::connection> changed_connection_list;
+
+ sigc::signal<void> signal_changed_;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+protected:
+ virtual void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+ virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+ virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc);
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ void on_value_node_child_added(synfig::ValueNode::Handle value_node,synfig::ValueNode::Handle child);
+ void on_value_node_child_removed(synfig::ValueNode::Handle value_node,synfig::ValueNode::Handle child);
+
+ void on_value_node_added(synfig::ValueNode::Handle value_node);
+ void on_value_node_deleted(synfig::ValueNode::Handle value_node);
+ virtual void on_value_node_changed(synfig::ValueNode::Handle value_node);
+ virtual void on_value_node_renamed(synfig::ValueNode::Handle value_node);
+ void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
+ void on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name);
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ LayerParamTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_,
+ LayerTree* layer_tree);
+ ~LayerParamTreeStore();
+
+ void rebuild();
+
+ void refresh();
+
+ void queue_refresh();
+
+ void queue_rebuild();
+
+ void refresh_row(Gtk::TreeModel::Row &row);
+
+ sigc::signal<void>& signal_changed() { return signal_changed_; }
+
+ void changed() { signal_changed_(); }
+
+ /*
+ -- ** -- S T A T I C P U B L I C M E T H O D S ---------------------------
+ */
+
+public:
+
+ static Glib::RefPtr<LayerParamTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree);
+}; // END of class LayerParamTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layertree.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007, 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layertree.h"
+#include "layerparamtreestore.h"
+#include "cellrenderer_value.h"
+#include "cellrenderer_timetrack.h"
+#include <synfigapp/action.h>
+#include <synfigapp/instance.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/paned.h>
+#include "app.h"
+#include "instance.h"
+#include <gtkmm/treemodelsort.h>
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+# include <synfig/timepointcollect.h>
+#endif // TIMETRACK_IN_PARAMS_PANEL
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef SMALL_BUTTON
+#define SMALL_BUTTON(button,stockid,tooltip) \
+ button = manage(new class Gtk::Button()); \
+ icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize)); \
+ button->add(*icon); \
+ tooltips_.set_tip(*button,tooltip); \
+ icon->set_padding(0,0);\
+ icon->show(); \
+ button->set_relief(Gtk::RELIEF_NONE); \
+ button->show()
+#endif
+
+#ifndef NORMAL_BUTTON
+#define NORMAL_BUTTON(button,stockid,tooltip) \
+ button = manage(new class Gtk::Button()); \
+ icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON)); \
+ button->add(*icon); \
+ tooltips_.set_tip(*button,tooltip); \
+ icon->set_padding(0,0);\
+ icon->show(); \
+ /*button->set_relief(Gtk::RELIEF_NONE);*/ \
+ button->show()
+#endif
+
+#define NEW_SMALL_BUTTON(x,y,z) Gtk::Button *SMALL_BUTTON(x,y,z)
+
+#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+LayerTree::LayerTree():
+ layer_amount_adjustment_(1,0,1,0.01,0.01,0)
+{
+ param_tree_view_=new Gtk::TreeView;
+ layer_tree_view_=new Gtk::TreeView;
+
+ //Gtk::HPaned* hpaned(manage(new Gtk::HPaned()));
+ //hpaned->show();
+ //attach(*hpaned, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
+ //attach(*create_layer_tree(), 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+ create_layer_tree();
+ create_param_tree();
+
+ //hpaned->pack1(*create_layer_tree(),false,false);
+ //hpaned->pack2(*create_param_tree(),true,false);
+ //hpaned->set_position(200);
+ hbox=manage(new Gtk::HBox());
+
+ attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+ attach(blend_method_widget, 2, 3, 1, 2,Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+
+ layer_amount_hscale=manage(new Gtk::HScale(layer_amount_adjustment_));
+ layer_amount_hscale->set_digits(2);
+ layer_amount_hscale->set_value_pos(Gtk::POS_LEFT);
+ layer_amount_hscale->set_sensitive(false);
+ layer_amount_hscale->set_update_policy( Gtk::UPDATE_DISCONTINUOUS);
+ attach(*layer_amount_hscale, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 1, 1);
+ layer_amount_adjustment_.signal_value_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_amount_value_changed));
+
+ Gtk::Image *icon;
+ //Gtk::IconSize iconsize(Gtk::IconSize::from_name("synfig-small_icon"));
+ Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ SMALL_BUTTON(button_raise,"gtk-go-up","Raise");
+ SMALL_BUTTON(button_lower,"gtk-go-down","Lower");
+ SMALL_BUTTON(button_duplicate,"synfig-duplicate","Duplicate");
+ SMALL_BUTTON(button_encapsulate,"synfig-encapsulate","Encapsulate");
+ SMALL_BUTTON(button_delete,"gtk-delete","Delete");
+
+ hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
+ hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
+ hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
+ hbox->pack_start(*button_encapsulate,Gtk::PACK_SHRINK);
+ hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
+
+ // button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_raise_pressed));
+ // button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_lower_pressed));
+ // button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_duplicate_pressed));
+ // button_encapsulate->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_encapsulate_pressed));
+ // button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_delete_pressed));
+
+ button_raise->set_sensitive(false);
+ button_lower->set_sensitive(false);
+ button_duplicate->set_sensitive(false);
+ button_encapsulate->set_sensitive(false);
+ button_delete->set_sensitive(false);
+
+ get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_selection_changed));
+
+ get_layer_tree_view().set_reorderable(true);
+ get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+ //get_param_tree_view().get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+ get_layer_tree_view().show();
+ get_param_tree_view().show();
+
+ hbox->show();
+ layer_amount_hscale->show();
+ blend_method_widget.show();
+
+ tooltips_.enable();
+ disable_amount_changed_signal=false;
+
+ blend_method_widget.set_param_desc(ParamDesc(Color::BlendMethod(),"blend_method"));
+
+ blend_method_widget.set_value((int)Color::BLEND_COMPOSITE);
+ blend_method_widget.set_size_request(150,-1);
+ blend_method_widget.set_sensitive(false);
+ blend_method_widget.signal_activate().connect(sigc::mem_fun(*this, &studio::LayerTree::on_blend_method_changed));
+}
+
+LayerTree::~LayerTree()
+{
+ if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+ synfig::info("LayerTree::~LayerTree(): Deleted");
+}
+
+Gtk::Widget*
+LayerTree::create_layer_tree()
+{
+ const LayerTreeStore::Model model;
+
+ { // --- O N / O F F ----------------------------------------------------
+ //int index;
+ //index=get_layer_tree_view().append_column_editable(_(" "),layer_model.active);
+ //Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
+
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_(" ")) );
+
+ // Set up the icon cell-renderer
+ Gtk::CellRendererToggle* cellrenderer = Gtk::manage( new Gtk::CellRendererToggle() );
+ cellrenderer->signal_toggled().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_toggle));
+
+ column->pack_start(*cellrenderer,false);
+ column->add_attribute(cellrenderer->property_active(), layer_model.active);
+ get_layer_tree_view().append_column(*column);
+ }
+
+ { // --- I C O N --------------------------------------------------------
+ int index;
+ index=get_layer_tree_view().append_column(_("Z"),layer_model.icon);
+ Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
+ get_layer_tree_view().set_expander_column(*column);
+
+ column->set_sort_column(layer_model.z_depth);
+ //column->set_reorderable();
+ //column->set_resizable();
+ //column->set_clickable();
+
+ //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+ //column->pack_start(*icon_cellrenderer,false);
+ //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
+ }
+ //get_layer_tree_view().append_column(_("Z"),layer_model.z_depth);
+ { // --- N A M E --------------------------------------------------------
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Name")) );
+
+ // Set up the icon cell-renderer
+ Gtk::CellRendererText* cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
+ column->pack_start(*cellrenderer,false);
+ column->add_attribute(cellrenderer->property_text(), layer_model.label);
+ cellrenderer->signal_edited().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_renamed));
+ cellrenderer->property_editable()=true;
+
+ column->set_reorderable();
+ // column->set_resizable();
+ column->set_clickable(true);
+ column->set_sort_column(layer_model.label);
+
+ get_layer_tree_view().append_column(*column);
+
+ // int index;
+// index=get_layer_tree_view().append_column_editable(_("Layer"),layer_model.label);
+ //Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
+
+ //get_layer_tree_view().set_expander_column(*column);
+
+ //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+ //column->pack_start(*icon_cellrenderer,false);
+ //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
+ }
+ { // --- Z D E P T H ----------------------------------------------------
+ int index;
+ index=get_layer_tree_view().append_column(_("Z"),layer_model.z_depth);
+ column_z_depth=get_layer_tree_view().get_column(index-1);
+
+ column_z_depth->set_reorderable();
+ column_z_depth->set_resizable();
+ column_z_depth->set_clickable();
+
+ column_z_depth->set_sort_column(layer_model.z_depth);
+ }
+
+ get_layer_tree_view().set_enable_search(true);
+ get_layer_tree_view().set_search_column(layer_model.label);
+ get_layer_tree_view().set_search_equal_func(sigc::ptr_fun(&studio::LayerTreeStore::search_func));
+
+ std::list<Gtk::TargetEntry> listTargets;
+ listTargets.push_back( Gtk::TargetEntry("LAYER") );
+ get_layer_tree_view().drag_dest_set(listTargets);
+
+ // This makes things easier to read.
+ get_layer_tree_view().set_rules_hint();
+
+ // Make us more sensitive to several events
+ //get_layer_tree_view().add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+
+ get_layer_tree_view().signal_event().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_tree_event));
+ get_layer_tree_view().show();
+
+ Gtk::ScrolledWindow *scroll = manage(new class Gtk::ScrolledWindow());
+ scroll->set_flags(Gtk::CAN_FOCUS);
+ scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ //scroll->add(get_layer_tree_view());
+ scroll->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+ scroll->show();
+
+ return scroll;
+}
+
+Gtk::Widget*
+LayerTree::create_param_tree()
+{
+ Pango::AttrList attr_list;
+ {
+ Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*8));
+ pango_size.set_start_index(0);
+ pango_size.set_end_index(64);
+ attr_list.change(pango_size);
+ }
+
+ Gtk::IconSize icon_size(Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ { // --- N A M E --------------------------------------------------------
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Name")) );
+
+ // Set up the icon cell-renderer
+ Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+ column->pack_start(*icon_cellrenderer,false);
+ column->add_attribute(icon_cellrenderer->property_pixbuf(), param_model.icon);
+
+ // Pack the label into the column
+ //column->pack_start(layer_model.label,true);
+ Gtk::CellRendererText* text_cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
+ column->pack_start(*text_cellrenderer,false);
+ column->add_attribute(text_cellrenderer->property_text(), param_model.label);
+ text_cellrenderer->property_attributes()=attr_list;
+
+ text_cellrenderer->property_foreground()=Glib::ustring("#7f7f7f");
+ column->add_attribute(text_cellrenderer->property_foreground_set(),param_model.is_inconsistent);
+
+ // Pack the label into the column
+ //column->pack_start(param_model.label,true);
+
+ // Set up the value-node icon cell-renderer to be on the far right
+ Gtk::CellRendererPixbuf* valuenode_icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+ column->pack_end(*valuenode_icon_cellrenderer,false);
+ valuenode_icon_cellrenderer->property_pixbuf()=Gtk::Button().render_icon(Gtk::StockID("synfig-value_node"),icon_size);
+ column->add_attribute(valuenode_icon_cellrenderer->property_visible(), param_model.is_shared);
+
+ // Finish setting up the column
+ column->set_reorderable();
+ column->set_resizable();
+ column->set_clickable();
+
+ get_param_tree_view().append_column(*column);
+ }
+ { // --- V A L U E -----------------------------------------------------
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Value")) );
+
+ // Set up the value cell-renderer
+ cellrenderer_value=LayerParamTreeStore::add_cell_renderer_value(column);
+ cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::LayerTree::on_edited_value));
+ cellrenderer_value->property_value()=synfig::ValueBase();
+ column->add_attribute(cellrenderer_value->property_param_desc(), param_model.param_desc);
+ column->add_attribute(cellrenderer_value->property_inconsistent(),param_model.is_inconsistent);
+ //cellrenderer_value->property_canvas()=canvas_interface->get_canvas(); // Is this line necessary?
+ cellrenderer_value->property_attributes()=attr_list;
+
+ // Finish setting up the column
+ get_param_tree_view().append_column(*column);
+ column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
+ column->set_clickable();
+ column->set_min_width(120);
+ column->set_reorderable();
+ column->set_resizable();
+ }
+ { // --- T Y P E --------------------------------------------------------
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Type")) );
+ Gtk::CellRendererText* text_cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
+ column->pack_start(*text_cellrenderer,false);
+ column->add_attribute(text_cellrenderer->property_text(), param_model.type);
+ text_cellrenderer->property_attributes()=attr_list;
+ get_param_tree_view().append_column(*column);
+ column->set_reorderable();
+ column->set_resizable();
+ column->set_clickable();
+ column->set_sort_column(param_model.type);
+ }
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+ { // --- T I M E T R A C K --------------------------------------------
+ Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
+ column_time_track=column;
+
+ // Set up the value-node cell-renderer
+ cellrenderer_time_track=LayerParamTreeStore::add_cell_renderer_value_node(column);
+ cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
+ cellrenderer_time_track->signal_waypoint_clicked_cellrenderer().connect(sigc::mem_fun(*this, &studio::LayerTree::on_waypoint_clicked_layertree) );
+ cellrenderer_time_track->signal_waypoint_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_waypoint_changed) );
+ column->add_attribute(cellrenderer_time_track->property_value_desc(), param_model.value_desc);
+ column->add_attribute(cellrenderer_time_track->property_canvas(), param_model.canvas);
+ column->add_attribute(cellrenderer_time_track->property_visible(), param_model.is_value_node);
+
+ // Finish setting up the column
+ column->set_reorderable();
+ column->set_resizable();
+ column->set_min_width(200);
+
+ if (!getenv("SYNFIG_DISABLE_PARAMS_PANEL_TIMETRACK"))
+ get_param_tree_view().append_column(*column);
+ }
+#endif // TIMETRACK_IN_PARAMS_PANEL
+
+ // This makes things easier to read.
+ get_param_tree_view().set_rules_hint();
+
+ // Make us more sensitive to several events
+ get_param_tree_view().add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+
+ get_param_tree_view().signal_event().connect(sigc::mem_fun(*this, &studio::LayerTree::on_param_tree_event));
+ get_param_tree_view().show();
+
+ Gtk::ScrolledWindow *scroll = manage(new class Gtk::ScrolledWindow());
+ scroll->set_flags(Gtk::CAN_FOCUS);
+ scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ //scroll->add(get_param_tree_view());
+ scroll->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+ scroll->show();
+
+ //column_time_track->set_visible(false);
+
+ return scroll;
+}
+
+void
+LayerTree::on_waypoint_changed( synfig::Waypoint waypoint , synfig::ValueNode::Handle value_node)
+{
+ synfigapp::Action::ParamList param_list;
+ param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+ param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+ param_list.add("value_node",value_node);
+ param_list.add("waypoint",waypoint);
+// param_list.add("time",canvas_interface()->get_time());
+
+ etl::handle<studio::Instance>::cast_static(layer_tree_store_->canvas_interface()->get_instance())->process_action("WaypointSetSmart", param_list);
+}
+
+void
+LayerTree::select_layer(synfig::Layer::Handle layer)
+{
+ Gtk::TreeModel::Children::iterator iter;
+ if(layer_tree_store_->find_layer_row(layer,iter))
+ {
+ if(sorted_layer_tree_store_)
+ iter=sorted_layer_tree_store_->convert_child_iter_to_iter(iter);
+
+ Gtk::TreePath path(iter);
+ for(int i=path.get_depth();i;i--)
+ {
+ int j;
+ path=Gtk::TreePath(iter);
+ for(j=i;j;j--)
+ path.up();
+ get_layer_tree_view().expand_row(path,false);
+ }
+ get_layer_tree_view().scroll_to_row(Gtk::TreePath(iter));
+ get_layer_tree_view().get_selection()->select(iter);
+ }
+}
+
+void
+LayerTree::select_all_children(Gtk::TreeModel::Children::iterator iter)
+{
+ get_layer_tree_view().get_selection()->select(iter);
+ if((bool)(*iter)[layer_model.children_lock])
+ return;
+ get_layer_tree_view().expand_row(layer_tree_store_->get_path(iter),false);
+ Gtk::TreeModel::Children children(iter->children());
+ for(iter=children.begin();iter!=children.end();++iter)
+ select_all_children(iter);
+}
+
+void
+LayerTree::select_all_children_layers(synfig::Layer::Handle layer)
+{
+ Gtk::TreeModel::Children::iterator iter;
+ if(layer_tree_store_->find_layer_row(layer,iter))
+ select_all_children(iter);
+}
+
+void
+LayerTree::select_layers(const LayerList &layer_list)
+{
+ LayerList::const_iterator iter;
+ for(iter = layer_list.begin(); iter != layer_list.end(); ++iter)
+ select_layer(*iter);
+}
+
+static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerTree::LayerList* ret)
+{
+ const LayerTreeStore::Model layer_tree_model;
+ ret->push_back((Layer::Handle)(*iter)[layer_tree_model.layer]);
+}
+
+LayerTree::LayerList
+LayerTree::get_selected_layers()const
+{
+ Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<Gtk::TreeView&>(get_layer_tree_view()).get_selection();
+
+ if(!selection)
+ return LayerList();
+
+ LayerList ret;
+
+ selection->selected_foreach_iter(
+ sigc::bind(
+ sigc::ptr_fun(
+ &__layer_grabber
+ ),
+ &ret
+ )
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+LayerTree::get_selected_layer()const
+{
+ LayerList layers(get_selected_layers());
+
+ if(layers.empty())
+ return 0;
+
+ return *layers.begin();
+}
+
+void
+LayerTree::clear_selected_layers()
+{
+ get_layer_tree_view().get_selection()->unselect_all();
+}
+
+void
+LayerTree::set_show_timetrack(bool x)
+{
+ //column_time_track->set_visible(x);
+// column_time_track->set_visible(false);
+ column_z_depth->set_visible(x);
+}
+
+void
+LayerTree::set_model(Glib::RefPtr<LayerTreeStore> layer_tree_store)
+{
+ layer_tree_store_=layer_tree_store;
+
+ if(false)
+ {
+ sorted_layer_tree_store_=Gtk::TreeModelSort::create(layer_tree_store);
+
+ sorted_layer_tree_store_->set_default_sort_func(sigc::ptr_fun(&studio::LayerTreeStore::z_sorter));
+
+ //sorted_store->set_sort_func(model.time.index(),sigc::mem_fun(&studio::KeyframeTreeStore::time_sorter));
+ //sorted_store->set_sort_column(model.time.index(), Gtk::SORT_ASCENDING);
+
+ get_layer_tree_view().set_model(sorted_layer_tree_store_);
+ }
+ else
+ get_layer_tree_view().set_model(layer_tree_store_);
+
+ layer_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::LayerTree::on_dirty_preview));
+
+ //layer_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::LayerTree::on_dirty_preview));
+
+ layer_tree_store_->canvas_interface()->signal_time_changed().connect(
+ sigc::mem_fun(
+ &get_param_tree_view(),
+ &Gtk::Widget::queue_draw
+ )
+ );
+ if(!param_tree_store_)
+ {
+ param_tree_store_=LayerParamTreeStore::create(layer_tree_store_->canvas_interface(), this);
+ get_param_tree_view().set_model(param_tree_store_);
+ }
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+ if(cellrenderer_time_track && layer_tree_store_ && layer_tree_store_->canvas_interface())
+ cellrenderer_time_track->set_canvas_interface(layer_tree_store_->canvas_interface());
+#endif // TIMETRACK_IN_PARAMS_PANEL
+}
+
+void
+LayerTree::set_time_adjustment(Gtk::Adjustment &adjustment)
+{
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+ cellrenderer_time_track->set_adjustment(adjustment);
+#endif // TIMETRACK_IN_PARAMS_PANEL
+ adjustment.signal_value_changed().connect(sigc::mem_fun(get_param_tree_view(),&Gtk::TreeView::queue_draw));
+ adjustment.signal_changed().connect(sigc::mem_fun(get_param_tree_view(),&Gtk::TreeView::queue_draw));
+}
+
+void
+LayerTree::on_dirty_preview()
+{
+/*
+ if(quick_layer && !disable_amount_changed_signal)
+ {
+ layer_amount_hscale->set_sensitive(true);
+ disable_amount_changed_signal=true;
+ layer_amount_adjustment_.set_value(quick_layer->get_param("amount").get(Real()));
+ disable_amount_changed_signal=false;
+ if(quick_layer->get_param("blend_method").is_valid())
+ {
+ blend_method_widget.set_sensitive(true);
+ disable_amount_changed_signal=true;
+ blend_method_widget.set_value(quick_layer->get_param("blend_method"));
+ disable_amount_changed_signal=false;
+ }
+ }
+*/
+}
+
+void
+LayerTree::on_selection_changed()
+{
+ synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+
+ Gtk::TreeIter iter;
+ if(last_top_selected_layer && !layer_tree_store_->find_layer_row(last_top_selected_layer,iter))
+ {
+ if(layer_list.empty())
+ {
+ last_top_selected_layer=0;
+ layer_tree_view_->get_selection()->select(last_top_selected_path);
+ return;
+ }
+ }
+
+ {
+ if(!layer_list.empty())
+ {
+ last_top_selected_layer=layer_list.front();
+ last_top_selected_path=*layer_tree_view_->get_selection()->get_selected_rows().begin();
+ }
+ else
+ {
+ last_top_selected_layer=0;
+ }
+ }
+
+ if(layer_list.empty())
+ {
+ button_raise->set_sensitive(false);
+ button_lower->set_sensitive(false);
+ button_duplicate->set_sensitive(false);
+ button_encapsulate->set_sensitive(false);
+ button_delete->set_sensitive(false);
+ layer_amount_hscale->set_sensitive(false);
+ blend_method_widget.set_sensitive(false);
+ return;
+ }
+
+ button_raise->set_sensitive(true);
+ button_lower->set_sensitive(true);
+ button_duplicate->set_sensitive(true);
+ button_encapsulate->set_sensitive(true);
+ button_delete->set_sensitive(true);
+
+ if(layer_list.size()==1 && (*layer_list.begin())->get_param("amount").is_valid()&& (*layer_list.begin())->get_param("amount").same_type_as(Real()))
+ {
+ quick_layer=*layer_list.begin();
+ }
+ else
+ quick_layer=0;
+
+ if(quick_layer)
+ {
+ layer_amount_hscale->set_sensitive(true);
+ disable_amount_changed_signal=true;
+ layer_amount_adjustment_.set_value(quick_layer->get_param("amount").get(Real()));
+ disable_amount_changed_signal=false;
+ if(quick_layer->get_param("blend_method").is_valid())
+ {
+ blend_method_widget.set_sensitive(true);
+ disable_amount_changed_signal=true;
+ blend_method_widget.set_value(quick_layer->get_param("blend_method"));
+ disable_amount_changed_signal=false;
+ }
+ else
+ blend_method_widget.set_sensitive(false);
+ }
+ else
+ {
+ layer_amount_hscale->set_sensitive(false);
+ blend_method_widget.set_sensitive(false);
+ }
+}
+
+void
+LayerTree::on_blend_method_changed()
+{
+ if(disable_amount_changed_signal)
+ return;
+ if(!quick_layer)
+ return;
+
+ if(quick_layer->get_param("blend_method").is_valid())
+ {
+ disable_amount_changed_signal=true;
+ signal_edited_value()(synfigapp::ValueDesc(quick_layer,"blend_method"),blend_method_widget.get_value());
+ disable_amount_changed_signal=false;
+ }
+}
+
+void
+LayerTree::on_amount_value_changed()
+{
+ if(disable_amount_changed_signal)
+ return;
+ if(!quick_layer)
+ return;
+
+ disable_amount_changed_signal=true;
+ signal_edited_value()(synfigapp::ValueDesc(quick_layer,"amount"),synfig::ValueBase(layer_amount_adjustment_.get_value()));
+ disable_amount_changed_signal=false;
+}
+
+void
+LayerTree::on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value)
+{
+ Gtk::TreePath path(path_string);
+
+ const Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
+ if(!row)
+ return;
+ row[param_model.value]=value;
+ //signal_edited_value()(row[param_model.value_desc],value);
+}
+
+void
+LayerTree::on_layer_renamed(const Glib::ustring&path_string,const Glib::ustring& value)
+{
+ Gtk::TreePath path(path_string);
+
+ const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+ if(!row)
+ return;
+ row[layer_model.label]=value;
+ get_layer_tree_view().columns_autosize();
+}
+
+void
+LayerTree::on_layer_toggle(const Glib::ustring& path_string)
+{
+ Gtk::TreePath path(path_string);
+
+ const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+ bool active=static_cast<bool>(row[layer_model.active]);
+ row[layer_model.active]=!active;
+}
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+void
+LayerTree::on_waypoint_clicked_layertree(const etl::handle<synfig::Node>& node __attribute__ ((unused)),
+ const synfig::Time& time __attribute__ ((unused)),
+ const synfig::Time& time_offset __attribute__ ((unused)),
+ int button __attribute__ ((unused)))
+{
+ std::set<synfig::Waypoint, std::less<UniqueID> > waypoint_set;
+ synfig::waypoint_collect(waypoint_set,time,node);
+
+ synfigapp::ValueDesc value_desc;
+
+ if (waypoint_set.size() == 1)
+ {
+ ValueNode::Handle value_node(waypoint_set.begin()->get_parent_value_node());
+ assert(value_node);
+
+ Gtk::TreeRow row;
+ if (param_tree_store_->find_first_value_node(value_node, row) && row)
+ value_desc = static_cast<synfigapp::ValueDesc>(row[param_tree_store_->model.value_desc]);
+ }
+
+ if (!waypoint_set.empty())
+ signal_waypoint_clicked_layertree()(value_desc,waypoint_set,button);
+}
+#endif // TIMETRACK_IN_PARAMS_PANEL
+
+bool
+LayerTree::on_layer_tree_event(GdkEvent *event)
+{
+ switch(event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!get_layer_tree_view().get_path_at_pos(
+ int(event->button.x),int(event->button.y), // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+ const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+ if(column->get_first_cell_renderer()==cellrenderer_time_track)
+ return signal_layer_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
+ else
+#endif // TIMETRACK_IN_PARAMS_PANEL
+ if(column->get_first_cell_renderer()==cellrenderer_value)
+ return signal_layer_user_click()(event->button.button,row,COLUMNID_VALUE);
+ else
+ return signal_layer_user_click()(event->button.button,row,COLUMNID_NAME);
+
+ }
+ break;
+
+ case GDK_MOTION_NOTIFY:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!get_layer_tree_view().get_path_at_pos(
+ (int)event->button.x,(int)event->button.y, // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+
+ if(!get_layer_tree_view().get_model()->get_iter(path))
+ break;
+
+ Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+ if(cellrenderer_time_track==column->get_first_cell_renderer())
+ // Movement on TimeLine
+ return true;
+ else
+#endif // TIMETRACK_IN_PARAMS_PANEL
+ if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
+ {
+ tooltips_.unset_tip(*this);
+ Glib::ustring tooltips_string(row[layer_model.tooltip]);
+ last_tooltip_path=path;
+ if(!tooltips_string.empty())
+ {
+ tooltips_.set_tip(*this,tooltips_string);
+ tooltips_.force_window();
+ }
+ }
+ }
+ break;
+ case GDK_BUTTON_RELEASE:
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool
+LayerTree::on_param_tree_event(GdkEvent *event)
+{
+ switch(event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!get_param_tree_view().get_path_at_pos(
+ int(event->button.x),int(event->button.y), // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+ const Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+ if(column && column->get_first_cell_renderer()==cellrenderer_time_track)
+ {
+ Gdk::Rectangle rect;
+ get_param_tree_view().get_cell_area(path,*column,rect);
+ cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
+ cellrenderer_time_track->property_canvas()=row[param_model.canvas];
+ cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+ get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+ return true;
+ //return signal_param_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
+ }
+ else
+#endif // TIMETRACK_IN_PARAMS_PANEL
+ {
+ if(event->button.button==3)
+ {
+ LayerList layer_list(get_selected_layers());
+ if(layer_list.size()<=1)
+ {
+ synfigapp::ValueDesc value_desc(row[param_model.value_desc]);
+ Gtk::Menu* menu(manage(new Gtk::Menu()));
+ menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), menu));
+ App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc,0.5f);
+ menu->popup(event->button.button,gtk_get_current_event_time());
+ return true;
+ }
+ Gtk::Menu* menu(manage(new Gtk::Menu()));
+ menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), menu));
+ std::list<synfigapp::ValueDesc> value_desc_list;
+ ParamDesc param_desc(row[param_model.param_desc]);
+ for(;!layer_list.empty();layer_list.pop_back())
+ value_desc_list.push_back(synfigapp::ValueDesc(layer_list.back(),param_desc.get_name()));
+ App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc_list);
+ menu->popup(event->button.button,gtk_get_current_event_time());
+ return true;
+ }
+ else
+ {
+ if(column->get_first_cell_renderer()==cellrenderer_value)
+ return signal_param_user_click()(event->button.button,row,COLUMNID_VALUE);
+ else
+ return signal_param_user_click()(event->button.button,row,COLUMNID_NAME);
+ }
+ }
+ }
+ break;
+
+ case GDK_MOTION_NOTIFY:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!get_param_tree_view().get_path_at_pos(
+ (int)event->motion.x,(int)event->motion.y, // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+
+ if(!get_param_tree_view().get_model()->get_iter(path))
+ break;
+
+ Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+ if((event->motion.state&GDK_BUTTON1_MASK ||event->motion.state&GDK_BUTTON3_MASK) && column && cellrenderer_time_track==column->get_first_cell_renderer())
+ {
+ Gdk::Rectangle rect;
+ get_param_tree_view().get_cell_area(path,*column,rect);
+ cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
+ cellrenderer_time_track->property_canvas()=row[param_model.canvas];
+ cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+ get_param_tree_view().queue_draw();
+ //get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+ return true;
+ }
+ else
+#endif // TIMETRACK_IN_PARAMS_PANEL
+ if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
+ {
+ tooltips_.unset_tip(*this);
+ Glib::ustring tooltips_string(row[layer_model.tooltip]);
+ last_tooltip_path=path;
+ if(!tooltips_string.empty())
+ {
+ tooltips_.set_tip(*this,tooltips_string);
+ tooltips_.force_window();
+ }
+ }
+ }
+ break;
+ case GDK_BUTTON_RELEASE:
+ {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!get_param_tree_view().get_path_at_pos(
+ (int)event->button.x,(int)event->button.y, // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ ) break;
+
+ if(!get_param_tree_view().get_model()->get_iter(path))
+ break;
+
+ Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+ if(column && cellrenderer_time_track==column->get_first_cell_renderer())
+ {
+ Gdk::Rectangle rect;
+ get_param_tree_view().get_cell_area(path,*column,rect);
+ cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
+ cellrenderer_time_track->property_canvas()=row[param_model.canvas];
+ cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+ get_param_tree_view().queue_draw();
+ get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+ return true;
+
+ }
+#endif // TIMETRACK_IN_PARAMS_PANEL
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+// void
+// LayerTree::on_raise_pressed()
+// {
+// synfigapp::Action::ParamList param_list;
+// param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+// param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+// param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+//
+// {
+// synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+// synfigapp::SelectionManager::LayerList::iterator iter;
+//
+// for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+// param_list.add("layer",Layer::Handle(*iter));
+// }
+// synfigapp::Action::Handle action(synfigapp::Action::create("LayerRaise"));
+// action->set_param_list(param_list);
+// layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+// }
+
+// void
+// LayerTree::on_lower_pressed()
+// {
+// synfigapp::Action::ParamList param_list;
+// param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+// param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+// param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+//
+// {
+// synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+// synfigapp::SelectionManager::LayerList::iterator iter;
+//
+// for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+// param_list.add("layer",Layer::Handle(*iter));
+// }
+//
+// synfigapp::Action::Handle action(synfigapp::Action::create("LayerLower"));
+// action->set_param_list(param_list);
+// layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+// }
+
+// void
+// LayerTree::on_duplicate_pressed()
+// {
+// synfigapp::Action::ParamList param_list;
+// param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+// param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+// param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+//
+// {
+// synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+// synfigapp::SelectionManager::LayerList::iterator iter;
+//
+// for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+// param_list.add("layer",Layer::Handle(*iter));
+// }
+//
+// synfigapp::Action::Handle action(synfigapp::Action::create("LayerDuplicate"));
+// action->set_param_list(param_list);
+// layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+// }
+
+// void
+// LayerTree::on_encapsulate_pressed()
+// {
+// synfigapp::Action::ParamList param_list;
+// param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+// param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+// param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+//
+// {
+// synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+// synfigapp::SelectionManager::LayerList::iterator iter;
+//
+// for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+// param_list.add("layer",Layer::Handle(*iter));
+// }
+//
+// synfigapp::Action::Handle action(synfigapp::Action::create("LayerEncapsulate"));
+// action->set_param_list(param_list);
+// layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+// }
+
+// void
+// LayerTree::on_delete_pressed()
+// {
+// synfigapp::Action::ParamList param_list;
+// param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+// param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+// param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+//
+// {
+// synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+// synfigapp::SelectionManager::LayerList::iterator iter;
+//
+// for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+// param_list.add("layer",Layer::Handle(*iter));
+// }
+//
+// synfigapp::Action::Handle action(synfigapp::Action::create("LayerRemove"));
+// action->set_param_list(param_list);
+// layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+// }
+
+/*
+void
+LayerTree::on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&context, Gtk::SelectionData& selection_data, guint info, guint time)
+{
+ synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
+ synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
+ synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(get_selection()
+ Gtk::TreeRow row = *(get_selection()->get_selected());
+
+ if(synfig::String(gdk_atom_name(selection_data->target))=="LAYER" && (bool)row[model.is_layer])
+ {
+ Layer* layer(((Layer::Handle)row[model.layer]).get());
+ assert(layer);
+ selection_data.set(8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
+ return;
+ }
+}
+
+void
+LayerTree::on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, Gtk::SelectionData& selection_data, guint info, guint time)
+{
+ synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
+ synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
+ synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
+ synfig::info("Dropped x=%d, y=%d",x,y);
+ bool success=false;
+ bool dropped_on_specific_row=false;
+
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!get_path_at_pos(
+ x,y, // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ )
+ {
+ dropped_on_specific_row=false;
+ }
+ else
+ dropped_on_specific_row=true;
+
+ Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+ if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+ {
+ if(synfig::String(selection_data.get_data_type())=="LAYER")do
+ {
+ Layer::Handle src(*reinterpret_cast<Layer**>(selection_data.get_data()));
+ assert(src);
+
+ Canvas::Handle dest_canvas;
+ Layer::Handle dest_layer;
+
+ if(dropped_on_specific_row)
+ {
+ dest_canvas=(Canvas::Handle)(row[model.canvas]);
+ dest_layer=(Layer::Handle)(row[model.layer]);
+ assert(dest_canvas);
+ }
+ else
+ dest_canvas=layer_tree_store_->canvas_interface()->get_canvas();
+
+ // In this case, we are just moving.
+ if(dest_canvas==src->get_canvas())
+ {
+ if(!dest_layer || dest_layer==src)
+ break;
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
+ action->set_param("canvas",dest_canvas);
+ action->set_param("canvas_interface",layer_tree_store_->canvas_interface());
+ action->set_param("layer",src);
+ action->set_param("new_index",dest_canvas->get_depth(dest_layer));
+ if(layer_tree_store_->canvas_interface()->get_instance()->perform_action(action))
+ success=true;
+ else
+ success=false;
+ break;
+ }
+ }while(0);
+ }
+
+ // Finish the drag
+ context->drag_finish(success, false, time);
+}
+*/
+
+/*bool
+LayerTree::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& context,int x, int y, guint time)
+{
+ return get_layer_tree_view().on_drag_motion(context,x,y,time);
+}
+
+void
+LayerTree::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, Gtk::SelectionData& selection_data, guint info, guint time)
+{
+ get_layer_tree_view().on_drag_data_received(context,x,y,selection_data,info,time);
+*/
+/*
+ if(context->gobj()->source_window==context->gobj()->dest_window)
+ {
+ Gtk::TreeView::on_drag_data_received(context,x,y,selection_data,info,time);
+ return;
+ }
+
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *column;
+ int cell_x, cell_y;
+ if(!get_path_at_pos(
+ x,y, // x, y
+ path, // TreeModel::Path&
+ column, //TreeViewColumn*&
+ cell_x,cell_y //int&cell_x,int&cell_y
+ )
+ )
+ {
+ context->drag_finish(false, false, time);
+ }
+
+ if(layer_tree_store_->row_drop_possible(path,selection_data))
+ {
+ if(layer_tree_store_->drag_data_received(path,selection_data))
+ context->drag_finish(true, false, time);
+ }
+ context->drag_finish(false, false, time);
+}
+*/
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layertree.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_LAYERTREE_H
+#define __SYNFIG_STUDIO_LAYERTREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/box.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/scale.h>
+#include <gtkmm/button.h>
+
+#include <synfigapp/canvasinterface.h>
+#include <synfigapp/value_desc.h>
+#include "layertreestore.h"
+#include "layerparamtreestore.h"
+#include <synfig/valuenode_animated.h>
+
+#include "widgets/widget_value.h"
+
+/* === M A C R O S ========================================================= */
+
+// comment this out if you don't want the params dialog to have a 'timetrack' column
+// (alternatively, export SYNFIG_DISABLE_PARAMS_PANEL_TIMETRACK=1 in environment at runtime)
+#define TIMETRACK_IN_PARAMS_PANEL
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class TreeModelSort; };
+
+namespace studio {
+
+class CellRenderer_TimeTrack;
+class CellRenderer_ValueBase;
+
+class LayerTree : public Gtk::Table
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+
+ typedef studio::ColumnID ColumnID;
+/* enum ColumnID
+ {
+ COLUMNID_NAME,
+ COLUMNID_VALUE,
+ COLUMNID_TIME_TRACK,
+
+ COLUMNID_END //!< \internal
+ };
+*/
+ typedef std::list<synfig::Layer::Handle> LayerList;
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ //LayerTreeStore::Model model;
+
+ LayerTreeStore::Model layer_model;
+ LayerParamTreeStore::Model param_model;
+
+ synfig::Layer::Handle last_top_selected_layer;
+ Gtk::TreePath last_top_selected_path;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ Gtk::Tooltips tooltips_;
+ Gtk::TreePath last_tooltip_path;
+
+ Gtk::TreeView* layer_tree_view_;
+
+ Gtk::TreeView* param_tree_view_;
+
+ Gtk::HBox *hbox;
+
+ Gtk::Adjustment layer_amount_adjustment_;
+
+ Gtk::HScale *layer_amount_hscale;
+
+ synfig::Layer::Handle quick_layer;
+
+ Glib::RefPtr<LayerTreeStore> layer_tree_store_;
+
+ Glib::RefPtr<LayerParamTreeStore> param_tree_store_;
+
+ Glib::RefPtr<Gtk::TreeModelSort> sorted_layer_tree_store_;
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+ CellRenderer_TimeTrack *cellrenderer_time_track;
+#endif // TIMETRACK_IN_PARAMS_PANEL
+
+ Gtk::TreeView::Column* column_time_track;
+
+ Gtk::TreeView::Column* column_z_depth;
+
+ CellRenderer_ValueBase *cellrenderer_value;
+
+ sigc::signal<void,synfig::Layer::Handle> signal_layer_toggle_;
+
+ sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase> signal_edited_value_;
+
+ sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_layer_user_click_;
+
+ sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_param_user_click_;
+
+ sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int> signal_waypoint_clicked_layertree_;
+
+ bool disable_amount_changed_signal;
+
+ Gtk::Button *button_raise;
+ Gtk::Button *button_lower;
+ Gtk::Button *button_duplicate;
+ Gtk::Button *button_encapsulate;
+ Gtk::Button *button_delete;
+
+ Widget_ValueBase blend_method_widget;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+ Gtk::Widget* create_layer_tree();
+ Gtk::Widget* create_param_tree();
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ void on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value);
+
+ void on_layer_renamed(const Glib::ustring&path_string,const Glib::ustring& value);
+
+ void on_layer_toggle(const Glib::ustring& path_string);
+
+ void on_waypoint_clicked_layertree(const etl::handle<synfig::Node>& node, const synfig::Time&, const synfig::Time&, int button);
+
+ void on_waypoint_changed( synfig::Waypoint waypoint , synfig::ValueNode::Handle value_node);
+
+ bool on_layer_tree_event(GdkEvent *event);
+
+ bool on_param_tree_event(GdkEvent *event);
+
+ void on_selection_changed();
+
+ void on_dirty_preview();
+
+ void on_amount_value_changed();
+
+ void on_blend_method_changed();
+
+public:
+
+ // void on_raise_pressed();
+
+ // void on_lower_pressed();
+
+ // void on_duplicate_pressed();
+
+ // void on_encapsulate_pressed();
+
+ // void on_delete_pressed();
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ //Gtk::TreeView* get_param_tree_view() { return param_tree_view_; }
+ //Gtk::TreeView& param_tree_view() { return *param_tree_view_; }
+ Gtk::HBox& get_hbox() { return *hbox; }
+
+ Gtk::TreeView& get_layer_tree_view() { return *layer_tree_view_; }
+ Gtk::TreeView& get_param_tree_view() { return *param_tree_view_; }
+
+ const Gtk::TreeView& get_layer_tree_view()const { return *layer_tree_view_; }
+ const Gtk::TreeView& get_param_tree_view()const { return *param_tree_view_; }
+
+ Glib::RefPtr<Gtk::TreeSelection> get_selection() { return get_layer_tree_view().get_selection(); }
+ Glib::SignalProxy1< bool,GdkEvent* > signal_event () { return get_layer_tree_view().signal_event(); }
+
+ LayerTree();
+ ~LayerTree();
+
+ void set_model(Glib::RefPtr<LayerTreeStore> layer_tree_store_);
+
+ void set_time_adjustment(Gtk::Adjustment &adjustment);
+
+ void set_show_timetrack(bool x=true);
+
+ //! Signal called when layer is toggled.
+ sigc::signal<void,synfig::Layer::Handle>& signal_layer_toggle() { return signal_layer_toggle_; }
+
+ //! Signal called with a value has been edited.
+ sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase>& signal_edited_value() { return signal_edited_value_; }
+
+ sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_layer_user_click() { return signal_layer_user_click_; }
+
+ sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_param_user_click() { return signal_param_user_click_; }
+
+ sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int>& signal_waypoint_clicked_layertree() { return signal_waypoint_clicked_layertree_; }
+
+ etl::handle<synfigapp::SelectionManager> get_selection_manager() { return layer_tree_store_->canvas_interface()->get_selection_manager(); }
+
+ void select_layer(synfig::Layer::Handle layer);
+ void select_layers(const LayerList& layer_list);
+ void select_all_children_layers(synfig::Layer::Handle layer);
+ void select_all_children(Gtk::TreeModel::Children::iterator iter);
+ LayerList get_selected_layers()const;
+ synfig::Layer::Handle get_selected_layer()const;
+ void clear_selected_layers();
+
+}; // END of LayerTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layertreestore.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layertreestore.h"
+#include "iconcontroller.h"
+#include <gtkmm/button.h>
+#include <synfig/paramdesc.h>
+#include <synfigapp/action.h>
+#include <synfigapp/instance.h>
+#include "app.h"
+#include "instance.h"
+#include <synfig/layer_pastecanvas.h>
+#include <synfigapp/action_system.h>
+
+#include <gtk/gtkversion.h>
+#include <ETL/clock>
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static LayerTreeStore::Model& ModelHack()
+{
+ static LayerTreeStore::Model* model(0);
+ if(!model)model=new LayerTreeStore::Model;
+ return *model;
+}
+
+LayerTreeStore::LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+ Gtk::TreeStore (ModelHack()),
+ queued (false),
+ canvas_interface_ (canvas_interface_)
+{
+ layer_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ // Connect Signals to Terminals
+ canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_status_changed));
+ canvas_interface()->signal_layer_lowered().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_lowered));
+ canvas_interface()->signal_layer_raised().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_raised));
+ canvas_interface()->signal_layer_removed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_removed));
+ canvas_interface()->signal_layer_inserted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_inserted));
+ canvas_interface()->signal_layer_moved().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_moved));
+ //canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_param_changed));
+ canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_new_description));
+
+ canvas_interface()->signal_time_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::refresh));
+
+ //canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_changed));
+ //canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_added));
+ //canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_deleted));
+ //canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_replaced));
+
+ set_default_sort_func(sigc::ptr_fun(index_sorter));
+
+// rebuild();
+}
+
+LayerTreeStore::~LayerTreeStore()
+{
+ if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+ synfig::info("LayerTreeStore::~LayerTreeStore(): Deleted");
+}
+
+int
+LayerTreeStore::z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+ const Model model;
+
+ float diff((float)(*rhs)[model.z_depth]-(float)(*lhs)[model.z_depth]);
+
+ if(diff<0)
+ return -1;
+ if(diff>0)
+ return 1;
+ return 0;
+}
+
+int
+LayerTreeStore::index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+ const Model model;
+
+ return ((int)(*rhs)[model.index]-(int)(*lhs)[model.index]);
+}
+
+bool
+LayerTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
+{
+ const Model model;
+
+ Glib::ustring substr(x.uppercase());
+ Glib::ustring label((*iter)[model.label]);
+ label=label.uppercase();
+
+ return label.find(substr)==Glib::ustring::npos;
+}
+
+
+Glib::RefPtr<LayerTreeStore>
+LayerTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
+{
+ return Glib::RefPtr<LayerTreeStore>(new LayerTreeStore(canvas_interface_));
+}
+
+void
+LayerTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+ if(column==model.index.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<int> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(layer->get_depth());
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else if(column==model.z_depth.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<float> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(layer->get_z_depth(canvas_interface()->get_time())*1.0001+layer->get_depth());
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else if(column==model.children_lock.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),x.value_type());
+ x.set(false);
+
+ ValueBase v(layer->get_param("children_lock"));
+ if(v.same_type_as(bool()))
+ x.set(v.get(bool()));
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else if(column==model.label.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(layer->get_non_empty_description());
+
+ g_value_init(value.gobj(),x.value_type());
+ //g_value_copy(x.gobj(),value.gobj());
+ value=x;
+ }
+ else if(column==model.tooltip.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),x.value_type());
+
+
+ x.set(layer->get_local_name());
+
+ g_value_init(value.gobj(),x.value_type());
+ //g_value_copy(x.gobj(),value.gobj());
+ value=x;
+ }
+ else if(column==model.canvas.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<Canvas::Handle> x;
+ g_value_init(x.gobj(),x.value_type());
+
+
+ x.set(layer->get_canvas());
+
+ g_value_init(value.gobj(),x.value_type());
+ //g_value_copy(x.gobj(),value.gobj());
+ value=x;
+ }
+ else if(column==model.active.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),x.value_type());
+
+ x.set(layer->active());
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else if(column==model.icon.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+ if(!layer)return;
+
+ Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
+ g_value_init(x.gobj(),x.value_type());
+
+ //x.set(layer_icon);
+ x.set(get_tree_pixbuf_layer(layer->get_name()));
+
+ g_value_init(value.gobj(),x.value_type());
+ g_value_copy(x.gobj(),value.gobj());
+ }
+ else
+ Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+void
+LayerTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+ //if(!iterator_sane(row))
+ // return;
+
+ if(column>=get_n_columns_vfunc())
+ {
+ g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
+ return;
+ }
+
+ if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+ {
+ g_warning("LayerTreeStore::set_value_impl: Bad value type");
+ return;
+ }
+
+ try
+ {
+ if(column==model.label.index())
+ {
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),model.label.type());
+ g_value_copy(value.gobj(),x.gobj());
+
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+ if(!layer)
+ return;
+ synfig::String new_desc(x.get());
+
+ if(new_desc==layer->get_local_name())
+ new_desc=synfig::String();
+
+ if(new_desc==layer->get_description())
+ return;
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetDesc"));
+
+ if(!action)
+ return;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("layer",layer);
+ action->set_param("new_description",synfig::String(x.get()));
+
+ canvas_interface()->get_instance()->perform_action(action);
+ return;
+ }
+ else if(column==model.active.index())
+ {
+ synfig::Layer::Handle layer((*iter)[model.layer]);
+
+ if(!layer)return;
+
+ Glib::Value<bool> x;
+ g_value_init(x.gobj(),model.active.type());
+ g_value_copy(value.gobj(),x.gobj());
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
+
+ if(!action)
+ return;
+
+ action->set_param("canvas",canvas_interface()->get_canvas());
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("layer",layer);
+ action->set_param("new_status",bool(x.get()));
+
+ canvas_interface()->get_instance()->perform_action(action);
+ return;
+ }
+ else
+ Gtk::TreeStore::set_value_impl(iter,column, value);
+
+ }
+ catch(std::exception x)
+ {
+ g_warning("%s", x.what());
+ }
+}
+
+
+
+
+bool
+LayerTreeStore::row_draggable_vfunc (const TreeModel::Path& /*path*/)const
+{
+ //if(!get_iter(path)) return false;
+// Gtk::TreeModel::Row row(*get_iter(path));
+
+ return true;
+// return (bool)true;
+}
+
+bool
+LayerTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
+{
+ if(!const_cast<LayerTreeStore*>(this)->get_iter(path)) return false;
+ //synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
+ //synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
+ //synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+ Gtk::TreeModel::Row row(*const_cast<LayerTreeStore*>(this)->get_iter(path));
+
+ if((bool)true)
+ {
+ Layer* layer(((Layer::Handle)row[model.layer]).get());
+ assert(layer);
+ bool included(false);
+
+ //gtk_selection_data_set (selection_data, gdk_atom_intern("LAYER",false), 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
+
+ std::vector<Layer*> layers;
+ // The following is a hack for multiple row DND
+ {
+ synfigapp::SelectionManager::LayerList bleh(get_canvas_interface()->get_selection_manager()->get_selected_layers());
+ if(bleh.empty())
+ {
+ selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
+ return true;
+ }
+ while(!bleh.empty())
+ {
+ if(bleh.back().get()==layer)
+ included=true;
+ layers.push_back(bleh.back().get());
+ bleh.pop_back();
+ }
+ }
+ if(!included)
+ layers.push_back(layer);
+ selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
+
+ return true;
+ }
+ return false;
+}
+
+bool
+LayerTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
+{
+ return true;
+}
+
+bool
+LayerTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
+{
+ //if(!const_cast<LayerTreeStore*>(this)->get_iter(dest)) return false;
+
+ //synfig::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
+ //synfig::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
+ //synfig::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+ //Gtk::TreeModel::Row row(*get_iter(dest));
+
+ if(synfig::String(selection_data.get_data_type())=="LAYER" && (bool)true)
+ {
+ //Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+ //assert(src);
+
+ //return true;
+ TreeModel::Path dest_parent(dest);
+ if(!dest_parent.up() || dest.get_depth()==1)
+ {
+ //row=(*get_iter(dest));
+ //dest_canvas=(Canvas::Handle)(row[model.canvas]);
+ return true;
+ }
+ else if((bool)const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))
+ return (bool)(Canvas::Handle)(*const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))[model.contained_canvas];
+ }
+ return false;
+}
+
+bool
+LayerTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
+{
+
+ //if(!dest_parent.up() || !get_iter(dest)) return false;
+
+ bool ret=false;
+ int i(0);
+
+
+ //synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
+ //synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
+ //synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
+ synfigapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Move Layers"));
+
+ // Save the selection data
+ synfigapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+
+ if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+ {
+ Gtk::TreeModel::Row row;
+ Canvas::Handle dest_canvas;
+
+ int dest_layer_depth=dest.back();
+
+ TreeModel::Path dest_parent(dest);
+ if(!dest_parent.up() || !get_iter(dest_parent))
+ {
+ TreeModel::Path dest_(dest);
+ if(!get_iter(dest_))
+ dest_.prev();
+
+ if(!get_iter(dest_))
+ return false;
+
+ {
+ row=(*get_iter(dest_));
+ dest_canvas=(Canvas::Handle)(row[model.canvas]);
+ }
+ }
+ else
+ {
+ row=(*get_iter(dest_parent));
+ dest_canvas=row[model.contained_canvas];
+ }
+
+ assert(dest_canvas);
+
+ Layer::Handle dest_layer(row[model.layer]);
+
+ if(synfig::String(selection_data.get_data_type())=="LAYER")for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
+ {
+ //synfig::info("dest_layer_depth=%d",dest_layer_depth);
+
+ Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+ assert(src);
+ if(dest_layer==src)
+ continue;
+
+ if(dest_canvas==src->get_canvas() && src->get_depth()<dest_layer_depth)
+ dest_layer_depth--;
+
+ // In this case, we are just moving.
+// if(dest_canvas==src->get_canvas())
+ {
+ //if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
+ // dest_layer_depth--;
+ if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
+ continue;
+
+ synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
+ action->set_param("canvas",dest_canvas);
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("layer",src);
+ action->set_param("new_index",dest_layer_depth);
+ action->set_param("dest_canvas",dest_canvas);
+ if(canvas_interface()->get_instance()->perform_action(action))
+ ret=true;
+ else
+ {
+ passive_grouper.cancel();
+ return false;
+ }
+ continue;
+ }
+ /*else // In this case we need to remove and then add
+ {
+
+ synfigapp::Action::Handle action;
+ action=synfigapp::Action::create("LayerRemove");
+ action->set_param("canvas",Canvas::Handle(src->get_canvas()));
+ if(!action->set_param("canvas_interface",App::get_instance(src->get_canvas())->find_canvas_interface(src->get_canvas())))
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("layer",src);
+ if(!canvas_interface()->get_instance()->perform_action(action))
+ {
+ passive_grouper.cancel();
+ ret=false;
+ return false;
+ }
+
+ action=synfigapp::Action::create("LayerAdd");
+ action->set_param("canvas",dest_canvas);
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("new",src);
+ if(!canvas_interface()->get_instance()->perform_action(action))
+ {
+ passive_grouper.cancel();
+ ret=false;
+ return false;
+ }
+
+ if(dest_layer_depth!=0)
+ {
+ action=synfigapp::Action::create("LayerMove");
+ action->set_param("canvas",dest_canvas);
+ action->set_param("canvas_interface",canvas_interface());
+ action->set_param("layer",src);
+ action->set_param("new_index",dest_layer_depth);
+ if(!canvas_interface()->get_instance()->perform_action(action))
+ {
+ passive_grouper.cancel();
+ ret=false;
+ return false;
+ }
+ }
+ ret=true;
+ }
+ */
+ }
+ }
+ synfig::info("I supposedly moved %d layers",i);
+
+ // Reselect the previously selected layers
+ canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
+
+ return ret;
+}
+
+void
+LayerTreeStore::queue_rebuild()
+{
+ if (queued) return;
+ queued = false;
+ queue_connection.disconnect();
+ queue_connection=Glib::signal_timeout().connect(
+ sigc::bind_return(
+ sigc::mem_fun(*this,&LayerTreeStore::rebuild),
+ false
+ )
+ ,150);
+}
+
+void
+LayerTreeStore::rebuild()
+{
+ if (queued) queued = false;
+
+ // disconnect any subcanvas_changed connections
+ std::map<synfig::Layer::Handle, sigc::connection>::iterator iter;
+ for (iter = subcanvas_changed_connections.begin(); iter != subcanvas_changed_connections.end(); iter++)
+ iter->second.disconnect();
+ subcanvas_changed_connections.clear();
+
+ //etl::clock timer;timer.reset();
+
+ //synfig::warning("---------rebuilding layer table---------");
+ // Save the selection data
+ synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+
+ // Clear out the current list
+ clear();
+
+ // Go ahead and add all the layers
+ std::for_each(
+ canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
+ sigc::mem_fun(*this, &studio::LayerTreeStore::on_layer_added)
+ );
+
+ // Reselect the previously selected layers
+ if(!layer_list.empty())
+ canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
+
+ //synfig::info("LayerTreeStore::rebuild() took %f seconds",float(timer()));
+}
+
+void
+LayerTreeStore::refresh()
+{
+ etl::clock timer;timer.reset();
+
+ Gtk::TreeModel::Children children_(children());
+
+ Gtk::TreeModel::Children::iterator iter;
+
+ if(!children_.empty())
+ for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
+ {
+ Gtk::TreeRow row=*iter;
+ refresh_row(row);
+ }
+ //synfig::info("LayerTreeStore::refresh() took %f seconds",float(timer()));
+}
+
+void
+LayerTreeStore::refresh_row(Gtk::TreeModel::Row &row)
+{
+ Layer::Handle layer=row[model.layer];
+ /*
+ {
+ row[model.name] = layer->get_local_name();
+ if(layer->get_description().empty())
+ {
+ row[model.label] = layer->get_local_name();
+ row[model.tooltip] = Glib::ustring("Layer");
+ }
+ else
+ {
+ row[model.label] = layer->get_description();
+ row[model.tooltip] = layer->get_local_name();
+ }
+ }
+ */
+
+ if(layer->dynamic_param_list().count("z_depth"))
+ row[model.z_depth]=Time::begin();
+ // row_changed(get_path(row),row);
+
+ Gtk::TreeModel::Children children = row.children();
+ Gtk::TreeModel::Children::iterator iter;
+
+ if(!children.empty())
+ for(iter = children.begin(); iter && iter != children.end(); ++iter)
+ {
+ Gtk::TreeRow row=*iter;
+ refresh_row(row);
+ }
+}
+
+
+void
+LayerTreeStore::set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle)
+{
+ //row[model.id] = handle->get_name();
+ //row[model.name] = handle->get_local_name();
+ /*if(handle->get_description().empty())
+ {
+ //row[model.label] = handle->get_local_name();
+ row[model.tooltip] = Glib::ustring("Layer");
+ }
+ else
+ {
+ //row[model.label] = handle->get_description();
+ row[model.tooltip] = handle->get_local_name();
+ }*/
+
+ //row[model.active] = handle->active();
+ row[model.layer] = handle;
+ //row[model.canvas] = handle->get_canvas();
+ //row[model.icon] = layer_icon;
+
+ synfig::Layer::ParamList paramlist=handle->get_param_list();
+
+ synfig::Layer::Vocab vocab=handle->get_param_vocab();
+ synfig::Layer::Vocab::iterator iter;
+
+ for(iter=vocab.begin();iter!=vocab.end();++iter)
+ {
+ if(iter->get_hidden())
+ continue;
+ if(handle->get_param(iter->get_name()).get_type()!=ValueBase::TYPE_CANVAS)
+ continue;
+
+ {
+ Canvas::Handle canvas;
+ canvas=handle->get_param(iter->get_name()).get(canvas);
+ if(!canvas)
+ continue;
+
+ Canvas::reverse_iterator iter;
+ row[model.contained_canvas]=canvas;
+
+ for(iter=canvas->rbegin();iter!=canvas->rend();++iter)
+ {
+ Gtk::TreeRow row_(*(prepend(row.children())));
+ set_row_layer(row_,*iter);
+ }
+ continue;
+ }
+
+ /*
+ etl::handle<ValueNode> value_node;
+ if(handle.constant()->dynamic_param_list().count(iter->get_name()))
+ value_node=handle->dynamic_param_list()[iter->get_name()];
+
+ Gtk::TreeRow child_row = *(append(row.children()));
+ set_row_param(
+ child_row,
+ handle,
+ iter->get_name(),
+ iter->get_local_name(),
+ paramlist[iter->get_name()],
+ value_node,
+ &*iter
+ );
+ */
+ }
+}
+
+void
+LayerTreeStore::on_layer_added(synfig::Layer::Handle layer)
+{
+ if (etl::handle<Layer_PasteCanvas>::cast_dynamic(layer))
+ subcanvas_changed_connections[layer] =
+ (etl::handle<Layer_PasteCanvas>::cast_dynamic(layer))->signal_subcanvas_changed().connect(
+ sigc::mem_fun(*this,&studio::LayerTreeStore::queue_rebuild)
+ );
+
+ assert(layer);
+ Gtk::TreeRow row;
+ if(canvas_interface()->get_canvas()==layer->get_canvas())
+ {
+ row=*(prepend());
+ }
+ else
+ {
+ Gtk::TreeModel::Children::iterator iter;
+ if(!find_canvas_row(layer->get_canvas(),iter))
+ {
+ rebuild();
+ return;
+ }
+ row=*(prepend(iter->children()));
+ }
+ set_row_layer(row,layer);
+}
+
+void
+LayerTreeStore::on_layer_removed(synfig::Layer::Handle handle)
+{
+ if (etl::handle<Layer_PasteCanvas>::cast_dynamic(handle))
+ {
+ subcanvas_changed_connections[handle].disconnect();
+ subcanvas_changed_connections.erase(handle);
+ }
+ Gtk::TreeModel::Children::iterator iter;
+ if(find_layer_row(handle,iter))
+ erase(iter);
+ else
+ {
+ synfig::error("LayerTreeStore::on_layer_removed():Unable to find layer to be removed, forced to rebuild...");
+ rebuild();
+ }
+}
+
+void
+LayerTreeStore::on_layer_inserted(synfig::Layer::Handle handle,int depth)
+{
+ if(depth==0)
+ {
+ on_layer_added(handle);
+ return;
+ }
+
+ Gtk::TreeModel::Children children_(children());
+ if(canvas_interface()->get_canvas()!=handle->get_canvas())
+ {
+ Gtk::TreeModel::Children::iterator iter;
+ if(!find_canvas_row(handle->get_canvas(),iter))
+ {
+ synfig::error("LayerTreeStore::on_layer_inserted():Unable to find canvas row, forced to rebuild...");
+ rebuild();
+ return;
+ }
+ children_=iter->children();
+ }
+
+ Gtk::TreeModel::Children::iterator iter(children_.begin());
+ while(depth-- && iter)
+ {
+ ++iter;
+ if(!iter || iter==children_.end())
+ {
+ synfig::error("LayerTreeStore::on_layer_inserted():Unable to achieve desired depth, forced to rebuild...");
+ rebuild();
+ return;
+ }
+ }
+
+ Gtk::TreeModel::Row row(*insert(iter));
+ set_row_layer(row,handle);
+}
+
+void
+LayerTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
+{
+ Gtk::TreeModel::Children::iterator iter;
+ if(find_layer_row(handle,iter))
+ (*iter)[model.layer]=handle;
+ else
+ {
+ synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
+ rebuild();
+ }
+}
+
+void
+LayerTreeStore::on_layer_lowered(synfig::Layer::Handle layer)
+{
+ Gtk::TreeModel::Children::iterator iter, iter2;
+ if(find_layer_row(layer,iter))
+ {
+ // Save the selection data
+ //synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+ iter2=iter;
+ iter2++;
+ if(!iter2)
+ {
+ rebuild();
+ return;
+ }
+
+ //Gtk::TreeModel::Row row(*iter);
+ Gtk::TreeModel::Row row2 = *iter2;
+ synfig::Layer::Handle layer2=row2[model.layer];
+
+ erase(iter2);
+ row2=*insert(iter);
+ set_row_layer(row2,layer2);
+
+ }
+ else
+ rebuild();
+}
+
+void
+LayerTreeStore::on_layer_raised(synfig::Layer::Handle layer)
+{
+ Gtk::TreeModel::Children::iterator iter, iter2;
+
+ Gtk::TreeModel::Children children_(children());
+
+ if(find_layer_row_(layer, canvas_interface()->get_canvas(), children_, iter,iter2))
+ {
+ if(iter!=iter2)
+ {
+ //Gtk::TreeModel::Row row = *iter;
+ Gtk::TreeModel::Row row2 = *iter2;
+ synfig::Layer::Handle layer2=row2[model.layer];
+
+ erase(iter2);
+ iter++;
+ row2=*insert(iter);
+ set_row_layer(row2,layer2);
+
+ return;
+ }
+ }
+
+ rebuild();
+}
+
+void
+LayerTreeStore::on_layer_moved(synfig::Layer::Handle layer,int depth, synfig::Canvas::Handle /*canvas*/)
+{
+ on_layer_removed(layer);
+ on_layer_inserted(layer,depth);
+}
+
+void
+LayerTreeStore::on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name)
+{
+ if(param_name=="z_depth")
+ {
+ Gtk::TreeModel::Children::iterator iter;
+ if(find_layer_row(handle,iter))
+ {
+ (*iter)[model.z_depth]=Time::begin();
+ }
+ }
+
+ /*
+ Gtk::TreeModel::Children::iterator iter;
+ if(find_layer_row(handle,iter))
+ {
+ Gtk::TreeModel::Children children(iter->children());
+
+ for(iter = children.begin(); iter && iter != children.end(); ++iter)
+ {
+ if((Glib::ustring)(*iter)[model.param_name]==param_name)
+ {
+ Gtk::TreeRow row=*iter;
+ refresh_row(row);
+ return;
+ }
+ }
+ }
+ rebuild();
+ */
+}
+
+void
+LayerTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
+{
+ Gtk::TreeModel::Children::iterator iter;
+ if(find_layer_row(handle,iter))
+ {
+ Gtk::TreeRow row(*iter);
+
+ Layer::Handle layer(row[model.layer]);
+
+ if(desc.empty())
+ {
+ //row[model.label]=layer->get_local_name();
+ row[model.tooltip]=Glib::ustring(_("Layer"));
+ }
+ else
+ //row[model.label]=layer->get_description();
+ row[model.tooltip]=layer->get_local_name();
+ }
+ else
+ {
+ rebuild();
+ }
+}
+
+bool
+LayerTreeStore::find_canvas_row_(synfig::Canvas::Handle canvas, synfig::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter)
+{
+ if(canvas==parent)
+ return false;
+
+ {
+ for(iter=layers.begin(); iter && iter != layers.end(); ++iter)
+ {
+ Gtk::TreeModel::Row row = *iter;
+ if(canvas==(synfig::Canvas::Handle)row[model.contained_canvas])
+ return true;
+ }
+
+ iter=children().end();
+ //return false;
+ }
+
+ Gtk::TreeModel::Children::iterator iter2;
+ //Gtk::TreeModel::Children::iterator iter3;
+
+ for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+ {
+ Gtk::TreeModel::Row row = *iter2;
+ assert((bool)true);
+
+ if(row.children().empty())
+ continue;
+
+ Canvas::Handle sub_canvas((*row.children().begin())[model.canvas]);
+ if(!sub_canvas)
+ continue;
+
+ if(find_canvas_row_(canvas,sub_canvas,iter2->children(),iter))
+ return true;
+ }
+
+ iter=children().end();
+ return false;
+}
+
+bool
+LayerTreeStore::find_canvas_row(synfig::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter)
+{
+ return find_canvas_row_(canvas,canvas_interface()->get_canvas(),children(),iter);
+}
+
+
+bool
+LayerTreeStore::find_layer_row_(const synfig::Layer::Handle &layer, synfig::Canvas::Handle /*canvas*/, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
+{
+ assert(layer);
+
+ //if(layer->get_canvas()==canvas)
+ {
+ for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
+ {
+ Gtk::TreeModel::Row row = *iter;
+ if(layer==(synfig::Layer::Handle)row[model.layer])
+ return true;
+ }
+
+ iter=children().end();
+ //return false;
+ }
+
+ Gtk::TreeModel::Children::iterator iter2;
+
+ for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+ {
+ Gtk::TreeModel::Row row = *iter2;
+ assert((bool)true);
+
+ if(row.children().empty())
+ continue;
+
+ Canvas::Handle canvas((*row.children().begin())[model.canvas]);
+ if(!canvas)
+ continue;
+
+ if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
+ return true;
+ }
+
+ iter=children().end();
+ return false;
+}
+
+bool
+LayerTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
+{
+ Gtk::TreeModel::Children::iterator prev;
+ return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
+}
+
+bool
+LayerTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
+{
+ Gtk::TreeModel::Children::iterator iter;
+ if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
+ return false;
+ if(iter==children().begin())
+ return false;
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layertreestore.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_LAYERTREESTORE_H
+#define __SYNFIG_STUDIO_LAYERTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <gtkmm/treeview.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerTreeStore : virtual public Gtk::TreeStore
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+
+ class Model : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+ Gtk::TreeModelColumn<Glib::ustring> label;
+ Gtk::TreeModelColumn<Glib::ustring> name;
+ Gtk::TreeModelColumn<Glib::ustring> id;
+
+ Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
+
+ Gtk::TreeModelColumn<Glib::ustring> tooltip;
+
+
+ Gtk::TreeModelColumn<bool> active;
+ Gtk::TreeModelColumn<synfig::Layer::Handle> layer;
+ Gtk::TreeModelColumn<synfig::Canvas::Handle> contained_canvas;
+
+ Gtk::TreeModelColumn<bool> children_lock;
+
+ Gtk::TreeModelColumn<float> z_depth;
+ Gtk::TreeModelColumn<int> index;
+
+ Model()
+ {
+ add(icon);
+ add(label);
+ add(name);
+ add(id);
+ add(canvas);
+ add(tooltip);
+ add(active);
+ add(layer);
+ add(contained_canvas);
+ add(z_depth);
+ add(index);
+ add(children_lock);
+ }
+ };
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ //! TreeModel for the layers
+ const Model model;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ bool queued;
+
+ sigc::connection queue_connection;
+
+ std::map<synfig::Layer::Handle, sigc::connection> subcanvas_changed_connections;
+
+ etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
+
+ Glib::RefPtr<Gdk::Pixbuf> layer_icon;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- P R O T E C T E D M E T H O D S -----------------------------------
+ */
+
+private:
+ virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+ virtual void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+
+ virtual bool row_draggable_vfunc (const TreeModel::Path& path)const;
+ virtual bool drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
+ virtual bool drag_data_delete_vfunc (const TreeModel::Path& path);
+ virtual bool drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
+ virtual bool row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ bool on_layer_tree_event(GdkEvent *event);
+
+ void on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc);
+
+ void on_layer_added(synfig::Layer::Handle handle);
+
+ void on_layer_removed(synfig::Layer::Handle handle);
+
+ void on_layer_inserted(synfig::Layer::Handle handle,int depth);
+
+ void on_layer_moved(synfig::Layer::Handle handle,int depth, synfig::Canvas::Handle canvas);
+
+ void on_layer_status_changed(synfig::Layer::Handle handle,bool);
+
+ void on_layer_lowered(synfig::Layer::Handle handle);
+
+ void on_layer_raised(synfig::Layer::Handle handle);
+
+ void on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name);
+
+ //void on_value_node_added(synfig::ValueNode::Handle value_node);
+
+ //void on_value_node_deleted(synfig::ValueNode::Handle value_node);
+
+ //void on_value_node_changed(synfig::ValueNode::Handle value_node);
+
+ //void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
+
+ bool find_layer_row_(const synfig::Layer::Handle &handle, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
+
+ bool find_canvas_row_(synfig::Canvas::Handle canvas, synfig::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter);
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+ ~LayerTreeStore();
+
+ etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+ etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+ etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+ bool find_canvas_row(synfig::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter);
+
+ bool find_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+ bool find_prev_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+ void queue_rebuild();
+
+ void rebuild();
+
+ void refresh();
+
+ void refresh_row(Gtk::TreeModel::Row &row);
+
+ void set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle);
+
+ static int z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+ static int index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+
+ //void set_row_param(Gtk::TreeRow &row,synfig::Layer::Handle &handle,const std::string& name, const std::string& local_name, const synfig::ValueBase &value, etl::handle<synfig::ValueNode> value_node,synfig::ParamDesc *param_desc);
+
+ //virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc);
+ static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
+
+ /*
+ -- ** -- S T A T I C P U B L I C M E T H O D S ---------------------------
+ */
+
+public:
+
+ static Glib::RefPtr<LayerTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+
+
+}; // END of class LayerTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file metadatatreestore.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2008 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "metadatatreestore.h"
+#include <synfigapp/canvasinterface.h>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static MetaDataTreeStore::Model& ModelHack()
+{
+ static MetaDataTreeStore::Model* model(0);
+ if(!model)model=new MetaDataTreeStore::Model;
+ return *model;
+}
+
+MetaDataTreeStore::MetaDataTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+ Gtk::TreeStore (ModelHack()),
+ canvas_interface_ (canvas_interface_)
+{
+ // Connect the signal
+ get_canvas()->signal_meta_data_changed().connect(sigc::mem_fun(*this,&MetaDataTreeStore::meta_data_changed));
+
+ rebuild();
+}
+
+MetaDataTreeStore::~MetaDataTreeStore()
+{
+ if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+ synfig::info("MetaDataTreeStore::~MetaDataTreeStore(): Deleted");
+}
+
+Glib::RefPtr<MetaDataTreeStore>
+MetaDataTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
+{
+ return Glib::RefPtr<MetaDataTreeStore>(new MetaDataTreeStore(canvas_interface_));
+}
+
+void
+MetaDataTreeStore::meta_data_changed(synfig::String /*key*/)
+{
+ rebuild();
+}
+
+void
+MetaDataTreeStore::rebuild()
+{
+ clear();
+
+ std::list<String> keys(get_canvas()->get_meta_data_keys());
+
+ for(;!keys.empty();keys.pop_front())
+ {
+ Gtk::TreeRow row(*append());
+ row[model.key]=keys.front();
+ }
+}
+
+void
+MetaDataTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+ if(column>=get_n_columns_vfunc())
+ {
+ g_warning("MetaDataTreeStore::set_value_impl: Bad column (%d)",column);
+ return;
+ }
+
+ if(column==model.data.index())
+ {
+ synfig::String key((Glib::ustring)(*iter)[model.key]);
+ g_value_init(value.gobj(),G_TYPE_STRING);
+ g_value_set_string(value.gobj(),get_canvas()->get_meta_data(key).c_str());
+ return;
+ }
+ else
+ Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+void
+MetaDataTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+ if(column>=get_n_columns_vfunc())
+ {
+ g_warning("MetaDataTreeStore::set_value_impl: Bad column (%d)",column);
+ return;
+ }
+
+ if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+ {
+ g_warning("MetaDataTreeStore::set_value_impl: Bad value type");
+ return;
+ }
+
+ if(column==model.data.index())
+ {
+ Glib::Value<Glib::ustring> x;
+ g_value_init(x.gobj(),model.data.type());
+ g_value_copy(value.gobj(),x.gobj());
+
+ synfig::String key((Glib::ustring)(*iter)[model.key]);
+ synfig::String new_data(x.get());
+
+ get_canvas_interface()->set_meta_data(key,new_data);
+ }
+ else
+ Gtk::TreeStore::set_value_impl(iter,column, value);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file metadatatreestore.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_METADATATREESTORE_H
+#define __SYNFIG_STUDIO_METADATATREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <synfigapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfigapp { class CanvasInterface; }
+
+namespace studio {
+
+class MetaDataTreeStore : virtual public Gtk::TreeStore
+{
+ /*
+ -- ** -- P U B L I C T Y P E S ---------------------------------------------
+ */
+
+public:
+
+ class Model : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ public:
+ Gtk::TreeModelColumn<Glib::ustring> key;
+ Gtk::TreeModelColumn<Glib::ustring> data;
+
+ Model()
+ {
+ add(key);
+ add(data);
+ }
+ };
+
+ /*
+ -- ** -- P U B L I C D A T A ------------------------------------------------
+ */
+
+public:
+
+ const Model model;
+
+ /*
+ -- ** -- P R I V A T E D A T A ---------------------------------------------
+ */
+
+private:
+
+ etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
+
+ /*
+ -- ** -- P R I V A T E M E T H O D S ---------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- S I G N A L T E R M I N A L S -------------------------------------
+ */
+
+private:
+
+ void meta_data_changed(synfig::String key);
+
+ /*
+ -- ** -- P U B L I C M E T H O D S -----------------------------------------
+ */
+
+public:
+
+ ~MetaDataTreeStore();
+
+ etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface() { return canvas_interface_; }
+ etl::loose_handle<const synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+ synfig::Canvas::Handle get_canvas()const { return canvas_interface_->get_canvas(); }
+ synfig::Canvas::Handle get_canvas() { return canvas_interface_->get_canvas(); }
+
+ void rebuild();
+
+ void refresh() { rebuild(); }
+
+ /*
+ -- ** -- P R O T E C T E D M E T H O D S -----------------------------------
+ */
+
+protected:
+ MetaDataTreeStore(etl::loose_handle<synfigapp::CanvasInterface>);
+ void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+ void set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value);
+
+public:
+
+ static Glib::RefPtr<MetaDataTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface>);
+
+}; // END of class MetaDataTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif