source: synfigstudio/trunk/fuentes/src/gui/trees/childrentree.cpp @ 481

Last change on this file since 481 was 481, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 14.4 KB
Line 
1/* === S Y N F I G ========================================================= */
2/*!     \file childrentree.cpp
3**      \brief Template File
4**
5**      $Id$
6**
7**      \legal
8**      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9**      Copyright (c) 2008 Chris Moore
10**
11**      This package is free software; you can redistribute it and/or
12**      modify it under the terms of the GNU General Public License as
13**      published by the Free Software Foundation; either version 2 of
14**      the License, or (at your option) any later version.
15**
16**      This package is distributed in the hope that it will be useful,
17**      but WITHOUT ANY WARRANTY; without even the implied warranty of
18**      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19**      General Public License for more details.
20**      \endlegal
21*/
22/* ========================================================================= */
23
24/* === H E A D E R S ======================================================= */
25
26#ifdef USING_PCH
27#       include "pch.h"
28#else
29#ifdef HAVE_CONFIG_H
30#       include <config.h>
31#endif
32
33#include "trees/childrentree.h"
34#include "cellrenderer/cellrenderer_value.h"
35#include "cellrenderer/cellrenderer_timetrack.h"
36#include <synfigapp/action.h>
37#include <synfigapp/instance.h>
38#include <gtkmm/scrolledwindow.h>
39#include <synfig/timepointcollect.h>
40
41#include "general.h"
42
43#endif
44
45/* === U S I N G =========================================================== */
46
47using namespace std;
48using namespace etl;
49using namespace synfig;
50using namespace studio;
51
52/* === M A C R O S ========================================================= */
53
54#ifndef SMALL_BUTTON
55#define SMALL_BUTTON(button,stockid,tooltip)    \
56        button = manage(new class Gtk::Button());       \
57        icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize));    \
58        button->add(*icon);     \
59        button->set_tooltip_text(,tooltip);     \
60        icon->set_padding(0,0);\
61        icon->show();   \
62        button->set_relief(Gtk::RELIEF_NONE); \
63        button->show()
64#endif
65
66#ifndef NORMAL_BUTTON
67#define NORMAL_BUTTON(button,stockid,tooltip)   \
68        button = manage(new class Gtk::Button());       \
69        icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON));       \
70        button->add(*icon);     \
71        button->set_tooltip_text(,tooltip);     \
72        icon->set_padding(0,0);\
73        icon->show();   \
74        /*button->set_relief(Gtk::RELIEF_NONE);*/ \
75        button->show()
76#endif
77
78#define NEW_SMALL_BUTTON(x,y,z) Gtk::Button *SMALL_BUTTON(x,y,z)
79
80#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
81
82/* === G L O B A L S ======================================================= */
83
84/* === P R O C E D U R E S ================================================= */
85
86/* === M E T H O D S ======================================================= */
87
88ChildrenTree::ChildrenTree()
89{
90        const ChildrenTreeStore::Model model;
91
92        {       // --- N A M E --------------------------------------------------------
93                Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ID")) );
94
95                // Set up the icon cell-renderer
96                Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
97                column->pack_start(*icon_cellrenderer,false);
98                column->add_attribute(icon_cellrenderer->property_pixbuf(), model.icon);
99
100                // Pack the label into the column
101                column->pack_start(model.label,true);
102
103                // Finish setting up the column
104                column->set_reorderable();
105                column->set_resizable();
106                column->set_clickable();
107                column->set_min_width(150);
108                column->set_sort_column(model.label);
109                tree_view.append_column(*column);
110        }
111        {       // --- T Y P E --------------------------------------------------------
112                int cols_count = tree_view.append_column(_("Type"),model.type);
113                Gtk::TreeViewColumn* column = tree_view.get_column(cols_count-1);
114                if(column)
115                {
116                        column->set_reorderable();
117                        column->set_resizable();
118                        column->set_clickable();
119                        column->set_sort_column(model.type);
120                }
121        }
122        {       // --- V A L U E  -----------------------------------------------------
123                Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ValueBase")) );
124
125                // Set up the value cell-renderer
126                cellrenderer_value=ChildrenTreeStore::add_cell_renderer_value(column);
127                cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_edited_value));
128                cellrenderer_value->property_value()=synfig::ValueBase();
129                column->add_attribute(cellrenderer_value->property_value_desc(), model.value_desc);
130
131                // Finish setting up the column
132                tree_view.append_column(*column);
133                column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
134                column->set_min_width(150);
135                column->set_reorderable();
136                column->set_resizable();
137                column->set_clickable(false);
138        }
139        {       // --- T I M E   T R A C K --------------------------------------------
140                Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
141                column_time_track=column;
142
143                // Set up the value-node cell-renderer
144                cellrenderer_time_track=ChildrenTreeStore::add_cell_renderer_value_node(column);
145                cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
146                cellrenderer_time_track->signal_waypoint_clicked_cellrenderer().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_waypoint_clicked_childrentree) );
147                column->add_attribute(cellrenderer_time_track->property_value_desc(), model.value_desc);
148                column->add_attribute(cellrenderer_time_track->property_canvas(), model.canvas);
149
150                //column->pack_start(*cellrenderer_time_track);
151
152                // Finish setting up the column
153                column->set_reorderable();
154                column->set_resizable();
155                tree_view.append_column(*column);
156        }
157
158        // This makes things easier to read.
159        tree_view.set_rules_hint();
160
161        // Make us more sensitive to several events
162        tree_view.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
163
164        tree_view.signal_event().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_tree_event));
165        tree_view.signal_query_tooltip().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_tree_view_query_tooltip));
166
167        // Create a scrolled window for that tree
168        Gtk::ScrolledWindow *scroll_children_tree = manage(new class Gtk::ScrolledWindow());
169        scroll_children_tree->set_can_focus(true);
170        scroll_children_tree->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
171        scroll_children_tree->add(tree_view);
172        scroll_children_tree->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
173        scroll_children_tree->show();
174
175        attach(*scroll_children_tree, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
176
177        hbox=manage(new Gtk::HBox());
178
179        attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
180
181        tree_view.set_enable_search(true);
182        tree_view.set_search_column(model.label);
183
184/*  // Buttons to raise/lower/duplicate/delete children valuenodes
185        //   Commented out because these functions are not implemented
186    //   and children sort themselves alphabetically
187
188        Gtk::Image *icon;
189        //Gtk::IconSize iconsize(Gtk::IconSize::from_name("synfig-small_icon"));
190        Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
191
192        SMALL_BUTTON(button_raise,"gtk-go-up",_("Raise"));
193        SMALL_BUTTON(button_lower,"gtk-go-down",_("Lower"));
194        SMALL_BUTTON(button_duplicate,"synfig-duplicate",_("Duplicate"));
195        SMALL_BUTTON(button_delete,"gtk-delete",_("Delete"));
196
197        hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
198        hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
199        hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
200        hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
201
202        button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_raise_pressed));
203        button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_lower_pressed));
204        button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_duplicate_pressed));
205        button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_delete_pressed));
206
207        button_raise->set_sensitive(false);
208        button_lower->set_sensitive(false);
209        button_duplicate->set_sensitive(false);
210        button_delete->set_sensitive(false);
211*/
212
213        get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_selection_changed));
214
215        tree_view.set_reorderable(true);
216
217        hbox->show();
218        tree_view.show();
219
220        tree_view.set_has_tooltip();
221
222        //get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
223}
224
225ChildrenTree::~ChildrenTree()
226{
227}
228
229void
230ChildrenTree::set_show_timetrack(bool x)
231{
232        column_time_track->set_visible(x);
233}
234
235void
236ChildrenTree::set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store)
237{
238        children_tree_store_=children_tree_store;
239        tree_view.set_model(children_tree_store_);
240        cellrenderer_time_track->set_canvas_interface(children_tree_store_->canvas_interface()); // am I smart people?  (cellrenderer/cellrenderer_timetrack.h:176)
241        children_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::ChildrenTree::on_dirty_preview));
242}
243
244void
245ChildrenTree::set_time_adjustment(const Glib::RefPtr<Gtk::Adjustment> &adjustment)
246{
247        cellrenderer_time_track->set_adjustment(adjustment);
248}
249
250void
251ChildrenTree::on_dirty_preview()
252{
253}
254
255void
256ChildrenTree::on_selection_changed()
257{
258        if(0)
259                {
260                button_raise->set_sensitive(false);
261                button_lower->set_sensitive(false);
262                button_duplicate->set_sensitive(false);
263                button_delete->set_sensitive(false);
264                return;
265        }
266}
267
268void
269ChildrenTree::on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value)
270{
271        Gtk::TreePath path(path_string);
272
273        const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
274
275        row[model.value]=value;
276//      signal_edited_value()(row[model.value_desc],value);
277}
278
279void
280ChildrenTree::on_waypoint_clicked_childrentree(const etl::handle<synfig::Node>& node __attribute__ ((unused)),
281                                                                                           const synfig::Time& time __attribute__ ((unused)),
282                                                                                           const synfig::Time& time_offset __attribute__ ((unused)),
283                                                                                           const synfig::Time& time_dilation __attribute__ ((unused)),
284                                                                                           int button __attribute__ ((unused)))
285{
286        std::set<synfig::Waypoint, std::less<UniqueID> > waypoint_set;
287        synfig::waypoint_collect(waypoint_set,time,node);
288
289        synfigapp::ValueDesc value_desc;
290
291        if (waypoint_set.size() == 1)
292        {
293                ValueNode::Handle value_node(waypoint_set.begin()->get_parent_value_node());
294                assert(value_node);
295
296                Gtk::TreeRow row;
297                if (children_tree_store_->find_first_value_node(value_node, row) && row)
298                        value_desc = static_cast<synfigapp::ValueDesc>(row[model.value_desc]);
299        }
300
301        if (!waypoint_set.empty())
302                signal_waypoint_clicked_childrentree()(value_desc,waypoint_set,button);
303}
304
305bool
306ChildrenTree::on_tree_event(GdkEvent *event)
307{
308    switch(event->type)
309    {
310        case GDK_BUTTON_PRESS:
311                {
312                        Gtk::TreeModel::Path path;
313                        Gtk::TreeViewColumn *column;
314                        int cell_x, cell_y;
315                        if(!tree_view.get_path_at_pos(
316                                int(event->button.x),int(event->button.y),      // x, y
317                                path, // TreeModel::Path&
318                                column, //TreeViewColumn*&
319                                cell_x,cell_y //int&cell_x,int&cell_y
320                                )
321                        ) break;
322                        const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
323
324                        if(column->get_first_cell()==cellrenderer_time_track)
325                        {
326                                Gdk::Rectangle rect;
327                                tree_view.get_cell_area(path,*column,rect);
328                                cellrenderer_time_track->property_value_desc()=row[model.value_desc];
329                                cellrenderer_time_track->property_canvas()=row[model.canvas];
330                                cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
331                                queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
332                                return true;
333                        }
334                        else if(column->get_first_cell()==cellrenderer_value)
335                                return signal_user_click()(event->button.button,row,COLUMNID_VALUE);
336                        else
337                                return signal_user_click()(event->button.button,row,COLUMNID_ID);
338
339                }
340                break;
341
342        case GDK_MOTION_NOTIFY:
343                {
344                        Gtk::TreeModel::Path path;
345                        Gtk::TreeViewColumn *column;
346                        int cell_x, cell_y;
347                        if(!tree_view.get_path_at_pos(
348                                (int)event->button.x,(int)event->button.y,      // x, y
349                                path, // TreeModel::Path&
350                                column, //TreeViewColumn*&
351                                cell_x,cell_y //int&cell_x,int&cell_y
352                                )
353                        ) break;
354
355                        if(!tree_view.get_model()->get_iter(path))
356                                break;
357
358                        Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
359
360                        if(cellrenderer_time_track==column->get_first_cell())
361                        {
362                                // Movement on TimeLine
363                                Gdk::Rectangle rect;
364                                tree_view.get_cell_area(path,*column,rect);
365                                cellrenderer_time_track->property_value_desc()=row[model.value_desc];
366                                cellrenderer_time_track->property_canvas()=row[model.canvas];
367                                cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
368                                queue_draw();
369                                //queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
370                                return true;
371                        }
372                }
373                break;
374        case GDK_BUTTON_RELEASE:
375                {
376                        Gtk::TreeModel::Path path;
377                        Gtk::TreeViewColumn *column;
378                        int cell_x, cell_y;
379                        if(!tree_view.get_path_at_pos(
380                                   (int)event->button.x,(int)event->button.y,   // x, y
381                                   path, // TreeModel::Path&
382                                   column, //TreeViewColumn*&
383                                   cell_x,cell_y //int&cell_x,int&cell_y
384                                   )
385                                ) break;
386
387                        if(!tree_view.get_model()->get_iter(path))
388                                break;
389
390                        Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
391
392                        if(column && cellrenderer_time_track == column->get_first_cell())
393                        {
394                                Gdk::Rectangle rect;
395                                tree_view.get_cell_area(path,*column,rect);
396                                cellrenderer_time_track->property_value_desc()=row[model.value_desc];
397                                cellrenderer_time_track->property_canvas()=row[model.canvas];
398                                cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
399                                queue_draw();
400                                queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
401                                return true;
402                        }
403                }
404                break;
405        default:
406                break;
407        }
408        return false;
409}
410
411bool
412ChildrenTree::on_tree_view_query_tooltip(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip)
413{
414        if(keyboard_tooltip)
415                return false;
416        Gtk::TreeModel::Path path;
417        Gtk::TreeViewColumn *column;
418        int cell_x, cell_y;
419        int bx, by;
420        get_tree_view().convert_widget_to_bin_window_coords(x, y, bx, by);
421        if(!get_tree_view().get_path_at_pos(bx, by, path, column, cell_x,cell_y))
422                return false;
423        Gtk::TreeIter iter(get_tree_view().get_model()->get_iter(path));
424        if(!iter)
425                return false;
426        Gtk::TreeRow row = *(iter);
427        Glib::ustring tooltip_string(row[model.tooltip]);
428        if(tooltip_string.empty())
429                return false;
430        tooltip->set_text(tooltip_string);
431        get_tree_view().set_tooltip_row(tooltip, path);
432        return true;
433}
434
435void
436ChildrenTree::on_raise_pressed()
437{
438}
439
440void
441ChildrenTree::on_lower_pressed()
442{
443}
444
445void
446ChildrenTree::on_duplicate_pressed()
447{
448}
449
450void
451ChildrenTree::on_delete_pressed()
452{
453}
Note: See TracBrowser for help on using the repository browser.