initial commit
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / zoombar.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "apatchgui.inc"
23 #include "clip.h"
24 #include "edl.h"
25 #include "edlsession.h"
26 #include "language.h"
27 #include "localsession.h"
28 #include "maincursor.h"
29 #include "mwindow.h"
30 #include "mwindowgui.h"
31 #include "mainsession.h"
32 #include "mtimebar.h"
33 #include "preferences.h"
34 #include "theme.h"
35 #include "trackcanvas.h"
36 #include "tracks.h"
37 #include "units.h"
38 #include "vpatchgui.inc"
39 #include "zoombar.h"
40
41
42
43
44 ZoomBar::ZoomBar(MWindow *mwindow, MWindowGUI *gui)
45  : BC_SubWindow(mwindow->theme->mzoom_x,
46         mwindow->theme->mzoom_y,
47         mwindow->theme->mzoom_w,
48         mwindow->theme->mzoom_h)
49 {
50         this->gui = gui;
51         this->mwindow = mwindow;
52         old_position = 0;
53 }
54
55 ZoomBar::~ZoomBar()
56 {
57         delete sample_zoom;
58         delete amp_zoom;
59         delete track_zoom;
60 }
61
62 void ZoomBar::create_objects()
63 {
64         int x = 3;
65         int y = get_h() / 2 -
66                 mwindow->theme->get_image_set("zoombar_menu", 0)[0]->get_h() / 2;
67
68         draw_top_background(get_parent(), 0, 0, get_w(), get_h());
69         sample_zoom = new SampleZoomPanel(mwindow, this, x, y);
70         sample_zoom->create_objects();
71         sample_zoom->set_tooltip(_("Duration visible in the timeline"));
72         x += sample_zoom->get_w();
73         amp_zoom = new AmpZoomPanel(mwindow, this, x, y);
74         amp_zoom->create_objects();
75         amp_zoom->set_tooltip(_("Audio waveform scale"));
76         x += amp_zoom->get_w();
77         track_zoom = new TrackZoomPanel(mwindow, this, x, y);
78         track_zoom->create_objects();
79         track_zoom->set_tooltip(_("Height of tracks in the timeline"));
80         x += track_zoom->get_w() + 10;
81
82         int wid = 120;
83         for( int i=AUTOGROUPTYPE_AUDIO_FADE; i<=AUTOGROUPTYPE_Y; ++i ) {
84                 int ww = BC_GenericButton::calculate_w(this, AutoTypeMenu::to_text(i));
85                 if( ww > wid ) wid = ww;
86         }
87         add_subwindow(auto_type = new AutoTypeMenu(mwindow, this, x, y, wid));
88         auto_type->create_objects();
89         x += auto_type->get_w() + 10;
90 #define DEFAULT_TEXT "000.00 to 000.00"
91         add_subwindow(auto_zoom = new AutoZoom(mwindow, this, x, y, 0));
92         x += auto_zoom->get_w();
93         add_subwindow(auto_zoom_text = new ZoomTextBox(
94                 mwindow,
95                 this,
96                 x,
97                 y,
98                 DEFAULT_TEXT));
99         x += auto_zoom_text->get_w() + 5;
100         add_subwindow(auto_zoom = new AutoZoom(mwindow, this, x, y, 1));
101         update_autozoom();
102         x += auto_zoom->get_w() + 5;
103
104         add_subwindow(from_value = new FromTextBox(mwindow, this, x, y));
105         x += from_value->get_w() + 5;
106         add_subwindow(length_value = new LengthTextBox(mwindow, this, x, y));
107         x += length_value->get_w() + 5;
108         add_subwindow(to_value = new ToTextBox(mwindow, this, x, y));
109         x += to_value->get_w() + 5;
110
111         update_formatting(from_value);
112         update_formatting(length_value);
113         update_formatting(to_value);
114
115         add_subwindow(playback_value = new BC_Title(x, 100, "--", MEDIUMFONT, RED));
116
117         add_subwindow(zoom_value = new BC_Title(x, 100, "--", MEDIUMFONT, BLACK));
118         update();
119 }
120
121
122 void ZoomBar::update_formatting(BC_TextBox *dst)
123 {
124         dst->set_separators(
125                 Units::format_to_separators(mwindow->edl->session->time_format));
126 }
127
128 void ZoomBar::resize_event()
129 {
130         reposition_window(mwindow->theme->mzoom_x, mwindow->theme->mzoom_y,
131                 mwindow->theme->mzoom_w, mwindow->theme->mzoom_h);
132         draw_top_background(get_parent(), 0, 0, get_w(), get_h());
133 }
134
135 void ZoomBar::redraw_time_dependancies()
136 {
137 // Recalculate sample zoom menu
138         sample_zoom->update_menu();
139         sample_zoom->update(mwindow->edl->local_session->zoom_sample);
140         update_formatting(from_value);
141         update_formatting(length_value);
142         update_formatting(to_value);
143         update_autozoom();
144         update_clocks();
145 }
146
147 int ZoomBar::draw()
148 {
149         update();
150         return 0;
151 }
152
153 void ZoomBar::update_autozoom()
154 {
155         char string[BCTEXTLEN];
156         int autogroup_type = mwindow->edl->local_session->zoombar_showautotype;
157         switch( autogroup_type ) {
158         case AUTOGROUPTYPE_AUDIO_FADE:
159         case AUTOGROUPTYPE_VIDEO_FADE:
160                 sprintf(string, "%0.01f to %0.01f\n",
161                         mwindow->edl->local_session->automation_mins[autogroup_type],
162                         mwindow->edl->local_session->automation_maxs[autogroup_type]);
163                 break;
164         case AUTOGROUPTYPE_ZOOM:
165         case AUTOGROUPTYPE_SPEED:
166                 sprintf(string, "%0.03f to %0.03f\n",
167                         mwindow->edl->local_session->automation_mins[autogroup_type],
168                         mwindow->edl->local_session->automation_maxs[autogroup_type]);
169                 break;
170         case AUTOGROUPTYPE_X:
171         case AUTOGROUPTYPE_Y:
172                 sprintf(string, "%0.0f to %.0f\n",
173                         mwindow->edl->local_session->automation_mins[autogroup_type],
174                         mwindow->edl->local_session->automation_maxs[autogroup_type]);
175                 break;
176         }
177         auto_zoom_text->update(string);
178         const char *group_name = AutoTypeMenu::to_text(autogroup_type);
179         auto_type->set_text(group_name);
180 }
181
182 int ZoomBar::update()
183 {
184         sample_zoom->update(mwindow->edl->local_session->zoom_sample);
185         amp_zoom->update(mwindow->edl->local_session->zoom_y);
186         track_zoom->update(mwindow->edl->local_session->zoom_track);
187         update_autozoom();
188         update_clocks();
189         return 0;
190 }
191
192 int ZoomBar::update_clocks()
193 {
194         from_value->update_position(mwindow->edl->local_session->get_selectionstart(1));
195         length_value->update_position(mwindow->edl->local_session->get_selectionend(1) -
196                 mwindow->edl->local_session->get_selectionstart(1));
197         to_value->update_position(mwindow->edl->local_session->get_selectionend(1));
198         return 0;
199 }
200
201 int ZoomBar::update_playback(int64_t new_position)
202 {
203         if(new_position != old_position)
204         {
205                 Units::totext(string, new_position,
206                                 mwindow->edl->session->sample_rate,
207                                 mwindow->edl->session->time_format,
208                                 mwindow->edl->session->frame_rate,
209                                 mwindow->edl->session->frames_per_foot);
210                 playback_value->update(string);
211                 old_position = new_position;
212         }
213         return 0;
214 }
215
216 int ZoomBar::resize_event(int w, int h)
217 {
218 // don't change anything but y and width
219         reposition_window(0, h - this->get_h(), w, this->get_h());
220         return 0;
221 }
222
223
224 // Values for which_one
225 #define SET_FROM 1
226 #define SET_LENGTH 2
227 #define SET_TO 3
228
229
230 int ZoomBar::set_selection(int which_one)
231 {
232         double start_position = mwindow->edl->local_session->get_selectionstart(1);
233         double end_position = mwindow->edl->local_session->get_selectionend(1);
234         double length = end_position - start_position;
235
236 // Fix bogus results
237
238         switch(which_one)
239         {
240                 case SET_LENGTH:
241                         start_position = Units::text_to_seconds(from_value->get_text(),
242                                 mwindow->edl->session->sample_rate,
243                                 mwindow->edl->session->time_format,
244                                 mwindow->edl->session->frame_rate,
245                                 mwindow->edl->session->frames_per_foot);
246                         length = Units::text_to_seconds(length_value->get_text(),
247                                 mwindow->edl->session->sample_rate,
248                                 mwindow->edl->session->time_format,
249                                 mwindow->edl->session->frame_rate,
250                                 mwindow->edl->session->frames_per_foot);
251                         end_position = start_position + length;
252
253                         if(end_position < start_position)
254                         {
255                                 start_position = end_position;
256                                 mwindow->edl->local_session->set_selectionend(
257                                         mwindow->edl->local_session->get_selectionstart(1));
258                         }
259                         break;
260
261                 case SET_FROM:
262                         start_position = Units::text_to_seconds(from_value->get_text(),
263                                 mwindow->edl->session->sample_rate,
264                                 mwindow->edl->session->time_format,
265                                 mwindow->edl->session->frame_rate,
266                                 mwindow->edl->session->frames_per_foot);
267                         end_position = Units::text_to_seconds(to_value->get_text(),
268                                 mwindow->edl->session->sample_rate,
269                                 mwindow->edl->session->time_format,
270                                 mwindow->edl->session->frame_rate,
271                                 mwindow->edl->session->frames_per_foot);
272
273                         if(end_position < start_position)
274                         {
275                                 end_position = start_position;
276                                 mwindow->edl->local_session->set_selectionend(
277                                         mwindow->edl->local_session->get_selectionstart(1));
278                         }
279                         break;
280
281                 case SET_TO:
282                         start_position = Units::text_to_seconds(from_value->get_text(),
283                                 mwindow->edl->session->sample_rate,
284                                 mwindow->edl->session->time_format,
285                                 mwindow->edl->session->frame_rate,
286                                 mwindow->edl->session->frames_per_foot);
287                         end_position = Units::text_to_seconds(to_value->get_text(),
288                                 mwindow->edl->session->sample_rate,
289                                 mwindow->edl->session->time_format,
290                                 mwindow->edl->session->frame_rate,
291                                 mwindow->edl->session->frames_per_foot);
292
293                         if(end_position < start_position)
294                         {
295                                 start_position = end_position;
296                                 mwindow->edl->local_session->set_selectionend(
297                                         mwindow->edl->local_session->get_selectionstart(1));
298                         }
299                         break;
300         }
301
302         mwindow->edl->local_session->set_selectionstart(
303                 mwindow->edl->align_to_frame(start_position, 1));
304         mwindow->edl->local_session->set_selectionend(
305                 mwindow->edl->align_to_frame(end_position, 1));
306
307
308         mwindow->gui->update_timebar_highlights();
309         mwindow->gui->hide_cursor(1);
310         mwindow->gui->show_cursor(1);
311         update();
312         mwindow->sync_parameters(CHANGE_PARAMS);
313         mwindow->gui->flash_canvas(1);
314
315         return 0;
316 }
317
318
319
320
321
322
323
324
325
326
327
328
329 SampleZoomPanel::SampleZoomPanel(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
330  : ZoomPanel(mwindow, zoombar, mwindow->edl->local_session->zoom_sample,
331                 x, y, 110, MIN_ZOOM_TIME, MAX_ZOOM_TIME, ZOOM_TIME)
332 {
333         this->mwindow = mwindow;
334         this->zoombar = zoombar;
335 }
336 int SampleZoomPanel::handle_event()
337 {
338         mwindow->zoom_sample((int64_t)get_value());
339         return 1;
340 }
341
342
343 AmpZoomPanel::AmpZoomPanel(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
344  : ZoomPanel(mwindow, zoombar, mwindow->edl->local_session->zoom_y,
345                 x, y, 80, MIN_AMP_ZOOM, MAX_AMP_ZOOM, ZOOM_LONG)
346 {
347         this->mwindow = mwindow;
348         this->zoombar = zoombar;
349 }
350 int AmpZoomPanel::handle_event()
351 {
352         mwindow->zoom_amp((int64_t)get_value());
353         return 1;
354 }
355
356 TrackZoomPanel::TrackZoomPanel(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
357  : ZoomPanel(mwindow, zoombar, mwindow->edl->local_session->zoom_track,
358                 x, y, 70, MIN_TRACK_ZOOM, MAX_TRACK_ZOOM, ZOOM_LONG)
359 {
360         this->mwindow = mwindow;
361         this->zoombar = zoombar;
362 }
363 int TrackZoomPanel::handle_event()
364 {
365         mwindow->zoom_track((int64_t)get_value());
366         zoombar->amp_zoom->update(mwindow->edl->local_session->zoom_y);
367         return 1;
368 }
369
370
371
372
373 AutoZoom::AutoZoom(MWindow *mwindow, ZoomBar *zoombar, int x, int y, int changemax)
374  : BC_Tumbler(x, y, mwindow->theme->get_image_set("zoombar_tumbler"))
375 {
376         this->mwindow = mwindow;
377         this->zoombar = zoombar;
378         this->changemax = changemax;
379         if (changemax)
380                 set_tooltip(_("Automation range maximum"));
381         else
382                 set_tooltip(_("Automation range minimum"));
383 }
384
385 int AutoZoom::handle_up_event()
386 {
387         mwindow->change_currentautorange(mwindow->edl->local_session->zoombar_showautotype,1,changemax);
388
389         mwindow->gui->zoombar->update_autozoom();
390         mwindow->gui->draw_overlays(0);
391         mwindow->gui->update_patchbay();
392         mwindow->gui->flash_canvas(1);
393         return 1;
394 }
395
396 int AutoZoom::handle_down_event()
397 {
398         mwindow->change_currentautorange(mwindow->edl->local_session->zoombar_showautotype,0,changemax);
399
400         mwindow->gui->zoombar->update_autozoom();
401         mwindow->gui->draw_overlays(0);
402         mwindow->gui->update_patchbay();
403         mwindow->gui->flash_canvas(1);
404         return 1;
405 }
406
407
408
409 AutoTypeMenu::AutoTypeMenu(MWindow *mwindow, ZoomBar *zoombar, int x, int y, int wid)
410         : BC_PopupMenu(x, y, wid, to_text(mwindow->edl->local_session->zoombar_showautotype), 1)
411 {
412         this->mwindow = mwindow;
413         this->zoombar = zoombar;
414         set_tooltip(_("Automation Type"));
415 }
416
417 void AutoTypeMenu::create_objects()
418 {
419         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_AUDIO_FADE)));
420         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_VIDEO_FADE)));
421         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_ZOOM)));
422         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_SPEED)));
423         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_X)));
424         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_Y)));
425 }
426
427 const char* AutoTypeMenu::to_text(int mode)
428 {
429         switch(mode) {
430         case AUTOGROUPTYPE_AUDIO_FADE: return _("Audio Fade:");
431         case AUTOGROUPTYPE_VIDEO_FADE: return _("Video Fade:");
432         case AUTOGROUPTYPE_ZOOM: return _("Zoom:");
433         case AUTOGROUPTYPE_SPEED: return _("Speed:");
434         case AUTOGROUPTYPE_X: return "X:";
435         case AUTOGROUPTYPE_Y: return "Y:";
436         }
437         return "??";
438 }
439
440 int AutoTypeMenu::from_text(char *text)
441 {
442         if(!strcmp(text, to_text(AUTOGROUPTYPE_AUDIO_FADE))) return AUTOGROUPTYPE_AUDIO_FADE;
443         if(!strcmp(text, to_text(AUTOGROUPTYPE_VIDEO_FADE))) return AUTOGROUPTYPE_VIDEO_FADE;
444         if(!strcmp(text, to_text(AUTOGROUPTYPE_ZOOM))) return AUTOGROUPTYPE_ZOOM;
445         if(!strcmp(text, to_text(AUTOGROUPTYPE_SPEED))) return AUTOGROUPTYPE_SPEED;
446         if(!strcmp(text, to_text(AUTOGROUPTYPE_X))) return AUTOGROUPTYPE_X;
447         if(!strcmp(text, to_text(AUTOGROUPTYPE_Y))) return AUTOGROUPTYPE_Y;
448         return AUTOGROUPTYPE_INT255;
449 }
450
451 int AutoTypeMenu::handle_event()
452 {
453         mwindow->edl->local_session->zoombar_showautotype = from_text(this->get_text());
454         this->zoombar->update_autozoom();
455         return 1;
456 }
457
458
459 ZoomTextBox::ZoomTextBox(MWindow *mwindow, ZoomBar *zoombar, int x, int y, const char *text)
460  : BC_TextBox(x, y, 130, 1, text)
461 {
462         this->mwindow = mwindow;
463         this->zoombar = zoombar;
464         set_tooltip(_("Automation range"));
465 }
466
467 int ZoomTextBox::button_press_event()
468 {
469         if (!(get_buttonpress() == 4 || get_buttonpress() == 5)) {
470                 BC_TextBox::button_press_event();
471                 return 0;
472         }
473         if (!is_event_win()) return 0;
474
475         int changemax = 1;
476         if (get_relative_cursor_x() < get_w()/2)
477                 changemax = 0;
478
479         // increment
480         if (get_buttonpress() == 4)
481                 mwindow->change_currentautorange(mwindow->edl->local_session->zoombar_showautotype, 1, changemax);
482
483         // decrement
484         if (get_buttonpress() == 5)
485                 mwindow->change_currentautorange(mwindow->edl->local_session->zoombar_showautotype, 0, changemax);
486
487         mwindow->gui->zoombar->update_autozoom();
488         mwindow->gui->draw_overlays(0);
489         mwindow->gui->update_patchbay();
490         mwindow->gui->flash_canvas(1);
491         return 1;
492 }
493
494 int ZoomTextBox::handle_event()
495 {
496         float min, max;
497         if (sscanf(this->get_text(),"%f to%f",&min, &max) == 2)
498         {
499                 AUTOMATIONVIEWCLAMPS(min, mwindow->edl->local_session->zoombar_showautotype);
500                 AUTOMATIONVIEWCLAMPS(max, mwindow->edl->local_session->zoombar_showautotype);
501                 if (max > min)
502                 {
503                         mwindow->edl->local_session->automation_mins[mwindow->edl->local_session->zoombar_showautotype] = min;
504                         mwindow->edl->local_session->automation_maxs[mwindow->edl->local_session->zoombar_showautotype] = max;
505                         mwindow->gui->zoombar->update_autozoom();
506                         mwindow->gui->draw_overlays(0);
507                         mwindow->gui->update_patchbay();
508                         mwindow->gui->flash_canvas(1);
509                 }
510         }
511         // TODO: Make the text turn red when it's a bad range..
512         return 0;
513 }
514
515
516
517
518
519 FromTextBox::FromTextBox(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
520  : BC_TextBox(x, y, 90, 1, "")
521 {
522         this->mwindow = mwindow;
523         this->zoombar = zoombar;
524         set_tooltip(_("Selection start time"));
525 }
526
527 int FromTextBox::handle_event()
528 {
529         if(get_keypress() == 13)
530         {
531                 zoombar->set_selection(SET_FROM);
532                 return 1;
533         }
534         return 0;
535 }
536
537 int FromTextBox::update_position(double new_position)
538 {
539         Units::totext(string,
540                 new_position,
541                 mwindow->edl->session->time_format,
542                 mwindow->edl->session->sample_rate,
543                 mwindow->edl->session->frame_rate,
544                 mwindow->edl->session->frames_per_foot);
545 //printf("FromTextBox::update_position %f %s\n", new_position, string);
546         update(string);
547         return 0;
548 }
549
550
551
552
553
554
555 LengthTextBox::LengthTextBox(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
556  : BC_TextBox(x, y, 90, 1, "")
557 {
558         this->mwindow = mwindow;
559         this->zoombar = zoombar;
560         set_tooltip(_("Selection length"));
561 }
562
563 int LengthTextBox::handle_event()
564 {
565         if(get_keypress() == 13)
566         {
567                 zoombar->set_selection(SET_LENGTH);
568                 return 1;
569         }
570         return 0;
571 }
572
573 int LengthTextBox::update_position(double new_position)
574 {
575         Units::totext(string,
576                 new_position,
577                 mwindow->edl->session->time_format,
578                 mwindow->edl->session->sample_rate,
579                 mwindow->edl->session->frame_rate,
580                 mwindow->edl->session->frames_per_foot);
581         update(string);
582         return 0;
583 }
584
585
586
587
588
589 ToTextBox::ToTextBox(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
590  : BC_TextBox(x, y, 90, 1, "")
591 {
592         this->mwindow = mwindow;
593         this->zoombar = zoombar;
594         set_tooltip(_("Selection end time"));
595 }
596
597 int ToTextBox::handle_event()
598 {
599         if(get_keypress() == 13)
600         {
601                 zoombar->set_selection(SET_TO);
602                 return 1;
603         }
604         return 0;
605 }
606
607 int ToTextBox::update_position(double new_position)
608 {
609         Units::totext(string, new_position,
610                 mwindow->edl->session->time_format,
611                 mwindow->edl->session->sample_rate,
612                 mwindow->edl->session->frame_rate,
613                 mwindow->edl->session->frames_per_foot);
614         update(string);
615         return 0;
616 }