Fixed initialisation of tf in file_open(). Without setting the memory to 0,
[cinelerra_cv/mob.git] / cinelerra / playtransport.C
blob05d7f8e46511baa8bba87ea4ea9a1620c72ad6d9
1 #include "edl.h"
2 #include "keys.h"
3 #include "language.h"
4 #include "localsession.h"
5 #include "mwindow.h"
6 #include "playbackengine.h"
7 #include "playtransport.h"
8 #include "preferences.h"
9 #include "theme.h"
10 #include "transportque.h"
11 #include "vframe.h"
12 #include "localsession.h"
16 PlayTransport::PlayTransport(MWindow *mwindow, 
17         BC_WindowBase *subwindow, 
18         int x, 
19         int y)
21         this->subwindow = subwindow;
22         this->mwindow = mwindow;
23         this->x = x;
24         this->y = y;
25         this->slider = 0;
26         this->engine = 0;
30 PlayTransport::~PlayTransport()
32         delete forward_play;
33         delete frame_forward_play;
34         delete reverse_play;
35         delete frame_reverse_play;
36         delete fast_reverse;
37         delete fast_play;
38         delete rewind_button;
39         delete stop_button;
40         delete end_button;
43 void PlayTransport::set_engine(PlaybackEngine *engine)
45         this->engine = engine;
48 void PlayTransport::set_slider(BC_Slider *slider)
50         this->slider = slider;
53 int PlayTransport::get_transport_width(MWindow *mwindow)
55         return mwindow->theme->get_image_set("stop")[0]->get_w() * 7 +
56                 mwindow->theme->get_image_set("rewind")[0]->get_w() * 2;
59 int PlayTransport::create_objects()
61         int x = this->x, y = this->y;
62         subwindow->add_subwindow(rewind_button = new RewindButton(mwindow, this, x, y));
63         x += rewind_button->get_w();
64         subwindow->add_subwindow(fast_reverse = new FastReverseButton(mwindow, this, x, y)); 
65         x += fast_reverse->get_w();
66         subwindow->add_subwindow(reverse_play = new ReverseButton(mwindow, this, x, y)); 
67         x += reverse_play->get_w();
68         subwindow->add_subwindow(frame_reverse_play = new FrameReverseButton(mwindow, this, x, y)); 
69         x += frame_reverse_play->get_w();
70         subwindow->add_subwindow(stop_button = new StopButton(mwindow, this, x, y)); 
71         x += stop_button->get_w();
72         subwindow->add_subwindow(frame_forward_play = new FramePlayButton(mwindow, this, x, y)); 
73         x += frame_forward_play->get_w();
74         subwindow->add_subwindow(forward_play = new PlayButton(mwindow, this, x, y)); 
75         x += forward_play->get_w();
76         subwindow->add_subwindow(fast_play = new FastPlayButton(mwindow, this, x, y)); 
77         x += fast_play->get_w();
78         subwindow->add_subwindow(end_button = new EndButton(mwindow, this, x, y)); 
79         x += end_button->get_w();
81         reverse = 0;
82         speed = 0;
84         return 0;
87 void PlayTransport::reposition_buttons(int x, int y)
89         this->x = x;
90         this->y = y;
91         rewind_button->reposition_window(x, y);
92         x += rewind_button->get_w();
93         fast_reverse->reposition_window(x, y);
94         x += fast_reverse->get_w();
95         reverse_play->reposition_window(x, y);
96         x += reverse_play->get_w();
97         frame_reverse_play->reposition_window(x, y);
98         x += frame_reverse_play->get_w();
99         stop_button->reposition_window(x, y);
100         x += stop_button->get_w();
101         frame_forward_play->reposition_window(x, y);
102         x += frame_forward_play->get_w();
103         forward_play->reposition_window(x, y);
104         x += forward_play->get_w();
105         fast_play->reposition_window(x, y);
106         x += fast_play->get_w();
107         end_button->reposition_window(x, y);
108         x += end_button->get_w();
111 int PlayTransport::get_w()
113         return end_button->get_x() + end_button->get_w() - rewind_button->get_x();
116 int PlayTransport::flip_vertical(int vertical, int &x, int &y)
118         if(vertical)
119         {
120                 rewind_button->reposition_window(x, y); 
121                 y += rewind_button->get_h();
122                 fast_reverse->reposition_window(x, y); 
123                 y += fast_reverse->get_h();
124                 reverse_play->reposition_window(x, y); 
125                 y += reverse_play->get_h();
126                 frame_reverse_play->reposition_window(x, y); 
127                 y += frame_reverse_play->get_h();
128                 stop_button->reposition_window(x, y); 
129                 y += stop_button->get_h();
130                 frame_forward_play->reposition_window(x, y); 
131                 y += frame_forward_play->get_h();
132                 forward_play->reposition_window(x, y); 
133                 y += forward_play->get_h();
134                 fast_play->reposition_window(x, y); 
135                 y += fast_play->get_h();
136                 end_button->reposition_window(x, y); 
137                 y += end_button->get_h();
138         }
139         else
140         {
141                 rewind_button->reposition_window(x, y - 2); 
142                 x += rewind_button->get_w();
143                 fast_reverse->reposition_window(x, y - 2); 
144                 x += fast_reverse->get_w();
145                 reverse_play->reposition_window(x, y - 2); 
146                 x += reverse_play->get_w();
147                 frame_reverse_play->reposition_window(x, y - 2); 
148                 x += frame_reverse_play->get_w();
149                 stop_button->reposition_window(x, y - 2); 
150                 x += stop_button->get_w();
151                 frame_forward_play->reposition_window(x, y - 2); 
152                 x += frame_forward_play->get_w();
153                 forward_play->reposition_window(x, y - 2); 
154                 x += forward_play->get_w();
155                 fast_play->reposition_window(x, y - 2); 
156                 x += fast_play->get_w();
157                 end_button->reposition_window(x, y - 2); 
158                 x += end_button->get_w();
159         }
161         return 0;
164 int PlayTransport::keypress_event()
166         int result = 0;
167         if(subwindow->shift_down())
168         {
169                 switch(subwindow->get_keypress())
170                 {
171                         case END:
172                                 subwindow->lock_window("PlayTransport::keypress_event 1");
173                                 goto_end();                                   
174                                 result = 1; 
175                                 subwindow->unlock_window();
176                                 break;
177                         case HOME:
178                                 subwindow->lock_window("PlayTransport::keypress_event 2");
179                         goto_start();                                 
180                                 result = 1; 
181                                 subwindow->unlock_window();
182                                 break;
183                 }
184                 return result;
185         }
187 // Set playback range to in/out points if CTRL is down
188         int use_inout = 0;
189         if(subwindow->ctrl_down())
190         {
191                 use_inout = 1;
192         }
193         subwindow->unlock_window();
196         switch(subwindow->get_keypress())
197         {
198                 case KPPLUS:        handle_transport(FAST_REWIND, 0, use_inout);                result = 1; break;
199                 case KP6:           handle_transport(NORMAL_REWIND, 0, use_inout);              result = 1; break;
200                 case KP5:           handle_transport(SLOW_REWIND, 0, use_inout);                result = 1; break;
201                 case KP4:           handle_transport(SINGLE_FRAME_REWIND, 0, use_inout);        result = 1; break;
202                 case KP1:           handle_transport(SINGLE_FRAME_FWD, 0, use_inout);                     result = 1; break;
203                 case KP2:           handle_transport(SLOW_FWD, 0, use_inout);                             result = 1; break;
204                 case KP3:           handle_transport(NORMAL_FWD, 0, use_inout);                           result = 1; break;
205                 case KPENTER:       handle_transport(FAST_FWD, 0, use_inout);                             result = 1; break;
206                 case KPINS:         handle_transport(STOP, 0, use_inout);                       result = 1; break;
207                 case ' ':           handle_transport(NORMAL_FWD, 0, use_inout);                 result = 1; break;
208                 case 'k':           handle_transport(STOP, 0, use_inout);                                         result = 1; break;
209                 case END:
210                         subwindow->lock_window("PlayTransport::keypress_event 3");
211                         goto_end();                                   
212                         result = 1; 
213                         subwindow->unlock_window();
214                         break;
215                 case HOME:
216                         subwindow->lock_window("PlayTransport::keypress_event 4");
217                     goto_start();                                 
218                         result = 1; 
219                         subwindow->unlock_window();
220                         break;
221         }
223         subwindow->lock_window("PlayTransport::keypress_event 5");
225         return result;
229 void PlayTransport::goto_start()
231         handle_transport(REWIND, 1, 0);
234 void PlayTransport::goto_end()
236         handle_transport(GOTO_END, 1, 0);
241 void PlayTransport::handle_transport(int command, 
242         int wait_tracking,
243         int use_inout,
244         int update_refresh)
246         if(!get_edl()) return;
248 // Stop requires transferring the output buffer to a refresh buffer.
249         int do_stop = 0;
250 //printf("PlayTransport::handle_transport 1 %d\n", command);
251         int prev_command = engine->command->command;
252         int prev_direction = engine->command->get_direction();
253         int prev_single_frame = engine->command->single_frame();
255 // Dispatch command
256         switch(command)
257         {
258 // Commands that play back
259                 case FAST_REWIND:
260                 case NORMAL_REWIND:
261                 case SLOW_REWIND:
262                 case SINGLE_FRAME_REWIND:
263                 case SINGLE_FRAME_FWD:
264                 case SLOW_FWD:
265                 case NORMAL_FWD:
266                 case FAST_FWD:
267 // Same direction pressed twice.  Stop
268                         if(prev_command == command && 
269                                 !prev_single_frame)
270                         {
271                                 do_stop = 1;
272                         }
273                         else
274 // Resume or change direction
275                         if(prev_command != STOP &&
276                                 prev_command != COMMAND_NONE &&
277                                 prev_command != SINGLE_FRAME_FWD &&
278                                 prev_command != SINGLE_FRAME_REWIND)
279                         {
280                                 engine->que->send_command(STOP,
281                                         CHANGE_NONE, 
282                                         0,
283                                         0,
284                                         0,
285                                         0);
286                                 engine->interrupt_playback(wait_tracking);
287                                 engine->que->send_command(command,
288                                         CHANGE_NONE, 
289                                         get_edl(),
290                                         1,
291                                         1,
292                                         use_inout);
293                         }
294                         else
295 // Start from scratch
296                         {
297                                 engine->que->send_command(command,
298                                         CHANGE_NONE, 
299                                         get_edl(),
300                                         1,
301                                         0,
302                                         use_inout);
303                         }
304                         break;
306 // Commands that stop
307                 case STOP:
308                         do_stop = 1;
309                         break;
311                 case REWIND:
312                 case GOTO_END:
313                         engine->que->send_command(STOP,
314                                 CHANGE_NONE, 
315                                 0,
316                                 0,
317                                 0,
318                                 0);
319                         engine->interrupt_playback(wait_tracking);
320                         break;
321         }
323         if(do_stop)
324         {
325                 engine->que->send_command(STOP,
326                         CHANGE_NONE, 
327                         0,
328                         0,
329                         0,
330                         0);
331                 engine->interrupt_playback(wait_tracking);
332 // This is necessary to get an OpenGL output buffer
333 // printf("PlayTransport::handle_transport 2 update_refresh=%d prev_command=%d prev_direction=%d\n", 
334 // update_refresh, prev_command, prev_direction);
335                 if(!prev_single_frame && 
336                         update_refresh &&
337                         prev_command != STOP &&
338                         prev_command != COMMAND_NONE)
339                 {
340                         engine->que->send_command(
341                                 (prev_direction == PLAY_FORWARD) ? SINGLE_FRAME_REWIND : SINGLE_FRAME_FWD,
342                                 CHANGE_NONE, 
343                                 get_edl(),
344                                 1,
345                                 0,
346                                 0);
347                 }
348         }
351 EDL* PlayTransport::get_edl()
353         return mwindow->edl;
356 int PlayTransport::pause_transport()
358         if(active_button) active_button->set_mode(PLAY_MODE);
359         return 0;
363 int PlayTransport::reset_transport()
365         fast_reverse->set_mode(PLAY_MODE);
366         reverse_play->set_mode(PLAY_MODE);
367         forward_play->set_mode(PLAY_MODE);
368         frame_reverse_play->set_mode(PLAY_MODE);
369         frame_forward_play->set_mode(PLAY_MODE);
370         fast_play->set_mode(PLAY_MODE);
371         return 0;
374 PTransportButton::PTransportButton(MWindow *mwindow, PlayTransport *transport, int x, int y, VFrame **data)
375  : BC_Button(x, y, data)
377         this->mwindow = mwindow;
378         this->transport = transport;
379         mode = PLAY_MODE;
381 PTransportButton::~PTransportButton()
385 int PTransportButton::set_mode(int mode)
387         this->mode = mode;
388         return 0;
392 RewindButton::RewindButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
393  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("rewind"))
395         set_tooltip(_("Rewind ( Home )"));
397 int RewindButton::handle_event()
399 //      unlock_window();
400         transport->goto_start();
401 //      lock_window();
402         return 1;
405 FastReverseButton::FastReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
406  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastrev")) 
408         set_tooltip(_("Fast reverse ( + )"));
410 int FastReverseButton::handle_event() 
412         unlock_window();
413         transport->handle_transport(FAST_REWIND, 0, ctrl_down());
414         lock_window("FastReverseButton::handle_event");
415         return 1;
418 // Reverse playback normal speed
420 ReverseButton::ReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
421  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("reverse")) 
423         set_tooltip(_("Normal reverse ( 6 )"));
425 int ReverseButton::handle_event()
427         unlock_window();
428         transport->handle_transport(NORMAL_REWIND, 0, ctrl_down());
429         lock_window("ReverseButton::handle_event");
430         return 1;
433 // Reverse playback one frame
435 FrameReverseButton::FrameReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
436  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("framerev"))
438         set_tooltip(_("Frame reverse ( 4 )"));
440 int FrameReverseButton::handle_event()
442         unlock_window();
443         transport->handle_transport(SINGLE_FRAME_REWIND, 0, ctrl_down());
444         lock_window("FrameReverseButton::handle_event");
445         return 1;
448 // forward playback normal speed
450 PlayButton::PlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
451  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("play")) 
453         set_tooltip(_("Normal forward ( 3 )"));
455 int PlayButton::handle_event()
457         unlock_window();
458         transport->handle_transport(NORMAL_FWD, 0, ctrl_down());
459         lock_window("PlayButton::handle_event");
460         return 1;
465 // forward playback one frame
467 FramePlayButton::FramePlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
468  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("framefwd")) 
470         set_tooltip(_("Frame forward ( 1 )"));
472 int FramePlayButton::handle_event()
474         unlock_window();
475         transport->handle_transport(SINGLE_FRAME_FWD, 0, ctrl_down());
476         lock_window("FramePlayButton::handle_event");
477         return 1;
482 FastPlayButton::FastPlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
483  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastfwd")) 
485         set_tooltip(_("Fast forward ( Enter )"));
487 int FastPlayButton::handle_event() 
489         unlock_window();
490         transport->handle_transport(FAST_FWD, 0, ctrl_down());
491         lock_window("FastPlayButton::handle_event");
492         return 1;
495 EndButton::EndButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
496  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("end")) 
498         set_tooltip(_("Jump to end ( End )"));
500 int EndButton::handle_event()
501 {       
502 //      unlock_window();
503         transport->goto_end();
504 //      lock_window();
505         return 1;
508 StopButton::StopButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
509  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("stop")) 
511         set_tooltip(_("Stop ( 0 )"));
513 int StopButton::handle_event()
515         unlock_window();
516         transport->handle_transport(STOP, 0, 0);
517         lock_window("StopButton::handle_event");
518         return 1;