4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "localsession.h"
27 #include "mwindowgui.h"
28 #include "playbackengine.h"
29 #include "playtransport.h"
30 #include "preferences.h"
32 #include "transportque.h"
37 PlayTransport::PlayTransport(MWindow *mwindow,
38 BC_WindowBase *subwindow,
42 this->subwindow = subwindow;
43 this->mwindow = mwindow;
48 this->using_inout = 0;
52 PlayTransport::~PlayTransport()
55 delete frame_forward_play;
57 delete frame_reverse_play;
65 void PlayTransport::set_engine(PlaybackEngine *engine)
67 this->engine = engine;
70 int PlayTransport::get_transport_width(MWindow *mwindow)
72 return mwindow->theme->get_image_set("stop")[0]->get_w() * 7 +
73 mwindow->theme->get_image_set("rewind")[0]->get_w() * 2;
76 void PlayTransport::create_objects()
78 int x = this->x, y = this->y;
79 subwindow->add_subwindow(rewind_button = new RewindButton(mwindow, this, x, y));
80 x += rewind_button->get_w();
81 subwindow->add_subwindow(fast_reverse = new FastReverseButton(mwindow, this, x, y));
82 x += fast_reverse->get_w();
83 subwindow->add_subwindow(reverse_play = new ReverseButton(mwindow, this, x, y));
84 x += reverse_play->get_w();
85 subwindow->add_subwindow(frame_reverse_play = new FrameReverseButton(mwindow, this, x, y));
86 x += frame_reverse_play->get_w();
87 subwindow->add_subwindow(stop_button = new StopButton(mwindow, this, x, y));
88 x += stop_button->get_w();
89 subwindow->add_subwindow(frame_forward_play = new FramePlayButton(mwindow, this, x, y));
90 x += frame_forward_play->get_w();
91 subwindow->add_subwindow(forward_play = new PlayButton(mwindow, this, x, y));
92 x += forward_play->get_w();
93 subwindow->add_subwindow(fast_play = new FastPlayButton(mwindow, this, x, y));
94 x += fast_play->get_w();
95 subwindow->add_subwindow(end_button = new EndButton(mwindow, this, x, y));
96 x += end_button->get_w();
103 void PlayTransport::reposition_buttons(int x, int y)
107 rewind_button->reposition_window(x, y);
108 x += rewind_button->get_w();
109 fast_reverse->reposition_window(x, y);
110 x += fast_reverse->get_w();
111 reverse_play->reposition_window(x, y);
112 x += reverse_play->get_w();
113 frame_reverse_play->reposition_window(x, y);
114 x += frame_reverse_play->get_w();
115 stop_button->reposition_window(x, y);
116 x += stop_button->get_w();
117 frame_forward_play->reposition_window(x, y);
118 x += frame_forward_play->get_w();
119 forward_play->reposition_window(x, y);
120 x += forward_play->get_w();
121 fast_play->reposition_window(x, y);
122 x += fast_play->get_w();
123 end_button->reposition_window(x, y);
124 x += end_button->get_w();
127 int PlayTransport::get_w()
129 return end_button->get_x() + end_button->get_w() - rewind_button->get_x();
132 int PlayTransport::flip_vertical(int vertical, int &x, int &y)
136 rewind_button->reposition_window(x, y);
137 y += rewind_button->get_h();
138 fast_reverse->reposition_window(x, y);
139 y += fast_reverse->get_h();
140 reverse_play->reposition_window(x, y);
141 y += reverse_play->get_h();
142 frame_reverse_play->reposition_window(x, y);
143 y += frame_reverse_play->get_h();
144 stop_button->reposition_window(x, y);
145 y += stop_button->get_h();
146 frame_forward_play->reposition_window(x, y);
147 y += frame_forward_play->get_h();
148 forward_play->reposition_window(x, y);
149 y += forward_play->get_h();
150 fast_play->reposition_window(x, y);
151 y += fast_play->get_h();
152 end_button->reposition_window(x, y);
153 y += end_button->get_h();
157 rewind_button->reposition_window(x, y - 2);
158 x += rewind_button->get_w();
159 fast_reverse->reposition_window(x, y - 2);
160 x += fast_reverse->get_w();
161 reverse_play->reposition_window(x, y - 2);
162 x += reverse_play->get_w();
163 frame_reverse_play->reposition_window(x, y - 2);
164 x += frame_reverse_play->get_w();
165 stop_button->reposition_window(x, y - 2);
166 x += stop_button->get_w();
167 frame_forward_play->reposition_window(x, y - 2);
168 x += frame_forward_play->get_w();
169 forward_play->reposition_window(x, y - 2);
170 x += forward_play->get_w();
171 fast_play->reposition_window(x, y - 2);
172 x += fast_play->get_w();
173 end_button->reposition_window(x, y - 2);
174 x += end_button->get_w();
180 int PlayTransport::keypress_event()
183 if(subwindow->shift_down())
185 switch(subwindow->get_keypress())
188 subwindow->lock_window("PlayTransport::keypress_event 1");
190 subwindow->unlock_window();
193 subwindow->lock_window("PlayTransport::keypress_event 2");
195 subwindow->unlock_window();
204 // Set playback range to in/out points if CTRL is down
206 if(subwindow->ctrl_down())
210 using_inout = use_inout;
211 subwindow->unlock_window();
214 switch(subwindow->get_keypress())
216 case KPPLUS: handle_transport(FAST_REWIND, 0, use_inout); break;
217 case KP6: handle_transport(NORMAL_REWIND, 0, use_inout); break;
218 case KP5: handle_transport(SLOW_REWIND, 0, use_inout); break;
219 case KP4: handle_transport(SINGLE_FRAME_REWIND, 0, use_inout); break;
220 case KP1: handle_transport(SINGLE_FRAME_FWD, 0, use_inout); break;
221 case KP2: handle_transport(SLOW_FWD, 0, use_inout); break;
222 case KP3: handle_transport(NORMAL_FWD, 0, use_inout); break;
223 case KPENTER: handle_transport(FAST_FWD, 0, use_inout); break;
224 case KPINS: handle_transport(STOP, 0, use_inout); break;
226 int prev_command = engine->command->command;
227 int new_command = prev_command == COMMAND_NONE ||
228 prev_command == CURRENT_FRAME ||
229 prev_command == PAUSE ||
230 prev_command == STOP ? NORMAL_FWD : STOP;
231 handle_transport(new_command, 0, use_inout); break;
233 case 'k': handle_transport(STOP, 0, use_inout); break;
235 subwindow->lock_window("PlayTransport::keypress_event 3");
237 subwindow->unlock_window();
240 subwindow->lock_window("PlayTransport::keypress_event 4");
242 subwindow->unlock_window();
249 subwindow->lock_window("PlayTransport::keypress_event 5");
255 void PlayTransport::goto_start()
257 handle_transport(REWIND, 1, 0);
260 void PlayTransport::goto_end()
262 handle_transport(GOTO_END, 1, 0);
267 void PlayTransport::handle_transport(int command,
272 if(!get_edl()) return;
274 // Stop requires transferring the output buffer to a refresh buffer.
276 //printf("PlayTransport::handle_transport 1 %d\n", command);
277 int prev_command = engine->command->command;
278 int prev_direction = engine->command->get_direction();
279 int prev_single_frame = engine->command->single_frame();
284 // Commands that play back
288 case SINGLE_FRAME_REWIND:
289 case SINGLE_FRAME_FWD:
293 // Same direction pressed twice. Stop
294 if(prev_command == command &&
300 // Resume or change direction
301 if(prev_command != STOP &&
302 prev_command != COMMAND_NONE &&
303 prev_command != SINGLE_FRAME_FWD &&
304 prev_command != SINGLE_FRAME_REWIND)
306 engine->que->send_command(STOP,
312 engine->interrupt_playback(wait_tracking);
313 engine->que->send_command(command,
321 // Start from scratch
323 engine->que->send_command(command,
332 // Commands that stop
339 engine->que->send_command(STOP,
345 engine->interrupt_playback(wait_tracking);
351 engine->que->send_command(STOP,
357 engine->interrupt_playback(wait_tracking);
358 // This is necessary to get an OpenGL output buffer
359 // printf("PlayTransport::handle_transport 2 update_refresh=%d prev_command=%d prev_direction=%d\n",
360 // update_refresh, prev_command, prev_direction);
361 if(!prev_single_frame &&
363 prev_command != STOP &&
364 prev_command != COMMAND_NONE)
366 engine->que->send_command(
367 (prev_direction == PLAY_FORWARD) ? SINGLE_FRAME_REWIND : SINGLE_FRAME_FWD,
377 EDL* PlayTransport::get_edl()
382 int PlayTransport::pause_transport()
384 if(active_button) active_button->set_mode(PLAY_MODE);
389 int PlayTransport::reset_transport()
391 fast_reverse->set_mode(PLAY_MODE);
392 reverse_play->set_mode(PLAY_MODE);
393 forward_play->set_mode(PLAY_MODE);
394 frame_reverse_play->set_mode(PLAY_MODE);
395 frame_forward_play->set_mode(PLAY_MODE);
396 fast_play->set_mode(PLAY_MODE);
400 PTransportButton::PTransportButton(MWindow *mwindow, PlayTransport *transport, int x, int y, VFrame **data)
401 : BC_Button(x, y, data)
403 this->mwindow = mwindow;
404 this->transport = transport;
407 PTransportButton::~PTransportButton()
411 int PTransportButton::set_mode(int mode)
418 RewindButton::RewindButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
419 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("rewind"))
421 set_tooltip(_("Rewind ( Home )"));
423 int RewindButton::handle_event()
426 transport->goto_start();
431 FastReverseButton::FastReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
432 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastrev"))
434 set_tooltip(_("Fast reverse ( + )"));
436 int FastReverseButton::handle_event()
439 transport->handle_transport(FAST_REWIND, 0, ctrl_down());
440 lock_window("FastReverseButton::handle_event");
444 // Reverse playback normal speed
446 ReverseButton::ReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
447 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("reverse"))
449 set_tooltip(_("Normal reverse ( 6 )"));
451 int ReverseButton::handle_event()
454 transport->handle_transport(NORMAL_REWIND, 0, ctrl_down());
455 lock_window("ReverseButton::handle_event");
459 // Reverse playback one frame
461 FrameReverseButton::FrameReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
462 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("framerev"))
464 set_tooltip(_("Frame reverse ( 4 )"));
466 int FrameReverseButton::handle_event()
469 transport->handle_transport(SINGLE_FRAME_REWIND, 0, ctrl_down());
470 lock_window("FrameReverseButton::handle_event");
474 // forward playback normal speed
476 PlayButton::PlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
477 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("play"))
479 set_tooltip(_("Normal forward ( 3 )"));
481 int PlayButton::handle_event()
484 transport->handle_transport(NORMAL_FWD, 0, ctrl_down());
485 lock_window("PlayButton::handle_event");
491 // forward playback one frame
493 FramePlayButton::FramePlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
494 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("framefwd"))
496 set_tooltip(_("Frame forward ( 1 )"));
498 int FramePlayButton::handle_event()
501 transport->handle_transport(SINGLE_FRAME_FWD, 0, ctrl_down());
502 lock_window("FramePlayButton::handle_event");
508 FastPlayButton::FastPlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
509 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastfwd"))
511 set_tooltip(_("Fast forward ( Enter )"));
513 int FastPlayButton::handle_event()
516 transport->handle_transport(FAST_FWD, 0, ctrl_down());
517 lock_window("FastPlayButton::handle_event");
521 EndButton::EndButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
522 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("end"))
524 set_tooltip(_("Jump to end ( End )"));
526 int EndButton::handle_event()
529 transport->goto_end();
534 StopButton::StopButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
535 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("stop"))
537 set_tooltip(_("Stop ( 0 )"));
539 int StopButton::handle_event()
542 transport->handle_transport(STOP, 0, 0);
543 lock_window("StopButton::handle_event");
549 void PlayTransport::change_position(double position)
551 EDL *edl = get_edl();
553 int prev_command = engine->command->command;
555 if( prev_command != STOP && prev_command != COMMAND_NONE &&
556 prev_command != SINGLE_FRAME_FWD && prev_command != SINGLE_FRAME_REWIND ) {
557 engine->que->send_command(STOP, CHANGE_NONE, 0, 0, 0, 0);
558 engine->interrupt_playback(0);
560 mwindow->gui->lock_window("PlayTransport::change_position");
561 mwindow->goto_position(position);
562 mwindow->gui->unlock_window();
564 switch(prev_command) {
571 engine->que->send_command(prev_command, CHANGE_NONE,
572 get_edl(), 1, 1, using_inout);