r956: README.BUILD - add more library recommendations
[cinelerra_cv/ct.git] / cinelerra / mwindowmove.C
blob7dae8788cd446114355532aae33868b218dc2f48
1 #include "automation.h"
2 #include "clip.h"
3 #include "cplayback.h"
4 #include "cwindow.h"
5 #include "cwindowgui.h"
6 #include "edits.h"
7 #include "edl.h"
8 #include "edlsession.h"
9 #include "labels.h"
10 #include "localsession.h"
11 #include "maincursor.h"
12 #include "mainsession.h"
13 #include "mtimebar.h"
14 #include "mwindow.h"
15 #include "mwindowgui.h"
16 #include "patchbay.h"
17 #include "playbackengine.h"
18 #include "plugin.h"
19 #include "samplescroll.h"
20 #include "trackcanvas.h"
21 #include "tracks.h"
22 #include "transportque.h"
23 #include "zoombar.h"
26 void MWindow::update_plugins()
28 // Show plugins which are visible and hide plugins which aren't
29 // Update plugin pointers in plugin servers
33 int MWindow::expand_sample(double fixed_sample)
35         if(gui)
36         {
37                 if(edl->local_session->zoom_sample < 0x100000)
38                 {
39                         int64_t new_zoom_sample = edl->local_session->zoom_sample * 2;
40                         int64_t view_start;
41                         if (fixed_sample < 0)
42                                 view_start = -1;
43                         else
44                         {
45                                 double viewstart_position = (double)edl->local_session->view_start * 
46                                         edl->local_session->zoom_sample /
47                                         edl->session->sample_rate * 2 - fixed_sample;
48                                 view_start = Units::round(viewstart_position *
49                                         edl->session->sample_rate /
50                                         new_zoom_sample);
51                         }
53                         zoom_sample(new_zoom_sample, view_start);
54                 }
55         }
56         return 0;
59 int MWindow::zoom_in_sample(double fixed_sample)
61         if(gui)
62         {
63                 if(edl->local_session->zoom_sample > 1)
64                 {
65                         int64_t new_zoom_sample = edl->local_session->zoom_sample / 2;
66                         int64_t view_start;
67                         if (fixed_sample < 0)
68                                 view_start = -1;
69                         else
70                         {
71                                 double viewstart_position = (double)edl->local_session->view_start * 
72                                         edl->local_session->zoom_sample /
73                                         edl->session->sample_rate;
74                                 viewstart_position = viewstart_position + (fixed_sample - viewstart_position) / 2;
76                                 view_start = Units::round(viewstart_position *
77                                         edl->session->sample_rate /
78                                         new_zoom_sample);
79                         }
80                         
81                         zoom_sample(new_zoom_sample, view_start);
82                 }
83         }
84         return 0;
87 int MWindow::zoom_sample(int64_t zoom_sample, int64_t view_start)
89         CLIP(zoom_sample, 1, 0x100000);
90         edl->local_session->zoom_sample = zoom_sample;
91         if (view_start < 0)
92                 find_cursor();
93         else
94                 edl->local_session->view_start = view_start;
95                         
96         gui->get_scrollbars();
98         if(!gui->samplescroll) edl->local_session->view_start = 0;
99         samplemovement(edl->local_session->view_start);
100         gui->zoombar->sample_zoom->update(zoom_sample);
101         return 0;
104 void MWindow::find_cursor()
106 //      if((edl->local_session->selectionend > 
107 //              (double)gui->canvas->get_w() * 
108 //              edl->local_session->zoom_sample / 
109 //              edl->session->sample_rate) ||
110 //              (edl->local_session->selectionstart > 
111 //              (double)gui->canvas->get_w() * 
112 //              edl->local_session->zoom_sample / 
113 //              edl->session->sample_rate))
114 //      {
115                 edl->local_session->view_start = 
116                         Units::round((edl->local_session->get_selectionend(1) + 
117                         edl->local_session->get_selectionstart(1)) / 
118                         2 *
119                         edl->session->sample_rate /
120                         edl->local_session->zoom_sample - 
121                         (double)gui->canvas->get_w() / 
122                         2);
123 //      }
124 //      else
125 //              edl->local_session->view_start = 0;
127 //printf("MWindow::find_cursor %f\n", edl->local_session->view_start);
128         if(edl->local_session->view_start < 0) edl->local_session->view_start = 0;
132 void MWindow::fit_selection()
134         if(EQUIV(edl->local_session->get_selectionstart(1),
135                 edl->local_session->get_selectionend(1)))
136         {
137                 double total_samples = edl->tracks->total_length() * 
138                         edl->session->sample_rate;
139                 for(edl->local_session->zoom_sample = 1; 
140                         gui->canvas->get_w() * edl->local_session->zoom_sample < total_samples; 
141                         edl->local_session->zoom_sample *= 2)
142                         ;
143         }
144         else
145         {
146                 double total_samples = (edl->local_session->get_selectionend(1) - 
147                         edl->local_session->get_selectionstart(1)) * 
148                         edl->session->sample_rate;
149                 for(edl->local_session->zoom_sample = 1; 
150                         gui->canvas->get_w() * edl->local_session->zoom_sample < total_samples; 
151                         edl->local_session->zoom_sample *= 2)
152                         ;
153         }
155         edl->local_session->zoom_sample = MIN(0x100000, 
156                 edl->local_session->zoom_sample);
157         zoom_sample(edl->local_session->zoom_sample);
161 void MWindow::fit_autos(int doall)
163         float min = 0, max = 0;
164         double start, end;
166 // Test all autos
167         if(EQUIV(edl->local_session->get_selectionstart(1),
168                 edl->local_session->get_selectionend(1)))
169         {
170                 start = 0;
171                 end = edl->tracks->total_length();
172         }
173         else
174 // Test autos in highlighting only
175         {
176                 start = edl->local_session->get_selectionstart(1);
177                 end = edl->local_session->get_selectionend(1);
178         }
180         int forstart = edl->local_session->zoombar_showautotype;
181         int forend   = edl->local_session->zoombar_showautotype + 1;
182         
183         if (doall) {
184                 forstart = 0;
185                 forend   = AUTOGROUPTYPE_COUNT;
186         }
188         for (int i = forstart; i < forend; i++)
189         {
190 // Adjust min and max
191                 edl->tracks->get_automation_extents(&min, &max, start, end, i);
192 //printf("MWindow::fit_autos %d %f %f results in ", i, min, max);
194                 float range = max - min;
195                 switch (i) 
196                 {
197                 case AUTOGROUPTYPE_AUDIO_FADE:
198                 case AUTOGROUPTYPE_VIDEO_FADE:
199                         if (range < 0.1) {
200                                 min = MIN(min, edl->local_session->automation_mins[i]);
201                                 max = MAX(max, edl->local_session->automation_maxs[i]);
202                         }
203                         break;
204                 case AUTOGROUPTYPE_ZOOM:
205                         if (range < 0.001) {
206                                 min = floor(min*50)/100;
207                                 max = floor(max*200)/100;
208                         }
209                         break;
210                 case AUTOGROUPTYPE_X:
211                 case AUTOGROUPTYPE_Y:
212                         if (range < 5) {
213                                 min = floor((min+max)/2) - 50;
214                                 max = floor((min+max)/2) + 50;
215                         }
216                         break;
217                 }
218 //printf("%f %f\n", min, max);
219                 if (!Automation::autogrouptypes_fixedrange[i]) 
220                 {
221                         edl->local_session->automation_mins[i] = min;
222                         edl->local_session->automation_maxs[i] = max;
223                 }
224         }
226 // Show range in zoombar
227         gui->zoombar->update();
229 // Draw
230         gui->canvas->draw_overlays();
231         gui->canvas->flash();
235 void MWindow::change_currentautorange(int autogrouptype, int increment, int changemax) {
236         float val;
237         if (changemax) {
238                 val = edl->local_session->automation_maxs[autogrouptype];
239         } else {
240                 val = edl->local_session->automation_mins[autogrouptype];
241         }
243         if (increment) 
244         {
245                 switch (autogrouptype) {
246                 case AUTOGROUPTYPE_AUDIO_FADE:
247                         val += 2;
248                         break;
249                 case AUTOGROUPTYPE_VIDEO_FADE:
250                         val += 1;
251                         break;
252                 case AUTOGROUPTYPE_ZOOM:
253                         if (val == 0) 
254                                 val = 0.001;
255                         else 
256                                 val = val*2;
257                         break;
258                 case AUTOGROUPTYPE_X:
259                 case AUTOGROUPTYPE_Y:
260                         val = floor(val + 5);
261                         break;
262                 }
263         } 
264         else 
265         { // decrement
266                 switch (autogrouptype) {
267                 case AUTOGROUPTYPE_AUDIO_FADE:
268                         val -= 2;
269                         break;
270                 case AUTOGROUPTYPE_VIDEO_FADE:
271                         val -= 1;
272                         break;
273                 case AUTOGROUPTYPE_ZOOM:
274                         if (val > 0) val = val/2;
275                         break;
276                 case AUTOGROUPTYPE_X:
277                 case AUTOGROUPTYPE_Y:
278                         val = floor(val-5);
279                         break;
280                 }
281         }
283         AUTOMATIONVIEWCLAMPS(val, autogrouptype);
285         if (changemax) {
286                 if (val > edl->local_session->automation_mins[autogrouptype])
287                         edl->local_session->automation_maxs[autogrouptype] = val;
288         }
289         else
290         {
291                 if (val < edl->local_session->automation_maxs[autogrouptype])
292                         edl->local_session->automation_mins[autogrouptype] = val;
293         }
297 void MWindow::expand_autos(int changeall, int domin, int domax)
299         if (changeall)
300                 for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
301                         if (domin) change_currentautorange(i, 1, 0);
302                         if (domax) change_currentautorange(i, 1, 1);
303                 }
304         else
305         {
306                 if (domin) change_currentautorange(edl->local_session->zoombar_showautotype, 1, 0);
307                 if (domax) change_currentautorange(edl->local_session->zoombar_showautotype, 1, 1);
308         }
309         gui->zoombar->update_autozoom();
310         gui->canvas->draw_overlays();
311         gui->patchbay->update();
312         gui->canvas->flash();
315 void MWindow::shrink_autos(int changeall, int domin, int domax)
317         if (changeall)
318                 for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
319                         if (domin) change_currentautorange(i, 0, 0);
320                         if (domax) change_currentautorange(i, 0, 1);
321                 }
322         else
323         {
324                 if (domin) change_currentautorange(edl->local_session->zoombar_showautotype, 0, 0);
325                 if (domax) change_currentautorange(edl->local_session->zoombar_showautotype, 0, 1);
326         }
327         gui->zoombar->update_autozoom();
328         gui->canvas->draw_overlays();
329         gui->patchbay->update();
330         gui->canvas->flash();
334 void MWindow::zoom_amp(int64_t zoom_amp)
336         edl->local_session->zoom_y = zoom_amp;
337         gui->canvas->draw(0, 0);
338         gui->canvas->flash();
339         gui->patchbay->update();
340         gui->flush();
343 void MWindow::zoom_track(int64_t zoom_track)
345         edl->local_session->zoom_y = (int64_t)((float)edl->local_session->zoom_y * 
346                 zoom_track / 
347                 edl->local_session->zoom_track);
348         CLAMP(edl->local_session->zoom_y, MIN_AMP_ZOOM, MAX_AMP_ZOOM);
349         edl->local_session->zoom_track = zoom_track;
350         trackmovement(edl->local_session->track_start);
351 //printf("MWindow::zoom_track %d %d\n", edl->local_session->zoom_y, edl->local_session->zoom_track);
354 void MWindow::trackmovement(int track_start)
356         edl->local_session->track_start = track_start;
357         if(edl->local_session->track_start < 0) edl->local_session->track_start = 0;
358         edl->tracks->update_y_pixels(theme);
359         gui->get_scrollbars();
360         gui->canvas->draw(0, 0);
361         gui->patchbay->update();
362         gui->canvas->flash();
363         gui->flush();
366 void MWindow::move_up(int64_t distance)
368         if(!gui->trackscroll) return;
369         if(distance == 0) distance = edl->local_session->zoom_track;
370         edl->local_session->track_start -= distance;
371         trackmovement(edl->local_session->track_start);
374 void MWindow::move_down(int64_t distance)
376         if(!gui->trackscroll) return;
377         if(distance == 0) distance = edl->local_session->zoom_track;
378         edl->local_session->track_start += distance;
379         trackmovement(edl->local_session->track_start);
382 int MWindow::goto_end()
384         int64_t old_view_start = edl->local_session->view_start;
386         if(edl->tracks->total_length() > (double)gui->canvas->get_w() * 
387                 edl->local_session->zoom_sample / 
388                 edl->session->sample_rate)
389         {
390                 edl->local_session->view_start = 
391                         Units::round(edl->tracks->total_length() * 
392                                 edl->session->sample_rate /
393                                 edl->local_session->zoom_sample - 
394                                 gui->canvas->get_w() / 
395                                 2);
396         }
397         else
398         {
399                 edl->local_session->view_start = 0;
400         }
402         if(gui->shift_down())
403         {
404                 edl->local_session->set_selectionend(edl->tracks->total_length());
405         }
406         else
407         {
408                 edl->local_session->set_selectionstart(edl->tracks->total_length());
409                 edl->local_session->set_selectionend(edl->tracks->total_length());
410         }
412         if(edl->local_session->view_start != old_view_start) 
413                 samplemovement(edl->local_session->view_start);
415         update_plugin_guis();
416         gui->patchbay->update();
417         gui->cursor->update();
418         gui->canvas->activate();
419         gui->zoombar->update();
420         cwindow->update(1, 0, 0, 0, 0);
421         return 0;
424 int MWindow::goto_start()
426         int64_t old_view_start = edl->local_session->view_start;
428         edl->local_session->view_start = 0;
429         if(gui->shift_down())
430         {
431                 edl->local_session->set_selectionstart(0);
432         }
433         else
434         {
435                 edl->local_session->set_selectionstart(0);
436                 edl->local_session->set_selectionend(0);
437         }
439         if(edl->local_session->view_start != old_view_start)
440                 samplemovement(edl->local_session->view_start);
442         update_plugin_guis();
443         gui->patchbay->update();
444         gui->cursor->update();
445         gui->canvas->activate();
446         gui->zoombar->update();
447         cwindow->update(1, 0, 0, 0, 0);
448         return 0;
451 int MWindow::samplemovement(int64_t view_start)
453         edl->local_session->view_start = view_start;
454         if(edl->local_session->view_start < 0) edl->local_session->view_start = 0;
455         gui->canvas->draw();
456         gui->cursor->show();
457         gui->canvas->flash();
458         gui->timebar->update();
459         gui->zoombar->update();
461         if(gui->samplescroll) gui->samplescroll->set_position();
462         return 0;
465 int MWindow::move_left(int64_t distance)
467         if(!distance) 
468                 distance = gui->canvas->get_w() / 
469                         10;
470         edl->local_session->view_start -= distance;
471         if(edl->local_session->view_start < 0) edl->local_session->view_start = 0;
472         samplemovement(edl->local_session->view_start);
473         return 0;
476 int MWindow::move_right(int64_t distance)
478         if(!distance) 
479                 distance = gui->canvas->get_w() / 
480                         10;
481         edl->local_session->view_start += distance;
482         samplemovement(edl->local_session->view_start);
483         return 0;
486 void MWindow::select_all()
488         edl->local_session->set_selectionstart(0);
489         edl->local_session->set_selectionend(edl->tracks->total_length());
490         gui->update(0, 1, 1, 1, 0, 1, 0);
491         gui->canvas->activate();
492         cwindow->update(1, 0, 0);
495 int MWindow::next_label(int shift_down)
497         Label *current = edl->labels->next_label(
498                         edl->local_session->get_selectionstart(1));
500         if(current)
501         {
503                 edl->local_session->set_selectionend(current->position);
504                 if(!shift_down) 
505                         edl->local_session->set_selectionstart(
506                                 edl->local_session->get_selectionend(1));
508                 update_plugin_guis();
509                 if(edl->local_session->get_selectionend(1) >= 
510                         (double)edl->local_session->view_start *
511                         edl->local_session->zoom_sample /
512                         edl->session->sample_rate + 
513                         gui->canvas->time_visible() ||
514                         edl->local_session->get_selectionend(1) < (double)edl->local_session->view_start *
515                         edl->local_session->zoom_sample /
516                         edl->session->sample_rate)
517                 {
518                         samplemovement((int64_t)(edl->local_session->get_selectionend(1) *
519                                 edl->session->sample_rate /
520                                 edl->local_session->zoom_sample - 
521                                 gui->canvas->get_w() / 
522                                 2));
523                         cwindow->update(1, 0, 0, 0, 0);
524                 }
525                 else
526                 {
527                         gui->patchbay->update();
528                         gui->timebar->update();
529                         gui->cursor->hide(0);
530                         gui->cursor->draw(1);
531                         gui->zoombar->update();
532                         gui->canvas->flash();
533                         gui->flush();
534                         cwindow->update(1, 0, 0);
535                 }
536         }
537         else
538         {
539                 goto_end();
540         }
541         return 0;
544 int MWindow::prev_label(int shift_down)
546         Label *current = edl->labels->prev_label(
547                         edl->local_session->get_selectionstart(1));;
549         if(current)
550         {
551                 edl->local_session->set_selectionstart(current->position);
552                 if(!shift_down) 
553                         edl->local_session->set_selectionend(edl->local_session->get_selectionstart(1));
555                 update_plugin_guis();
556 // Scroll the display
557                 if(edl->local_session->get_selectionstart(1) >= edl->local_session->view_start *
558                         edl->local_session->zoom_sample /
559                         edl->session->sample_rate + 
560                         gui->canvas->time_visible() 
561                 ||
562                         edl->local_session->get_selectionstart(1) < edl->local_session->view_start *
563                         edl->local_session->zoom_sample /
564                         edl->session->sample_rate)
565                 {
566                         samplemovement((int64_t)(edl->local_session->get_selectionstart(1) *
567                                 edl->session->sample_rate /
568                                 edl->local_session->zoom_sample - 
569                                 gui->canvas->get_w() / 
570                                 2));
571                         cwindow->update(1, 0, 0, 0, 0);
572                 }
573                 else
574 // Don't scroll the display
575                 {
576                         gui->patchbay->update();
577                         gui->timebar->update();
578                         gui->cursor->hide(0);
579                         gui->cursor->draw(1);
580                         gui->zoombar->update();
581                         gui->canvas->flash();
582                         gui->flush();
583                         cwindow->update(1, 0, 0);
584                 }
585         }
586         else
587         {
588                 goto_start();
589         }
590         return 0;
598 int MWindow::next_edit_handle(int shift_down)
600         double position = edl->local_session->get_selectionend(1);
601         Units::fix_double(&position);
602         double new_position = INFINITY;
603 // Test for edit handles after cursor position
604         for (Track *track = edl->tracks->first; track; track = track->next)
605         {
606                 if (track->record)
607                 {
608                         for (Edit *edit = track->edits->first; edit; edit = edit->next)
609                         {
610                                 double edit_end = track->from_units(edit->startproject + edit->length);
611                                 Units::fix_double(&edit_end);
612                                 if (edit_end > position && edit_end < new_position)
613                                         new_position = edit_end;
614                         }
615                 }
616         }
618         if(new_position != INFINITY)
619         {
621                 edl->local_session->set_selectionend(new_position);
622 printf("MWindow::next_edit_handle %d\n", shift_down);
623                 if(!shift_down) 
624                         edl->local_session->set_selectionstart(
625                                 edl->local_session->get_selectionend(1));
627                 update_plugin_guis();
628                 if(edl->local_session->get_selectionend(1) >= 
629                         (double)edl->local_session->view_start *
630                         edl->local_session->zoom_sample /
631                         edl->session->sample_rate + 
632                         gui->canvas->time_visible() ||
633                         edl->local_session->get_selectionend(1) < (double)edl->local_session->view_start *
634                         edl->local_session->zoom_sample /
635                         edl->session->sample_rate)
636                 {
637                         samplemovement((int64_t)(edl->local_session->get_selectionend(1) *
638                                 edl->session->sample_rate /
639                                 edl->local_session->zoom_sample - 
640                                 gui->canvas->get_w() / 
641                                 2));
642                         cwindow->update(1, 0, 0, 0, 0);
643                 }
644                 else
645                 {
646                         gui->patchbay->update();
647                         gui->timebar->update();
648                         gui->cursor->hide(0);
649                         gui->cursor->draw(1);
650                         gui->zoombar->update();
651                         gui->canvas->flash();
652                         gui->flush();
653                         cwindow->update(1, 0, 0);
654                 }
655         }
656         else
657         {
658                 goto_end();
659         }
660         return 0;
663 int MWindow::prev_edit_handle(int shift_down)
665         double position = edl->local_session->get_selectionstart(1);
666         double new_position = -1;
667         Units::fix_double(&position);
668 // Test for edit handles before cursor position
669         for (Track *track = edl->tracks->first; track; track = track->next)
670         {
671                 if (track->record)
672                 {
673                         for (Edit *edit = track->edits->first; edit; edit = edit->next)
674                         {
675                                 double edit_end = track->from_units(edit->startproject);
676                                 Units::fix_double(&edit_end);
677                                 if (edit_end < position && edit_end > new_position)
678                                         new_position = edit_end;
679                         }
680                 }
681         }
683         if(new_position != -1)
684         {
686                 edl->local_session->set_selectionstart(new_position);
687 printf("MWindow::next_edit_handle %d\n", shift_down);
688                 if(!shift_down) 
689                         edl->local_session->set_selectionend(edl->local_session->get_selectionstart(1));
691                 update_plugin_guis();
692 // Scroll the display
693                 if(edl->local_session->get_selectionstart(1) >= edl->local_session->view_start *
694                         edl->local_session->zoom_sample /
695                         edl->session->sample_rate + 
696                         gui->canvas->time_visible() 
697                 ||
698                         edl->local_session->get_selectionstart(1) < edl->local_session->view_start *
699                         edl->local_session->zoom_sample /
700                         edl->session->sample_rate)
701                 {
702                         samplemovement((int64_t)(edl->local_session->get_selectionstart(1) *
703                                 edl->session->sample_rate /
704                                 edl->local_session->zoom_sample - 
705                                 gui->canvas->get_w() / 
706                                 2));
707                         cwindow->update(1, 0, 0, 0, 0);
708                 }
709                 else
710 // Don't scroll the display
711                 {
712                         gui->patchbay->update();
713                         gui->timebar->update();
714                         gui->cursor->hide(0);
715                         gui->cursor->draw(1);
716                         gui->zoombar->update();
717                         gui->canvas->flash();
718                         gui->flush();
719                         cwindow->update(1, 0, 0);
720                 }
721         }
722         else
723         {
724                 goto_start();
725         }
726         return 0;
736 int MWindow::expand_y()
738         int result = edl->local_session->zoom_y * 2;
739         result = MIN(result, MAX_AMP_ZOOM);
740         zoom_amp(result);
741         gui->zoombar->update();
742         return 0;
745 int MWindow::zoom_in_y()
747         int result = edl->local_session->zoom_y / 2;
748         result = MAX(result, MIN_AMP_ZOOM);
749         zoom_amp(result);
750         gui->zoombar->update();
751         return 0;
754 int MWindow::expand_t()
756         int result = edl->local_session->zoom_track * 2;
757         result = MIN(result, MAX_TRACK_ZOOM);
758         zoom_track(result);
759         gui->zoombar->update();
760         return 0;
763 int MWindow::zoom_in_t()
765         int result = edl->local_session->zoom_track / 2;
766         result = MAX(result, MIN_TRACK_ZOOM);
767         zoom_track(result);
768         gui->zoombar->update();
769         return 0;