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"
33 #include "transportque.h"
38 PlayTransport::PlayTransport(MWindow *mwindow,
39 BC_WindowBase *subwindow,
43 this->subwindow = subwindow;
44 this->mwindow = mwindow;
49 this->using_inout = 0;
53 PlayTransport::~PlayTransport()
56 delete frame_forward_play;
58 delete frame_reverse_play;
66 void PlayTransport::set_engine(PlaybackEngine *engine)
68 this->engine = engine;
71 int PlayTransport::get_transport_width(MWindow *mwindow)
73 return mwindow->theme->get_image_set("stop")[0]->get_w() * 7 +
74 mwindow->theme->get_image_set("rewind")[0]->get_w() * 2;
77 void PlayTransport::create_objects()
79 int x = this->x, y = this->y;
80 subwindow->add_subwindow(rewind_button = new RewindButton(mwindow, this, x, y));
81 x += rewind_button->get_w();
82 subwindow->add_subwindow(fast_reverse = new FastReverseButton(mwindow, this, x, y));
83 x += fast_reverse->get_w();
84 subwindow->add_subwindow(reverse_play = new ReverseButton(mwindow, this, x, y));
85 x += reverse_play->get_w();
86 subwindow->add_subwindow(frame_reverse_play = new FrameReverseButton(mwindow, this, x, y));
87 x += frame_reverse_play->get_w();
88 subwindow->add_subwindow(stop_button = new StopButton(mwindow, this, x, y));
89 x += stop_button->get_w();
90 subwindow->add_subwindow(frame_forward_play = new FramePlayButton(mwindow, this, x, y));
91 x += frame_forward_play->get_w();
92 subwindow->add_subwindow(forward_play = new PlayButton(mwindow, this, x, y));
93 x += forward_play->get_w();
94 subwindow->add_subwindow(fast_play = new FastPlayButton(mwindow, this, x, y));
95 x += fast_play->get_w();
96 subwindow->add_subwindow(end_button = new EndButton(mwindow, this, x, y));
97 x += end_button->get_w();
104 void PlayTransport::reposition_buttons(int x, int y)
108 rewind_button->reposition_window(x, y);
109 x += rewind_button->get_w();
110 fast_reverse->reposition_window(x, y);
111 x += fast_reverse->get_w();
112 reverse_play->reposition_window(x, y);
113 x += reverse_play->get_w();
114 frame_reverse_play->reposition_window(x, y);
115 x += frame_reverse_play->get_w();
116 stop_button->reposition_window(x, y);
117 x += stop_button->get_w();
118 frame_forward_play->reposition_window(x, y);
119 x += frame_forward_play->get_w();
120 forward_play->reposition_window(x, y);
121 x += forward_play->get_w();
122 fast_play->reposition_window(x, y);
123 x += fast_play->get_w();
124 end_button->reposition_window(x, y);
125 x += end_button->get_w();
128 int PlayTransport::get_w()
130 return end_button->get_x() + end_button->get_w() - rewind_button->get_x();
133 int PlayTransport::is_stopped()
135 return engine->is_playing_back ? 0 : 1;
138 int PlayTransport::flip_vertical(int vertical, int &x, int &y)
142 rewind_button->reposition_window(x, y);
143 y += rewind_button->get_h();
144 fast_reverse->reposition_window(x, y);
145 y += fast_reverse->get_h();
146 reverse_play->reposition_window(x, y);
147 y += reverse_play->get_h();
148 frame_reverse_play->reposition_window(x, y);
149 y += frame_reverse_play->get_h();
150 stop_button->reposition_window(x, y);
151 y += stop_button->get_h();
152 frame_forward_play->reposition_window(x, y);
153 y += frame_forward_play->get_h();
154 forward_play->reposition_window(x, y);
155 y += forward_play->get_h();
156 fast_play->reposition_window(x, y);
157 y += fast_play->get_h();
158 end_button->reposition_window(x, y);
159 y += end_button->get_h();
163 rewind_button->reposition_window(x, y - 2);
164 x += rewind_button->get_w();
165 fast_reverse->reposition_window(x, y - 2);
166 x += fast_reverse->get_w();
167 reverse_play->reposition_window(x, y - 2);
168 x += reverse_play->get_w();
169 frame_reverse_play->reposition_window(x, y - 2);
170 x += frame_reverse_play->get_w();
171 stop_button->reposition_window(x, y - 2);
172 x += stop_button->get_w();
173 frame_forward_play->reposition_window(x, y - 2);
174 x += frame_forward_play->get_w();
175 forward_play->reposition_window(x, y - 2);
176 x += forward_play->get_w();
177 fast_play->reposition_window(x, y - 2);
178 x += fast_play->get_w();
179 end_button->reposition_window(x, y - 2);
180 x += end_button->get_w();
186 int PlayTransport::keypress_event()
188 int key = subwindow->get_keypress();
189 return do_keypress(key);
192 int PlayTransport::do_keypress(int key)
195 // unqualified keys, still holding lock
205 int ctrl_key = subwindow->ctrl_down() ? 1 : 0;
206 int shft_key = subwindow->shift_down() ? 1 : 0;
207 int alt_key = subwindow->alt_down() ? 1 : 0;
208 int use_inout = ctrl_key;
209 int toggle_audio = shft_key & ~ctrl_key;
210 int loop_play = shft_key & ctrl_key;
213 int curr_command = engine->command->command;
214 subwindow->unlock_window();
218 if( key >= SKEY_MIN && key <= SKEY_MAX ) {
219 speed = SHUTTLE_MAX_SPEED *
220 (key - (SKEY_MAX + SKEY_MIN)/2.f) /
221 ((SKEY_MAX - SKEY_MIN) / 2.f);
224 command = speed < 1 ? SLOW_REWIND :
225 speed > 1 ? FAST_REWIND : NORMAL_REWIND;
227 else if( speed > 0 ) {
228 command = speed < 1 ? SLOW_FWD :
229 speed > 1 ? FAST_FWD : NORMAL_FWD;
237 case KPINS: command = STOP; break;
238 case KPPLUS: command = FAST_REWIND; break;
239 case KP6: command = NORMAL_REWIND; break;
240 case KP5: command = SLOW_REWIND; break;
241 case KP4: command = SINGLE_FRAME_REWIND; break;
242 case KP1: command = SINGLE_FRAME_FWD; break;
243 case KP2: command = SLOW_FWD; break;
244 case KP3: command = NORMAL_FWD; break;
245 case KPENTER: command = FAST_FWD; break;
248 switch( curr_command ) {
254 command = NORMAL_FWD;
262 if( alt_key ) command = SINGLE_FRAME_REWIND;
265 if( alt_key ) command = SLOW_REWIND;
268 if( alt_key ) command = NORMAL_REWIND;
271 if( alt_key ) command = FAST_REWIND;
274 if( alt_key ) command = SINGLE_FRAME_FWD;
277 if( alt_key ) command = SLOW_FWD;
280 if( alt_key ) command = NORMAL_FWD;
283 if( alt_key ) command = FAST_FWD;
286 if( alt_key ) command = STOP;
290 handle_transport(command, 0, use_inout, toggle_audio, loop_play, speed);
294 subwindow->lock_window("PlayTransport::keypress_event 5");
299 void PlayTransport::goto_start()
301 handle_transport(REWIND, 1);
304 void PlayTransport::goto_end()
306 handle_transport(GOTO_END, 1);
311 void PlayTransport::handle_transport(int command, int wait_tracking,
312 int use_inout, int toggle_audio, int loop_play, float speed)
314 EDL *edl = get_edl();
316 using_inout = use_inout;
319 mwindow->handle_mixers(edl, command, wait_tracking,
320 use_inout, toggle_audio, 0, speed);
321 engine->next_command->toggle_audio = toggle_audio;
322 engine->next_command->loop_play = loop_play;
323 engine->next_command->speed = speed;
324 engine->send_command(command, edl, wait_tracking, use_inout);
327 EDL* PlayTransport::get_edl()
332 int PlayTransport::pause_transport()
334 if(active_button) active_button->set_mode(PLAY_MODE);
339 int PlayTransport::reset_transport()
341 fast_reverse->set_mode(PLAY_MODE);
342 reverse_play->set_mode(PLAY_MODE);
343 forward_play->set_mode(PLAY_MODE);
344 frame_reverse_play->set_mode(PLAY_MODE);
345 frame_forward_play->set_mode(PLAY_MODE);
346 fast_play->set_mode(PLAY_MODE);
350 PTransportButton::PTransportButton(MWindow *mwindow, PlayTransport *transport, int x, int y, VFrame **data)
351 : BC_Button(x, y, data)
353 this->mwindow = mwindow;
354 this->transport = transport;
357 PTransportButton::~PTransportButton()
361 int PTransportButton::set_mode(int mode)
367 int PTransportButton::play_command(const char *lock_msg, int command)
369 int ctrl_key = transport->subwindow->ctrl_down() ? 1 : 0;
370 int shft_key = transport->subwindow->shift_down() ? 1 : 0;
371 int use_inout = ctrl_key;
372 int toggle_audio = shft_key & ~ctrl_key;
373 int loop_play = shft_key & ctrl_key;
375 transport->handle_transport(command, 0, use_inout, toggle_audio, loop_play, 0);
376 lock_window(lock_msg);
381 RewindButton::RewindButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
382 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("rewind"))
384 set_tooltip(_("Rewind ( Home )"));
386 int RewindButton::handle_event()
389 transport->goto_start();
394 FastReverseButton::FastReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
395 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastrev"))
397 set_tooltip(_("Fast reverse ( + or Alt-p )"));
399 int FastReverseButton::handle_event()
401 return play_command("FastReverseButton::handle_event", FAST_REWIND);
404 // Reverse playback normal speed
406 ReverseButton::ReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
407 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("reverse"))
409 set_tooltip(_("Normal reverse ( 6 or Alt-o )"));
411 int ReverseButton::handle_event()
413 return play_command("ReverseButton::handle_event", NORMAL_REWIND);
416 // Reverse playback one frame
418 FrameReverseButton::FrameReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
419 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("framerev"))
421 set_tooltip(_("Frame reverse ( 4 or Alt-u )"));
423 int FrameReverseButton::handle_event()
426 transport->handle_transport(SINGLE_FRAME_REWIND, 0, ctrl_down());
427 lock_window("FrameReverseButton::handle_event");
431 // forward playback normal speed
433 PlayButton::PlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
434 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("play"))
436 set_tooltip(_("Normal forward ( 3 or Alt-l )"));
438 int PlayButton::handle_event()
440 return play_command("PlayButton::handle_event", NORMAL_FWD);
445 // forward playback one frame
447 FramePlayButton::FramePlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
448 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("framefwd"))
450 set_tooltip(_("Frame forward ( 1 or Alt-j )"));
452 int FramePlayButton::handle_event()
455 transport->handle_transport(SINGLE_FRAME_FWD, 0, ctrl_down());
456 lock_window("FramePlayButton::handle_event");
462 FastPlayButton::FastPlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
463 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastfwd"))
465 set_tooltip(_("Fast forward ( Enter or Alt-; )"));
467 int FastPlayButton::handle_event()
469 return play_command("FastPlayButton::handle_event", FAST_FWD);
472 EndButton::EndButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
473 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("end"))
475 set_tooltip(_("Jump to end ( End )"));
477 int EndButton::handle_event()
480 transport->goto_end();
485 StopButton::StopButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
486 : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("stop"))
488 set_tooltip(_("Stop ( 0 or Alt-m )"));
490 int StopButton::handle_event()
493 transport->handle_transport(STOP);
494 lock_window("StopButton::handle_event");
500 void PlayTransport::change_position(double position)
502 if( !get_edl() ) return;
503 int command = engine->command->command;
505 engine->stop_playback(0);
506 mwindow->gui->lock_window("PlayTransport::change_position");
507 mwindow->goto_position(position);
508 mwindow->gui->unlock_window();
517 engine->next_command->realtime = 1;
518 engine->next_command->resume = 1;
519 engine->transport_command(command, CHANGE_NONE, get_edl(), using_inout);