group selection rework, rm inv title clr, add titlebar alpha textbox, default proxy...
[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                         double startproject = track->from_units(edit->startproject);
122                         if( edl->equivalent(startproject, position) ) {
123                                 edit->is_selected = sense >= 0 ? sense :
124                                         edit->is_selected ? 0 : 1;
125                                 break;
126                         }
127                 }
128         }
129 }
130
131 void Tracks::get_selected_edits(ArrayList<Edit*> *drag_edits)
132 {
133         drag_edits->remove_all();
134         for( Track *track=first; track; track=track->next ) {
135                 if( !track->record ) continue;
136                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
137                         if( !edit->is_selected ) continue;
138                         drag_edits->append(edit);
139                 }
140         }
141 }
142
143 void Tracks::get_automation_extents(float *min,
144         float *max,
145         double start,
146         double end,
147         int autogrouptype)
148 {
149         *min = 0;
150         *max = 0;
151         int coords_undefined = 1;
152         for(Track *current = first; current; current = NEXT)
153         {
154                 if(current->record)
155                 {
156                         current->automation->get_extents(min,
157                                 max,
158                                 &coords_undefined,
159                                 current->to_units(start, 0),
160                                 current->to_units(end, 1),
161                                 autogrouptype);
162                 }
163         }
164 }
165
166
167 void Tracks::copy_from(Tracks *tracks)
168 {
169         Track *new_track = 0;
170
171         delete_all_tracks();
172         for(Track *current = tracks->first; current; current = NEXT)
173         {
174                 switch(current->data_type)
175                 {
176                 case TRACK_AUDIO:
177                         new_track = add_audio_track(0, 0);
178                         break;
179                 case TRACK_VIDEO:
180                         new_track = add_video_track(0, 0);
181                         break;
182                 case TRACK_SUBTITLE:
183                         new_track = add_subttl_track(0, 0);
184                         break;
185                 default:
186                         continue;
187                 }
188                 new_track->copy_from(current);
189         }
190 }
191
192 Tracks& Tracks::operator=(Tracks &tracks)
193 {
194 printf("Tracks::operator= 1\n");
195         copy_from(&tracks);
196         return *this;
197 }
198
199 int Tracks::load(FileXML *xml,
200         int &track_offset,
201         uint32_t load_flags)
202 {
203 // add the appropriate type of track
204         char string[BCTEXTLEN];
205         Track *track = 0;
206         string[0] = 0;
207
208         xml->tag.get_property("TYPE", string);
209
210         if((load_flags & LOAD_ALL) == LOAD_ALL ||
211                 (load_flags & LOAD_EDITS)) {
212                 if(!strcmp(string, "VIDEO")) {
213                         track = add_video_track(0, 0);
214                 }
215                 else if(!strcmp(string, "SUBTTL")) {
216                         track = add_subttl_track(0, 0);
217                 }
218                 else {
219                         track = add_audio_track(0, 0);    // default to audio
220                 }
221         }
222         else {
223                 track = get_item_number(track_offset++);
224         }
225
226 // load it
227         if( track ) track->load(xml, track_offset, load_flags);
228
229         return 0;
230 }
231
232 Track* Tracks::add_audio_track(int above, Track *dst_track)
233 {
234         ATrack* new_track = new ATrack(edl, this);
235         if(!dst_track)
236         {
237                 dst_track = (above ? first : last);
238         }
239
240         if(above)
241         {
242                 insert_before(dst_track, (Track*)new_track);
243         }
244         else
245         {
246                 insert_after(dst_track, (Track*)new_track);
247 // Shift effects referenced below the destination track
248         }
249
250 // Shift effects referenced below the new track
251         for(Track *track = last;
252                 track && track != new_track;
253                 track = track->previous)
254         {
255                 change_modules(number_of(track) - 1, number_of(track), 0);
256         }
257
258
259         new_track->create_objects();
260         new_track->set_default_title();
261
262         int current_pan = 0;
263         for(Track *current = first;
264                 current != (Track*)new_track;
265                 current = NEXT)
266         {
267                 if(current->data_type == TRACK_AUDIO) current_pan++;
268                 if(current_pan >= edl->session->audio_channels) current_pan = 0;
269         }
270
271
272
273         PanAuto* pan_auto =
274                 (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
275         pan_auto->values[current_pan] = 1.0;
276
277         BC_Pan::calculate_stick_position(edl->session->audio_channels,
278                 edl->session->achannel_positions,
279                 pan_auto->values,
280                 MAX_PAN,
281                 PAN_RADIUS,
282                 pan_auto->handle_x,
283                 pan_auto->handle_y);
284         return new_track;
285 }
286
287 Track* Tracks::add_video_track(int above, Track *dst_track)
288 {
289         VTrack* new_track = new VTrack(edl, this);
290         if(!dst_track)
291                 dst_track = (above ? first : last);
292         if(above)
293                 insert_before(dst_track, (Track*)new_track);
294         else
295                 insert_after(dst_track, (Track*)new_track);
296
297         for(Track *track = last; track && track != new_track; track = track->previous)
298                 change_modules(number_of(track) - 1, number_of(track), 0);
299
300         new_track->create_objects();
301         new_track->set_default_title();
302         return new_track;
303 }
304
305
306 Track* Tracks::add_subttl_track(int above, Track *dst_track)
307 {
308         STrack* new_track = new STrack(edl, this);
309         if(!dst_track)
310                 dst_track = (above ? first : last);
311
312         if(above)
313                 insert_before(dst_track, (Track*)new_track);
314         else
315                 insert_after(dst_track, (Track*)new_track);
316
317         for(Track *track = last; track && track != new_track; track = track->previous)
318                 change_modules(number_of(track) - 1, number_of(track), 0);
319
320         new_track->create_objects();
321         new_track->set_default_title();
322 //      new_track->paste_silence(0,total_length(),0);
323         return new_track;
324 }
325
326
327 int Tracks::delete_track(Track *track)
328 {
329         if (!track)
330                 return 0;
331
332         int old_location = number_of(track);
333         detach_shared_effects(old_location);
334
335 // Shift effects referencing effects below the deleted track
336         for(Track *current = track;
337                 current;
338                 current = NEXT)
339         {
340                 change_modules(number_of(current), number_of(current) - 1, 0);
341         }
342         if(track) delete track;
343
344         return 0;
345 }
346
347 int Tracks::detach_shared_effects(int module)
348 {
349         for(Track *current = first; current; current = NEXT)
350         {
351                 current->detach_shared_effects(module);
352         }
353
354         return 0;
355  }
356
357 int Tracks::total_of(int type)
358 {
359         int result = 0;
360
361         for(Track *current = first; current; current = NEXT)
362         {
363                 long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
364                 Auto *mute_keyframe = 0;
365                 current->automation->autos[AUTOMATION_MUTE]->
366                         get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe);
367                 IntAuto *mute_auto = (IntAuto *)mute_keyframe;
368
369                 result +=
370                         (current->play && type == PLAY) ||
371                         (current->record && type == RECORD) ||
372                         (current->gang && type == GANG) ||
373                         (current->draw && type == DRAW) ||
374                         (mute_auto->value && type == MUTE) ||
375                         (current->expand_view && type == EXPAND);
376         }
377         return result;
378 }
379
380 int Tracks::recordable_audio_tracks()
381 {
382         int result = 0;
383         for(Track *current = first; current; current = NEXT)
384                 if(current->data_type == TRACK_AUDIO && current->record) result++;
385         return result;
386 }
387
388 int Tracks::recordable_video_tracks()
389 {
390         int result = 0;
391         for(Track *current = first; current; current = NEXT)
392         {
393                 if(current->data_type == TRACK_VIDEO && current->record) result++;
394         }
395         return result;
396 }
397
398
399 int Tracks::playable_audio_tracks()
400 {
401         int result = 0;
402
403         for(Track *current = first; current; current = NEXT)
404         {
405                 if(current->data_type == TRACK_AUDIO && current->play)
406                 {
407                         result++;
408                 }
409         }
410
411         return result;
412 }
413
414 int Tracks::playable_video_tracks()
415 {
416         int result = 0;
417
418         for(Track *current = first; current; current = NEXT)
419         {
420                 if(current->data_type == TRACK_VIDEO && current->play)
421                 {
422                         result++;
423                 }
424         }
425         return result;
426 }
427
428 int Tracks::total_audio_tracks()
429 {
430         int result = 0;
431         for(Track *current = first; current; current = NEXT)
432                 if(current->data_type == TRACK_AUDIO) result++;
433         return result;
434 }
435
436 int Tracks::total_video_tracks()
437 {
438         int result = 0;
439         for(Track *current = first; current; current = NEXT)
440                 if(current->data_type == TRACK_VIDEO) result++;
441         return result;
442 }
443
444 double Tracks::total_playable_length()
445 {
446         double total = 0;
447         for(Track *current = first; current; current = NEXT)
448         {
449                 if( current->play )
450                 {
451                         double length = current->get_length();
452                         if(length > total) total = length;
453                 }
454         }
455         return total;
456 }
457
458 double Tracks::total_recordable_length()
459 {
460         double total = -1;
461         for(Track *current = first; current; current = NEXT)
462         {
463                 if(current->record)
464                 {
465                         double length = current->get_length();
466                         if(length > total) total = length;
467                 }
468         }
469         return total;
470 }
471
472 double Tracks::total_length()
473 {
474         double total = 0;
475         for(Track *current = first; current; current = NEXT)
476         {
477                 double length = current->get_length();
478                 if(length > total) total = length;
479         }
480         return total;
481 }
482
483 double Tracks::total_audio_length()
484 {
485         double total = 0;
486         for(Track *current = first; current; current = NEXT)
487         {
488                 if(current->data_type == TRACK_AUDIO &&
489                         current->get_length() > total) total = current->get_length();
490         }
491         return total;
492 }
493
494 double Tracks::total_video_length()
495 {
496         double total = 0;
497         for(Track *current = first; current; current = NEXT)
498         {
499                 if(current->data_type == TRACK_VIDEO &&
500                         current->get_length() > total) total = current->get_length();
501         }
502         return total;
503 }
504
505 double Tracks::total_length_framealigned(double fps)
506 {
507         if (total_audio_tracks() && total_video_tracks())
508                 return MIN(floor(total_audio_length() * fps), floor(total_video_length() * fps)) / fps;
509
510         if (total_audio_tracks())
511                 return floor(total_audio_length() * fps) / fps;
512
513         if (total_video_tracks())
514                 return floor(total_video_length() * fps) / fps;
515
516         return 0;
517 }
518
519 void Tracks::translate_projector(float offset_x, float offset_y)
520 {
521         for(Track *current = first; current; current = NEXT)
522         {
523                 if(current->data_type == TRACK_VIDEO)
524                 {
525                         ((VTrack*)current)->translate(offset_x, offset_y, 0);
526                 }
527         }
528 }
529
530 void Tracks::update_y_pixels(Theme *theme)
531 {
532 //      int y = -edl->local_session->track_start;
533         int y = 0;
534         for(Track *current = first; current; current = NEXT)
535         {
536 //printf("Tracks::update_y_pixels %d\n", y);
537                 current->y_pixel = y;
538                 y += current->vertical_span(theme);
539         }
540 }
541
542 int Tracks::dump(FILE *fp)
543 {
544         for(Track* current = first; current; current = NEXT)
545         {
546                 fprintf(fp,"  Track: %p\n", current);
547                 current->dump(fp);
548                 fprintf(fp,"\n");
549         }
550         return 0;
551 }
552
553 void Tracks::select_all(int type,
554                 int value)
555 {
556         for(Track* current = first; current; current = NEXT)
557         {
558                 double position = edl->local_session->get_selectionstart(1);
559
560                 if(type == PLAY) current->play = value;
561                 if(type == RECORD) current->record = value;
562                 if(type == GANG) current->gang = value;
563                 if(type == DRAW) current->draw = value;
564
565                 if(type == MUTE)
566                 {
567                         ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
568                 }
569
570                 if(type == EXPAND) current->expand_view = value;
571         }
572 }
573
574 // ===================================== file operations
575
576 int Tracks::popup_transition(int cursor_x, int cursor_y)
577 {
578         int result = 0;
579         for(Track* current = first; current && !result; current = NEXT)
580         {
581                 result = current->popup_transition(cursor_x, cursor_y);
582         }
583         return result;
584 }
585
586
587 int Tracks::change_channels(int oldchannels, int newchannels)
588 {
589         for(Track *current = first; current; current = NEXT)
590         { current->change_channels(oldchannels, newchannels); }
591         return 0;
592 }
593
594
595
596 int Tracks::totalpixels()
597 {
598         int result = 0;
599         for(Track* current = first; current; current = NEXT)
600         {
601                 result += edl->local_session->zoom_track;
602         }
603         return result;
604 }
605
606 int Tracks::number_of(Track *track)
607 {
608         int i = 0;
609         for(Track *current = first; current && current != track; current = NEXT)
610         {
611                 i++;
612         }
613         return i;
614 }
615
616 Track* Tracks::number(int number)
617 {
618         Track *current;
619         int i = 0;
620         for(current = first; current && i < number; current = NEXT)
621         {
622                 i++;
623         }
624         return current;
625 }
626
627
628 int Tracks::total_playable_vtracks()
629 {
630         int result = 0;
631         for(Track *current = first; current; current = NEXT)
632         {
633                 if(current->data_type == TRACK_VIDEO && current->play) result++;
634         }
635         return result;
636 }
637
638 int Tracks::plugin_exists(Plugin *plugin)
639 {
640         for(Track *track = first; track; track = track->next)
641         {
642                 if(track->plugin_exists(plugin)) return 1;
643         }
644         return 0;
645 }
646
647 int Tracks::track_exists(Track *track)
648 {
649         for(Track *current = first; current; current = NEXT)
650         {
651                 if(current == track) return 1;
652         }
653         return 0;
654 }
655
656 int Tracks::new_group(int id)
657 {
658         int count = 0;
659         for( Track *track=first; track; track=track->next ) {
660                 if( !track->record ) continue;
661                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
662                         if( !edit->is_selected ) continue;
663                         edit->group_id = id;
664                         ++count;
665                 }
666         }
667         return count;
668 }
669
670 int Tracks::set_group_selected(int id, int v)
671 {
672         int count = 0;
673         for( Track *track=first; track; track=track->next ) {
674                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
675                         if( edit->group_id != id ) continue;
676                         edit->is_selected = v >= 0 ? v : !edit->is_selected ? 1 : 0;
677                         ++count;
678                 }
679         }
680         return count;
681 }
682
683 int Tracks::del_group(int id)
684 {
685         int count = 0;
686         for( Track *track=first; track; track=track->next ) {
687                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
688                         if( edit->group_id != id ) continue;
689                         edit->is_selected = 1;
690                         edit->group_id = 0;
691                         ++count;
692                 }
693         }
694         return count;
695 }
696
697 Track *Tracks::get(int idx, int data_type)
698 {
699         for(Track *current = first; current; current = NEXT)
700         {
701                 if( current->data_type != data_type ) continue;
702                 if( --idx < 0 ) return current;
703         }
704         return 0;
705 }
706