dd8dd8a0e758f66df3176368b9a7b7d988611a11
[synfig.git] / synfig-studio / trunk / src / gtkmm / layergrouptree.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file layergrouptree.cpp
3 **      \brief Template File
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === H E A D E R S ======================================================= */
24
25 #ifdef USING_PCH
26 #       include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #       include <config.h>
30 #endif
31
32 #include <synfig/layer.h>
33 #include "layergrouptree.h"
34 #include <gtkmm/treemodelsort.h>
35 #include <ETL/misc>
36
37 #include "general.h"
38
39 #endif
40
41 /* === U S I N G =========================================================== */
42
43 using namespace std;
44 using namespace etl;
45 using namespace synfig;
46 using namespace studio;
47
48 /* === M A C R O S ========================================================= */
49
50 /* === G L O B A L S ======================================================= */
51
52 /* === P R O C E D U R E S ================================================= */
53
54 /* === M E T H O D S ======================================================= */
55
56 LayerGroupTree::LayerGroupTree()
57 {
58         const LayerGroupTreeStore::Model model;
59
60
61         {       // --- O N / O F F ----------------------------------------------------
62                 int index;
63                 index=append_column_editable(_(" "),model.active);
64                 //Gtk::TreeView::Column* column = get_column(index-1);
65         }
66         {       // --- I C O N --------------------------------------------------------
67                 int index;
68                 index=append_column(_(" "),model.icon);
69                 Gtk::TreeView::Column* column = get_column(index-1);
70                 set_expander_column(*column);
71         }
72         {       // --- N A M E --------------------------------------------------------
73                 int index;
74                 index=append_column_editable(_("Name"),model.label);
75                 label_column = get_column(index-1);
76
77                 //column->set_sort_column(layer_model.index);
78
79                 //set_expander_column(*column);
80                 //column->set_reorderable();
81                 //column->set_resizable();
82                 //column->set_clickable(false);
83
84                 //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
85                 //column->pack_start(*icon_cellrenderer,false);
86                 //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
87         }
88
89         set_enable_search(true);
90         set_search_column(model.label);
91         set_search_equal_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::search_func));
92
93         // This makes things easier to read.
94         set_rules_hint();
95
96         // Make us more sensitive to several events
97         add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
98
99         set_reorderable(true);
100
101         get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
102
103         //set_flags(get_flags()|Gtk::RECEIVES_DEFAULT|Gtk::HAS_GRAB);
104
105         //std::list<Gtk::TargetEntry> listTargets;
106         //listTargets.push_back( Gtk::TargetEntry("LAYER") );
107         //listTargets.push_back( Gtk::TargetEntry("GROUP") );
108         //drag_dest_set(listTargets);
109 }
110
111 LayerGroupTree::~LayerGroupTree()
112 {
113         if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
114                 synfig::info("LayerGroupTree::~LayerGroupTree(): Deleted");
115 }
116
117 void
118 LayerGroupTree::set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store)
119 {
120         layer_group_tree_store_=layer_group_tree_store;
121         LayerGroupTreeStore::Model model;
122
123 #if 0
124         {
125                 Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(layer_group_tree_store_));
126                 sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
127                 sorted_store->set_sort_func(model.time.index(),sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
128                 sorted_store->set_sort_column(model.time.index(), Gtk::SORT_ASCENDING);
129                 Gtk::TreeView::set_model(sorted_store);
130         }
131 #else
132                 Gtk::TreeView::set_model(layer_group_tree_store);
133 #endif
134 }
135
136 void
137 LayerGroupTree::set_editable(bool x)
138 {
139         editable_=x;
140 /*
141         if(editable_)
142         {
143                 cell_renderer_time->property_editable()=true;
144                 cell_renderer_time_delta->property_editable()=true;
145                 cell_renderer_description->property_editable()=true;
146         }
147         else
148         {
149                 cell_renderer_time->property_editable()=false;
150                 cell_renderer_time_delta->property_editable()=false;
151                 cell_renderer_description->property_editable()=false;
152         }
153 */
154 }
155 /*
156 void
157 LayerGroupTree::on_edited_time(const Glib::ustring&path_string,synfig::Time time)
158 {
159         Gtk::TreePath path(path_string);
160
161         const Gtk::TreeRow row(*(get_model()->get_iter(path)));
162
163         synfig::Keyframe keyframe(row[model.keyframe]);
164         if(time!=keyframe.get_time())
165         {
166                 row[model.time]=time;
167                 //keyframe.set_time(time);
168                 //signal_edited_time()(keyframe,time);
169                 //signal_edited()(keyframe);
170         }
171 }
172
173 void
174 LayerGroupTree::on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time)
175 {
176         Gtk::TreePath path(path_string);
177
178         const Gtk::TreeRow row(*(get_model()->get_iter(path)));
179
180         if(row)row[model.time_delta]=time;
181 }
182
183 void
184 LayerGroupTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
185 {
186         Gtk::TreePath path(path_string);
187
188         const Gtk::TreeRow row = *(get_model()->get_iter(path));
189
190         const synfig::String description(desc);
191         synfig::Keyframe keyframe(row[model.keyframe]);
192         if(description!=keyframe.get_description())
193         {
194                 row[model.description]=desc;
195                 keyframe.set_description(description);
196                 signal_edited_description()(keyframe,description);
197                 signal_edited()(keyframe);
198         }
199 }
200 */
201
202 bool
203 LayerGroupTree::on_event(GdkEvent *event)
204 {
205     switch(event->type)
206     {
207         case GDK_BUTTON_PRESS:
208                 {
209                         Gtk::TreeModel::Path path;
210                         Gtk::TreeViewColumn *column;
211                         int cell_x, cell_y;
212                         int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
213                         //tree_to_widget_coords (,, wx, wy);
214                         if(!get_path_at_pos(
215                                 wx,wy,  // x, y
216                                 path, // TreeModel::Path&
217                                 column, //TreeViewColumn*&
218                                 cell_x,cell_y //int&cell_x,int&cell_y
219                                 )
220                         ) break;
221                         const Gtk::TreeRow row = *(get_model()->get_iter(path));
222
223                         if(row[model.is_layer] && event->button.button==3)
224                         {
225                                 signal_popup_layer_menu()((Layer::Handle)row[model.layer]);
226                                 return true;
227                         }
228
229                         /*signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
230                         if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
231                         {
232                                 layer_group_tree_store_->canvas_interface()->set_time(row[model.time]);
233                         }*/
234                 }
235                 break;
236         case GDK_2BUTTON_PRESS:
237                 {
238                         Gtk::TreeModel::Path path;
239                         Gtk::TreeViewColumn *column;
240                         int cell_x, cell_y;
241                         if(!get_path_at_pos(
242                                 int(event->button.x),int(event->button.y),      // x, y
243                                 path, // TreeModel::Path&
244                                 column, //TreeViewColumn*&
245                                 cell_x,cell_y //int&cell_x,int&cell_y
246                                 )
247                         ) break;
248                         const Gtk::TreeRow row = *(get_model()->get_iter(path));
249
250                         LayerList layer_list(row[model.all_layers]);
251                         if(!layer_list.empty())
252                         {
253                                 if(!(event->button.state&GDK_CONTROL_MASK))
254                                 {
255                                         layer_group_tree_store_->canvas_interface()->get_selection_manager()->clear_selected_layers();
256                                 }
257                                 layer_group_tree_store_->canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
258                                 return true;
259                         }
260                 }
261                 break;
262         case GDK_BUTTON_RELEASE:
263                 break;
264         default:
265                 break;
266         }
267         return Gtk::TreeView::on_event(event);
268         //return false;
269 }
270
271 static inline void __group_grabber(const Gtk::TreeModel::iterator& iter, std::list<synfig::String>* ret)
272 {
273         const LayerGroupTreeStore::Model model;
274         if((bool)(*iter)[model.is_group])
275                 ret->push_back((Glib::ustring)(*iter)[model.group_name]);
276 }
277
278 std::list<synfig::String>
279 LayerGroupTree::get_selected_groups()const
280 {
281         Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
282
283         if(!selection)
284                 return std::list<synfig::String>();
285
286         std::list<synfig::String> ret;
287
288         selection->selected_foreach_iter(
289                 sigc::bind(
290                         sigc::ptr_fun(
291                                 &__group_grabber
292                         ),
293                         &ret
294                 )
295         );
296
297         return ret;
298 }
299
300 static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerGroupTree::LayerList* ret)
301 {
302         const LayerGroupTreeStore::Model model;
303         if((bool)(*iter)[model.is_layer])
304                 ret->push_back((Layer::Handle)(*iter)[model.layer]);
305 }
306
307 LayerGroupTree::LayerList
308 LayerGroupTree::get_selected_layers()const
309 {
310         Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
311
312         if(!selection)
313                 return LayerList();
314
315         LayerList ret;
316
317         selection->selected_foreach_iter(
318                 sigc::bind(
319                         sigc::ptr_fun(
320                                 &__layer_grabber
321                         ),
322                         &ret
323                 )
324         );
325
326         return ret;
327 }
328
329 void
330 LayerGroupTree::set_cursor(const Gtk::TreeModel::Path& path, bool start_editing)
331 {
332         Gtk::TreeView::set_cursor(path, *label_column, start_editing);
333 }