inter-view map media popup tweaks, new vicon mode/size prefs
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / vwindow.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2012 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 "asset.h"
23 #include "assets.h"
24 #include "bcsignals.h"
25 #include "clip.h"
26 #include "clipedit.h"
27 #include "bchash.h"
28 #include "edl.h"
29 #include "edlsession.h"
30 #include "filesystem.h"
31 #include "filexml.h"
32 #include "indexable.h"
33 #include "language.h"
34 #include "localsession.h"
35 #include "mainclock.h"
36 #include "mainmenu.h"
37 #include "mainsession.h"
38 #include "mwindow.h"
39 #include "mwindowgui.h"
40 #include "playbackengine.h"
41 #include "tracks.h"
42 #include "transportque.h"
43 #include "vplayback.h"
44 #include "vtimebar.h"
45 #include "vtracking.h"
46 #include "vwindow.h"
47 #include "vwindowgui.h"
48
49
50 VWindow::VWindow(MWindow *mwindow)
51  : BC_DialogThread()
52 {
53         this->mwindow = mwindow;
54         gui = 0;
55         playback_engine = 0;
56         playback_cursor = 0;
57         clip_edit = 0;
58         indexable = 0;
59         edl = 0;
60 }
61
62
63 VWindow::~VWindow()
64 {
65         close_window();
66 //printf("VWindow::~VWindow 1\n");
67         delete playback_engine;
68 //printf("VWindow::~VWindow 1\n");
69         delete playback_cursor;
70         delete_source(1, 0);
71         delete clip_edit;
72 //printf("VWindow::~VWindow 2\n");
73 }
74
75 void VWindow::delete_source(int do_main_edl, int update_gui)
76 {
77 //printf("VWindow::delete_source %d %d %p %p\n", __LINE__, gui->get_window_lock(), edl, indexable);
78         if(do_main_edl) mwindow->edl->remove_vwindow_edl(get_edl());
79
80         if( edl ) {
81                 edl->Garbage::remove_user();
82                 edl = 0;
83         }
84
85         if( indexable ) {
86                 indexable->Garbage::remove_user();
87                 indexable = 0;
88         }
89
90         if( update_gui ) {
91                 gui->change_source(0, _("Viewer"));
92                 gui->clock->clear();
93         }
94 }
95
96
97 void VWindow::load_defaults()
98 {
99 }
100
101 void VWindow::create_objects()
102 {
103 }
104
105
106 void VWindow::handle_done_event(int result)
107 {
108         playback_engine->interrupt_playback(1);
109         delete_source(1, 0);
110         if( mwindow->in_destructor ) return;
111
112         int total = 0;
113         for(int i = 0; i < mwindow->vwindows.size(); i++)
114         {
115
116 //printf("VWindow::handle_done_event %d %d\n", __LINE__, mwindow->vwindows.get(i)->is_running());
117                 if(mwindow->vwindows.get(i)->is_running()) total++;
118         }
119 // subtract ourselves
120         total--;
121
122 // Update the menu if no viewers visible
123         if(!total)
124         {
125                 mwindow->gui->lock_window("VWindowGUI::close_event");
126                 mwindow->gui->mainmenu->show_vwindow->set_checked(0);
127                 mwindow->gui->unlock_window();
128
129                 mwindow->session->show_vwindow = 0;
130                 mwindow->save_defaults();
131         }
132 }
133
134 BC_Window* VWindow::new_gui()
135 {
136 //printf("VWindow::create_objects 1\n");
137         gui = new VWindowGUI(mwindow, this);
138 //printf("VWindow::create_objects 1\n");
139         gui->create_objects();
140 //printf("VWindow::create_objects 1\n");
141
142         playback_engine = new VPlayback(mwindow, this, gui->canvas);
143 //printf("VWindow::create_objects 1\n");
144
145 // Start command loop
146         playback_engine->create_objects();
147 //printf("VWindow::create_objects 1\n");
148         gui->transport->set_engine(playback_engine);
149 //printf("VWindow::create_objects 1\n");
150         playback_cursor = new VTracking(mwindow, this);
151 //printf("VWindow::create_objects 1\n");
152         playback_cursor->create_objects();
153 //printf("VWindow::create_objects 2\n");
154
155         clip_edit = new ClipEdit(mwindow, 0, this);
156         return gui;
157 }
158
159 void VWindow::handle_close_event(int result)
160 {
161         delete playback_engine;
162         playback_engine = 0;
163 }
164
165
166 EDL* VWindow::get_edl()
167 {
168 //      return mwindow->edl->vwindow_edl;
169         return edl;
170 }
171
172 Indexable* VWindow::get_source()
173 {
174         return this->indexable;
175 }
176
177 void VWindow::change_source(int edl_number)
178 {
179         if(!is_running()) return;
180         if( playback_engine->is_playing_back )
181                 stop_playback(1);
182
183         gui->lock_window("VWindow::change_source 1");
184 //printf("VWindow::change_source %d %p\n", __LINE__, mwindow->edl->get_vwindow_edl(edl_number));
185         if( edl_number >= 0 && edl_number < mwindow->edl->total_vwindow_edls() &&
186                  mwindow->edl->get_vwindow_edl(edl_number) )
187         {
188                 this->edl = mwindow->edl->get_vwindow_edl(edl_number);
189                 this->edl->Garbage::add_user();
190                 gui->change_source(get_edl(), get_edl()->local_session->clip_title);
191                 update_position(CHANGE_ALL, 1, 1, 1);
192         }
193         else
194         {
195                 delete_source(1, 1);
196 //              if(indexable) indexable->Garbage::remove_user();
197 //              indexable = 0;
198 //              mwindow->edl->vwindow_edl_shared = 0;
199         }
200         gui->unlock_window();
201 }
202
203 void VWindow::change_source(Indexable *indexable)
204 {
205         if( !indexable->is_asset ) {
206                 change_source((EDL*)indexable);
207                 return;
208         }
209         if(!running()) return;
210         if( playback_engine->is_playing_back )
211                 stop_playback(1);
212
213         gui->lock_window("VWindow::change_source 2");
214
215         char title[BCTEXTLEN];
216         FileSystem fs;
217         fs.extract_name(title, indexable->path);
218         delete_source(1, 0);
219
220 // Create EDL
221         this->edl = new EDL(mwindow->edl);
222         this->edl->create_objects();
223         mwindow->edl->append_vwindow_edl(this->edl, 1);
224
225 // Generate EDL off of main EDL for cutting
226         Asset *asset = new Asset;
227         asset->copy_from((Asset*)indexable, 0);
228         this->indexable = asset;
229         mwindow->asset_to_edl(this->edl, asset);
230
231 // Update GUI
232         gui->change_source(this->edl, title);
233         update_position(CHANGE_ALL, 1, 1, 1);
234
235         gui->unlock_window();
236 }
237
238 void VWindow::change_source(EDL *edl)
239 {
240         if(!running()) return;
241         if( playback_engine->is_playing_back )
242                 stop_playback(1);
243
244 //printf("VWindow::change_source %d %p\n", __LINE__, edl);
245 // EDLs are identical
246 //      if(edl && mwindow->edl->vwindow_edl &&
247 //              edl->id == mwindow->edl->vwindow_edl->id) return;
248         if(edl && get_edl() && edl->id == get_edl()->id) return;
249
250         gui->lock_window("VWindow::change_source 3");
251
252         delete_source(1, 0);
253
254         if(edl)
255         {
256                 mwindow->edl->append_vwindow_edl(edl, 1);
257                 this->edl = edl;
258                 this->edl->Garbage::add_user();
259                 edl->local_session->preview_start = 0;
260                 edl->local_session->preview_end = -1;
261 //              mwindow->edl->vwindow_edl = edl;
262 // in order not to later delete edl if it is shared
263 //              edl->Garbage::add_user();
264 //              mwindow->edl->vwindow_edl_shared = 1;
265
266 // Update GUI
267                 gui->change_source(edl, edl->local_session->clip_title);
268                 update_position(CHANGE_ALL, 1, 1, 1);
269         }
270         else
271                 gui->change_source(edl, _("Viewer"));
272         gui->unlock_window();
273 }
274
275
276 void VWindow::goto_start()
277 {
278         if(get_edl())
279         {
280                 get_edl()->local_session->set_selectionstart(0);
281                 get_edl()->local_session->set_selectionend(0);
282                 update_position(CHANGE_NONE,
283                         0,
284                         1,
285                         0);
286         }
287 }
288
289 void VWindow::goto_end()
290 {
291         if(get_edl())
292         {
293                 double position = get_edl()->tracks->total_length();
294                 get_edl()->local_session->set_selectionstart(position);
295                 get_edl()->local_session->set_selectionend(position);
296                 update_position(CHANGE_NONE,
297                         0,
298                         1,
299                         0);
300         }
301 }
302
303 void VWindow::update(int do_timebar)
304 {
305         if(do_timebar)
306                 gui->timebar->update(1);
307         gui->edit_panel->update();
308 }
309
310 void VWindow::update_position(int change_type,
311         int use_slider,
312         int update_slider,
313         int lock_window)
314 {
315         EDL *edl = get_edl();
316         if(edl)
317         {
318 //printf("VWindow::update_position %d\n", __LINE__);
319 //edl->dump();
320                 playback_engine->refresh_frame(change_type, edl);
321
322                 double position = edl->local_session->get_selectionstart(1);
323                 if(lock_window) gui->lock_window("VWindow::update_position");
324                 gui->clock->update(position);
325                 gui->timebar->update(1);
326                 if(lock_window) gui->unlock_window();
327         }
328 }
329
330 void VWindow::stop_playback(int wait)
331 {
332         playback_engine->stop_playback(wait);
333 }
334
335 int VWindow::update_position(double position)
336 {
337         EDL *edl = get_edl();
338         if(edl)
339         {
340                 gui->unlock_window();
341
342                 playback_engine->interrupt_playback(1);
343
344                 position = mwindow->edl->align_to_frame(position, 0);
345                 position = MAX(0, position);
346
347                 edl->local_session->set_selectionstart(position);
348                 edl->local_session->set_selectionend(position);
349
350                 gui->lock_window("VWindow::update_position 1");
351                 update_position(CHANGE_NONE, 0, 1, 0);
352         }
353
354         return 1;
355 }
356
357 void VWindow::set_inpoint()
358 {
359         EDL *edl = get_edl();
360         if(edl)
361         {
362                 edl->set_inpoint(edl->local_session->get_selectionstart(1));
363                 gui->timebar->update(1);
364         }
365 }
366
367 void VWindow::set_outpoint()
368 {
369         EDL *edl = get_edl();
370         if(edl)
371         {
372                 edl->set_outpoint(edl->local_session->get_selectionstart(1));
373                 gui->timebar->update(1);
374         }
375 }
376
377 void VWindow::unset_inoutpoint()
378 {
379         EDL *edl = get_edl();
380         if(edl)
381         {
382                 edl->unset_inoutpoint();
383                 gui->timebar->update(1);
384         }
385 }
386
387 void VWindow::copy(int all)
388 {
389         EDL *edl = get_edl();
390         if(edl)
391         {
392                 double start = all ? 0 :
393                         edl->local_session->get_selectionstart();
394                 double end = all ? edl->tracks->total_length() :
395                         edl->local_session->get_selectionend();
396                 EDL *copy_edl = new EDL; // no parent or assets wont be copied
397                 copy_edl->create_objects();
398                 copy_edl->copy_all(edl);
399                 FileXML file;
400                 copy_edl->copy(start, end, 0, &file, "", 1);
401                 copy_edl->remove_user();
402                 const char *file_string = file.string();
403                 long file_length = strlen(file_string);
404                 mwindow->gui->lock_window();
405                 mwindow->gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
406                 mwindow->gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
407                 mwindow->gui->unlock_window();
408         }
409 }
410
411 void VWindow::splice_selection()
412 {
413 }
414
415 void VWindow::overwrite_selection()
416 {
417 }
418