my log
[synfig.git] / synfig-studio / trunk / src / gtkmm / childrentree.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file childrentree.cpp
3 **      \brief Template File
4 **
5 **      $Id: childrentree.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #ifdef USING_PCH
25 #       include "pch.h"
26 #else
27 #ifdef HAVE_CONFIG_H
28 #       include <config.h>
29 #endif
30
31 #include "childrentree.h"
32 #include "cellrenderer_value.h"
33 #include "cellrenderer_timetrack.h"
34 #include <synfigapp/action.h>
35 #include <synfigapp/instance.h>
36 #include <gtkmm/scrolledwindow.h>
37
38 #endif
39
40 /* === U S I N G =========================================================== */
41
42 using namespace std;
43 using namespace etl;
44 using namespace synfig;
45 using namespace studio;
46
47 /* === M A C R O S ========================================================= */
48
49 #ifndef SMALL_BUTTON
50 #define SMALL_BUTTON(button,stockid,tooltip)    \
51         button = manage(new class Gtk::Button());       \
52         icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize));    \
53         button->add(*icon);     \
54         tooltips_.set_tip(*button,tooltip);     \
55         icon->set_padding(0,0);\
56         icon->show();   \
57         button->set_relief(Gtk::RELIEF_NONE); \
58         button->show()
59 #endif
60
61 #ifndef NORMAL_BUTTON
62 #define NORMAL_BUTTON(button,stockid,tooltip)   \
63         button = manage(new class Gtk::Button());       \
64         icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON));       \
65         button->add(*icon);     \
66         tooltips_.set_tip(*button,tooltip);     \
67         icon->set_padding(0,0);\
68         icon->show();   \
69         /*button->set_relief(Gtk::RELIEF_NONE);*/ \
70         button->show()
71 #endif
72
73 #define NEW_SMALL_BUTTON(x,y,z) Gtk::Button *SMALL_BUTTON(x,y,z)
74
75 #define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
76
77 /* === G L O B A L S ======================================================= */
78
79 /* === P R O C E D U R E S ================================================= */
80
81 /* === M E T H O D S ======================================================= */
82
83 ChildrenTree::ChildrenTree()
84 {
85         const ChildrenTreeStore::Model model;
86
87         {       // --- N A M E --------------------------------------------------------
88                 Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ID")) );
89
90                 // Set up the icon cell-renderer
91                 Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
92                 column->pack_start(*icon_cellrenderer,false);
93                 column->add_attribute(icon_cellrenderer->property_pixbuf(), model.icon);
94
95                 // Pack the label into the column
96                 column->pack_start(model.label,true);
97
98                 // Finish setting up the column         
99                 column->set_reorderable();
100                 column->set_resizable();
101                 column->set_clickable();
102                 column->set_min_width(150);
103                 column->set_sort_column_id(model.label);
104                 tree_view.append_column(*column);
105                 
106         }
107         {       // --- T Y P E --------------------------------------------------------
108                 int cols_count = tree_view.append_column(_("Type"),model.type);
109                 Gtk::TreeViewColumn* column = tree_view.get_column(cols_count-1);
110                 if(column)
111                 {
112                         column->set_reorderable();
113                         column->set_resizable();
114                         column->set_clickable();
115                         column->set_sort_column_id(model.type);
116                 }
117         }
118         {       // --- V A L U E  -----------------------------------------------------
119                 Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ValueBase")) );
120                 
121                 // Set up the value cell-renderer
122                 cellrenderer_value=ChildrenTreeStore::add_cell_renderer_value(column);
123                 cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_edited_value));
124                 cellrenderer_value->property_value()=synfig::ValueBase();
125
126                 // Finish setting up the column
127                 tree_view.append_column(*column);
128                 column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
129                 column->set_min_width(150);
130                 column->set_reorderable();
131                 column->set_resizable();
132                 column->set_clickable(false);
133         }
134         {       // --- T I M E   T R A C K --------------------------------------------
135                 Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
136                 column_time_track=column;
137                 
138                 // Set up the value-node cell-renderer
139                 cellrenderer_time_track=ChildrenTreeStore::add_cell_renderer_value_node(column);
140                 cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
141                 cellrenderer_time_track->signal_waypoint_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_waypoint_clicked) );
142                 column->add_attribute(cellrenderer_time_track->property_value_desc(), model.value_desc);
143                 column->add_attribute(cellrenderer_time_track->property_canvas(), model.canvas);
144
145                 //column->pack_start(*cellrenderer_time_track);
146                                 
147                 // Finish setting up the column
148                 column->set_reorderable();
149                 column->set_resizable();
150                 tree_view.append_column(*column);
151         }
152
153         // This makes things easier to read.
154         tree_view.set_rules_hint();
155         
156         // Make us more sensitive to several events
157         tree_view.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
158         
159         tree_view.signal_event().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_tree_event));
160
161         // Create a scrolled window for that tree
162         Gtk::ScrolledWindow *scroll_children_tree = manage(new class Gtk::ScrolledWindow());
163         scroll_children_tree->set_flags(Gtk::CAN_FOCUS);
164         scroll_children_tree->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
165         scroll_children_tree->add(tree_view);
166         scroll_children_tree->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
167         scroll_children_tree->show();
168
169         attach(*scroll_children_tree, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
170
171         hbox=manage(new Gtk::HBox());
172         
173         attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
174
175         
176         
177         tree_view.set_enable_search(true);
178         tree_view.set_search_column(model.label);
179         
180         
181 /*
182         Gtk::Image *icon;
183         //Gtk::IconSize iconsize(Gtk::IconSize::from_name("synfig-small_icon"));
184         Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
185
186         SMALL_BUTTON(button_raise,"gtk-go-up","Raise");
187         SMALL_BUTTON(button_lower,"gtk-go-down","Lower");
188         SMALL_BUTTON(button_duplicate,"synfig-duplicate","Duplicate");
189         SMALL_BUTTON(button_delete,"gtk-delete","Delete");
190         
191         hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
192         hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
193         hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
194         hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
195
196         button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_raise_pressed));
197         button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_lower_pressed));
198         button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_duplicate_pressed));
199         button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_delete_pressed));
200
201         button_raise->set_sensitive(false);
202         button_lower->set_sensitive(false);
203         button_duplicate->set_sensitive(false);
204         button_delete->set_sensitive(false);
205 */
206
207
208
209         get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_selection_changed));
210
211
212         tree_view.set_reorderable(true);
213
214         hbox->show();
215         tree_view.show();
216
217         tooltips_.enable();
218
219         //get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
220 }
221
222
223 ChildrenTree::~ChildrenTree()
224 {
225 }
226
227 void
228 ChildrenTree::set_show_timetrack(bool x)
229 {
230         column_time_track->set_visible(x);
231 }
232
233 void
234 ChildrenTree::set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store)
235 {
236         children_tree_store_=children_tree_store;
237         tree_view.set_model(children_tree_store_);
238         children_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::ChildrenTree::on_dirty_preview));
239 }
240
241 void
242 ChildrenTree::set_time_adjustment(Gtk::Adjustment &adjustment)
243 {
244         cellrenderer_time_track->set_adjustment(adjustment);
245 }
246
247 void
248 ChildrenTree::on_dirty_preview()
249 {
250 }
251
252 void
253 ChildrenTree::on_selection_changed()
254 {       
255         if(0)
256                 {
257                 button_raise->set_sensitive(false);
258                 button_lower->set_sensitive(false);
259                 button_duplicate->set_sensitive(false);
260                 button_delete->set_sensitive(false);
261                 return;
262         }
263 }
264
265
266 void
267 ChildrenTree::on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value)
268 {
269         Gtk::TreePath path(path_string);
270         
271         const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
272
273         row[model.value]=value;
274 //      signal_edited_value()(row[model.value_desc],value);
275 }
276
277 void
278 ChildrenTree::on_waypoint_clicked(const Glib::ustring &path_string, synfig::Waypoint waypoint,int button)
279 {
280         Gtk::TreePath path(path_string);
281         
282         const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
283         
284         signal_waypoint_clicked()(static_cast<synfigapp::ValueDesc>(row[model.value_desc]),waypoint,button);
285 }
286
287 bool
288 ChildrenTree::on_tree_event(GdkEvent *event)
289 {
290     switch(event->type)
291     {
292         case GDK_BUTTON_PRESS:
293                 {
294                         Gtk::TreeModel::Path path;
295                         Gtk::TreeViewColumn *column;
296                         int cell_x, cell_y;
297                         if(!tree_view.get_path_at_pos(
298                                 int(event->button.x),int(event->button.y),      // x, y
299                                 path, // TreeModel::Path&
300                                 column, //TreeViewColumn*&
301                                 cell_x,cell_y //int&cell_x,int&cell_y
302                                 )
303                         ) break;
304                         const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
305                         
306                         if(column->get_first_cell_renderer()==cellrenderer_time_track)
307                         {
308                                 return signal_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
309                         }
310                         else if(column->get_first_cell_renderer()==cellrenderer_value)
311                                 return signal_user_click()(event->button.button,row,COLUMNID_VALUE);
312                         else
313                                 return signal_user_click()(event->button.button,row,COLUMNID_ID);
314                         
315                 }
316                 break;
317                 
318         case GDK_MOTION_NOTIFY:
319                 {
320                         Gtk::TreeModel::Path path;
321                         Gtk::TreeViewColumn *column;
322                         int cell_x, cell_y;
323                         if(!tree_view.get_path_at_pos(
324                                 (int)event->button.x,(int)event->button.y,      // x, y
325                                 path, // TreeModel::Path&
326                                 column, //TreeViewColumn*&
327                                 cell_x,cell_y //int&cell_x,int&cell_y
328                                 )
329                         ) break;
330                         
331                         if(!tree_view.get_model()->get_iter(path))
332                                 break;
333                         
334                         Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
335                         
336                         if(cellrenderer_time_track==column->get_first_cell_renderer())
337                         {
338                                 // Movement on TimeLine
339                                 return true;
340                         }
341                         else
342                         if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
343                         {
344                                 tooltips_.unset_tip(*this);
345                                 Glib::ustring tooltips_string(row[model.tooltip]);
346                                 last_tooltip_path=path;
347                                 if(!tooltips_string.empty())
348                                 {
349                                         tooltips_.set_tip(*this,tooltips_string);
350                                         tooltips_.force_window();
351                                 }
352                         }
353                 }
354                 break;
355         case GDK_BUTTON_RELEASE:
356                 break;
357         default:
358                 break;
359         }
360         return false;
361 }
362
363 void
364 ChildrenTree::on_raise_pressed()
365 {
366 }
367
368 void
369 ChildrenTree::on_lower_pressed()
370 {
371 }
372
373 void
374 ChildrenTree::on_duplicate_pressed()
375 {
376 }
377
378 void
379 ChildrenTree::on_delete_pressed()
380 {
381 }