tweak zoom/fullscr to remember cwdw scale after fullscr
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / tracks.C
1 /*
2  * CINELERRA
3  * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #include "atrack.h"
22 #include "automation.h"
23 #include "clip.h"
24 #include "bchash.h"
25 #include "edit.h"
26 #include "edits.h"
27 #include "edl.h"
28 #include "edlsession.h"
29 #include "file.h"
30 #include "filexml.h"
31 #include "intauto.h"
32 #include "intautos.h"
33 #include "localsession.h"
34 #include "module.h"
35 #include "panauto.h"
36 #include "panautos.h"
37 #include "patchbay.h"
38 #include "mainsession.h"
39 #include "strack.h"
40 #include "theme.h"
41 #include "track.h"
42 #include "trackcanvas.h"
43 #include "tracks.h"
44 #include "transportque.inc"
45 #include "vtrack.h"
46 #include <string.h>
47
48 Tracks::Tracks(EDL *edl)
49  : List<Track>()
50 {
51         this->edl = edl;
52 }
53
54 Tracks::Tracks()
55  : List<Track>()
56 {
57 }
58
59
60 Tracks::~Tracks()
61 {
62         delete_all_tracks();
63 }
64
65
66
67
68
69 void Tracks::equivalent_output(Tracks *tracks, double *result)
70 {
71         if(total_playable_vtracks() != tracks->total_playable_vtracks())
72         {
73                 *result = 0;
74         }
75         else
76         {
77                 Track *current = first;
78                 Track *that_current = tracks->first;
79                 while(current || that_current)
80                 {
81 // Get next video track
82                         while(current && current->data_type != TRACK_VIDEO)
83                                 current = NEXT;
84
85                         while(that_current && that_current->data_type != TRACK_VIDEO)
86                                 that_current = that_current->next;
87
88 // One doesn't exist but the other does
89                         if((!current && that_current) ||
90                                 (current && !that_current))
91                         {
92                                 *result = 0;
93                                 break;
94                         }
95                         else
96 // Both exist
97                         if(current && that_current)
98                         {
99                                 current->equivalent_output(that_current, result);
100                                 current = NEXT;
101                                 that_current = that_current->next;
102                         }
103                 }
104         }
105 }
106
107
108 void Tracks::clear_selected_edits()
109 {
110         for( Track *track=first; track; track=track->next ) {
111                 for( Edit *edit=track->edits->first; edit; edit=edit->next )
112                         edit->is_selected = 0;
113         }
114 }
115
116 void Tracks::select_affected_edits(double position, Track *start_track, int sense)
117 {
118         for( Track *track=start_track; track; track=track->next ) {
119                 if( !track->record ) continue;
120                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
121                         if( edit->silence() ) continue;
122                         double startproject = track->from_units(edit->startproject);
123                         if( edl->equivalent(startproject, position) ) {
124                                 edit->is_selected = sense >= 0 ? sense :
125                                         edit->is_selected ? 0 : 1;
126                                 break;
127                         }
128                 }
129         }
130 }
131
132 void Tracks::get_selected_edits(ArrayList<Edit*> *drag_edits)
133 {
134         drag_edits->remove_all();
135         for( Track *track=first; track; track=track->next ) {
136                 if( !track->record ) continue;
137                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
138                         if( !edit->is_selected ) continue;
139                         drag_edits->append(edit);
140                 }
141         }
142 }
143
144 void Tracks::get_automation_extents(float *min,
145         float *max,
146         double start,
147         double end,
148         int autogrouptype)
149 {
150         *min = 0;
151         *max = 0;
152         int coords_undefined = 1;
153         for(Track *current = first; current; current = NEXT)
154         {
155                 if(current->record)
156                 {
157                         current->automation->get_extents(min,
158                                 max,
159                                 &coords_undefined,
160                                 current->to_units(start, 0),
161                                 current->to_units(end, 1),
162                                 autogrouptype);
163                 }
164         }
165 }
166
167
168 void Tracks::copy_from(Tracks *tracks)
169 {
170         Track *new_track = 0;
171
172         delete_all_tracks();
173         int solo_track_id = tracks->edl->local_session->solo_track_id;
174
175         for(Track *current = tracks->first; current; current = NEXT)
176         {
177                 switch(current->data_type)
178                 {
179                 case TRACK_AUDIO:
180                         new_track = add_audio_track(0, 0);
181                         break;
182                 case TRACK_VIDEO:
183                         new_track = add_video_track(0, 0);
184                         break;
185                 case TRACK_SUBTITLE:
186                         new_track = add_subttl_track(0, 0);
187                         break;
188                 default:
189                         continue;
190                 }
191                 new_track->copy_from(current);
192
193                 if( current->get_id() == solo_track_id )
194                         edl->local_session->solo_track_id = new_track->get_id();
195         }
196 }
197
198 Tracks& Tracks::operator=(Tracks &tracks)
199 {
200 printf("Tracks::operator= 1\n");
201         copy_from(&tracks);
202         return *this;
203 }
204
205 int Tracks::load(FileXML *xml,
206         int &track_offset,
207         uint32_t load_flags)
208 {
209 // add the appropriate type of track
210         char string[BCTEXTLEN];
211         Track *track = 0;
212         string[0] = 0;
213
214         xml->tag.get_property("TYPE", string);
215
216         if((load_flags & LOAD_ALL) == LOAD_ALL ||
217                 (load_flags & LOAD_EDITS)) {
218                 if(!strcmp(string, "VIDEO")) {
219                         track = add_video_track(0, 0);
220                 }
221                 else if(!strcmp(string, "SUBTTL")) {
222                         track = add_subttl_track(0, 0);
223                 }
224                 else {
225                         track = add_audio_track(0, 0);    // default to audio
226                 }
227         }
228         else {
229                 track = get_item_number(track_offset++);
230         }
231
232 // load it
233         if( track ) track->load(xml, track_offset, load_flags);
234
235         return 0;
236 }
237
238 Track* Tracks::add_audio_track(int above, Track *dst_track)
239 {
240         ATrack* new_track = new ATrack(edl, this);
241         if(!dst_track)
242         {
243                 dst_track = (above ? first : last);
244         }
245
246         if(above)
247         {
248                 insert_before(dst_track, (Track*)new_track);
249         }
250         else
251         {
252                 insert_after(dst_track, (Track*)new_track);
253 // Shift effects referenced below the destination track
254         }
255
256 // Shift effects referenced below the new track
257         for(Track *track = last;
258                 track && track != new_track;
259                 track = track->previous)
260         {
261                 change_modules(number_of(track) - 1, number_of(track), 0);
262         }
263
264
265         new_track->create_objects();
266         new_track->set_default_title();
267
268         int current_pan = 0;
269         for(Track *current = first;
270                 current != (Track*)new_track;
271                 current = NEXT)
272         {
273                 if(current->data_type == TRACK_AUDIO) current_pan++;
274                 if(current_pan >= edl->session->audio_channels) current_pan = 0;
275         }
276
277
278
279         PanAuto* pan_auto =
280                 (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
281         pan_auto->values[current_pan] = 1.0;
282
283         BC_Pan::calculate_stick_position(edl->session->audio_channels,
284                 edl->session->achannel_positions,
285                 pan_auto->values,
286                 MAX_PAN,
287                 PAN_RADIUS,
288                 pan_auto->handle_x,
289                 pan_auto->handle_y);
290         return new_track;
291 }
292
293 Track* Tracks::add_video_track(int above, Track *dst_track)
294 {
295         VTrack* new_track = new VTrack(edl, this);
296         if(!dst_track)
297                 dst_track = (above ? first : last);
298         if(above)
299                 insert_before(dst_track, (Track*)new_track);
300         else
301                 insert_after(dst_track, (Track*)new_track);
302
303         for(Track *track = last; track && track != new_track; track = track->previous)
304                 change_modules(number_of(track) - 1, number_of(track), 0);
305
306         new_track->create_objects();
307         new_track->set_default_title();
308         return new_track;
309 }
310
311
312 Track* Tracks::add_subttl_track(int above, Track *dst_track)
313 {
314         STrack* new_track = new STrack(edl, this);
315         if(!dst_track)
316                 dst_track = (above ? first : last);
317
318         if(above)
319                 insert_before(dst_track, (Track*)new_track);
320         else
321                 insert_after(dst_track, (Track*)new_track);
322
323         for(Track *track = last; track && track != new_track; track = track->previous)
324                 change_modules(number_of(track) - 1, number_of(track), 0);
325
326         new_track->create_objects();
327         new_track->set_default_title();
328 //      new_track->paste_silence(0,total_length(),0);
329         return new_track;
330 }
331
332
333 int Tracks::delete_track(Track *track)
334 {
335         if (!track)
336                 return 0;
337
338         int old_location = number_of(track);
339         detach_shared_effects(old_location);
340
341 // Shift effects referencing effects below the deleted track
342         for(Track *current = track;
343                 current;
344                 current = NEXT)
345         {
346                 change_modules(number_of(current), number_of(current) - 1, 0);
347         }
348         if(track) delete track;
349
350         return 0;
351 }
352
353 int Tracks::detach_shared_effects(int module)
354 {
355         for(Track *current = first; current; current = NEXT)
356         {
357                 current->detach_shared_effects(module);
358         }
359
360         return 0;
361  }
362
363 int Tracks::total_of(int type)
364 {
365         int result = 0;
366
367         for(Track *current = first; current; current = NEXT)
368         {
369                 long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
370                 Auto *mute_keyframe = 0;
371                 current->automation->autos[AUTOMATION_MUTE]->
372                         get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe);
373                 IntAuto *mute_auto = (IntAuto *)mute_keyframe;
374
375                 result +=
376                         (current->play && type == PLAY) ||
377                         (current->record && type == RECORD) ||
378                         (current->gang && type == GANG) ||
379                         (current->draw && type == DRAW) ||
380                         (mute_auto->value && type == MUTE) ||
381                         (current->expand_view && type == EXPAND);
382         }
383         return result;
384 }
385
386 int Tracks::recordable_audio_tracks()
387 {
388         int result = 0;
389         for(Track *current = first; current; current = NEXT)
390                 if(current->data_type == TRACK_AUDIO && current->record) result++;
391         return result;
392 }
393
394 int Tracks::recordable_video_tracks()
395 {
396         int result = 0;
397         for(Track *current = first; current; current = NEXT)
398         {
399                 if(current->data_type == TRACK_VIDEO && current->record) result++;
400         }
401         return result;
402 }
403
404
405 int Tracks::playable_audio_tracks()
406 {
407         int result = 0;
408
409         for(Track *current = first; current; current = NEXT)
410         {
411                 if(current->data_type == TRACK_AUDIO && current->play)
412                 {
413                         result++;
414                 }
415         }
416
417         return result;
418 }
419
420 int Tracks::playable_video_tracks()
421 {
422         int result = 0;
423
424         for(Track *current = first; current; current = NEXT)
425         {
426                 if(current->data_type == TRACK_VIDEO && current->play)
427                 {
428                         result++;
429                 }
430         }
431         return result;
432 }
433
434 int Tracks::total_audio_tracks()
435 {
436         int result = 0;
437         for(Track *current = first; current; current = NEXT)
438                 if(current->data_type == TRACK_AUDIO) result++;
439         return result;
440 }
441
442 int Tracks::total_video_tracks()
443 {
444         int result = 0;
445         for(Track *current = first; current; current = NEXT)
446                 if(current->data_type == TRACK_VIDEO) result++;
447         return result;
448 }
449
450 double Tracks::total_playable_length()
451 {
452         double total = 0;
453         for(Track *current = first; current; current = NEXT)
454         {
455                 if( current->play )
456                 {
457                         double length = current->get_length();
458                         if(length > total) total = length;
459                 }
460         }
461         return total;
462 }
463
464 double Tracks::total_recordable_length()
465 {
466         double total = -1;
467         for(Track *current = first; current; current = NEXT)
468         {
469                 if(current->record)
470                 {
471                         double length = current->get_length();
472                         if(length > total) total = length;
473                 }
474         }
475         return total;
476 }
477
478 double Tracks::total_length()
479 {
480         double total = 0;
481         for(Track *current = first; current; current = NEXT)
482         {
483                 double length = current->get_length();
484                 if(length > total) total = length;
485         }
486         return total;
487 }
488
489 double Tracks::total_audio_length()
490 {
491         double total = 0;
492         for(Track *current = first; current; current = NEXT)
493         {
494                 if(current->data_type == TRACK_AUDIO &&
495                         current->get_length() > total) total = current->get_length();
496         }
497         return total;
498 }
499
500 double Tracks::total_video_length()
501 {
502         double total = 0;
503         for(Track *current = first; current; current = NEXT)
504         {
505                 if(current->data_type == TRACK_VIDEO &&
506                         current->get_length() > total) total = current->get_length();
507         }
508         return total;
509 }
510
511 double Tracks::total_length_framealigned(double fps)
512 {
513         if (total_audio_tracks() && total_video_tracks())
514                 return MIN(floor(total_audio_length() * fps), floor(total_video_length() * fps)) / fps;
515
516         if (total_audio_tracks())
517                 return floor(total_audio_length() * fps) / fps;
518
519         if (total_video_tracks())
520                 return floor(total_video_length() * fps) / fps;
521
522         return 0;
523 }
524
525 void Tracks::translate_fauto_xy(int fauto, float dx, float dy, int all)
526 {
527         Track *track = first;
528         for( ; track; track=track->next ) {
529                 if( !all && !track->record ) continue;
530                 if( track->data_type != TRACK_VIDEO ) continue;
531                 ((VTrack*)track)->translate(fauto, dx, dy, all);
532         }
533 }
534
535 void Tracks::translate_projector(float dx, float dy, int all)
536 {
537         translate_fauto_xy(AUTOMATION_PROJECTOR_X, dx, dy, all);
538 }
539
540 void Tracks::translate_camera(float dx, float dy, int all)
541 {
542         translate_fauto_xy(AUTOMATION_CAMERA_X, dx, dy, all);
543 }
544
545 void Tracks::crop_resize(float x, float y, float z)
546 {
547         float ctr_x = edl->session->output_w / 2.;
548         float ctr_y = edl->session->output_h / 2.;
549         Track *track = first;
550         for( ; track; track=track->next ) {
551                 if( !track->record ) continue;
552                 if( track->data_type != TRACK_VIDEO ) continue;
553                 float px, py, pz;
554                 track->get_projector(px, py, pz);
555                 float old_x = px + ctr_x;
556                 float old_y = py + ctr_y;
557                 float nx = (old_x - x) * z;
558                 float ny = (old_y - y) * z;
559                 track->set_projector(nx, ny, pz * z);
560         }
561 }
562
563 void Tracks::crop_shrink(float x, float y, float z)
564 {
565         float ctr_x = edl->session->output_w / 2.;
566         float ctr_y = edl->session->output_h / 2.;
567         Track *track = first;
568         for( ; track; track=track->next ) {
569                 if( !track->record ) continue;
570                 if( track->data_type != TRACK_VIDEO ) continue;
571                 float cx, cy, cz, px, py, pz;
572                 track->get_camera(cx, cy, cz);
573                 track->get_projector(px, py, pz);
574                 float dx = x - (px + ctr_x);
575                 float dy = y - (py + ctr_y);
576                 cz *= pz;
577                 cx += dx / cz;  cy += dy / cz;
578                 track->set_camera(cx, cy, cz * z);
579                 px += dx;  py += dy;
580                 track->set_projector(px, py, 1 / z);
581         }
582 }
583
584 void Tracks::update_y_pixels(Theme *theme)
585 {
586 //      int y = -edl->local_session->track_start;
587         int y = 0;
588         for(Track *current = first; current; current = NEXT)
589         {
590 //printf("Tracks::update_y_pixels %d\n", y);
591                 current->y_pixel = y;
592                 y += current->vertical_span(theme);
593         }
594 }
595
596 int Tracks::dump(FILE *fp)
597 {
598         for(Track* current = first; current; current = NEXT)
599         {
600                 fprintf(fp,"  Track: %p\n", current);
601                 current->dump(fp);
602                 fprintf(fp,"\n");
603         }
604         return 0;
605 }
606
607 void Tracks::select_all(int type,
608                 int value)
609 {
610         for(Track* current = first; current; current = NEXT)
611         {
612                 double position = edl->local_session->get_selectionstart(1);
613
614                 if(type == PLAY) current->play = value;
615                 if(type == RECORD) current->record = value;
616                 if(type == GANG) current->gang = value;
617                 if(type == DRAW) current->draw = value;
618
619                 if(type == MUTE)
620                 {
621                         ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
622                 }
623
624                 if(type == EXPAND) current->expand_view = value;
625         }
626 }
627
628 // ===================================== file operations
629
630 int Tracks::popup_transition(int cursor_x, int cursor_y)
631 {
632         int result = 0;
633         for(Track* current = first; current && !result; current = NEXT)
634         {
635                 result = current->popup_transition(cursor_x, cursor_y);
636         }
637         return result;
638 }
639
640
641 int Tracks::change_channels(int oldchannels, int newchannels)
642 {
643         for(Track *current = first; current; current = NEXT)
644         { current->change_channels(oldchannels, newchannels); }
645         return 0;
646 }
647
648
649
650 int Tracks::totalpixels()
651 {
652         int result = 0;
653         for(Track* current = first; current; current = NEXT)
654         {
655                 result += edl->local_session->zoom_track;
656         }
657         return result;
658 }
659
660 int Tracks::number_of(Track *track)
661 {
662         int i = 0;
663         for(Track *current = first; current && current != track; current = NEXT)
664         {
665                 i++;
666         }
667         return i;
668 }
669
670 Track* Tracks::number(int number)
671 {
672         Track *current;
673         int i = 0;
674         for(current = first; current && i < number; current = NEXT)
675         {
676                 i++;
677         }
678         return current;
679 }
680
681 Track* Tracks::get_track_by_id(int id)
682 {
683         Track *track = edl->tracks->first;
684         while( track && track->get_id() != id ) track = track->next;
685         return track;
686 }
687
688 int Tracks::total_playable_vtracks()
689 {
690         int result = 0;
691         for(Track *current = first; current; current = NEXT)
692         {
693                 if(current->data_type == TRACK_VIDEO && current->play) result++;
694         }
695         return result;
696 }
697
698 int Tracks::plugin_exists(Plugin *plugin)
699 {
700         for(Track *track = first; track; track = track->next)
701         {
702                 if(track->plugin_exists(plugin)) return 1;
703         }
704         return 0;
705 }
706
707 int Tracks::track_exists(Track *track)
708 {
709         for(Track *current = first; current; current = NEXT)
710         {
711                 if(current == track) return 1;
712         }
713         return 0;
714 }
715
716 int Tracks::new_group(int id)
717 {
718         int count = 0;
719         for( Track *track=first; track; track=track->next ) {
720                 if( !track->record ) continue;
721                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
722                         if( edit->group_id > 0 ) continue;
723                         if( !edit->is_selected ) continue;
724                         edit->group_id = id;
725                         ++count;
726                 }
727         }
728         return count;
729 }
730
731 int Tracks::set_group_selected(int id, int v)
732 {
733         int count = 0;
734         for( Track *track=first; track; track=track->next ) {
735                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
736                         if( edit->group_id != id ) continue;
737                         edit->is_selected = v >= 0 ? v : !edit->is_selected ? 1 : 0;
738                         ++count;
739                 }
740         }
741         return count;
742 }
743
744 int Tracks::del_group(int id)
745 {
746         int count = 0;
747         for( Track *track=first; track; track=track->next ) {
748                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
749                         if( edit->group_id != id ) continue;
750                         edit->is_selected = 1;
751                         edit->group_id = 0;
752                         ++count;
753                 }
754         }
755         return count;
756 }
757
758 Track *Tracks::get(int idx, int data_type)
759 {
760         for(Track *current = first; current; current = NEXT)
761         {
762                 if( current->data_type != data_type ) continue;
763                 if( --idx < 0 ) return current;
764         }
765         return 0;
766 }
767