Fix a crash when running single-threaded and dragging the time slider.
[synfig.git] / synfig-studio / trunk / src / gtkmm / canvasview.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file canvasview.h
3 **      \brief Template Header
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **      Copyright (c) 2007 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 /* === S T A R T =========================================================== */
25
26 #ifndef __SYNFIG_STUDIO_GTKMM_CANVASVIEW_H
27 #define __SYNFIG_STUDIO_GTKMM_CANVASVIEW_H
28
29 /* === H E A D E R S ======================================================= */
30
31 #include <gtkmm/window.h>
32 #include <gtkmm/image.h>
33 #include <gtkmm/tooltips.h>
34 #include <gtkmm/table.h>
35 #include <gtkmm/statusbar.h>
36 #include <gtkmm/progressbar.h>
37 #include <gtkmm/button.h>
38 #include <gtkmm/menu.h>
39 #include <gtkmm/treeview.h>
40 #include <gtkmm/treestore.h>
41 #include <gtkmm/scrolledwindow.h>
42 #include <gtkmm/notebook.h>
43 #include <gdkmm/device.h>
44
45 #include <synfigapp/canvasinterface.h>
46 #include <synfigapp/selectionmanager.h>
47
48 #include <synfig/canvas.h>
49 #include <synfig/string.h>
50 #include <synfig/time.h>
51
52 #include "instance.h"
53 #include "canvasproperties.h"
54 #include "canvasoptions.h"
55 #include "render.h"
56 #include "cellrenderer_timetrack.h"
57 #include "app.h"
58
59 #include "layertreestore.h"
60 #include "layertree.h"
61 #include "childrentreestore.h"
62 #include "childrentree.h"
63 #include "keyframetreestore.h"
64 #include "keyframetree.h"
65
66 #include "dialog_waypoint.h"
67 #include "dialog_keyframe.h"
68
69 #include "duckmatic.h"
70 #include <gtkmm/scale.h>
71
72 #include <gtkmm/uimanager.h>
73
74 #include "smach.h"
75
76 #include <memory>
77 #include <set>
78 #include <map>
79 #include <gtkmm/toggleaction.h>
80 #include <gtkmm/radioaction.h>
81 #include <synfig/rect.h>
82
83 #include "adjust_window.h"
84
85 #include <synfig/transform.h>
86
87 /* === M A C R O S ========================================================= */
88
89 #ifndef DEBUGPOINT_CLASS
90 #if     _DEBUG
91 #define DEBUGPOINT_CLASS(x)             struct debugpointclass_ ## x { debugpointclass_ ## x () { DEBUGPOINT(); } ~debugpointclass_ ## x () { DEBUGPOINT(); } } badfthguae_ ## x ;
92 #else
93 #define DEBUGPOINT_CLASS(x)
94 #endif
95 #endif
96
97 /* === T Y P E D E F S ===================================================== */
98
99 /* === C L A S S E S & S T R U C T S ======================================= */
100
101 namespace studio {
102
103 class CanvasViewUIInterface;
104 class CanvasViewSelectionManager;
105
106 class CellRenderer_TimeTrack;
107 class CellRenderer_ValueBase;
108 class UniversalScrubber;
109 class WorkArea;
110
111 class Duckmatic;
112
113 class Preview;
114 struct PreviewInfo;
115 class AudioContainer;
116
117 class Widget_Sound;
118 class Widget_Timeslider;
119 class Widget_Time;
120
121 class Dialog_SoundSelect;
122 class Dialog_Preview;
123
124 class synfig::TransformStack;
125 class Dock_Layers;
126 class Dock_Children;
127 class Dock_Keyframes;
128
129 class CanvasView : public Gtk::Window, public etl::shared_object
130 {
131         friend class UniversalScrubber;
132         friend class Dock_Layers;
133         friend class Dock_Children;
134         friend class Dock_Keyframes;
135
136         friend class CanvasViewUIInterface;
137         friend class CanvasViewSelectionManager;
138
139         friend class Duckmatic;
140
141         /*
142  -- ** -- P U B L I C   T Y P E S ---------------------------------------------
143         */
144
145 public:
146
147         typedef etl::handle<CanvasView> Handle;
148
149         typedef etl::handle<const CanvasView> ConstHandle;
150
151         typedef etl::loose_handle<CanvasView> LooseHandle;
152
153         typedef LayerTreeStore::Model LayerTreeModel;
154
155         typedef ChildrenTreeStore::Model ChildrenTreeModel;
156
157         //! Create an instance of this class whenever doing a longer task.
158         /*! Make sure that you check the bool value of this class occasionaly
159         **      to make sure the action has not been canceled. */
160         class IsWorking
161         {
162                 CanvasView &canvas_view_;
163
164         public:
165                 IsWorking(CanvasView &canvas_view_);
166                 ~IsWorking();
167                 operator bool()const;
168         };
169         friend class IsWorking;
170
171         typedef synfigapp::CanvasInterface::Mode Mode;
172
173         /*
174  -- ** -- P R I V A T E   D A T A ---------------------------------------------
175         */
176
177 public:
178         std::auto_ptr<WorkArea> work_area;
179
180         WorkArea* get_work_area() { return work_area.get(); }
181 private:
182
183         synfig::TransformStack curr_transform_stack;
184         bool curr_transform_stack_set;
185
186         synfig::Rect bbox;
187
188         DEBUGPOINT_CLASS(1);
189
190         //! State Machine
191         Smach smach_;
192
193         DEBUGPOINT_CLASS(2);
194
195         etl::loose_handle<Instance> instance_;
196         etl::handle<synfigapp::CanvasInterface> canvas_interface_;
197
198         DEBUGPOINT_CLASS(3);
199
200         //! Sound and information to play it
201         etl::handle<AudioContainer>             audio;
202         studio::Widget_Sound                    *disp_audio; //should this be put into thing too?
203
204         SigC::Connection                                playcon;
205         SigC::Connection                                stopcon;
206
207         std::auto_ptr<UniversalScrubber> universal_scrubber;
208
209         //! Tooltip controler
210         Gtk::Tooltips tooltips;
211
212         DEBUGPOINT_CLASS(4);
213
214         //! TreeModel for the layers
215         LayerTreeModel layer_tree_model;
216
217         //! TreeModel for the the children
218         ChildrenTreeModel children_tree_model;
219
220         //Glib::RefPtr<LayerTreeStore> layer_tree_store_;
221
222         //Glib::RefPtr<ChildrenTreeStore> children_tree_store_;
223
224         //Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_;
225
226         DEBUGPOINT_CLASS(5);
227
228         //std::map<synfig::String,Glib::RefPtr<Gtk::TreeModel> > tree_model_book_;
229         std::map<synfig::String,Glib::RefPtr<Glib::ObjectBase> > ref_obj_book_;
230         std::map<synfig::String,Gtk::Widget*> ext_widget_book_;
231
232
233         //! The time adjustment's scope is defined by the time_window adjustment
234         Gtk::Adjustment time_adjustment_;
235
236         //! The time_window adjustment governs the position of the time window on the whole time line
237         //Gtk::Adjustment time_window_adjustment_;
238         studio::Adjust_Window time_window_adjustment_;
239
240
241         LayerTree *layer_tree;
242
243         ChildrenTree *children_tree;
244
245         KeyframeTree *keyframe_tree;
246
247         Gtk::Widget *keyframe_tab_child;
248
249         Gtk::ProgressBar *progressbar;
250         Gtk::Statusbar *statusbar;
251
252         Gtk::TreeRow children_canvas_row;
253         Gtk::TreeRow children_valuenode_row;
254
255         Gtk::Button *stopbutton;
256         Gtk::Button *refreshbutton;
257         Gtk::Button *treetogglebutton;
258         Gtk::Notebook *notebook;
259         Gtk::Widget *timebar;
260
261         Widget_Time *current_time_widget;
262         void on_current_time_widget_changed();
263
264         std::auto_ptr<Widget_Timeslider>                timeslider;
265
266         std::list<sigc::connection> duck_changed_connections;
267
268
269
270         Gtk::Button *animatebutton;
271         Gtk::Button *keyframebutton;
272
273 /*      DEBUGPOINT_CLASS(8);
274
275         Gtk::Menu duckmaskmenu;
276         DEBUGPOINT_CLASS(77);
277         Gtk::Menu qualitymenu;
278         DEBUGPOINT_CLASS(6);
279
280         Gtk::Menu filemenu;
281         DEBUGPOINT_CLASS(777);
282         Gtk::Menu editmenu;
283         DEBUGPOINT_CLASS(71);
284         Gtk::Menu canvasmenu;
285         DEBUGPOINT_CLASS(73);
286 public:
287         Gtk::Menu layermenu;
288 private:
289         DEBUGPOINT_CLASS(74);
290         Gtk::Menu newlayermenu;
291         DEBUGPOINT_CLASS(76);
292         Gtk::Menu viewmenu;
293
294         DEBUGPOINT_CLASS(99);
295         Gtk::Menu keyframemenu;
296
297         Gtk::Menu parammenu;
298         DEBUGPOINT_CLASS(9);
299         Gtk::Menu trackmenu;
300         DEBUGPOINT_CLASS(7);
301
302         Gtk::CheckMenuItem* duck_mask_position;
303         Gtk::CheckMenuItem* duck_mask_vertex;
304         Gtk::CheckMenuItem* duck_mask_tangent;
305         Gtk::CheckMenuItem* duck_mask_radius;
306         Gtk::CheckMenuItem* duck_mask_width;
307         Gtk::CheckMenuItem* duck_mask_angle;
308 */
309         Gtk::Menu parammenu;
310
311
312         Glib::RefPtr<Gtk::ToggleAction> duck_mask_position;
313         Glib::RefPtr<Gtk::ToggleAction> duck_mask_vertex;
314         Glib::RefPtr<Gtk::ToggleAction> duck_mask_tangent;
315         Glib::RefPtr<Gtk::ToggleAction> duck_mask_radius;
316         Glib::RefPtr<Gtk::ToggleAction> duck_mask_width;
317         Glib::RefPtr<Gtk::ToggleAction> duck_mask_angle;
318
319         Gtk::RadioButtonGroup quality_group;
320
321         Glib::RefPtr<Gtk::ActionGroup> action_group;
322
323
324         etl::handle<synfigapp::UIInterface> ui_interface_;
325         etl::handle<synfigapp::SelectionManager> selection_manager_;
326
327         bool is_playing_;
328
329         sigc::signal<void> signal_deleted_;
330
331         bool rebuild_ducks_queued;
332         sigc::connection queue_rebuild_ducks_connection;
333
334         /*
335  -- ** -- P U B L I C   D A T A -----------------------------------------------
336         */
337
338 public:
339         void queue_rebuild_ducks();
340         sigc::signal<void>& signal_deleted() { return signal_deleted_; }
341
342         Gtk::Menu mainmenu;
343
344         bool duck_refresh_flag;
345         bool duck_refresh_needed;
346
347         //! This is for the IsWorking class.
348         int working_depth;
349
350         bool cancel;
351
352
353         /*
354  -- ** -- D I A L O G S -------------------------------------------------------
355         */
356
357 public:
358
359         CanvasProperties canvas_properties;
360         CanvasOptions canvas_options;
361         RenderSettings render_settings;
362         Dialog_Waypoint waypoint_dialog;
363         Dialog_Keyframe keyframe_dialog;
364
365         std::auto_ptr<Dialog_Preview>                   preview_dialog;
366         //std::auto_ptr<Dialog_PreviewOptions>  previewoption_dialog;
367         std::auto_ptr<Dialog_SoundSelect>               sound_dialog;
368
369         /*
370  -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
371         */
372
373 private:
374
375         // Constructor is private to force the use of the "create()" constructor
376         CanvasView(etl::loose_handle<Instance> instance,etl::handle<synfigapp::CanvasInterface> canvas_interface);
377
378         //! Constructor Helper
379         Gtk::Widget* create_layer_tree();
380
381         //! Constructor Helper
382         Gtk::Widget* create_children_tree();
383
384         //! Constructor Helper
385         Gtk::Widget* create_keyframe_tree();
386
387         //! Constructor Helper
388         Gtk::Widget* create_status_bar();
389
390         //! Constructor Helper - Initializes all of the menus
391         void init_menus();
392
393         bool duck_change_param(const synfig::Point &value,synfig::Layer::Handle layer, synfig::String param_name);
394
395         void refresh_time_window();
396
397         void time_was_changed();
398
399         void refresh_rend_desc();
400
401         void toggle_duck_mask(Duckmatic::Type type);
402
403         Gtk::Widget *create_work_area();
404
405         Gtk::Widget *create_time_bar();
406
407
408
409         void popup_param_menu_bezier(float location, synfigapp::ValueDesc value_desc)
410         { popup_param_menu(value_desc,location); }
411
412         void popup_param_menu(synfigapp::ValueDesc value_desc, float location=0);
413
414
415         void workarea_layer_selected(synfig::Layer::Handle layer);
416
417         void selected_layer_color_set(synfig::Color color);
418
419
420
421         void register_layer_type(synfig::Layer::Book::value_type &lyr,std::map<synfig::String,Gtk::Menu*>*);
422
423         //! Rebuilds the "new layer" menu
424         void build_new_layer_menu(Gtk::Menu &menu);
425
426         void rebuild_ducks_layer_(synfig::TransformStack& transform_stack, synfig::Canvas::Handle canvas, std::set<synfig::Layer::Handle>& selected_list);
427
428         /*
429  -- ** -- P U B L I C   M E T H O D S -----------------------------------------
430         */
431
432 public:
433         const synfig::TransformStack& get_curr_transform_stack()const { return curr_transform_stack; }
434
435         const synfig::Rect& get_bbox()const { return bbox; }
436
437         Glib::RefPtr<Glib::ObjectBase> get_ref_obj(const synfig::String& x);
438         Glib::RefPtr<const Glib::ObjectBase> get_ref_obj(const synfig::String& x)const;
439         void set_ref_obj(const synfig::String& x, Glib::RefPtr<Glib::ObjectBase> y);
440
441         Glib::RefPtr<Gtk::TreeModel> get_tree_model(const synfig::String& x);
442         Glib::RefPtr<const Gtk::TreeModel> get_tree_model(const synfig::String& x)const;
443         void set_tree_model(const synfig::String& x, Glib::RefPtr<Gtk::TreeModel> y);
444
445         Gtk::Widget* get_ext_widget(const synfig::String& x);
446         void set_ext_widget(const synfig::String& x, Gtk::Widget* y);
447
448         //std::map<synfig::String,Gtk::Widget*>& tree_view_book() { return tree_view_book_; }
449         //std::map<synfig::String,Gtk::Widget*>& ext_widget_book() { return tree_view_book_; }
450
451         void popup_main_menu();
452
453         Smach& get_smach() { return smach_; }
454
455         const Smach& get_smach()const { return smach_; }
456
457         Smach::event_result process_event_key(EventKey x);
458
459         void popup_layer_menu(synfig::Layer::Handle layer);
460
461         virtual ~CanvasView();
462
463         void set_mode(Mode x) { canvas_interface()->set_mode(x); }
464
465         Mode get_mode()const { return canvas_interface()->get_mode(); }
466
467         Gtk::Adjustment &time_adjustment() { return time_adjustment_; }
468
469         const Gtk::Adjustment &time_adjustment()const { return time_adjustment_; }
470
471         studio::Adjust_Window &time_window_adjustment() { return time_window_adjustment_; }
472
473         const studio::Adjust_Window &time_window_adjustment()const { return time_window_adjustment_; }
474
475         etl::handle<synfigapp::UIInterface> get_ui_interface() { return ui_interface_;}
476
477         etl::handle<synfigapp::SelectionManager> get_selection_manager() { return selection_manager_; }
478
479         Glib::RefPtr<Gtk::TreeModel> layer_tree_store() { return get_tree_model("layers"); }
480
481         Glib::RefPtr<const Gtk::TreeModel> layer_tree_store()const { return get_tree_model("layers"); }
482
483         Glib::RefPtr<Gtk::TreeModel> children_tree_store() { return get_tree_model("children"); }
484
485         Glib::RefPtr<const Gtk::TreeModel> children_tree_store()const { return get_tree_model("children"); }
486
487         Glib::RefPtr<Gtk::TreeModel> keyframe_tree_store() { return get_tree_model("keyframes"); }
488
489         Glib::RefPtr<const Gtk::TreeModel> keyframe_tree_store()const { return get_tree_model("keyframes"); }
490
491         void set_time(synfig::Time t) { canvas_interface_->set_time(t); }
492
493         synfig::Time get_time() { return canvas_interface_->get_time(); }
494
495         etl::handle<synfig::Canvas> get_canvas()const { return canvas_interface_->get_canvas(); }
496
497         etl::handle<Instance> get_instance()const { return instance_; }
498
499         etl::handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
500
501         etl::handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
502
503         void add_actions_to_menu(Gtk::Menu *menu,   const synfigapp::Action::ParamList &param_list, synfigapp::Action::Category category=synfigapp::Action::CATEGORY_ALL)const;
504
505         //! Updates the title of the window
506         void update_title();
507
508         //! Closes this canvas view
509         bool close();
510
511         //!     Stops the currently executing action
512         /*! \see get_cancel_status(), reset_cancel_status(), IsWorking */
513         void stop() { cancel=true; }
514
515         //! Returns the cancel status
516         /*! \see stop(), reset_cancel_status(), IsWorking */
517         bool get_cancel_status()const { return cancel; }
518
519         //! Resets the cancel status
520         /*! \see stop(), get_cancel_status(), IsWorking */
521         void reset_cancel_status() { cancel=false; }
522
523         void new_child_canvas();
524
525         //! Rebuilds layer_tree_store_ from the Canvas. Maintains selected items.
526         void rebuild_tables();
527
528         //! Builds layer_tree_store_ from the Canvas. Does not maintain selected items.
529         void build_tables();
530
531         //! Refreshes the data for the tables
532         void refresh_tables();
533
534         //void rebuild_layer_table();
535         //void build_layer_table();
536         //void refresh_layer_table();
537
538 //      void rebuild_canvas_table();
539 //      void build_canvas_table();
540 //      void refresh_canvas_table();
541
542 //      void rebuild_valuenode_table();
543 //      void build_valuenode_table();
544 //      void refresh_valuenode_table();
545
546         //! \writeme
547         void rebuild_ducks();
548
549         //bool add_to_ducks(synfigapp::ValueDesc value_desc, synfig::ParamDesc *param_desc=NULL);
550
551         //! Starts "playing" the animation in real-time
552         void play();
553
554         //! Shows the tables (Layer/Children)
555         void show_tables();
556
557         //! Hides the tables (Layer/Children)
558         void hide_tables();
559
560         //! Toggles the tables
561         void toggle_tables();
562
563         //! Gets the table status
564         bool tables_are_visible();
565
566         //! Shows the time bar
567         void show_timebar();
568
569         //! Hides the time bar
570         void hide_timebar();
571
572         //t Enables or disables interaction with the timebar
573         void set_sensitive_timebar(bool sensitive);
574
575         void time_zoom_in();
576         void time_zoom_out();
577
578         void add_layer(synfig::String x);
579
580         void show_keyframe_dialog();
581
582         void play_audio(float t);
583         void stop_audio();
584
585         void image_import();
586
587         void on_waypoint_clicked(synfigapp::ValueDesc,synfig::Waypoint, int button);
588
589         void preview_option() {on_preview_option();}
590
591         void present();
592
593         bool is_playing() { return is_playing_; }
594
595         /*
596  -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
597         */
598
599 private:
600
601         void on_unselect_layers();
602
603         void on_input_device_changed(GdkDevice*);
604
605         virtual void on_hide();
606
607         virtual bool on_focus_in_event(GdkEventFocus*);
608         virtual bool on_focus_out_event(GdkEventFocus*);
609
610         //bool on_children_tree_event(GdkEvent *event);
611
612         bool on_keyframe_tree_event(GdkEvent *event);
613
614         //void on_children_edited_value(const Glib::ustring&path_string,synfig::ValueBase value);
615
616         void on_dirty_preview();
617
618         bool on_children_user_click(int, Gtk::TreeRow, ChildrenTree::ColumnID);
619
620         bool on_layer_user_click(int, Gtk::TreeRow, LayerTree::ColumnID);
621
622 //      void on_layer_toggle(const Glib::ustring& path_string, Gtk::TreeModelColumn<bool> column);
623
624         void on_mode_changed(synfigapp::CanvasInterface::Mode mode);
625
626 //      void on_layer_waypoint_clicked(const Glib::ustring &, synfig::ValueNode_Animated::WaypointList::iterator);
627
628         //void on_children_waypoint_clicked(const Glib::ustring &, synfig::ValueNode_Animated::WaypointList::iterator);
629
630         void on_waypoint_changed();
631
632         void on_waypoint_delete();
633
634         void on_refresh_pressed();
635
636         void on_id_changed();
637
638         void on_time_changed();
639
640         /*
641         void on_layer_raise_pressed();
642         void on_layer_lower_pressed();
643         void on_layer_duplicate_pressed();
644         void on_layer_delete_pressed();
645         */
646
647         void on_keyframe_add_pressed();
648
649         void on_keyframe_duplicate_pressed();
650
651         void on_keyframe_remove_pressed();
652
653         void on_animate_button_pressed();
654
655         void on_keyframe_button_pressed();
656
657         void on_preview_option();
658         void on_preview_create(const PreviewInfo &);
659
660         void on_audio_option();
661         void on_audio_file_change(const std::string &f);
662         void on_audio_offset_change(const synfig::Time &t);
663
664         void on_audio_file_notify();
665         void on_audio_offset_notify();
666
667         bool on_duck_changed(const synfig::Point &value,const synfigapp::ValueDesc& value_desc);
668
669         void on_layer_toggle(synfig::Layer::Handle);
670
671         void on_edited_value(synfigapp::ValueDesc,synfig::ValueBase);
672
673         //void on_waypoint_clicked(synfigapp::ValueDesc,synfig::ValueNode_Animated::WaypointList::iterator, int button);
674
675         void on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time);
676
677         //void on_audio_play();
678         bool on_audio_scrub();
679
680 protected:
681         bool close_instance_when_safe();
682         bool on_delete_event(GdkEventAny* event);
683
684         /*
685  -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
686         */
687
688 public:
689
690         static etl::handle<studio::CanvasView> create(etl::loose_handle<Instance> instance,etl::handle<synfig::Canvas> canvas);
691 }; // END of class CanvasView
692
693 }; // END of namespace studio
694
695 /* === E N D =============================================================== */
696
697 #endif