r851: Merge 2.1:
[cinelerra_cv/ct.git] / cinelerra / mwindowmove.C
blobb48d2aed2a8c0b4696f27fa52c75367f588abe75
1 #include "clip.h"
2 #include "cplayback.h"
3 #include "cwindow.h"
4 #include "cwindowgui.h"
5 #include "edits.h"
6 #include "edl.h"
7 #include "edlsession.h"
8 #include "labels.h"
9 #include "localsession.h"
10 #include "maincursor.h"
11 #include "mainsession.h"
12 #include "mtimebar.h"
13 #include "mwindow.h"
14 #include "mwindowgui.h"
15 #include "patchbay.h"
16 #include "playbackengine.h"
17 #include "plugin.h"
18 #include "samplescroll.h"
19 #include "trackcanvas.h"
20 #include "tracks.h"
21 #include "transportque.h"
22 #include "zoombar.h"
25 void MWindow::update_plugins()
27 // Show plugins which are visible and hide plugins which aren't
28 // Update plugin pointers in plugin servers
32 int MWindow::expand_sample(double fixed_sample)
34         if(gui)
35         {
36                 if(edl->local_session->zoom_sample < 0x100000)
37                 {
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                         }
52                         
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()
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 // Adjust min and max
181         edl->tracks->get_automation_extents(&min, &max, start, end);
182 //printf("MWindow::fit_autos %f %f\n", min, max);
184 // Pad
185         float range = max - min;
186 // No automation visible
187         if(range < 0.001)
188         {
189                 min -= 1;
190                 max += 1;
191         }
192         float pad = range * 0.33;
193         min -= pad;
194         max += pad;
195         edl->local_session->automation_min = min;
196         edl->local_session->automation_max = max;
198 // Show range in zoombar
199         gui->zoombar->update();
201 // Draw
202         gui->canvas->draw_overlays();
203         gui->canvas->flash();
207 void MWindow::expand_autos()
209         float range = edl->local_session->automation_max - 
210                 edl->local_session->automation_min;
211         float center = range / 2 + 
212                 edl->local_session->automation_min;
213         if(EQUIV(range, 0)) range = 0.002;
214         edl->local_session->automation_min = center - range;
215         edl->local_session->automation_max = center + range;
216         gui->zoombar->update_autozoom();
217         gui->canvas->draw_overlays();
218         gui->canvas->flash();
221 void MWindow::shrink_autos()
223         float range = edl->local_session->automation_max - 
224                 edl->local_session->automation_min;
225         float center = range / 2 + 
226                 edl->local_session->automation_min;
227         float new_range = range / 4;
228         edl->local_session->automation_min = center - new_range;
229         edl->local_session->automation_max = center + new_range;
230         gui->zoombar->update_autozoom();
231         gui->canvas->draw_overlays();
232         gui->canvas->flash();
236 void MWindow::zoom_amp(int64_t zoom_amp)
238         edl->local_session->zoom_y = zoom_amp;
239         gui->canvas->draw(0, 0);
240         gui->canvas->flash();
241         gui->patchbay->update();
242         gui->flush();
245 void MWindow::zoom_track(int64_t zoom_track)
247         edl->local_session->zoom_y = (int64_t)((float)edl->local_session->zoom_y * 
248                 zoom_track / 
249                 edl->local_session->zoom_track);
250         CLAMP(edl->local_session->zoom_y, MIN_AMP_ZOOM, MAX_AMP_ZOOM);
251         edl->local_session->zoom_track = zoom_track;
252         trackmovement(edl->local_session->track_start);
253 //printf("MWindow::zoom_track %d %d\n", edl->local_session->zoom_y, edl->local_session->zoom_track);
256 void MWindow::trackmovement(int track_start)
258         edl->local_session->track_start = track_start;
259         if(edl->local_session->track_start < 0) edl->local_session->track_start = 0;
260         edl->tracks->update_y_pixels(theme);
261         gui->get_scrollbars();
262         gui->canvas->draw(0, 0);
263         gui->patchbay->update();
264         gui->canvas->flash();
265         gui->flush();
268 void MWindow::move_up(int64_t distance)
270         if(!gui->trackscroll) return;
271         if(distance == 0) distance = edl->local_session->zoom_track;
272         edl->local_session->track_start -= distance;
273         trackmovement(edl->local_session->track_start);
276 void MWindow::move_down(int64_t distance)
278         if(!gui->trackscroll) return;
279         if(distance == 0) distance = edl->local_session->zoom_track;
280         edl->local_session->track_start += distance;
281         trackmovement(edl->local_session->track_start);
284 int MWindow::goto_end()
286         int64_t old_view_start = edl->local_session->view_start;
288         if(edl->tracks->total_length() > (double)gui->canvas->get_w() * 
289                 edl->local_session->zoom_sample / 
290                 edl->session->sample_rate)
291         {
292                 edl->local_session->view_start = 
293                         Units::round(edl->tracks->total_length() * 
294                                 edl->session->sample_rate /
295                                 edl->local_session->zoom_sample - 
296                                 gui->canvas->get_w() / 
297                                 2);
298         }
299         else
300         {
301                 edl->local_session->view_start = 0;
302         }
304         if(gui->shift_down())
305         {
306                 edl->local_session->set_selectionend(edl->tracks->total_length());
307         }
308         else
309         {
310                 edl->local_session->set_selectionstart(edl->tracks->total_length());
311                 edl->local_session->set_selectionend(edl->tracks->total_length());
312         }
314         if(edl->local_session->view_start != old_view_start) 
315                 samplemovement(edl->local_session->view_start);
317         update_plugin_guis();
318         gui->patchbay->update();
319         gui->cursor->update();
320         gui->canvas->activate();
321         gui->zoombar->update();
322         cwindow->update(1, 0, 0, 0, 0);
323         return 0;
326 int MWindow::goto_start()
328         int64_t old_view_start = edl->local_session->view_start;
330         edl->local_session->view_start = 0;
331         if(gui->shift_down())
332         {
333                 edl->local_session->set_selectionstart(0);
334         }
335         else
336         {
337                 edl->local_session->set_selectionstart(0);
338                 edl->local_session->set_selectionend(0);
339         }
341         if(edl->local_session->view_start != old_view_start)
342                 samplemovement(edl->local_session->view_start);
344         update_plugin_guis();
345         gui->patchbay->update();
346         gui->cursor->update();
347         gui->canvas->activate();
348         gui->zoombar->update();
349         cwindow->update(1, 0, 0, 0, 0);
350         return 0;
353 int MWindow::samplemovement(int64_t view_start)
355         edl->local_session->view_start = view_start;
356         if(edl->local_session->view_start < 0) edl->local_session->view_start = 0;
357         gui->canvas->draw();
358         gui->cursor->show();
359         gui->canvas->flash();
360         gui->timebar->update();
361         gui->zoombar->update();
363         if(gui->samplescroll) gui->samplescroll->set_position();
364         return 0;
367 int MWindow::move_left(int64_t distance)
369         if(!distance) 
370                 distance = gui->canvas->get_w() / 
371                         10;
372         edl->local_session->view_start -= distance;
373         if(edl->local_session->view_start < 0) edl->local_session->view_start = 0;
374         samplemovement(edl->local_session->view_start);
375         return 0;
378 int MWindow::move_right(int64_t distance)
380         if(!distance) 
381                 distance = gui->canvas->get_w() / 
382                         10;
383         edl->local_session->view_start += distance;
384         samplemovement(edl->local_session->view_start);
385         return 0;
388 void MWindow::select_all()
390         edl->local_session->set_selectionstart(0);
391         edl->local_session->set_selectionend(edl->tracks->total_length());
392         gui->update(0, 1, 1, 1, 0, 1, 0);
393         gui->canvas->activate();
394         cwindow->update(1, 0, 0);
397 int MWindow::next_label()
399         Label *current = edl->labels->next_label(
400                         edl->local_session->get_selectionstart(1));
402         if(current)
403         {
405                 edl->local_session->set_selectionend(current->position);
406                 if(!gui->shift_down()) 
407                         edl->local_session->set_selectionstart(
408                                 edl->local_session->get_selectionend(1));
410                 if(edl->local_session->get_selectionend(1) >= 
411                         (double)edl->local_session->view_start *
412                         edl->local_session->zoom_sample /
413                         edl->session->sample_rate + 
414                         gui->canvas->time_visible() ||
415                         edl->local_session->get_selectionend(1) < (double)edl->local_session->view_start *
416                         edl->local_session->zoom_sample /
417                         edl->session->sample_rate)
418                 {
419                         samplemovement((int64_t)(edl->local_session->get_selectionend(1) *
420                                 edl->session->sample_rate /
421                                 edl->local_session->zoom_sample - 
422                                 gui->canvas->get_w() / 
423                                 2));
424                         cwindow->update(1, 0, 0, 0, 0);
425                 }
426                 else
427                 {
428                         update_plugin_guis();
429                         gui->patchbay->update();
430                         gui->timebar->update();
431                         gui->cursor->hide(0);
432                         gui->cursor->draw(1);
433                         gui->zoombar->update();
434                         gui->canvas->flash();
435                         gui->flush();
436                         cwindow->update(1, 0, 0);
437                 }
438         }
439         else
440         {
441                 goto_end();
442         }
443         return 0;
446 int MWindow::prev_label()
448         Label *current = edl->labels->prev_label(
449                         edl->local_session->get_selectionstart(1));;
451         if(current)
452         {
453                 edl->local_session->set_selectionstart(current->position);
454                 if(!gui->shift_down()) 
455                         edl->local_session->set_selectionend(edl->local_session->get_selectionstart(1));
457 // Scroll the display
458                 if(edl->local_session->get_selectionstart(1) >= edl->local_session->view_start *
459                         edl->local_session->zoom_sample /
460                         edl->session->sample_rate + 
461                         gui->canvas->time_visible() 
462                 ||
463                         edl->local_session->get_selectionstart(1) < edl->local_session->view_start *
464                         edl->local_session->zoom_sample /
465                         edl->session->sample_rate)
466                 {
467                         samplemovement((int64_t)(edl->local_session->get_selectionstart(1) *
468                                 edl->session->sample_rate /
469                                 edl->local_session->zoom_sample - 
470                                 gui->canvas->get_w() / 
471                                 2));
472                         cwindow->update(1, 0, 0, 0, 0);
473                 }
474                 else
475 // Don't scroll the display
476                 {
477                         update_plugin_guis();
478                         gui->patchbay->update();
479                         gui->timebar->update();
480                         gui->cursor->hide(0);
481                         gui->cursor->draw(1);
482                         gui->zoombar->update();
483                         gui->canvas->flash();
484                         gui->flush();
485                         cwindow->update(1, 0, 0);
486                 }
487         }
488         else
489         {
490                 goto_start();
491         }
492         return 0;
500 int MWindow::next_edit_handle()
502         double position = edl->local_session->get_selectionend(1);
503         double new_position = INFINITY;
504 // Test for edit handles after cursor position
505         for (Track *track = edl->tracks->first; track; track = track->next)
506         {
507                 if (track->record)
508                 {
509                         for (Edit *edit = track->edits->first; edit; edit = edit->next)
510                         {
511                                 double edit_end = track->from_units(edit->startproject + edit->length);
512                                 if (edit_end > position && edit_end < new_position)
513                                         new_position = edit_end;
514                         }
515                 }
516         }
518         if(new_position != INFINITY)
519         {
521                 edl->local_session->set_selectionend(new_position);
522                 if(!gui->shift_down()) 
523                         edl->local_session->set_selectionstart(
524                                 edl->local_session->get_selectionend(1));
526                 if(edl->local_session->get_selectionend(1) >= 
527                         (double)edl->local_session->view_start *
528                         edl->local_session->zoom_sample /
529                         edl->session->sample_rate + 
530                         gui->canvas->time_visible() ||
531                         edl->local_session->get_selectionend(1) < (double)edl->local_session->view_start *
532                         edl->local_session->zoom_sample /
533                         edl->session->sample_rate)
534                 {
535                         samplemovement((int64_t)(edl->local_session->get_selectionend(1) *
536                                 edl->session->sample_rate /
537                                 edl->local_session->zoom_sample - 
538                                 gui->canvas->get_w() / 
539                                 2));
540                         cwindow->update(1, 0, 0, 0, 0);
541                 }
542                 else
543                 {
544                         update_plugin_guis();
545                         gui->patchbay->update();
546                         gui->timebar->update();
547                         gui->cursor->hide(0);
548                         gui->cursor->draw(1);
549                         gui->zoombar->update();
550                         gui->canvas->flash();
551                         gui->flush();
552                         cwindow->update(1, 0, 0);
553                 }
554         }
555         else
556         {
557                 goto_end();
558         }
559         return 0;
562 int MWindow::prev_edit_handle()
564         double position = edl->local_session->get_selectionstart(1);
565         double new_position = -1;
566 // Test for edit handles before cursor position
567         for (Track *track = edl->tracks->first; track; track = track->next)
568         {
569                 if (track->record)
570                 {
571                         for (Edit *edit = track->edits->first; edit; edit = edit->next)
572                         {
573                                 double edit_end = track->from_units(edit->startproject);
574                                 if (edit_end < position && edit_end > new_position)
575                                         new_position = edit_end;
576                         }
577                 }
578         }
580         if(new_position != -1)
581         {
583                 edl->local_session->set_selectionstart(new_position);
584                 if(!gui->shift_down()) 
585                         edl->local_session->set_selectionend(edl->local_session->get_selectionstart(1));
587 // Scroll the display
588                 if(edl->local_session->get_selectionstart(1) >= edl->local_session->view_start *
589                         edl->local_session->zoom_sample /
590                         edl->session->sample_rate + 
591                         gui->canvas->time_visible() 
592                 ||
593                         edl->local_session->get_selectionstart(1) < edl->local_session->view_start *
594                         edl->local_session->zoom_sample /
595                         edl->session->sample_rate)
596                 {
597                         samplemovement((int64_t)(edl->local_session->get_selectionstart(1) *
598                                 edl->session->sample_rate /
599                                 edl->local_session->zoom_sample - 
600                                 gui->canvas->get_w() / 
601                                 2));
602                         cwindow->update(1, 0, 0, 0, 0);
603                 }
604                 else
605 // Don't scroll the display
606                 {
607                         update_plugin_guis();
608                         gui->patchbay->update();
609                         gui->timebar->update();
610                         gui->cursor->hide(0);
611                         gui->cursor->draw(1);
612                         gui->zoombar->update();
613                         gui->canvas->flash();
614                         gui->flush();
615                         cwindow->update(1, 0, 0);
616                 }
617         }
618         else
619         {
620                 goto_start();
621         }
622         return 0;
632 int MWindow::expand_y()
634         int result = edl->local_session->zoom_y * 2;
635         result = MIN(result, MAX_AMP_ZOOM);
636         zoom_amp(result);
637         gui->zoombar->update();
638         return 0;
641 int MWindow::zoom_in_y()
643         int result = edl->local_session->zoom_y / 2;
644         result = MAX(result, MIN_AMP_ZOOM);
645         zoom_amp(result);
646         gui->zoombar->update();
647         return 0;
650 int MWindow::expand_t()
652         int result = edl->local_session->zoom_track * 2;
653         result = MIN(result, MAX_TRACK_ZOOM);
654         zoom_track(result);
655         gui->zoombar->update();
656         return 0;
659 int MWindow::zoom_in_t()
661         int result = edl->local_session->zoom_track / 2;
662         result = MAX(result, MIN_TRACK_ZOOM);
663         zoom_track(result);
664         gui->zoombar->update();
665         return 0;