rework keyframe hide popup, keyframe auto render, textbox set_selection wide text
[goodguy/history.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         {
82                 edl->Garbage::remove_user();
83 //printf("VWindow::delete_source %d\n", __LINE__);
84                 edl = 0;
85         }
86
87 //      if(mwindow->edl->vwindow_edl && !mwindow->edl->vwindow_edl_shared)
88 //      {
89 //              mwindow->edl->vwindow_edl->Garbage::remove_user();
90 //              mwindow->edl->vwindow_edl = 0;
91 //              mwindow->edl->vwindow_edl_shared = 0;
92 //      }
93
94 //printf("VWindow::delete_source %d\n", __LINE__);
95         if(indexable) indexable->Garbage::remove_user();
96         indexable = 0;
97
98         if(update_gui) gui->change_source(0, _("Viewer"));
99 //printf("VWindow::delete_source %d\n", __LINE__);
100 }
101
102
103 void VWindow::load_defaults()
104 {
105 }
106
107 void VWindow::create_objects()
108 {
109 }
110
111
112 void VWindow::handle_done_event(int result)
113 {
114         playback_engine->interrupt_playback(1);
115         delete_source(1, 0);
116         if( mwindow->in_destructor ) return;
117
118         int total = 0;
119         for(int i = 0; i < mwindow->vwindows.size(); i++)
120         {
121
122 //printf("VWindow::handle_done_event %d %d\n", __LINE__, mwindow->vwindows.get(i)->is_running());
123                 if(mwindow->vwindows.get(i)->is_running()) total++;
124         }
125 // subtract ourselves
126         total--;
127
128 // Update the menu if no viewers visible
129         if(!total)
130         {
131                 mwindow->gui->lock_window("VWindowGUI::close_event");
132                 mwindow->gui->mainmenu->show_vwindow->set_checked(0);
133                 mwindow->gui->unlock_window();
134
135                 mwindow->session->show_vwindow = 0;
136                 mwindow->save_defaults();
137         }
138 }
139
140
141
142 BC_Window* VWindow::new_gui()
143 {
144 //printf("VWindow::create_objects 1\n");
145         gui = new VWindowGUI(mwindow, this);
146 //printf("VWindow::create_objects 1\n");
147         gui->create_objects();
148 //printf("VWindow::create_objects 1\n");
149
150         playback_engine = new VPlayback(mwindow, this, gui->canvas);
151 //printf("VWindow::create_objects 1\n");
152
153 // Start command loop
154         playback_engine->create_objects();
155 //printf("VWindow::create_objects 1\n");
156         gui->transport->set_engine(playback_engine);
157 //printf("VWindow::create_objects 1\n");
158         playback_cursor = new VTracking(mwindow, this);
159 //printf("VWindow::create_objects 1\n");
160         playback_cursor->create_objects();
161 //printf("VWindow::create_objects 2\n");
162
163         clip_edit = new ClipEdit(mwindow, 0, this);
164         return gui;
165 }
166
167
168 EDL* VWindow::get_edl()
169 {
170 //      return mwindow->edl->vwindow_edl;
171         return edl;
172 }
173
174 Indexable* VWindow::get_source()
175 {
176         return this->indexable;
177 }
178
179 void VWindow::change_source(int edl_number)
180 {
181         if(!is_running()) return;
182
183 //printf("VWindow::change_source %d %p\n", __LINE__, mwindow->edl->get_vwindow_edl(edl_number));
184         if( edl_number >= 0 && edl_number < mwindow->edl->total_vwindow_edls() &&
185                  mwindow->edl->get_vwindow_edl(edl_number) )
186         {
187                 this->edl = mwindow->edl->get_vwindow_edl(edl_number);
188                 this->edl->Garbage::add_user();
189                 gui->change_source(get_edl(), get_edl()->local_session->clip_title);
190                 update_position(CHANGE_ALL, 1, 1, 1);
191         }
192         else
193         {
194                 delete_source(1, 1);
195 //              if(indexable) indexable->Garbage::remove_user();
196 //              indexable = 0;
197 //              mwindow->edl->vwindow_edl_shared = 0;
198         }
199 }
200
201 void VWindow::change_source(Indexable *indexable)
202 {
203         if(!running()) return;
204 //      if(asset && this->asset &&
205 //              asset->id == this->asset->id &&
206 //              asset == this->asset) return;
207
208 //printf("VWindow::change_source %d\n", __LINE__);
209
210         char title[BCTEXTLEN];
211         FileSystem fs;
212         fs.extract_name(title, indexable->path);
213 //printf("VWindow::change_source 1\n");
214
215         delete_source(1, 0);
216 //printf("VWindow::change_source 1\n");
217
218 // Generate EDL off of main EDL for cutting
219         Asset *asset = 0;
220         EDL *nested_edl = 0;
221         if(indexable->is_asset)
222         {
223                 this->indexable = asset = new Asset;
224                 asset->copy_from((Asset*)indexable, 0);
225         }
226         else
227         {
228                 this->indexable = nested_edl = new EDL;
229                 nested_edl->create_objects();
230                 nested_edl->copy_all((EDL*)indexable);
231         }
232
233 // Create EDL
234         this->edl = new EDL(mwindow->edl);
235         this->edl->create_objects();
236         mwindow->edl->append_vwindow_edl(this->edl, 1);
237
238 //      mwindow->edl->vwindow_edl = new EDL(mwindow->edl);
239 //      mwindow->edl->vwindow_edl_shared = 0;
240 //      mwindow->edl->vwindow_edl->create_objects();
241
242 //printf("VWindow::change_source 1 %d %p %p\n", __LINE__, asset, nested_edl);
243         if(asset)
244                 mwindow->asset_to_edl(this->edl, asset);
245         else
246                 mwindow->edl_to_nested(this->edl, nested_edl);
247
248 // Update GUI
249         gui->change_source(this->edl, title);
250         update_position(CHANGE_ALL, 1, 1, 1);
251
252
253
254 //printf("VWindow::change_source 2\n");
255 }
256
257 void VWindow::change_source(EDL *edl)
258 {
259         if(!running()) return;
260 //printf("VWindow::change_source %d %p\n", __LINE__, edl);
261 // EDLs are identical
262 //      if(edl && mwindow->edl->vwindow_edl &&
263 //              edl->id == mwindow->edl->vwindow_edl->id) return;
264         if(edl && get_edl() && edl->id == get_edl()->id) return;
265
266         delete_source(1, 0);
267
268         if(edl)
269         {
270                 mwindow->edl->append_vwindow_edl(edl, 1);
271                 this->edl = edl;
272                 this->edl->Garbage::add_user();
273
274 //              mwindow->edl->vwindow_edl = edl;
275 // in order not to later delete edl if it is shared
276 //              edl->Garbage::add_user();
277 //              mwindow->edl->vwindow_edl_shared = 1;
278
279 // Update GUI
280                 gui->change_source(edl, edl->local_session->clip_title);
281                 update_position(CHANGE_ALL, 1, 1, 1);
282         }
283         else
284                 gui->change_source(edl, _("Viewer"));
285 }
286
287 void VWindow::change_source(char *folder, int item)
288 {
289 //printf("VWindow::change_source %d\n", __LINE__);
290         int result = 0;
291         if(!running()) return;
292 // Search EDLs
293         if(!strcasecmp(folder, CLIP_FOLDER))
294         {
295                 if(item < mwindow->edl->clips.total)
296                 {
297                         change_source(mwindow->edl->clips.values[item]);
298                         result = 1;
299                 }
300         }
301         else
302 // Search media
303         if(!strcasecmp(folder, MEDIA_FOLDER))
304         {
305                 if(item < mwindow->edl->assets->total())
306                 {
307                         change_source(mwindow->edl->assets->get_item_number(item));
308                         result = 1;
309                 }
310         }
311         else
312 // Search extra clip folders
313         {
314         }
315
316         if(!result)
317         {
318                 delete_source(1, 1);
319         }
320 }
321
322
323
324
325 void VWindow::goto_start()
326 {
327         if(get_edl())
328         {
329                 get_edl()->local_session->set_selectionstart(0);
330                 get_edl()->local_session->set_selectionend(0);
331                 update_position(CHANGE_NONE,
332                         0,
333                         1,
334                         0);
335         }
336 }
337
338 void VWindow::goto_end()
339 {
340         if(get_edl())
341         {
342                 double position = get_edl()->tracks->total_length();
343                 get_edl()->local_session->set_selectionstart(position);
344                 get_edl()->local_session->set_selectionend(position);
345                 update_position(CHANGE_NONE,
346                         0,
347                         1,
348                         0);
349         }
350 }
351
352 void VWindow::update(int do_timebar)
353 {
354         if(do_timebar)
355                 gui->timebar->update(1);
356 }
357
358 void VWindow::update_position(int change_type,
359         int use_slider,
360         int update_slider,
361         int lock_window)
362 {
363         EDL *edl = get_edl();
364         if(edl)
365         {
366 //printf("VWindow::update_position %d\n", __LINE__);
367 //edl->dump();
368                 playback_engine->que->send_command(CURRENT_FRAME,
369                         change_type,
370                         edl,
371                         1);
372
373                 double position = edl->local_session->get_selectionstart(1);
374                 Asset *asset = edl->assets->first;
375                 if( asset && asset->tcstart ) {
376                         double rate = asset->video_data ? asset->frame_rate :
377                                 asset->audio_data ? asset->sample_rate : 0;
378                         if( rate > 0 )
379                                 position += asset->tcstart / rate;
380                 }
381
382                 if(lock_window) gui->lock_window("VWindow::update_position");
383                 gui->clock->update(position);
384                 if(lock_window) gui->unlock_window();
385         }
386 }
387
388
389
390
391
392 int VWindow::update_position(double position)
393 {
394         EDL *edl = get_edl();
395         if(edl)
396         {
397                 gui->unlock_window();
398
399                 playback_engine->interrupt_playback(1);
400
401                 position = mwindow->edl->align_to_frame(position, 0);
402                 position = MAX(0, position);
403
404                 edl->local_session->set_selectionstart(position);
405                 edl->local_session->set_selectionend(position);
406
407                 gui->lock_window("VWindow::update_position 1");
408                 update_position(CHANGE_NONE, 0, 1, 0);
409         }
410
411         return 1;
412 }
413
414 void VWindow::set_inpoint()
415 {
416         EDL *edl = get_edl();
417         if(edl)
418         {
419                 edl->set_inpoint(edl->local_session->get_selectionstart(1));
420                 gui->timebar->update(1);
421         }
422 }
423
424 void VWindow::set_outpoint()
425 {
426         EDL *edl = get_edl();
427         if(edl)
428         {
429                 edl->set_outpoint(edl->local_session->get_selectionstart(1));
430                 gui->timebar->update(1);
431         }
432 }
433
434 void VWindow::clear_inpoint()
435 {
436         EDL *edl = get_edl();
437         if(edl)
438         {
439                 edl->local_session->unset_inpoint();
440                 gui->timebar->update(1);
441         }
442 }
443
444 void VWindow::clear_outpoint()
445 {
446         EDL *edl = get_edl();
447         if(edl)
448         {
449                 edl->local_session->unset_outpoint();
450                 gui->timebar->update(1);
451         }
452 }
453
454 void VWindow::copy()
455 {
456         EDL *edl = get_edl();
457         if(edl)
458         {
459                 double start = edl->local_session->get_selectionstart();
460                 double end = edl->local_session->get_selectionend();
461                 FileXML file;
462                 edl->copy(start,
463                         end,
464                         0,
465                         0,
466                         0,
467                         &file,
468                         "",
469                         1);
470                 const char *file_string = file.string();
471                 long file_length = strlen(file_string);
472                 mwindow->gui->lock_window();
473                 mwindow->gui->get_clipboard()->to_clipboard(file_string, file_length,
474                         SECONDARY_SELECTION);
475                 mwindow->gui->get_clipboard()->to_clipboard(file_string, file_length,
476                         BC_PRIMARY_SELECTION);
477                 mwindow->gui->unlock_window();
478         }
479 }
480
481 void VWindow::splice_selection()
482 {
483 }
484
485 void VWindow::overwrite_selection()
486 {
487 }
488