Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.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 "localsession.h"
38 #include "mainmenu.h"
39 #include "mainsession.h"
40 #include "mbuttons.h"
41 #include "mwindow.h"
42 #include "mwindowgui.h"
43 #include "playbackengine.h"
44 #include "playtransport.h"
45 #include "preferences.h"
46 #include "remotecontrol.h"
47 #include "theme.h"
48 #include "track.h"
49 #include "trackcanvas.h"
50 #include "tracks.h"
51 #include "transportque.h"
52
53 #include <unistd.h>
54
55
56
57 CWindow::CWindow(MWindow *mwindow)
58  : Thread(1, 0, 0)
59 {
60         this->mwindow = mwindow;
61 }
62
63
64 CWindow::~CWindow()
65 {
66         if(gui && running()) {
67                 gui->set_done(0);
68                 join();
69         }
70         delete gui;  gui = 0;
71         delete playback_engine;
72         delete playback_cursor;
73 }
74
75 void CWindow::create_objects()
76 {
77         destination = mwindow->defaults->get("CWINDOW_DESTINATION", 0);
78
79
80         gui = new CWindowGUI(mwindow, this);
81
82         gui->create_objects();
83
84
85         playback_engine = new CPlayback(mwindow, this, gui->canvas);
86
87
88 // Start command loop
89         playback_engine->create_objects();
90
91         gui->transport->set_engine(playback_engine);
92
93         playback_cursor = new CTracking(mwindow, this);
94
95         playback_cursor->create_objects();
96
97 }
98
99
100 void CWindow::show_window()
101 {
102         gui->lock_window("CWindow::show_cwindow");
103         gui->show_window();
104         gui->raise_window();
105         gui->flush();
106         gui->unlock_window();
107
108         gui->tool_panel->show_tool();
109 }
110
111 void CWindow::hide_window()
112 {
113         gui->hide_window();
114         gui->mwindow->session->show_cwindow = 0;
115 // Unlock in case MWindow is waiting for it.
116         gui->unlock_window();
117
118         gui->tool_panel->hide_tool();
119
120         mwindow->gui->lock_window("CWindowGUI::close_event");
121         mwindow->gui->mainmenu->show_cwindow->set_checked(0);
122         mwindow->gui->unlock_window();
123         mwindow->save_defaults();
124
125         gui->lock_window("CWindow::hide_window");
126 }
127
128
129 Track* CWindow::calculate_affected_track()
130 {
131         Track* affected_track = 0;
132         for(Track *track = mwindow->edl->tracks->first;
133                 track;
134                 track = track->next)
135         {
136                 if(track->data_type == TRACK_VIDEO &&
137                         track->record)
138                 {
139                         affected_track = track;
140                         break;
141                 }
142         }
143         return affected_track;
144 }
145
146 Auto* CWindow::calculate_affected_auto(Autos *autos, 
147         int create,
148         int *created,
149         int redraw)
150 {
151         Auto* affected_auto = 0;
152         if(created) *created = 0;
153
154         if(create)
155         {
156                 int total = autos->total();
157                 affected_auto = autos->get_auto_for_editing();
158
159 // Got created
160                 if(total != autos->total())
161                 {
162                         if(created) *created = 1;
163                         if(redraw)
164                         {
165 // May have to unlock CWindowGUI here.
166                                 mwindow->gui->lock_window("CWindow::calculate_affected_auto");
167                                 mwindow->gui->draw_overlays(1);
168                                 mwindow->gui->unlock_window();
169                         }
170                 }
171         }
172         else
173         {
174                 affected_auto = autos->get_prev_auto(PLAY_FORWARD, affected_auto);
175         }
176
177         return affected_auto;
178 }
179
180
181
182 void CWindow::calculate_affected_autos(FloatAuto **x_auto,
183         FloatAuto **y_auto,
184         FloatAuto **z_auto,
185         Track *track,
186         int use_camera,
187         int create_x,
188         int create_y,
189         int create_z)
190 {
191         if(x_auto) (*x_auto) = 0;
192         if(y_auto) (*y_auto) = 0;
193         if(z_auto) (*z_auto) = 0;
194
195         if(!track) return;
196
197         if(use_camera)
198         {
199                 if(x_auto) (*x_auto) = (FloatAuto*)calculate_affected_auto(
200                         track->automation->autos[AUTOMATION_CAMERA_X], create_x);
201                 if(y_auto) (*y_auto) = (FloatAuto*)calculate_affected_auto(
202                         track->automation->autos[AUTOMATION_CAMERA_Y], create_y);
203                 if(z_auto) (*z_auto) = (FloatAuto*)calculate_affected_auto(
204                         track->automation->autos[AUTOMATION_CAMERA_Z], create_z);
205         }
206         else
207         {
208                 if(x_auto) (*x_auto) = (FloatAuto*)calculate_affected_auto(
209                         track->automation->autos[AUTOMATION_PROJECTOR_X], create_x);
210                 if(y_auto) (*y_auto) = (FloatAuto*)calculate_affected_auto(
211                         track->automation->autos[AUTOMATION_PROJECTOR_Y], create_y);
212                 if(z_auto) (*z_auto) = (FloatAuto*)calculate_affected_auto(
213                         track->automation->autos[AUTOMATION_PROJECTOR_Z], create_z);
214         }
215 }
216
217
218
219
220
221 void CWindow::run()
222 {
223         gui->run_window();
224 }
225
226 void CWindow::update(int position, 
227         int overlays, 
228         int tool_window, 
229         int operation,
230         int timebar)
231 {
232
233         if(position)
234         {
235                 playback_engine->que->send_command(CURRENT_FRAME, 
236                         CHANGE_NONE,
237                         mwindow->edl,
238                         1);
239         }
240
241         gui->lock_window("CWindow::update 2");
242
243
244 // Create tool window
245         if(operation)
246         {
247                 gui->set_operation(mwindow->edl->session->cwindow_operation);
248         }
249
250
251 // Updated by video device.
252         if(overlays && !position)
253         {
254                 gui->canvas->draw_refresh();
255         }
256
257 // Update tool parameters
258 // Never updated by someone else
259         if(tool_window || position)
260         {
261                 gui->update_tool();
262         }
263
264         if(timebar)
265         {
266                 gui->timebar->update(1);
267         }
268
269         if(!mwindow->edl->session->cwindow_scrollbars)
270                 gui->zoom_panel->update(AUTO_ZOOM);
271         else
272                 gui->zoom_panel->update(mwindow->edl->session->cwindow_zoom);
273
274         gui->canvas->update_zoom(mwindow->edl->session->cwindow_xscroll,
275                         mwindow->edl->session->cwindow_yscroll, 
276                         mwindow->edl->session->cwindow_zoom);
277         gui->canvas->reposition_window(mwindow->edl, 
278                         mwindow->theme->ccanvas_x,
279                         mwindow->theme->ccanvas_y,
280                         mwindow->theme->ccanvas_w,
281                         mwindow->theme->ccanvas_h);
282
283
284
285
286         gui->unlock_window();
287
288
289
290
291 }
292
293 int CWindow::update_position(double position)
294 {
295         gui->unlock_window();
296
297         playback_engine->interrupt_playback(1);
298         
299         position = mwindow->edl->align_to_frame(position, 0);
300         position = MAX(0, position);
301
302         mwindow->gui->lock_window("CWindowSlider::handle_event 2");
303         mwindow->select_point(position);
304         mwindow->gui->unlock_window();
305
306         gui->lock_window("CWindow::update_position 1");
307         return 1;
308 }
309
310
311
312
313 CWindowRemoteHandler::
314 CWindowRemoteHandler(RemoteControl *remote_control)
315  : RemoteHandler(remote_control->gui, RED)
316 {
317         last_key = -1;
318 }
319
320 CWindowRemoteHandler::
321 ~CWindowRemoteHandler()
322 {
323 }
324
325 int CWindowRemoteHandler::remote_process_key(RemoteControl *remote_control, int key)
326 {
327         MWindowGUI *mwindow_gui = remote_control->mwindow_gui;
328         EDL *edl = mwindow_gui->mwindow->edl; 
329         if( !edl ) return 0;
330         PlayTransport *transport = mwindow_gui->mbuttons->transport;
331         if( !transport->get_edl() ) return 0;
332         PlaybackEngine *engine = transport->engine;
333         double position = engine->get_tracking_position();
334         double length = edl->tracks->total_length();
335         int next_command = -1, lastkey = last_key;
336         last_key = key;
337
338         switch( key ) {
339         case '1': case '2': case '3': case '4':
340         case '5': case '6': case '7': case '8':
341                 if( lastkey == 'e' ) {
342                         mwindow_gui->mwindow->select_asset(key-'1', 1);
343                         break;
344                 } // fall through
345         case '0': case '9':
346                 position = length * (key-'0')/10.0;
347                 break;
348         case UP:      position += 60.0;                 break;
349         case DOWN:    position -= 60.0;                 break;
350         case LEFT:    position -= 10.0;                 break;
351         case RIGHT:   position += 10.0;                 break;
352         case KPSTOP:  next_command = STOP;              break;
353         case KPREV:   next_command = NORMAL_REWIND;     break;
354         case KPPLAY:  next_command = NORMAL_FWD;        break;
355         case KPBACK:  next_command = FAST_REWIND;       break;
356         case KPFWRD:  next_command = FAST_FWD;          break;
357         case KPRECD:  next_command = SLOW_REWIND;       break;
358         case KPAUSE:  next_command = SLOW_FWD;          break;
359         case ' ':  next_command = NORMAL_FWD;           break;
360         case 'a':  gui->tile_windows(0);                return 1;
361         case 'b':  gui->tile_windows(1);                return 1;
362         case 'c':  gui->tile_windows(2);                return 1;
363         case 'd':
364                 mwindow_gui->channel_info->toggle_scan();
365                 return 1;
366         case 'e':
367                 break;
368         case 'f': {
369                 Canvas *canvas = mwindow_gui->mwindow->cwindow->gui->canvas;
370                 if( !canvas->get_fullscreen() )
371                         canvas->start_fullscreen();
372                 else
373                         canvas->stop_fullscreen();
374                 return 1; }
375         default:
376                 return -1;
377         }
378
379         if( next_command < 0 ) {
380                 if( position < 0 ) position = 0;
381                 transport->change_position(position);
382         }
383         else
384                 transport->handle_transport(next_command, 0, 0);
385         return 1;
386 }
387