synfig-studio  1.0.3
preview.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
21 /* ========================================================================= */
22 
23 /* === S T A R T =========================================================== */
24 
25 #ifndef __SYNFIG_PREVIEW_H
26 #define __SYNFIG_PREVIEW_H
27 
28 /* === H E A D E R S ======================================================= */
29 #include <ETL/handle>
30 #include <ETL/clock> /* indirectly includes winnt.h on WIN32 - needs to be included before gtkmm headers, which fix this */
31 
32 #include <gtkmm/drawingarea.h>
33 #include <gtkmm/table.h>
34 #include <gtkmm/adjustment.h>
35 #include <gtkmm/image.h>
36 #include <gdkmm/pixbuf.h>
37 #include <gtkmm/dialog.h>
38 #include <gtkmm/scrollbar.h>
39 #include <gtkmm/checkbutton.h>
40 #include <gui/canvasview.h>
41 #include <gtkmm/tooltip.h>
42 #include <gtkmm/alignment.h>
43 #include <gtkmm/comboboxtext.h>
44 
45 #include <synfig/time.h>
46 #include <synfig/vector.h>
47 #include <synfig/general.h>
48 #include <synfig/renddesc.h>
49 #include <synfig/canvas.h>
50 
51 #include "widgets/widget_sound.h"
52 #include "dials/jackdial.h"
53 
54 #include <vector>
55 
56 #ifdef WITH_JACK
57 #include <jack/jack.h>
58 #include <jack/transport.h>
59 #endif
60 
61 #include <synfig/soundprocessor.h>
62 
63 /* === M A C R O S ========================================================= */
64 
65 /* === T Y P E D E F S ===================================================== */
66 
67 /* === C L A S S E S & S T R U C T S ======================================= */
68 
69 namespace studio {
70 class AsyncRenderer;
71 
72 class Preview : public sigc::trackable, public etl::shared_object
73 {
74 public:
76  {
77  public:
78  float t;
79  Glib::RefPtr<Gdk::Pixbuf> buf; //at whatever resolution they are rendered at (resized at run time)
80  cairo_surface_t* surface;
81  FlipbookElem(): t(), surface(NULL) { }
82  //Copy constructor
83  FlipbookElem(const FlipbookElem& other): t(other.t) ,buf(other.buf), surface(cairo_surface_reference(other.surface))
84  {
85  }
87  {
88  if(surface)
89  cairo_surface_destroy(surface);
90  }
91  };
92 
93  etl::handle<studio::AsyncRenderer> renderer;
94 
95  sigc::signal<void, Preview *> signal_destroyed_; //so things can reference us without fear
96 
97  typedef std::vector<FlipbookElem> FlipBook;
98 private:
99 
100  FlipBook frames;
101 
103 
104  //synfig::RendDesc description; //for rendering the preview...
105  float zoom,fps;
106  float begintime,endtime;
107  float jack_offset;
108  bool overbegin,overend;
109  bool use_cairo;
110  int quality;
111 
112  float global_fps;
113 
114  //expose the frame information etc.
115  class Preview_Target;
116  class Preview_Target_Cairo;
117  void frame_finish(const Preview_Target *);
118 
119  sigc::signal0<void> sig_changed;
120 
121 public:
122 
124  float zoom = 0.5f, float fps = 15);
125  ~Preview();
126 
127  float get_zoom() const {return zoom;}
128  void set_zoom(float z){zoom = z;}
129 
130  float get_fps() const {return fps;}
131  void set_fps(float f){fps = f;}
132 
133  float get_global_fps() const {return global_fps;}
134  void set_global_fps(float f){global_fps = f;}
135 
136  float get_jack_offset() const {return jack_offset;}
137  void set_jack_offset(float t){jack_offset = t;}
138 
139  float get_begintime() const
140  {
141  if(overbegin)
142  return begintime;
143  else if(canvasview)
144  return get_canvas()->rend_desc().get_time_start();
145  else return -1;
146  }
147 
148  float get_endtime() const
149  {
150  if(overend)
151  return endtime;
152  else if(canvasview)
153  return get_canvas()->rend_desc().get_time_end();
154  else return -1;
155  }
156 
157  void set_begintime(float t) {begintime = t;}
158  void set_endtime(float t) {endtime = t;}
159 
160  bool get_overbegin() const {return overbegin;}
161  void set_overbegin(bool b) {overbegin = b;}
162 
163  bool get_overend() const {return overend;}
164  void set_overend(bool b) {overend = b;}
165 
166  bool get_use_cairo() const {return use_cairo;}
167  void set_use_cairo(bool b) {use_cairo = b;}
168 
169  int get_quality() const {return quality;}
170  void set_quality(int i) {quality = i;}
171 
172  synfig::Canvas::Handle get_canvas() const {return canvasview->get_canvas();}
173  studio::CanvasView::Handle get_canvasview() const {return canvasview;}
174 
176 
177  //signal interface
178  sigc::signal<void, Preview *> & signal_destroyed() { return signal_destroyed_; }
179  //sigc::signal<void, const synfig::RendDesc &> &signal_desc_change() {return signal_desc_change_;}
180 
181  //functions for exposing iterators through the preview
182  FlipBook::iterator begin() {return frames.begin();}
183  FlipBook::iterator end() {return frames.end();}
184 
185  FlipBook::const_iterator begin() const {return frames.begin();}
186  FlipBook::const_iterator end() const {return frames.end();}
187  void push_back(FlipbookElem fe) { frames.push_back(fe); }
188  // Used to clear the FlipBook. Do not use directly the std::vector<>::clear member
189  // because the cairo_surface_t* wouldn't be destroyed.
190  void clear();
191 
192  unsigned int numframes() const {return frames.size();}
193 
194  void render();
195 
196  sigc::signal0<void> &signal_changed() { return sig_changed; }
197 };
198 
199 class Widget_Preview : public Gtk::Table
200 {
201  Gtk::DrawingArea draw_area;
202  Glib::RefPtr<Gtk::Adjustment> adj_time_scrub; //the adjustment for the managed scrollbar
203  Gtk::HScale scr_time_scrub;
204  Gtk::ToggleButton b_loop;
205  Gtk::ScrolledWindow preview_window;
206  //Glib::RefPtr<Gdk::GC> gc_area;
207  Glib::RefPtr<Gdk::Pixbuf> currentbuf;
208  cairo_surface_t* current_surface;
209  int currentindex;
210  //double timeupdate;
211  double timedisp;
212  double audiotime;
213 
214  //preview encapsulation
215  etl::handle<Preview> preview;
216  sigc::connection prevchanged;
217 
218  Gtk::ToggleButton *jackbutton;
219  Widget_Time *offset_widget;
220  Glib::RefPtr<Gtk::Adjustment> adj_sound;
221 
222  Gtk::Label l_lasttime;
223  Gtk::Label l_currenttime;
224 
225  //only for internal stuff, doesn't set anything
226  bool playing;
227  bool singleframe;
228  bool toolbarisshown;
229 
230  //for accurate time tracking
231  etl::clock timer;
232 
233  //int curindex; //for later
234  sigc::connection timecon;
235 
236  synfig::SoundProcessor soundProcessor;
237 
238  void slider_move(); //later to be a time_slider that's cooler
239  bool play_update();
240 
241  //bool play_frameupdate();
242  void update();
243 
244  void scrub_updated(double t);
245 
246  void repreview();
247 
248  void whenupdated();
249 
250  void eraseall();
251 
252  bool scroll_move_event(GdkEvent *);
253  void disconnect_preview(Preview *);
254 
255  bool redraw(const Cairo::RefPtr<Cairo::Context> &cr);
256  void preview_draw();
257 
258  void hide_toolbar();
259  void show_toolbar();
260 
261 public:
262 
263  Widget_Preview();
264  ~Widget_Preview();
265 
266  //sets a signal to identify disconnection (so we don't hold onto it)...
267  void set_preview(etl::handle<Preview> prev);
268 
269  void clear();
270 
271  void play();
272  void pause();
273  void seek(const synfig::Time &t);
274  synfig::Time get_position() const;
275  synfig::Time get_time_start() const;
276  synfig::Time get_time_end() const;
277 
278 
279  void on_play_pause_pressed();
280 
281  void seek_frame(int frames);
282 
283  void stoprender();
284 
285  bool get_loop_flag() const {return b_loop.get_active();}
286  void set_loop_flag(bool b) {return b_loop.set_active(b);}
287 
288  virtual void on_show();
289  virtual void on_hide();
290 
291 protected:
292 
293  class ModelColumns : public Gtk::TreeModel::ColumnRecord
294  {
295  public:
296 
298  {
299  add(factor_id);
300  add(factor_value);
301  }
302 
303  Gtk::TreeModelColumn<Glib::ustring> factor_id;
304  Gtk::TreeModelColumn<Glib::ustring> factor_value;
305 
306  };
307 
309 
310  Gtk::ComboBoxText zoom_preview;
311  Glib::RefPtr<Gtk::ListStore> factor_refTreeModel;
312 
313 private:
314 
315  Gtk::HBox *toolbar;
316  Gtk::Button *play_button;
317  Gtk::Button *pause_button;
318  bool on_key_pressed(GdkEventKey*);
319  void on_zoom_entry_activated();
320 
321  bool is_time_equal_to_current_frame(const synfig::Time &time);
322 
323  JackDial *jackdial;
324  bool jack_enabled;
325  bool jack_is_playing;
326  synfig::Time jack_time;
327  synfig::Time jack_offset;
328  synfig::Time jack_initial_time;
329 
330  bool get_jack_enabled() { return jack_enabled; }
331  void set_jack_enabled(bool value);
332 
333 #ifdef WITH_JACK
334  void toggle_jack_button();
335  void on_jack_offset_changed();
336  Glib::Dispatcher jack_dispatcher;
337  jack_client_t *jack_client;
338  bool jack_synchronizing;
339  void on_jack_sync();
340  static int jack_sync_callback(jack_transport_state_t state, jack_position_t *pos, void *arg);
341 #endif
342 };
343 
344 }; // END of namespace studio
345 
346 /* === E N D =============================================================== */
347 
348 #endif