From: Nikita Kitaev Date: Sat, 17 Apr 2010 06:13:46 +0000 (-0700) Subject: Move treeviews/treestores into subfolder X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=27b5a5e825ecd199f7ef353e1ed45eb678991087;p=synfig.git Move treeviews/treestores into subfolder --- diff --git a/synfig-studio/src/gui/Makefile.am b/synfig-studio/src/gui/Makefile.am index caeb8e1..c6ba46d 100644 --- a/synfig-studio/src/gui/Makefile.am +++ b/synfig-studio/src/gui/Makefile.am @@ -199,37 +199,37 @@ STATE_CC = \ 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 = \ diff --git a/synfig-studio/src/gui/canvastreestore.cpp b/synfig-studio/src/gui/canvastreestore.cpp deleted file mode 100644 index f49d7a3..0000000 --- a/synfig-studio/src/gui/canvastreestore.cpp +++ /dev/null @@ -1,622 +0,0 @@ -/* === 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 -#endif - -#include "canvastreestore.h" -#include -#include "iconcontroller.h" -#include -#include -#include -#include -#include "cellrenderer_value.h" -#include "cellrenderer_timetrack.h" -#include - -#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 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 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 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 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 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 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 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 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 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 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 > 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;ilink_count();i++) - { - Gtk::TreeRow child_row=*(append(row.children())); - child_row[model.link_id] = i; - child_row[model.canvas] = static_cast(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; -} diff --git a/synfig-studio/src/gui/canvastreestore.h b/synfig-studio/src/gui/canvastreestore.h deleted file mode 100644 index faed8b6..0000000 --- a/synfig-studio/src/gui/canvastreestore.h +++ /dev/null @@ -1,195 +0,0 @@ -/* === 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 -#include -#include -#include -#include - -/* === 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 > icon; - Gtk::TreeModelColumn label; - Gtk::TreeModelColumn name; - Gtk::TreeModelColumn id; - - Gtk::TreeModelColumn canvas; - Gtk::TreeModelColumn is_canvas; - - Gtk::TreeModelColumn value_node; - Gtk::TreeModelColumn is_value_node; - Gtk::TreeModelColumn value; - Gtk::TreeModelColumn type; - Gtk::TreeModelColumn link_id; - Gtk::TreeModelColumn link_count; - - Gtk::TreeModelColumn is_editable; - - Gtk::TreeModelColumn is_shared; - Gtk::TreeModelColumn is_exported; - - Gtk::TreeModelColumn value_desc; - - Gtk::TreeModelColumn 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, sigc::connection> connection_map; - - /* - -- ** -- P R I V A T E D A T A --------------------------------------------- - */ - -private: - - etl::loose_handle 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 canvas_interface_); - ~CanvasTreeStore(); - - etl::loose_handle canvas_interface() { return canvas_interface_; } - etl::loose_handle 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 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 diff --git a/synfig-studio/src/gui/canvasview.h b/synfig-studio/src/gui/canvasview.h index d877c33..21a7f1d 100644 --- a/synfig-studio/src/gui/canvasview.h +++ b/synfig-studio/src/gui/canvasview.h @@ -58,12 +58,12 @@ #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" diff --git a/synfig-studio/src/gui/childrentree.cpp b/synfig-studio/src/gui/childrentree.cpp deleted file mode 100644 index 01ef95e..0000000 --- a/synfig-studio/src/gui/childrentree.cpp +++ /dev/null @@ -1,439 +0,0 @@ -/* === 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 -#endif - -#include "childrentree.h" -#include "cellrenderer_value.h" -#include "cellrenderer_timetrack.h" -#include -#include -#include -#include - -#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(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 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& node __attribute__ ((unused)), - const synfig::Time& time __attribute__ ((unused)), - const synfig::Time& time_offset __attribute__ ((unused)), - int button __attribute__ ((unused))) -{ - std::set > 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(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() -{ -} diff --git a/synfig-studio/src/gui/childrentree.h b/synfig-studio/src/gui/childrentree.h deleted file mode 100644 index 8584ed7..0000000 --- a/synfig-studio/src/gui/childrentree.h +++ /dev/null @@ -1,179 +0,0 @@ -/* === 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "childrentreestore.h" -#include - -#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 children_tree_store_; - - CellRenderer_TimeTrack *cellrenderer_time_track; - - Gtk::TreeView::Column* column_time_track; - - CellRenderer_ValueBase *cellrenderer_value; - - sigc::signal signal_edited_value_; - - sigc::signal signal_user_click_; - - sigc::signal >,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& 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 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 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& signal_edited_value() { return signal_edited_value_; } - - sigc::signal& signal_user_click() { return signal_user_click_; } - - sigc::signal >,int>& signal_waypoint_clicked_childrentree() { return signal_waypoint_clicked_childrentree_; } - - etl::handle get_selection_manager() { return children_tree_store_->canvas_interface()->get_selection_manager(); } - -}; // END of ChildrenTree - -}; // END of namespace studio - -/* === E N D =============================================================== */ - -#endif diff --git a/synfig-studio/src/gui/childrentreestore.cpp b/synfig-studio/src/gui/childrentreestore.cpp deleted file mode 100644 index cf8798f..0000000 --- a/synfig-studio/src/gui/childrentreestore.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* === 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 -#endif - -#include "childrentreestore.h" -#include "iconcontroller.h" -#include -#include -#include - -#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 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::create(etl::loose_handle canvas_interface_) -{ - return Glib::RefPtr(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 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()); - } -} diff --git a/synfig-studio/src/gui/childrentreestore.h b/synfig-studio/src/gui/childrentreestore.h deleted file mode 100644 index 5d0412a..0000000 --- a/synfig-studio/src/gui/childrentreestore.h +++ /dev/null @@ -1,143 +0,0 @@ -/* === 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 -#include -#include "canvastreestore.h" -#include -#include -#include - -/* === 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 changed_set_; - - std::set 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 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 create(etl::loose_handle canvas_interface_); -}; // END of class ChildrenTreeStore - -}; // END of namespace studio - -/* === E N D =============================================================== */ - -#endif diff --git a/synfig-studio/src/gui/dialogs/canvasproperties.cpp b/synfig-studio/src/gui/dialogs/canvasproperties.cpp index 25e48eb..434b6bf 100644 --- a/synfig-studio/src/gui/dialogs/canvasproperties.cpp +++ b/synfig-studio/src/gui/dialogs/canvasproperties.cpp @@ -36,7 +36,7 @@ #include #include #include -#include "metadatatreestore.h" +#include "trees/metadatatreestore.h" #include #include #include "app.h" diff --git a/synfig-studio/src/gui/docks/dock_canvasspecific.cpp b/synfig-studio/src/gui/docks/dock_canvasspecific.cpp index 1ef3a47..64f81e5 100644 --- a/synfig-studio/src/gui/docks/dock_canvasspecific.cpp +++ b/synfig-studio/src/gui/docks/dock_canvasspecific.cpp @@ -39,7 +39,6 @@ #include //#include #include -#include "metadatatreestore.h" #include "canvasview.h" #include diff --git a/synfig-studio/src/gui/docks/dock_children.cpp b/synfig-studio/src/gui/docks/dock_children.cpp index eaa6365..798049c 100644 --- a/synfig-studio/src/gui/docks/dock_children.cpp +++ b/synfig-studio/src/gui/docks/dock_children.cpp @@ -40,8 +40,8 @@ #include #include #include -#include "childrentreestore.h" -#include "childrentree.h" +#include "trees/childrentreestore.h" +#include "trees/childrentree.h" #include "canvasview.h" #include "general.h" diff --git a/synfig-studio/src/gui/docks/dock_curves.cpp b/synfig-studio/src/gui/docks/dock_curves.cpp index 4d1d97d..a436b68 100644 --- a/synfig-studio/src/gui/docks/dock_curves.cpp +++ b/synfig-studio/src/gui/docks/dock_curves.cpp @@ -39,10 +39,9 @@ #include #include #include "canvasview.h" -#include "layerparamtreestore.h" +#include "trees/layerparamtreestore.h" #include "workarea.h" #include "widgets/widget_curves.h" -#include "layerparamtreestore.h" #include #include #include "widgets/widget_timeslider.h" diff --git a/synfig-studio/src/gui/docks/dock_history.cpp b/synfig-studio/src/gui/docks/dock_history.cpp index 6ee6e51..5d477c6 100644 --- a/synfig-studio/src/gui/docks/dock_history.cpp +++ b/synfig-studio/src/gui/docks/dock_history.cpp @@ -42,7 +42,7 @@ #include #include #include -#include "historytreestore.h" +#include "trees/historytreestore.h" #include "general.h" diff --git a/synfig-studio/src/gui/docks/dock_keyframes.cpp b/synfig-studio/src/gui/docks/dock_keyframes.cpp index e741bbf..c05b92c 100644 --- a/synfig-studio/src/gui/docks/dock_keyframes.cpp +++ b/synfig-studio/src/gui/docks/dock_keyframes.cpp @@ -38,8 +38,8 @@ #include #include #include -#include "keyframetreestore.h" -#include "keyframetree.h" +#include "trees/keyframetreestore.h" +#include "trees/keyframetree.h" #include "canvasview.h" #include "keyframeactionmanager.h" diff --git a/synfig-studio/src/gui/docks/dock_layergroups.cpp b/synfig-studio/src/gui/docks/dock_layergroups.cpp index 8306a8e..03daeaf 100644 --- a/synfig-studio/src/gui/docks/dock_layergroups.cpp +++ b/synfig-studio/src/gui/docks/dock_layergroups.cpp @@ -41,8 +41,8 @@ #include #include "canvasview.h" -#include "layergrouptreestore.h" -#include "layergrouptree.h" +#include "trees/layergrouptreestore.h" +#include "trees/layergrouptree.h" #include "groupactionmanager.h" #include "general.h" diff --git a/synfig-studio/src/gui/docks/dock_layers.cpp b/synfig-studio/src/gui/docks/dock_layers.cpp index 152ffb1..df0e4af 100644 --- a/synfig-studio/src/gui/docks/dock_layers.cpp +++ b/synfig-studio/src/gui/docks/dock_layers.cpp @@ -40,8 +40,8 @@ #include #include #include -#include "layertreestore.h" -#include "layertree.h" +#include "trees/layertreestore.h" +#include "trees/layertree.h" #include "canvasview.h" #include "layeractionmanager.h" //#include diff --git a/synfig-studio/src/gui/docks/dock_metadata.cpp b/synfig-studio/src/gui/docks/dock_metadata.cpp index 5fe09f9..69dad23 100644 --- a/synfig-studio/src/gui/docks/dock_metadata.cpp +++ b/synfig-studio/src/gui/docks/dock_metadata.cpp @@ -38,7 +38,7 @@ #include #include #include -#include "metadatatreestore.h" +#include "trees/metadatatreestore.h" #include "canvasview.h" #include "general.h" diff --git a/synfig-studio/src/gui/docks/dock_params.cpp b/synfig-studio/src/gui/docks/dock_params.cpp index 79b965e..7494ca7 100644 --- a/synfig-studio/src/gui/docks/dock_params.cpp +++ b/synfig-studio/src/gui/docks/dock_params.cpp @@ -39,7 +39,7 @@ #include #include #include "canvasview.h" -#include "layerparamtreestore.h" +#include "trees/layerparamtreestore.h" #include "workarea.h" #include "general.h" diff --git a/synfig-studio/src/gui/docks/dock_timetrack.cpp b/synfig-studio/src/gui/docks/dock_timetrack.cpp index 61ba14d..adb8998 100644 --- a/synfig-studio/src/gui/docks/dock_timetrack.cpp +++ b/synfig-studio/src/gui/docks/dock_timetrack.cpp @@ -40,11 +40,10 @@ #include #include #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 diff --git a/synfig-studio/src/gui/groupactionmanager.cpp b/synfig-studio/src/gui/groupactionmanager.cpp index 54eab18..2d77407 100644 --- a/synfig-studio/src/gui/groupactionmanager.cpp +++ b/synfig-studio/src/gui/groupactionmanager.cpp @@ -31,7 +31,7 @@ #endif #include "groupactionmanager.h" -#include "layergrouptree.h" +#include "trees/layergrouptree.h" #include #include "instance.h" #include diff --git a/synfig-studio/src/gui/historytreestore.cpp b/synfig-studio/src/gui/historytreestore.cpp deleted file mode 100644 index 1f0eb9c..0000000 --- a/synfig-studio/src/gui/historytreestore.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* === 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 -#endif - -#include "historytreestore.h" -#include -#include "iconcontroller.h" -#include -#include -#include -#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 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::create(etl::loose_handle instance_) -{ - return Glib::RefPtr(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 action, bool /*is_active*/, bool is_undo, bool is_redo) -{ - assert(action); - - row[model.action] = action; - row[model.name] = static_cast(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(action.get()); - if(specific_action) - { - row[model.canvas] = specific_action->get_canvas(); - row[model.canvas_id] = specific_action->get_canvas()->get_id(); - } - - etl::handle group; - group=etl::handle::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 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 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)row[model.action]) - { - row[model.is_active]=action->is_active(); - return; - } - } -} - -bool -HistoryTreeStore::search_func(const Glib::RefPtr&,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; -} diff --git a/synfig-studio/src/gui/historytreestore.h b/synfig-studio/src/gui/historytreestore.h deleted file mode 100644 index 31a4b13..0000000 --- a/synfig-studio/src/gui/historytreestore.h +++ /dev/null @@ -1,172 +0,0 @@ -/* === 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 -#include -#include -#include - -/* === 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 > action; - Gtk::TreeModelColumn name; - Gtk::TreeModelColumn > icon; - Gtk::TreeModelColumn is_active; - Gtk::TreeModelColumn is_undo; - Gtk::TreeModelColumn is_redo; - - Gtk::TreeModelColumn canvas_id; - Gtk::TreeModelColumn 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 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 signal_undo_tree_changed_; - - /* - -- ** -- S I G N A L I N T E R F A C E S ----------------------------------- - */ - -public: - - sigc::signal& 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 action); - - void on_action_status_changed(etl::handle action); - - /* - -- ** -- P U B L I C M E T H O D S ----------------------------------------- - */ - -public: - - HistoryTreeStore(etl::loose_handle instance_); - ~HistoryTreeStore(); - - etl::loose_handle instance() { return instance_; } - etl::loose_handle instance()const { return instance_; } - - void rebuild(); - - void refresh() { rebuild(); } - - void insert_action(Gtk::TreeRow row,etl::handle action, bool is_active=true, bool is_undo=true, bool is_redo=false); - - static bool search_func(const Glib::RefPtr&,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 create(etl::loose_handle instance); - -}; // END of class HistoryTreeStore - -}; // END of namespace studio - -/* === E N D =============================================================== */ - -#endif diff --git a/synfig-studio/src/gui/instance.h b/synfig-studio/src/gui/instance.h index 16842c1..6536c86 100644 --- a/synfig-studio/src/gui/instance.h +++ b/synfig-studio/src/gui/instance.h @@ -34,7 +34,7 @@ #include #include #include -#include "historytreestore.h" +#include "trees/historytreestore.h" #include /* === M A C R O S ========================================================= */ diff --git a/synfig-studio/src/gui/keyframeactionmanager.cpp b/synfig-studio/src/gui/keyframeactionmanager.cpp index aaddf1f..906591b 100644 --- a/synfig-studio/src/gui/keyframeactionmanager.cpp +++ b/synfig-studio/src/gui/keyframeactionmanager.cpp @@ -31,7 +31,7 @@ #endif #include "keyframeactionmanager.h" -#include "keyframetree.h" +#include "trees/keyframetree.h" #include #include "instance.h" diff --git a/synfig-studio/src/gui/keyframetree.cpp b/synfig-studio/src/gui/keyframetree.cpp deleted file mode 100644 index e480292..0000000 --- a/synfig-studio/src/gui/keyframetree.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/* === 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 -#endif - -#include "keyframetree.h" -#include "cellrenderer_time.h" -#include -#include - -#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 keyframe_tree_store) -{ - keyframe_tree_store_=keyframe_tree_store; - KeyframeTreeStore::Model model; - - if(true) - { - Glib::RefPtr 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; -} diff --git a/synfig-studio/src/gui/keyframetree.h b/synfig-studio/src/gui/keyframetree.h deleted file mode 100644 index 31d820e..0000000 --- a/synfig-studio/src/gui/keyframetree.h +++ /dev/null @@ -1,149 +0,0 @@ -/* === 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 -#include -#include -#include -#include "keyframetreestore.h" -#include - -/* === 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 keyframe_tree_store_; - - CellRenderer_Time *cell_renderer_time; - - CellRenderer_Time *cell_renderer_time_delta; - - Gtk::CellRendererText *cell_renderer_description; - - sigc::signal signal_edited_; - - sigc::signal signal_edited_time_; - - sigc::signal signal_edited_description_; - - sigc::signal 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 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& signal_edited() { return signal_edited_; } - - //! Signal called when a time has been edited. - sigc::signal& signal_edited_time() { return signal_edited_time_; } - - //! Signal called when a description has been edited. - sigc::signal& signal_edited_description() { return signal_edited_description_; } - - sigc::signal& signal_user_click() { return signal_user_click_; } -}; // END of KeyframeTree - -}; // END of namespace studio - -/* === E N D =============================================================== */ - -#endif diff --git a/synfig-studio/src/gui/keyframetreestore.cpp b/synfig-studio/src/gui/keyframetreestore.cpp deleted file mode 100644 index 4e84001..0000000 --- a/synfig-studio/src/gui/keyframetreestore.cpp +++ /dev/null @@ -1,901 +0,0 @@ -/* === 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 -#endif - -#include "keyframetreestore.h" -#include -#include "iconcontroller.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "onemoment.h" -#include - -#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& model, const Gtk::TreeModel::Path& path): - gobject_ ( gtk_tree_row_reference_new(model->gobj(), const_cast(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 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::create(etl::loose_handle canvas_interface_) -{ - KeyframeTreeStore *store(new KeyframeTreeStore(canvas_interface_)); - Glib::RefPtr ret(store); - assert(ret); - return ret; -} - -void -KeyframeTreeStore::reset_stamp() -{ - stamp_=time(0)+reinterpret_cast(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(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 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 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 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(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(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(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(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 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 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 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 new_order; - for(unsigned int i=0;inew_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()); - } -} diff --git a/synfig-studio/src/gui/keyframetreestore.h b/synfig-studio/src/gui/keyframetreestore.h deleted file mode 100644 index c3efccf..0000000 --- a/synfig-studio/src/gui/keyframetreestore.h +++ /dev/null @@ -1,224 +0,0 @@ -/* === 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 -#include -#include -#include -#include - -/* === 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 time; - Gtk::TreeModelColumn description; - Gtk::TreeModelColumn keyframe; - Gtk::TreeModelColumn 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 canvas_interface_; - - //! Unique stamp for this TreeModel. - int stamp_; - - static KeyframeTreeStore_Class keyframe_tree_store_class_; - - //std::map 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 canvas_interface_); - ~KeyframeTreeStore(); - - etl::loose_handle canvas_interface() { return canvas_interface_; } - etl::loose_handle 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 create(etl::loose_handle 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 diff --git a/synfig-studio/src/gui/layeractionmanager.cpp b/synfig-studio/src/gui/layeractionmanager.cpp index c3a3be4..5f0538f 100644 --- a/synfig-studio/src/gui/layeractionmanager.cpp +++ b/synfig-studio/src/gui/layeractionmanager.cpp @@ -31,7 +31,7 @@ #endif #include "layeractionmanager.h" -#include "layertree.h" +#include "trees/layertree.h" #include #include #include diff --git a/synfig-studio/src/gui/layergrouptree.cpp b/synfig-studio/src/gui/layergrouptree.cpp deleted file mode 100644 index 3dd323e..0000000 --- a/synfig-studio/src/gui/layergrouptree.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* === 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 -#endif - -#include -#include "layergrouptree.h" -#include -#include - -#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 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 layer_group_tree_store) -{ - layer_group_tree_store_=layer_group_tree_store; - LayerGroupTreeStore::Model model; - -#if 0 - { - Glib::RefPtr 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* ret) -{ - const LayerGroupTreeStore::Model model; - if((bool)(*iter)[model.is_group]) - ret->push_back((Glib::ustring)(*iter)[model.group_name]); -} - -std::list -LayerGroupTree::get_selected_groups()const -{ - Glib::RefPtr selection=const_cast(*this).get_selection(); - - if(!selection) - return std::list(); - - std::list 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 selection=const_cast(*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); -} diff --git a/synfig-studio/src/gui/layergrouptree.h b/synfig-studio/src/gui/layergrouptree.h deleted file mode 100644 index a17c470..0000000 --- a/synfig-studio/src/gui/layergrouptree.h +++ /dev/null @@ -1,127 +0,0 @@ -/* === 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 -#include -#include -#include -#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 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 layer_group_tree_store_; - - Gtk::CellRendererText *cell_renderer_description; - - bool editable_; - - - sigc::signal > signal_popup_layer_menu_; - -// sigc::signal 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 get_model() { return layer_group_tree_store_; } - - sigc::signal >& signal_popup_layer_menu() { return signal_popup_layer_menu_; } - -// sigc::signal& signal_select_layers() { return signal_select_layers_; } - - void set_model(Glib::RefPtr layer_group_tree_store_); - - void set_editable(bool x=true); - - bool get_editable()const { return editable_; } - - std::list get_selected_groups()const; - - LayerList get_selected_layers()const; -}; // END of LayerGroupTree - -}; // END of namespace studio - -/* === E N D =============================================================== */ - -#endif diff --git a/synfig-studio/src/gui/layergrouptreestore.cpp b/synfig-studio/src/gui/layergrouptreestore.cpp deleted file mode 100644 index 332994f..0000000 --- a/synfig-studio/src/gui/layergrouptreestore.cpp +++ /dev/null @@ -1,1031 +0,0 @@ -/* === 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 -#endif - -#include "layergrouptreestore.h" -#include "iconcontroller.h" -#include -#include -#include -#include -#include "app.h" -#include "instance.h" -#include -#include "docks/dockmanager.h" -#include "docks/dockable.h" - -#include -#include -#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 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&,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::create(etl::loose_handle canvas_interface_) -{ - return Glib::RefPtr(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 x; - g_value_init(x.gobj(),x.value_type()); - - if((bool)(*iter)[model.is_group]) - { - set 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 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 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 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 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 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 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 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 > 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 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 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(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(this)->get_iter(path)); - - if((bool)row[model.is_layer]) - { - Layer* layer(((Layer::Handle)row[model.layer]).get()); - assert(layer); - - std::vector layers; - - layers.push_back(layer); - - selection_data.set("LAYER", 8, reinterpret_cast(&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(&*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(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(selection_data.get_data())); - //synfig::String src_group(const_cast(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(const_cast(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(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(const_cast(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 groups(canvas->get_groups()); - for(;groups.size();groups.erase(groups.begin())) - { - String group(*groups.begin()); - Gtk::TreeRow row(on_group_added(group)); - std::set 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 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 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; -} diff --git a/synfig-studio/src/gui/layergrouptreestore.h b/synfig-studio/src/gui/layergrouptreestore.h deleted file mode 100644 index cd0c196..0000000 --- a/synfig-studio/src/gui/layergrouptreestore.h +++ /dev/null @@ -1,202 +0,0 @@ -/* === 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 -#include -#include -#include -#include - -/* === 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 LayerList; - - class Model : public Gtk::TreeModel::ColumnRecord - { - public: - Gtk::TreeModelColumn > icon; - Gtk::TreeModelColumn label; - Gtk::TreeModelColumn tooltip; - - Gtk::TreeModelColumn group_name; - Gtk::TreeModelColumn parent_group_name; - - Gtk::TreeModelColumn canvas; - - Gtk::TreeModelColumn active; - Gtk::TreeModelColumn is_layer; - Gtk::TreeModelColumn is_group; - Gtk::TreeModelColumn layer; - - Gtk::TreeModelColumn all_layers; - Gtk::TreeModelColumn 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 canvas_interface_; - - Glib::RefPtr layer_icon; - Glib::RefPtr 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 layer); - void on_group_pair_removed(synfig::String group, etl::handle 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 canvas_interface_); - ~LayerGroupTreeStore(); - - Gtk::TreeRow on_group_added(synfig::String group); - etl::loose_handle canvas_interface() { return canvas_interface_; } - etl::loose_handle canvas_interface()const { return canvas_interface_; } - etl::loose_handle 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&,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 create(etl::loose_handle canvas_interface_); - -}; // END of class LayerGroupTreeStore - -}; // END of namespace studio - -/* === E N D =============================================================== */ - -#endif diff --git a/synfig-studio/src/gui/layerparamtreestore.cpp b/synfig-studio/src/gui/layerparamtreestore.cpp deleted file mode 100644 index 8fe850a..0000000 --- a/synfig-studio/src/gui/layerparamtreestore.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/* === 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 -#endif - -#include "layerparamtreestore.h" -#include "iconcontroller.h" -#include -#include -#include "layertree.h" -#include -#include -#include "app.h" -#include - -#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 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::create(etl::loose_handle canvas_interface_, LayerTree*layer_tree) -{ - return Glib::RefPtr(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 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 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 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 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 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 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 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(); -} diff --git a/synfig-studio/src/gui/layerparamtreestore.h b/synfig-studio/src/gui/layerparamtreestore.h deleted file mode 100644 index ce96cbe..0000000 --- a/synfig-studio/src/gui/layerparamtreestore.h +++ /dev/null @@ -1,166 +0,0 @@ -/* === 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 -#include -#include "canvastreestore.h" -#include -#include -#include - -/* === 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 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 param_desc; - - Gtk::TreeModelColumn is_inconsistent; - Gtk::TreeModelColumn 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 changed_connection_list; - - sigc::signal 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 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& 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 create(etl::loose_handle canvas_interface_, LayerTree*layer_tree); -}; // END of class LayerParamTreeStore - -}; // END of namespace studio - -/* === E N D =============================================================== */ - -#endif diff --git a/synfig-studio/src/gui/layertree.cpp b/synfig-studio/src/gui/layertree.cpp deleted file mode 100644 index a69f234..0000000 --- a/synfig-studio/src/gui/layertree.cpp +++ /dev/null @@ -1,1232 +0,0 @@ -/* === 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 -#endif - -#include "layertree.h" -#include "layerparamtreestore.h" -#include "cellrenderer_value.h" -#include "cellrenderer_timetrack.h" -#include -#include -#include -#include -#include "app.h" -#include "instance.h" -#include - -#ifdef TIMETRACK_IN_PARAMS_PANEL -# include -#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(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 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::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 selection=const_cast(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 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(row[layer_model.active]); - row[layer_model.active]=!active; -} - -#ifdef TIMETRACK_IN_PARAMS_PANEL -void -LayerTree::on_waypoint_clicked_layertree(const etl::handle& node __attribute__ ((unused)), - const synfig::Time& time __attribute__ ((unused)), - const synfig::Time& time_offset __attribute__ ((unused)), - int button __attribute__ ((unused))) -{ - std::set > 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(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 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&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(&layer), sizeof(layer)); - return; - } -} - -void -LayerTree::on_drop_drag_data_received(const Glib::RefPtr& 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(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& 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& 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); -} -*/ diff --git a/synfig-studio/src/gui/layertree.h b/synfig-studio/src/gui/layertree.h deleted file mode 100644 index cf06899..0000000 --- a/synfig-studio/src/gui/layertree.h +++ /dev/null @@ -1,261 +0,0 @@ -/* === 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "layertreestore.h" -#include "layerparamtreestore.h" -#include - -#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 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 layer_tree_store_; - - Glib::RefPtr param_tree_store_; - - Glib::RefPtr 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 signal_layer_toggle_; - - sigc::signal signal_edited_value_; - - sigc::signal signal_layer_user_click_; - - sigc::signal signal_param_user_click_; - - sigc::signal >,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& 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 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 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& signal_layer_toggle() { return signal_layer_toggle_; } - - //! Signal called with a value has been edited. - sigc::signal& signal_edited_value() { return signal_edited_value_; } - - sigc::signal& signal_layer_user_click() { return signal_layer_user_click_; } - - sigc::signal& signal_param_user_click() { return signal_param_user_click_; } - - sigc::signal >,int>& signal_waypoint_clicked_layertree() { return signal_waypoint_clicked_layertree_; } - - etl::handle 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 diff --git a/synfig-studio/src/gui/layertreestore.cpp b/synfig-studio/src/gui/layertreestore.cpp deleted file mode 100644 index 16b7fc8..0000000 --- a/synfig-studio/src/gui/layertreestore.cpp +++ /dev/null @@ -1,1081 +0,0 @@ -/* === 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 -#endif - -#include "layertreestore.h" -#include "iconcontroller.h" -#include -#include -#include -#include -#include "app.h" -#include "instance.h" -#include -#include - -#include -#include -#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 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&,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::create(etl::loose_handle canvas_interface_) -{ - return Glib::RefPtr(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 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 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 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 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 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 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 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 > 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 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 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(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(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(&layer), sizeof(layer)); - - std::vector 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(&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(&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(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(const_cast(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(this)->get_iter(dest_parent)) - return (bool)(Canvas::Handle)(*const_cast(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(const_cast(selection_data.get_data()))[i]); - assert(src); - if(dest_layer==src) - continue; - - if(dest_canvas==src->get_canvas() && src->get_depth()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::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 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::cast_dynamic(layer)) - subcanvas_changed_connections[layer] = - (etl::handle::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::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; -} diff --git a/synfig-studio/src/gui/layertreestore.h b/synfig-studio/src/gui/layertreestore.h deleted file mode 100644 index 5b33309..0000000 --- a/synfig-studio/src/gui/layertreestore.h +++ /dev/null @@ -1,226 +0,0 @@ -/* === 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 -#include -#include -#include -#include - -/* === 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 > icon; - Gtk::TreeModelColumn label; - Gtk::TreeModelColumn name; - Gtk::TreeModelColumn id; - - Gtk::TreeModelColumn canvas; - - Gtk::TreeModelColumn tooltip; - - - Gtk::TreeModelColumn active; - Gtk::TreeModelColumn layer; - Gtk::TreeModelColumn contained_canvas; - - Gtk::TreeModelColumn children_lock; - - Gtk::TreeModelColumn z_depth; - Gtk::TreeModelColumn 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 subcanvas_changed_connections; - - etl::loose_handle canvas_interface_; - - Glib::RefPtr 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 canvas_interface_); - ~LayerTreeStore(); - - etl::loose_handle canvas_interface() { return canvas_interface_; } - etl::loose_handle canvas_interface()const { return canvas_interface_; } - etl::loose_handle 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 value_node,synfig::ParamDesc *param_desc); - - //virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc); - static bool search_func(const Glib::RefPtr&,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 create(etl::loose_handle canvas_interface_); - - -}; // END of class LayerTreeStore - -}; // END of namespace studio - -/* === E N D =============================================================== */ - -#endif diff --git a/synfig-studio/src/gui/metadatatreestore.cpp b/synfig-studio/src/gui/metadatatreestore.cpp deleted file mode 100644 index 98bb7c6..0000000 --- a/synfig-studio/src/gui/metadatatreestore.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* === 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 -#endif - -#include "metadatatreestore.h" -#include - -#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 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::create(etl::loose_handle canvas_interface_) -{ - return Glib::RefPtr(new MetaDataTreeStore(canvas_interface_)); -} - -void -MetaDataTreeStore::meta_data_changed(synfig::String /*key*/) -{ - rebuild(); -} - -void -MetaDataTreeStore::rebuild() -{ - clear(); - - std::list 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 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); -} diff --git a/synfig-studio/src/gui/metadatatreestore.h b/synfig-studio/src/gui/metadatatreestore.h deleted file mode 100644 index 6ad41d4..0000000 --- a/synfig-studio/src/gui/metadatatreestore.h +++ /dev/null @@ -1,133 +0,0 @@ -/* === 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 -#include -#include -#include - -/* === 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 key; - Gtk::TreeModelColumn 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 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 get_canvas_interface() { return canvas_interface_; } - etl::loose_handle 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); - 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 create(etl::loose_handle); - -}; // END of class MetaDataTreeStore - -}; // END of namespace studio - -/* === E N D =============================================================== */ - -#endif diff --git a/synfig-studio/src/gui/trees/canvastreestore.cpp b/synfig-studio/src/gui/trees/canvastreestore.cpp new file mode 100644 index 0000000..8673c35 --- /dev/null +++ b/synfig-studio/src/gui/trees/canvastreestore.cpp @@ -0,0 +1,622 @@ +/* === 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 +#endif + +#include "trees/canvastreestore.h" +#include +#include "iconcontroller.h" +#include +#include +#include +#include +#include "cellrenderer_value.h" +#include "cellrenderer_timetrack.h" +#include + +#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 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 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 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 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 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 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 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 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 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 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 > 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;ilink_count();i++) + { + Gtk::TreeRow child_row=*(append(row.children())); + child_row[model.link_id] = i; + child_row[model.canvas] = static_cast(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; +} diff --git a/synfig-studio/src/gui/trees/canvastreestore.h b/synfig-studio/src/gui/trees/canvastreestore.h new file mode 100644 index 0000000..d7e119a --- /dev/null +++ b/synfig-studio/src/gui/trees/canvastreestore.h @@ -0,0 +1,195 @@ +/* === 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 +#include +#include +#include +#include + +/* === 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 > icon; + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn name; + Gtk::TreeModelColumn id; + + Gtk::TreeModelColumn canvas; + Gtk::TreeModelColumn is_canvas; + + Gtk::TreeModelColumn value_node; + Gtk::TreeModelColumn is_value_node; + Gtk::TreeModelColumn value; + Gtk::TreeModelColumn type; + Gtk::TreeModelColumn link_id; + Gtk::TreeModelColumn link_count; + + Gtk::TreeModelColumn is_editable; + + Gtk::TreeModelColumn is_shared; + Gtk::TreeModelColumn is_exported; + + Gtk::TreeModelColumn value_desc; + + Gtk::TreeModelColumn 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, sigc::connection> connection_map; + + /* + -- ** -- P R I V A T E D A T A --------------------------------------------- + */ + +private: + + etl::loose_handle 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 canvas_interface_); + ~CanvasTreeStore(); + + etl::loose_handle canvas_interface() { return canvas_interface_; } + etl::loose_handle 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 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 diff --git a/synfig-studio/src/gui/trees/childrentree.cpp b/synfig-studio/src/gui/trees/childrentree.cpp new file mode 100644 index 0000000..d2311e0 --- /dev/null +++ b/synfig-studio/src/gui/trees/childrentree.cpp @@ -0,0 +1,439 @@ +/* === 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 +#endif + +#include "trees/childrentree.h" +#include "cellrenderer_value.h" +#include "cellrenderer_timetrack.h" +#include +#include +#include +#include + +#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(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 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& node __attribute__ ((unused)), + const synfig::Time& time __attribute__ ((unused)), + const synfig::Time& time_offset __attribute__ ((unused)), + int button __attribute__ ((unused))) +{ + std::set > 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(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() +{ +} diff --git a/synfig-studio/src/gui/trees/childrentree.h b/synfig-studio/src/gui/trees/childrentree.h new file mode 100644 index 0000000..f2afc5c --- /dev/null +++ b/synfig-studio/src/gui/trees/childrentree.h @@ -0,0 +1,179 @@ +/* === 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "trees/childrentreestore.h" +#include + +#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 children_tree_store_; + + CellRenderer_TimeTrack *cellrenderer_time_track; + + Gtk::TreeView::Column* column_time_track; + + CellRenderer_ValueBase *cellrenderer_value; + + sigc::signal signal_edited_value_; + + sigc::signal signal_user_click_; + + sigc::signal >,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& 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 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 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& signal_edited_value() { return signal_edited_value_; } + + sigc::signal& signal_user_click() { return signal_user_click_; } + + sigc::signal >,int>& signal_waypoint_clicked_childrentree() { return signal_waypoint_clicked_childrentree_; } + + etl::handle get_selection_manager() { return children_tree_store_->canvas_interface()->get_selection_manager(); } + +}; // END of ChildrenTree + +}; // END of namespace studio + +/* === E N D =============================================================== */ + +#endif diff --git a/synfig-studio/src/gui/trees/childrentreestore.cpp b/synfig-studio/src/gui/trees/childrentreestore.cpp new file mode 100644 index 0000000..1ab3bfe --- /dev/null +++ b/synfig-studio/src/gui/trees/childrentreestore.cpp @@ -0,0 +1,389 @@ +/* === 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 +#endif + +#include "trees/childrentreestore.h" +#include "iconcontroller.h" +#include +#include +#include + +#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 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::create(etl::loose_handle canvas_interface_) +{ + return Glib::RefPtr(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 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()); + } +} diff --git a/synfig-studio/src/gui/trees/childrentreestore.h b/synfig-studio/src/gui/trees/childrentreestore.h new file mode 100644 index 0000000..ed81205 --- /dev/null +++ b/synfig-studio/src/gui/trees/childrentreestore.h @@ -0,0 +1,143 @@ +/* === 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 +#include +#include "trees/canvastreestore.h" +#include +#include +#include + +/* === 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 changed_set_; + + std::set 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 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 create(etl::loose_handle canvas_interface_); +}; // END of class ChildrenTreeStore + +}; // END of namespace studio + +/* === E N D =============================================================== */ + +#endif diff --git a/synfig-studio/src/gui/trees/historytreestore.cpp b/synfig-studio/src/gui/trees/historytreestore.cpp new file mode 100644 index 0000000..8375053 --- /dev/null +++ b/synfig-studio/src/gui/trees/historytreestore.cpp @@ -0,0 +1,235 @@ +/* === 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 +#endif + +#include "trees/historytreestore.h" +#include +#include "iconcontroller.h" +#include +#include +#include +#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 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::create(etl::loose_handle instance_) +{ + return Glib::RefPtr(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 action, bool /*is_active*/, bool is_undo, bool is_redo) +{ + assert(action); + + row[model.action] = action; + row[model.name] = static_cast(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(action.get()); + if(specific_action) + { + row[model.canvas] = specific_action->get_canvas(); + row[model.canvas_id] = specific_action->get_canvas()->get_id(); + } + + etl::handle group; + group=etl::handle::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 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 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)row[model.action]) + { + row[model.is_active]=action->is_active(); + return; + } + } +} + +bool +HistoryTreeStore::search_func(const Glib::RefPtr&,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; +} diff --git a/synfig-studio/src/gui/trees/historytreestore.h b/synfig-studio/src/gui/trees/historytreestore.h new file mode 100644 index 0000000..a0fec66 --- /dev/null +++ b/synfig-studio/src/gui/trees/historytreestore.h @@ -0,0 +1,172 @@ +/* === 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 +#include +#include +#include + +/* === 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 > action; + Gtk::TreeModelColumn name; + Gtk::TreeModelColumn > icon; + Gtk::TreeModelColumn is_active; + Gtk::TreeModelColumn is_undo; + Gtk::TreeModelColumn is_redo; + + Gtk::TreeModelColumn canvas_id; + Gtk::TreeModelColumn 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 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 signal_undo_tree_changed_; + + /* + -- ** -- S I G N A L I N T E R F A C E S ----------------------------------- + */ + +public: + + sigc::signal& 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 action); + + void on_action_status_changed(etl::handle action); + + /* + -- ** -- P U B L I C M E T H O D S ----------------------------------------- + */ + +public: + + HistoryTreeStore(etl::loose_handle instance_); + ~HistoryTreeStore(); + + etl::loose_handle instance() { return instance_; } + etl::loose_handle instance()const { return instance_; } + + void rebuild(); + + void refresh() { rebuild(); } + + void insert_action(Gtk::TreeRow row,etl::handle action, bool is_active=true, bool is_undo=true, bool is_redo=false); + + static bool search_func(const Glib::RefPtr&,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 create(etl::loose_handle instance); + +}; // END of class HistoryTreeStore + +}; // END of namespace studio + +/* === E N D =============================================================== */ + +#endif diff --git a/synfig-studio/src/gui/trees/keyframetree.cpp b/synfig-studio/src/gui/trees/keyframetree.cpp new file mode 100644 index 0000000..776ae65 --- /dev/null +++ b/synfig-studio/src/gui/trees/keyframetree.cpp @@ -0,0 +1,291 @@ +/* === 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 +#endif + +#include "trees/keyframetree.h" +#include "cellrenderer_time.h" +#include +#include + +#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 keyframe_tree_store) +{ + keyframe_tree_store_=keyframe_tree_store; + KeyframeTreeStore::Model model; + + if(true) + { + Glib::RefPtr 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; +} diff --git a/synfig-studio/src/gui/trees/keyframetree.h b/synfig-studio/src/gui/trees/keyframetree.h new file mode 100644 index 0000000..cb5d5ca --- /dev/null +++ b/synfig-studio/src/gui/trees/keyframetree.h @@ -0,0 +1,149 @@ +/* === 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 +#include +#include +#include +#include "trees/keyframetreestore.h" +#include + +/* === 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 keyframe_tree_store_; + + CellRenderer_Time *cell_renderer_time; + + CellRenderer_Time *cell_renderer_time_delta; + + Gtk::CellRendererText *cell_renderer_description; + + sigc::signal signal_edited_; + + sigc::signal signal_edited_time_; + + sigc::signal signal_edited_description_; + + sigc::signal 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 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& signal_edited() { return signal_edited_; } + + //! Signal called when a time has been edited. + sigc::signal& signal_edited_time() { return signal_edited_time_; } + + //! Signal called when a description has been edited. + sigc::signal& signal_edited_description() { return signal_edited_description_; } + + sigc::signal& signal_user_click() { return signal_user_click_; } +}; // END of KeyframeTree + +}; // END of namespace studio + +/* === E N D =============================================================== */ + +#endif diff --git a/synfig-studio/src/gui/trees/keyframetreestore.cpp b/synfig-studio/src/gui/trees/keyframetreestore.cpp new file mode 100644 index 0000000..d1925b4 --- /dev/null +++ b/synfig-studio/src/gui/trees/keyframetreestore.cpp @@ -0,0 +1,901 @@ +/* === 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 +#endif + +#include "trees/keyframetreestore.h" +#include +#include "iconcontroller.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "onemoment.h" +#include + +#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& model, const Gtk::TreeModel::Path& path): + gobject_ ( gtk_tree_row_reference_new(model->gobj(), const_cast(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 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::create(etl::loose_handle canvas_interface_) +{ + KeyframeTreeStore *store(new KeyframeTreeStore(canvas_interface_)); + Glib::RefPtr ret(store); + assert(ret); + return ret; +} + +void +KeyframeTreeStore::reset_stamp() +{ + stamp_=time(0)+reinterpret_cast(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(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 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 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 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(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(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(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(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 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 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 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 new_order; + for(unsigned int i=0;inew_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()); + } +} diff --git a/synfig-studio/src/gui/trees/keyframetreestore.h b/synfig-studio/src/gui/trees/keyframetreestore.h new file mode 100644 index 0000000..bfbd00d --- /dev/null +++ b/synfig-studio/src/gui/trees/keyframetreestore.h @@ -0,0 +1,224 @@ +/* === 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 +#include +#include +#include +#include + +/* === 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 time; + Gtk::TreeModelColumn description; + Gtk::TreeModelColumn keyframe; + Gtk::TreeModelColumn 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 canvas_interface_; + + //! Unique stamp for this TreeModel. + int stamp_; + + static KeyframeTreeStore_Class keyframe_tree_store_class_; + + //std::map 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 canvas_interface_); + ~KeyframeTreeStore(); + + etl::loose_handle canvas_interface() { return canvas_interface_; } + etl::loose_handle 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 create(etl::loose_handle 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 diff --git a/synfig-studio/src/gui/trees/layergrouptree.cpp b/synfig-studio/src/gui/trees/layergrouptree.cpp new file mode 100644 index 0000000..0be0596 --- /dev/null +++ b/synfig-studio/src/gui/trees/layergrouptree.cpp @@ -0,0 +1,334 @@ +/* === 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 +#endif + +#include +#include "trees/layergrouptree.h" +#include +#include + +#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 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 layer_group_tree_store) +{ + layer_group_tree_store_=layer_group_tree_store; + LayerGroupTreeStore::Model model; + +#if 0 + { + Glib::RefPtr 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* ret) +{ + const LayerGroupTreeStore::Model model; + if((bool)(*iter)[model.is_group]) + ret->push_back((Glib::ustring)(*iter)[model.group_name]); +} + +std::list +LayerGroupTree::get_selected_groups()const +{ + Glib::RefPtr selection=const_cast(*this).get_selection(); + + if(!selection) + return std::list(); + + std::list 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 selection=const_cast(*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); +} diff --git a/synfig-studio/src/gui/trees/layergrouptree.h b/synfig-studio/src/gui/trees/layergrouptree.h new file mode 100644 index 0000000..8f11024 --- /dev/null +++ b/synfig-studio/src/gui/trees/layergrouptree.h @@ -0,0 +1,127 @@ +/* === 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 +#include +#include +#include +#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 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 layer_group_tree_store_; + + Gtk::CellRendererText *cell_renderer_description; + + bool editable_; + + + sigc::signal > signal_popup_layer_menu_; + +// sigc::signal 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 get_model() { return layer_group_tree_store_; } + + sigc::signal >& signal_popup_layer_menu() { return signal_popup_layer_menu_; } + +// sigc::signal& signal_select_layers() { return signal_select_layers_; } + + void set_model(Glib::RefPtr layer_group_tree_store_); + + void set_editable(bool x=true); + + bool get_editable()const { return editable_; } + + std::list get_selected_groups()const; + + LayerList get_selected_layers()const; +}; // END of LayerGroupTree + +}; // END of namespace studio + +/* === E N D =============================================================== */ + +#endif diff --git a/synfig-studio/src/gui/trees/layergrouptreestore.cpp b/synfig-studio/src/gui/trees/layergrouptreestore.cpp new file mode 100644 index 0000000..02aa8eb --- /dev/null +++ b/synfig-studio/src/gui/trees/layergrouptreestore.cpp @@ -0,0 +1,1031 @@ +/* === 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 +#endif + +#include "trees/layergrouptreestore.h" +#include "iconcontroller.h" +#include +#include +#include +#include +#include "app.h" +#include "instance.h" +#include +#include "docks/dockmanager.h" +#include "docks/dockable.h" + +#include +#include +#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 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&,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::create(etl::loose_handle canvas_interface_) +{ + return Glib::RefPtr(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 x; + g_value_init(x.gobj(),x.value_type()); + + if((bool)(*iter)[model.is_group]) + { + set 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 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 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 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 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 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 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 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 > 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 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 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(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(this)->get_iter(path)); + + if((bool)row[model.is_layer]) + { + Layer* layer(((Layer::Handle)row[model.layer]).get()); + assert(layer); + + std::vector layers; + + layers.push_back(layer); + + selection_data.set("LAYER", 8, reinterpret_cast(&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(&*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(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(selection_data.get_data())); + //synfig::String src_group(const_cast(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(const_cast(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(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(const_cast(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 groups(canvas->get_groups()); + for(;groups.size();groups.erase(groups.begin())) + { + String group(*groups.begin()); + Gtk::TreeRow row(on_group_added(group)); + std::set 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 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 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; +} diff --git a/synfig-studio/src/gui/trees/layergrouptreestore.h b/synfig-studio/src/gui/trees/layergrouptreestore.h new file mode 100644 index 0000000..874bec9 --- /dev/null +++ b/synfig-studio/src/gui/trees/layergrouptreestore.h @@ -0,0 +1,202 @@ +/* === 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 +#include +#include +#include +#include + +/* === 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 LayerList; + + class Model : public Gtk::TreeModel::ColumnRecord + { + public: + Gtk::TreeModelColumn > icon; + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn tooltip; + + Gtk::TreeModelColumn group_name; + Gtk::TreeModelColumn parent_group_name; + + Gtk::TreeModelColumn canvas; + + Gtk::TreeModelColumn active; + Gtk::TreeModelColumn is_layer; + Gtk::TreeModelColumn is_group; + Gtk::TreeModelColumn layer; + + Gtk::TreeModelColumn all_layers; + Gtk::TreeModelColumn 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 canvas_interface_; + + Glib::RefPtr layer_icon; + Glib::RefPtr 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 layer); + void on_group_pair_removed(synfig::String group, etl::handle 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 canvas_interface_); + ~LayerGroupTreeStore(); + + Gtk::TreeRow on_group_added(synfig::String group); + etl::loose_handle canvas_interface() { return canvas_interface_; } + etl::loose_handle canvas_interface()const { return canvas_interface_; } + etl::loose_handle 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&,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 create(etl::loose_handle canvas_interface_); + +}; // END of class LayerGroupTreeStore + +}; // END of namespace studio + +/* === E N D =============================================================== */ + +#endif diff --git a/synfig-studio/src/gui/trees/layerparamtreestore.cpp b/synfig-studio/src/gui/trees/layerparamtreestore.cpp new file mode 100644 index 0000000..8fe850a --- /dev/null +++ b/synfig-studio/src/gui/trees/layerparamtreestore.cpp @@ -0,0 +1,577 @@ +/* === 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 +#endif + +#include "layerparamtreestore.h" +#include "iconcontroller.h" +#include +#include +#include "layertree.h" +#include +#include +#include "app.h" +#include + +#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 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::create(etl::loose_handle canvas_interface_, LayerTree*layer_tree) +{ + return Glib::RefPtr(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 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 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 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 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 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 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 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(); +} diff --git a/synfig-studio/src/gui/trees/layerparamtreestore.h b/synfig-studio/src/gui/trees/layerparamtreestore.h new file mode 100644 index 0000000..7d3eb99 --- /dev/null +++ b/synfig-studio/src/gui/trees/layerparamtreestore.h @@ -0,0 +1,166 @@ +/* === 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 +#include +#include "trees/canvastreestore.h" +#include +#include +#include + +/* === 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 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 param_desc; + + Gtk::TreeModelColumn is_inconsistent; + Gtk::TreeModelColumn 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 changed_connection_list; + + sigc::signal 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 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& 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 create(etl::loose_handle canvas_interface_, LayerTree*layer_tree); +}; // END of class LayerParamTreeStore + +}; // END of namespace studio + +/* === E N D =============================================================== */ + +#endif diff --git a/synfig-studio/src/gui/trees/layertree.cpp b/synfig-studio/src/gui/trees/layertree.cpp new file mode 100644 index 0000000..a69f234 --- /dev/null +++ b/synfig-studio/src/gui/trees/layertree.cpp @@ -0,0 +1,1232 @@ +/* === 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 +#endif + +#include "layertree.h" +#include "layerparamtreestore.h" +#include "cellrenderer_value.h" +#include "cellrenderer_timetrack.h" +#include +#include +#include +#include +#include "app.h" +#include "instance.h" +#include + +#ifdef TIMETRACK_IN_PARAMS_PANEL +# include +#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(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 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::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 selection=const_cast(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 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(row[layer_model.active]); + row[layer_model.active]=!active; +} + +#ifdef TIMETRACK_IN_PARAMS_PANEL +void +LayerTree::on_waypoint_clicked_layertree(const etl::handle& node __attribute__ ((unused)), + const synfig::Time& time __attribute__ ((unused)), + const synfig::Time& time_offset __attribute__ ((unused)), + int button __attribute__ ((unused))) +{ + std::set > 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(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 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&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(&layer), sizeof(layer)); + return; + } +} + +void +LayerTree::on_drop_drag_data_received(const Glib::RefPtr& 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(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& 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& 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); +} +*/ diff --git a/synfig-studio/src/gui/trees/layertree.h b/synfig-studio/src/gui/trees/layertree.h new file mode 100644 index 0000000..cf06899 --- /dev/null +++ b/synfig-studio/src/gui/trees/layertree.h @@ -0,0 +1,261 @@ +/* === 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "layertreestore.h" +#include "layerparamtreestore.h" +#include + +#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 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 layer_tree_store_; + + Glib::RefPtr param_tree_store_; + + Glib::RefPtr 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 signal_layer_toggle_; + + sigc::signal signal_edited_value_; + + sigc::signal signal_layer_user_click_; + + sigc::signal signal_param_user_click_; + + sigc::signal >,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& 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 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 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& signal_layer_toggle() { return signal_layer_toggle_; } + + //! Signal called with a value has been edited. + sigc::signal& signal_edited_value() { return signal_edited_value_; } + + sigc::signal& signal_layer_user_click() { return signal_layer_user_click_; } + + sigc::signal& signal_param_user_click() { return signal_param_user_click_; } + + sigc::signal >,int>& signal_waypoint_clicked_layertree() { return signal_waypoint_clicked_layertree_; } + + etl::handle 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 diff --git a/synfig-studio/src/gui/trees/layertreestore.cpp b/synfig-studio/src/gui/trees/layertreestore.cpp new file mode 100644 index 0000000..16b7fc8 --- /dev/null +++ b/synfig-studio/src/gui/trees/layertreestore.cpp @@ -0,0 +1,1081 @@ +/* === 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 +#endif + +#include "layertreestore.h" +#include "iconcontroller.h" +#include +#include +#include +#include +#include "app.h" +#include "instance.h" +#include +#include + +#include +#include +#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 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&,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::create(etl::loose_handle canvas_interface_) +{ + return Glib::RefPtr(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 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 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 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 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 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 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 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 > 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 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 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(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(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(&layer), sizeof(layer)); + + std::vector 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(&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(&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(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(const_cast(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(this)->get_iter(dest_parent)) + return (bool)(Canvas::Handle)(*const_cast(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(const_cast(selection_data.get_data()))[i]); + assert(src); + if(dest_layer==src) + continue; + + if(dest_canvas==src->get_canvas() && src->get_depth()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::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 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::cast_dynamic(layer)) + subcanvas_changed_connections[layer] = + (etl::handle::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::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; +} diff --git a/synfig-studio/src/gui/trees/layertreestore.h b/synfig-studio/src/gui/trees/layertreestore.h new file mode 100644 index 0000000..5b33309 --- /dev/null +++ b/synfig-studio/src/gui/trees/layertreestore.h @@ -0,0 +1,226 @@ +/* === 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 +#include +#include +#include +#include + +/* === 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 > icon; + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn name; + Gtk::TreeModelColumn id; + + Gtk::TreeModelColumn canvas; + + Gtk::TreeModelColumn tooltip; + + + Gtk::TreeModelColumn active; + Gtk::TreeModelColumn layer; + Gtk::TreeModelColumn contained_canvas; + + Gtk::TreeModelColumn children_lock; + + Gtk::TreeModelColumn z_depth; + Gtk::TreeModelColumn 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 subcanvas_changed_connections; + + etl::loose_handle canvas_interface_; + + Glib::RefPtr 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 canvas_interface_); + ~LayerTreeStore(); + + etl::loose_handle canvas_interface() { return canvas_interface_; } + etl::loose_handle canvas_interface()const { return canvas_interface_; } + etl::loose_handle 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 value_node,synfig::ParamDesc *param_desc); + + //virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc); + static bool search_func(const Glib::RefPtr&,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 create(etl::loose_handle canvas_interface_); + + +}; // END of class LayerTreeStore + +}; // END of namespace studio + +/* === E N D =============================================================== */ + +#endif diff --git a/synfig-studio/src/gui/trees/metadatatreestore.cpp b/synfig-studio/src/gui/trees/metadatatreestore.cpp new file mode 100644 index 0000000..98bb7c6 --- /dev/null +++ b/synfig-studio/src/gui/trees/metadatatreestore.cpp @@ -0,0 +1,152 @@ +/* === 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 +#endif + +#include "metadatatreestore.h" +#include + +#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 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::create(etl::loose_handle canvas_interface_) +{ + return Glib::RefPtr(new MetaDataTreeStore(canvas_interface_)); +} + +void +MetaDataTreeStore::meta_data_changed(synfig::String /*key*/) +{ + rebuild(); +} + +void +MetaDataTreeStore::rebuild() +{ + clear(); + + std::list 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 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); +} diff --git a/synfig-studio/src/gui/trees/metadatatreestore.h b/synfig-studio/src/gui/trees/metadatatreestore.h new file mode 100644 index 0000000..6ad41d4 --- /dev/null +++ b/synfig-studio/src/gui/trees/metadatatreestore.h @@ -0,0 +1,133 @@ +/* === 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 +#include +#include +#include + +/* === 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 key; + Gtk::TreeModelColumn 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 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 get_canvas_interface() { return canvas_interface_; } + etl::loose_handle 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); + 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 create(etl::loose_handle); + +}; // END of class MetaDataTreeStore + +}; // END of namespace studio + +/* === E N D =============================================================== */ + +#endif