cut with active speed auto correction, add locale pref, mod prores dft profile to...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / cwindow.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #include "autos.h"
23 #include "bchash.h"
24 #include "bcsignals.h"
25 #include "channelinfo.h"
26 #include "clip.h"
27 #include "cplayback.h"
28 #include "ctimebar.h"
29 #include "ctracking.h"
30 #include "cwindow.h"
31 #include "cwindowgui.h"
32 #include "cwindowtool.h"
33 #include "edl.h"
34 #include "keys.h"
35 #include "edl.h"
36 #include "edlsession.h"
37 #include "language.h"
38 #include "localsession.h"
39 #include "mainmenu.h"
40 #include "mainsession.h"
41 #include "mbuttons.h"
42 #include "mwindow.h"
43 #include "mwindowgui.h"
44 #include "playbackengine.h"
45 #include "playtransport.h"
46 #include "preferences.h"
47 #include "remotecontrol.h"
48 #include "theme.h"
49 #include "track.h"
50 #include "trackcanvas.h"
51 #include "tracks.h"
52 #include "transportque.h"
53
54 #include <unistd.h>
55
56
57
58 CWindow::CWindow(MWindow *mwindow)
59  : Thread(1, 0, 0)
60 {
61         this->mwindow = mwindow;
62         this->playback_engine = 0;
63         this->playback_cursor = 0;
64         this->mask_track_id = -1;
65         this->gui = 0;
66 }
67
68
69 CWindow::~CWindow()
70 {
71         if(gui && running()) {
72                 gui->set_done(0);
73         }
74         join();
75         delete gui;  gui = 0;
76         delete playback_engine;
77         delete playback_cursor;
78 }
79
80 void CWindow::create_objects()
81 {
82         gui = new CWindowGUI(mwindow, this);
83         gui->create_objects();
84         playback_engine = new CPlayback(mwindow, this, gui->canvas);
85 // Start command loop
86         playback_engine->create_objects();
87         gui->transport->set_engine(playback_engine);
88         playback_cursor = new CTracking(mwindow, this);
89         playback_cursor->create_objects();
90 }
91
92
93 void CWindow::show_window()
94 {
95         gui->lock_window("CWindow::show_cwindow");
96         gui->show_window();
97         gui->raise_window();
98         gui->flush();
99         gui->unlock_window();
100
101         gui->tool_panel->show_tool();
102 }
103
104 void CWindow::hide_window()
105 {
106         gui->hide_window();
107         gui->mwindow->session->show_cwindow = 0;
108 // Unlock in case MWindow is waiting for it.
109         gui->unlock_window();
110
111         gui->tool_panel->hide_tool();
112
113         mwindow->gui->lock_window("CWindowGUI::close_event");
114         mwindow->gui->mainmenu->show_cwindow->set_checked(0);
115         mwindow->gui->unlock_window();
116         mwindow->save_defaults();
117
118         gui->lock_window("CWindow::hide_window");
119 }
120
121
122 Track* CWindow::calculate_affected_track()
123 {
124         Track *track = mwindow->edl->tracks->first;
125         for( ; track; track=track->next ) {
126                 if( track->data_type != TRACK_VIDEO ) continue;
127                 if( track->is_armed() ) break;
128         }
129         return track;
130 }
131
132 Track* CWindow::calculate_mask_track()
133 {
134         Track *track = mwindow->edl->tracks->first;
135         for( ; track; track=track->next ) {
136                 if( track->data_type != TRACK_VIDEO ) continue;
137                 if( track->is_armed() && track->get_id() == mask_track_id ) break;
138         }
139         return track;
140 }
141
142
143 Auto* CWindow::calculate_affected_auto(Autos *autos,
144                 int create, int *created, int redraw)
145 {
146         Auto* affected_auto = 0;
147         if( created ) *created = 0;
148
149         if( create ) {
150                 int total = autos->total();
151                 affected_auto = autos->get_auto_for_editing(-1, create);
152
153 // Got created
154                 if( total != autos->total() ) {
155                         if( created ) *created = 1;
156                         if( redraw ) {
157 // May have to unlock CWindowGUI here.
158                                 mwindow->gui->lock_window("CWindow::calculate_affected_auto");
159                                 mwindow->gui->draw_overlays(1);
160                                 mwindow->gui->unlock_window();
161                         }
162                 }
163         }
164         else {
165                 affected_auto = autos->get_prev_auto(PLAY_FORWARD, affected_auto);
166         }
167
168         return affected_auto;
169 }
170
171
172
173 void CWindow::calculate_affected_autos(Track *track,
174                 FloatAuto **x_auto, FloatAuto **y_auto, FloatAuto **z_auto,
175                 int use_camera, int create_x, int create_y, int create_z,
176                 int redraw)
177 {
178         if( x_auto ) *x_auto = 0;
179         if( y_auto ) *y_auto = 0;
180         if( z_auto ) *z_auto = 0;
181         if( !track ) return;
182
183         int ix = use_camera ? AUTOMATION_CAMERA_X : AUTOMATION_PROJECTOR_X, x_created = 0;
184         int iy = use_camera ? AUTOMATION_CAMERA_Y : AUTOMATION_PROJECTOR_Y, y_created = 0;
185         int iz = use_camera ? AUTOMATION_CAMERA_Z : AUTOMATION_PROJECTOR_Z, z_created = 0;
186
187         if( x_auto )
188                 *x_auto = (FloatAuto*) calculate_affected_auto(track->automation->autos[ix],
189                                 create_x, &x_created, redraw);
190         if( y_auto )
191                 *y_auto = (FloatAuto*) calculate_affected_auto(track->automation->autos[iy],
192                                 create_y, &y_created, redraw);
193         if( z_auto ) *z_auto = (FloatAuto*) calculate_affected_auto(track->automation->autos[iz],
194                                 create_z, &z_created, redraw);
195 }
196
197 void CWindow::stop_playback(int wait)
198 {
199         playback_engine->stop_playback(wait);
200 }
201
202 void CWindow::run()
203 {
204         gui->run_window();
205 }
206
207 void CWindow::update(int dir, int overlays, int tool_window, int operation, int timebar)
208 {
209
210         if( dir )
211                 refresh_frame(CHANGE_NONE, dir);
212
213         gui->lock_window("CWindow::update 2");
214 // Create tool window
215         if( operation )
216                 gui->set_operation(mwindow->edl->session->cwindow_operation);
217
218 // Updated by video device.
219         if( overlays && !dir )
220                 gui->canvas->refresh(1);
221
222 // Update tool parameters
223 // Never updated by someone else
224         if( tool_window || dir )
225                 gui->update_tool();
226
227         if( timebar )
228                 gui->timebar->update(1);
229
230         double zoom = !mwindow->edl->session->cwindow_scrollbars ?
231                 0 : mwindow->edl->session->cwindow_zoom;
232         gui->zoom_panel->update(zoom);
233
234         gui->canvas->update_zoom(mwindow->edl->session->cwindow_xscroll,
235                         mwindow->edl->session->cwindow_yscroll,
236                         mwindow->edl->session->cwindow_zoom);
237         gui->canvas->update_geometry(mwindow->edl,
238                         mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y,
239                         mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h);
240
241         gui->unlock_window();
242 }
243
244 int CWindow::update_position(double position)
245 {
246         gui->unlock_window();
247
248         playback_engine->interrupt_playback(1);
249
250         position = mwindow->edl->align_to_frame(position, 0);
251         position = MAX(0, position);
252
253         mwindow->gui->lock_window("CWindowSlider::handle_event 2");
254         mwindow->select_point(position);
255         mwindow->gui->unlock_window();
256
257         gui->lock_window("CWindow::update_position 1");
258         return 1;
259 }
260
261 void CWindow::refresh_frame(int change_type, EDL *edl, int dir)
262 {
263         mwindow->refresh_mixers(dir);
264         playback_engine->refresh_frame(change_type, edl, dir);
265 }
266
267 void CWindow::refresh_frame(int change_type, int dir)
268 {
269         refresh_frame(change_type, mwindow->edl, dir);
270 }
271
272 CWindowKeyEvHandler::
273 CWindowKeyEvHandler(RemoteControl *remote_control)
274  : RemoteHandler(remote_control->gui, RED)
275 {
276         this->remote_control = remote_control;
277         this->mwindow = remote_control->mwindow_gui->mwindow;
278         last_key = -1;
279         key = -1;
280 }
281
282 CWindowKeyEvHandler::
283 ~CWindowKeyEvHandler()
284 {
285 }
286
287 int CWindowKeyEvHandler::remote_key(int key)
288 {
289         return remote_process_key(remote_control, key);
290 }
291
292 int CWindowKeyEvHandler::remote_process_key(RemoteControl *remote_control, int key)
293 {
294         EDL *edl = mwindow->edl;
295         if( !edl ) return 0;
296         PlayTransport *transport = mwindow->gui->mbuttons->transport;
297         if( !transport->get_edl() ) return 0;
298         PlaybackEngine *engine = transport->engine;
299         double position = engine->get_tracking_position();
300         double length = edl->tracks->total_length();
301         int next_command = -1;
302
303         switch( key ) {
304         case '1': case '2': case '3': case '4':
305         case '5': case '6': case '7': case '8':
306                 if( last_key == 'e' ) {
307                         mwindow->select_asset(key-'1', 1);
308                         break;
309                 } // fall through
310         case '0': case '9':
311                 position = length * (key-'0')/10.0;
312                 break;
313         case UP:      position += 60.0;                 break;
314         case DOWN:    position -= 60.0;                 break;
315         case LEFT:    position -= 10.0;                 break;
316         case RIGHT:   position += 10.0;                 break;
317         case KPSTOP:  next_command = STOP;              break;
318         case KPREV:   next_command = NORMAL_REWIND;     break;
319         case KPPLAY:  next_command = NORMAL_FWD;        break;
320         case KPBACK:  next_command = FAST_REWIND;       break;
321         case KPFWRD:  next_command = FAST_FWD;          break;
322         case KPRECD:  next_command = SLOW_REWIND;       break;
323         case KPAUSE:  next_command = SLOW_FWD;          break;
324         case ' ':  next_command = NORMAL_FWD;           break;
325         case 'a':  remote_control->gui->tile_windows(0);  return 1;
326         case 'b':  remote_control->gui->tile_windows(1);  return 1;
327         case 'c':  remote_control->gui->tile_windows(2);  return 1;
328         case KPFSCRN:
329         case 'f': {
330                 CWindowCanvas *canvas = mwindow->cwindow->gui->canvas;
331                 int on = canvas->get_fullscreen() ? 0 : 1;
332                 canvas->Canvas::set_fullscreen(on, 0);
333                 return 1; }
334         default:
335                 return -1;
336         }
337
338         if( next_command < 0 ) {
339                 if( position < 0 ) position = 0;
340                 transport->change_position(position);
341         }
342         else
343                 transport->handle_transport(next_command);
344         return 1;
345 }
346