8dca9e10232fe81c6f7b7115c3142ca299c09b4e
[goodguy/history.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,
206                                 new_position,
207                                 mwindow->edl->session->sample_rate,
208                                 mwindow->edl->session->time_format,
209                                 mwindow->edl->session->frame_rate,
210                                 mwindow->edl->session->frames_per_foot);
211                 playback_value->update(string);
212                 old_position = new_position;
213         }
214         return 0;
215 }
216
217 int ZoomBar::resize_event(int w, int h)
218 {
219 // don't change anything but y and width
220         reposition_window(0, h - this->get_h(), w, this->get_h());
221         return 0;
222 }
223
224
225 // Values for which_one
226 #define SET_FROM 1
227 #define SET_LENGTH 2
228 #define SET_TO 3
229
230
231 int ZoomBar::set_selection(int which_one)
232 {
233         double start_position = mwindow->edl->local_session->get_selectionstart(1);
234         double end_position = mwindow->edl->local_session->get_selectionend(1);
235         double length = end_position - start_position;
236
237 // Fix bogus results
238
239         switch(which_one)
240         {
241                 case SET_LENGTH:
242                         start_position = Units::text_to_seconds(from_value->get_text(),
243                                 mwindow->edl->session->sample_rate,
244                                 mwindow->edl->session->time_format,
245                                 mwindow->edl->session->frame_rate,
246                                 mwindow->edl->session->frames_per_foot);
247                         length = Units::text_to_seconds(length_value->get_text(),
248                                 mwindow->edl->session->sample_rate,
249                                 mwindow->edl->session->time_format,
250                                 mwindow->edl->session->frame_rate,
251                                 mwindow->edl->session->frames_per_foot);
252                         end_position = start_position + length;
253
254                         if(end_position < start_position)
255                         {
256                                 start_position = end_position;
257                                 mwindow->edl->local_session->set_selectionend(
258                                         mwindow->edl->local_session->get_selectionstart(1));
259                         }
260                         break;
261
262                 case SET_FROM:
263                         start_position = Units::text_to_seconds(from_value->get_text(),
264                                 mwindow->edl->session->sample_rate,
265                                 mwindow->edl->session->time_format,
266                                 mwindow->edl->session->frame_rate,
267                                 mwindow->edl->session->frames_per_foot);
268                         end_position = Units::text_to_seconds(to_value->get_text(),
269                                 mwindow->edl->session->sample_rate,
270                                 mwindow->edl->session->time_format,
271                                 mwindow->edl->session->frame_rate,
272                                 mwindow->edl->session->frames_per_foot);
273
274                         if(end_position < start_position)
275                         {
276                                 end_position = start_position;
277                                 mwindow->edl->local_session->set_selectionend(
278                                         mwindow->edl->local_session->get_selectionstart(1));
279                         }
280                         break;
281
282                 case SET_TO:
283                         start_position = Units::text_to_seconds(from_value->get_text(),
284                                 mwindow->edl->session->sample_rate,
285                                 mwindow->edl->session->time_format,
286                                 mwindow->edl->session->frame_rate,
287                                 mwindow->edl->session->frames_per_foot);
288                         end_position = Units::text_to_seconds(to_value->get_text(),
289                                 mwindow->edl->session->sample_rate,
290                                 mwindow->edl->session->time_format,
291                                 mwindow->edl->session->frame_rate,
292                                 mwindow->edl->session->frames_per_foot);
293
294                         if(end_position < start_position)
295                         {
296                                 start_position = end_position;
297                                 mwindow->edl->local_session->set_selectionend(
298                                         mwindow->edl->local_session->get_selectionstart(1));
299                         }
300                         break;
301         }
302
303         mwindow->edl->local_session->set_selectionstart(
304                 mwindow->edl->align_to_frame(start_position, 1));
305         mwindow->edl->local_session->set_selectionend(
306                 mwindow->edl->align_to_frame(end_position, 1));
307
308
309         mwindow->gui->update_timebar_highlights();
310         mwindow->gui->hide_cursor(1);
311         mwindow->gui->show_cursor(1);
312         update();
313         mwindow->sync_parameters(CHANGE_PARAMS);
314         mwindow->gui->flash_canvas(1);
315
316         return 0;
317 }
318
319
320
321
322
323
324
325
326
327
328
329
330 SampleZoomPanel::SampleZoomPanel(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
331  : ZoomPanel(mwindow, zoombar, mwindow->edl->local_session->zoom_sample,
332                 x, y, 110, MIN_ZOOM_TIME, MAX_ZOOM_TIME, ZOOM_TIME)
333 {
334         this->mwindow = mwindow;
335         this->zoombar = zoombar;
336 }
337 int SampleZoomPanel::handle_event()
338 {
339         mwindow->zoom_sample((int64_t)get_value());
340         return 1;
341 }
342
343
344 AmpZoomPanel::AmpZoomPanel(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
345  : ZoomPanel(mwindow, zoombar, mwindow->edl->local_session->zoom_y,
346                 x, y, 80, MIN_AMP_ZOOM, MAX_AMP_ZOOM, ZOOM_LONG)
347 {
348         this->mwindow = mwindow;
349         this->zoombar = zoombar;
350 }
351 int AmpZoomPanel::handle_event()
352 {
353         mwindow->zoom_amp((int64_t)get_value());
354         return 1;
355 }
356
357 TrackZoomPanel::TrackZoomPanel(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
358  : ZoomPanel(mwindow, zoombar, mwindow->edl->local_session->zoom_track,
359                 x, y, 70, MIN_TRACK_ZOOM, MAX_TRACK_ZOOM, ZOOM_LONG)
360 {
361         this->mwindow = mwindow;
362         this->zoombar = zoombar;
363 }
364 int TrackZoomPanel::handle_event()
365 {
366         mwindow->zoom_track((int64_t)get_value());
367         zoombar->amp_zoom->update(mwindow->edl->local_session->zoom_y);
368         return 1;
369 }
370
371
372
373
374 AutoZoom::AutoZoom(MWindow *mwindow, ZoomBar *zoombar, int x, int y, int changemax)
375  : BC_Tumbler(x, y, mwindow->theme->get_image_set("zoombar_tumbler"))
376 {
377         this->mwindow = mwindow;
378         this->zoombar = zoombar;
379         this->changemax = changemax;
380         if (changemax)
381                 set_tooltip(_("Automation range maximum"));
382         else
383                 set_tooltip(_("Automation range minimum"));
384 }
385
386 int AutoZoom::handle_up_event()
387 {
388         mwindow->change_currentautorange(mwindow->edl->local_session->zoombar_showautotype,1,changemax);
389
390         mwindow->gui->zoombar->update_autozoom();
391         mwindow->gui->draw_overlays(0);
392         mwindow->gui->update_patchbay();
393         mwindow->gui->flash_canvas(1);
394         return 1;
395 }
396
397 int AutoZoom::handle_down_event()
398 {
399         mwindow->change_currentautorange(mwindow->edl->local_session->zoombar_showautotype,0,changemax);
400
401         mwindow->gui->zoombar->update_autozoom();
402         mwindow->gui->draw_overlays(0);
403         mwindow->gui->update_patchbay();
404         mwindow->gui->flash_canvas(1);
405         return 1;
406 }
407
408
409
410 AutoTypeMenu::AutoTypeMenu(MWindow *mwindow, ZoomBar *zoombar, int x, int y, int wid)
411         : BC_PopupMenu(x, y, wid, to_text(mwindow->edl->local_session->zoombar_showautotype), 1)
412 {
413         this->mwindow = mwindow;
414         this->zoombar = zoombar;
415         set_tooltip(_("Automation Type"));
416 }
417
418 void AutoTypeMenu::create_objects()
419 {
420         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_AUDIO_FADE)));
421         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_VIDEO_FADE)));
422         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_ZOOM)));
423         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_SPEED)));
424         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_X)));
425         add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_Y)));
426 }
427
428 const char* AutoTypeMenu::to_text(int mode)
429 {
430         switch(mode) {
431         case AUTOGROUPTYPE_AUDIO_FADE: return _("Audio Fade:");
432         case AUTOGROUPTYPE_VIDEO_FADE: return _("Video Fade:");
433         case AUTOGROUPTYPE_ZOOM: return _("Zoom:");
434         case AUTOGROUPTYPE_SPEED: return _("Speed:");
435         case AUTOGROUPTYPE_X: return "X:";
436         case AUTOGROUPTYPE_Y: return "Y:";
437         }
438         return "??";
439 }
440
441 int AutoTypeMenu::from_text(char *text)
442 {
443         if(!strcmp(text, to_text(AUTOGROUPTYPE_AUDIO_FADE))) return AUTOGROUPTYPE_AUDIO_FADE;
444         if(!strcmp(text, to_text(AUTOGROUPTYPE_VIDEO_FADE))) return AUTOGROUPTYPE_VIDEO_FADE;
445         if(!strcmp(text, to_text(AUTOGROUPTYPE_ZOOM))) return AUTOGROUPTYPE_ZOOM;
446         if(!strcmp(text, to_text(AUTOGROUPTYPE_SPEED))) return AUTOGROUPTYPE_SPEED;
447         if(!strcmp(text, to_text(AUTOGROUPTYPE_X))) return AUTOGROUPTYPE_X;
448         if(!strcmp(text, to_text(AUTOGROUPTYPE_Y))) return AUTOGROUPTYPE_Y;
449         return AUTOGROUPTYPE_INT255;
450 }
451
452 int AutoTypeMenu::handle_event()
453 {
454         mwindow->edl->local_session->zoombar_showautotype = from_text(this->get_text());
455         this->zoombar->update_autozoom();
456         return 1;
457 }
458
459
460 ZoomTextBox::ZoomTextBox(MWindow *mwindow, ZoomBar *zoombar, int x, int y, const char *text)
461  : BC_TextBox(x, y, 130, 1, text)
462 {
463         this->mwindow = mwindow;
464         this->zoombar = zoombar;
465         set_tooltip(_("Automation range"));
466 }
467
468 int ZoomTextBox::button_press_event()
469 {
470         if (!(get_buttonpress() == 4 || get_buttonpress() == 5)) {
471                 BC_TextBox::button_press_event();
472                 return 0;
473         }
474         if (!is_event_win()) return 0;
475
476         int changemax = 1;
477         if (get_relative_cursor_x() < get_w()/2)
478                 changemax = 0;
479
480         // increment
481         if (get_buttonpress() == 4)
482                 mwindow->change_currentautorange(mwindow->edl->local_session->zoombar_showautotype, 1, changemax);
483
484         // decrement
485         if (get_buttonpress() == 5)
486                 mwindow->change_currentautorange(mwindow->edl->local_session->zoombar_showautotype, 0, changemax);
487
488         mwindow->gui->zoombar->update_autozoom();
489         mwindow->gui->draw_overlays(0);
490         mwindow->gui->update_patchbay();
491         mwindow->gui->flash_canvas(1);
492         return 1;
493 }
494
495 int ZoomTextBox::handle_event()
496 {
497         float min, max;
498         if (sscanf(this->get_text(),"%f to%f",&min, &max) == 2)
499         {
500                 AUTOMATIONVIEWCLAMPS(min, mwindow->edl->local_session->zoombar_showautotype);
501                 AUTOMATIONVIEWCLAMPS(max, mwindow->edl->local_session->zoombar_showautotype);
502                 if (max > min)
503                 {
504                         mwindow->edl->local_session->automation_mins[mwindow->edl->local_session->zoombar_showautotype] = min;
505                         mwindow->edl->local_session->automation_maxs[mwindow->edl->local_session->zoombar_showautotype] = max;
506                         mwindow->gui->zoombar->update_autozoom();
507                         mwindow->gui->draw_overlays(0);
508                         mwindow->gui->update_patchbay();
509                         mwindow->gui->flash_canvas(1);
510                 }
511         }
512         // TODO: Make the text turn red when it's a bad range..
513         return 0;
514 }
515
516
517
518
519
520 FromTextBox::FromTextBox(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
521  : BC_TextBox(x, y, 90, 1, "")
522 {
523         this->mwindow = mwindow;
524         this->zoombar = zoombar;
525         set_tooltip(_("Selection start time"));
526 }
527
528 int FromTextBox::handle_event()
529 {
530         if(get_keypress() == 13)
531         {
532                 zoombar->set_selection(SET_FROM);
533                 return 1;
534         }
535         return 0;
536 }
537
538 int FromTextBox::update_position(double new_position)
539 {
540         new_position += mwindow->edl->session->get_frame_offset() /
541                                                  mwindow->edl->session->frame_rate;;
542         Units::totext(string,
543                 new_position,
544                 mwindow->edl->session->time_format,
545                 mwindow->edl->session->sample_rate,
546                 mwindow->edl->session->frame_rate,
547                 mwindow->edl->session->frames_per_foot);
548 //printf("FromTextBox::update_position %f %s\n", new_position, string);
549         update(string);
550         return 0;
551 }
552
553
554
555
556
557
558 LengthTextBox::LengthTextBox(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
559  : BC_TextBox(x, y, 90, 1, "")
560 {
561         this->mwindow = mwindow;
562         this->zoombar = zoombar;
563         set_tooltip(_("Selection length"));
564 }
565
566 int LengthTextBox::handle_event()
567 {
568         if(get_keypress() == 13)
569         {
570                 zoombar->set_selection(SET_LENGTH);
571                 return 1;
572         }
573         return 0;
574 }
575
576 int LengthTextBox::update_position(double new_position)
577 {
578         Units::totext(string,
579                 new_position,
580                 mwindow->edl->session->time_format,
581                 mwindow->edl->session->sample_rate,
582                 mwindow->edl->session->frame_rate,
583                 mwindow->edl->session->frames_per_foot);
584         update(string);
585         return 0;
586 }
587
588
589
590
591
592 ToTextBox::ToTextBox(MWindow *mwindow, ZoomBar *zoombar, int x, int y)
593  : BC_TextBox(x, y, 90, 1, "")
594 {
595         this->mwindow = mwindow;
596         this->zoombar = zoombar;
597         set_tooltip(_("Selection end time"));
598 }
599
600 int ToTextBox::handle_event()
601 {
602         if(get_keypress() == 13)
603         {
604                 zoombar->set_selection(SET_TO);
605                 return 1;
606         }
607         return 0;
608 }
609
610 int ToTextBox::update_position(double new_position)
611 {
612         new_position += mwindow->edl->session->get_frame_offset() /
613                                                  mwindow->edl->session->frame_rate;
614         Units::totext(string,
615                 new_position,
616                 mwindow->edl->session->time_format,
617                 mwindow->edl->session->sample_rate,
618                 mwindow->edl->session->frame_rate,
619                 mwindow->edl->session->frames_per_foot);
620         update(string);
621         return 0;
622 }