r602: Fix baver's code... don't insert timecode when show_tc is not set
[cinelerra_cv/mob.git] / cinelerra / patchgui.C
blob103c013fa2549d8415a82ad5b497c2a6a62add62
1 #include "automation.h"
2 #include "bcsignals.h"
3 #include "cplayback.h"
4 #include "cwindow.h"
5 #include "edl.h"
6 #include "edlsession.h"
7 #include "intauto.h"
8 #include "intautos.h"
9 #include "language.h"
10 #include "localsession.h"
11 #include "mainsession.h"
12 #include "mainundo.h"
13 #include "mwindow.h"
14 #include "mwindowgui.h"
15 #include "patchbay.h"
16 #include "patchgui.h"
17 #include "playbackengine.h"
18 #include "theme.h"
19 #include "track.h"
20 #include "trackcanvas.h"
21 #include "tracks.h"
22 #include "transportque.h"
23 #include "vframe.h"
27 PatchGUI::PatchGUI(MWindow *mwindow, 
28                 PatchBay *patchbay, 
29                 Track *track, 
30                 int x, 
31                 int y)
33         this->mwindow = mwindow;
34         this->patchbay = patchbay;
35         this->track = track;
36         this->x = x;
37         this->y = y;
38         title = 0;
39         record = 0;
40         play = 0;
41 //      automate = 0;
42         gang = 0;
43         draw = 0;
44         mute = 0;
45         expand = 0;
46         nudge = 0;
47         change_source = 0;
48         track_id = -1;
49         if(track) track_id = track->get_id();
52 PatchGUI::~PatchGUI()
54         if(title) delete title;
55         if(record) delete record;
56         if(play) delete play;
57 //      if(automate) delete automate;
58         if(gang) delete gang;
59         if(draw) delete draw;
60         if(mute) delete mute;
61         if(expand) delete expand;
62         if(nudge) delete nudge;
65 int PatchGUI::create_objects()
67         return update(x, y);
70 int PatchGUI::reposition(int x, int y)
72         int x1 = 0;
73         int y1 = 0;
76         if(x != this->x || y != this->y)
77         {
78                 this->x = x;
79                 this->y = y;
81                 if(title)
82                 {
83 TRACE("PatchGUI::reposition 1\n");
84                         title->reposition_window(x1, y1 + y);
85 TRACE("PatchGUI::reposition 2\n");
86                 }
87                 y1 += mwindow->theme->title_h;
89                 if(play)
90                 {
91 TRACE("PatchGUI::reposition 3\n");
92                         play->reposition_window(x1, y1 + y);
93                         x1 += play->get_w();
94 TRACE("PatchGUI::reposition 4\n");
95                         record->reposition_window(x1, y1 + y);
96                         x1 += record->get_w();
97 TRACE("PatchGUI::reposition 5\n");
98 //                      automate->reposition_window(x1, y1 + y);
99 //                      x1 += automate->get_w();
100                         gang->reposition_window(x1, y1 + y);
101                         x1 += gang->get_w();
102 TRACE("PatchGUI::reposition 6\n");
103                         draw->reposition_window(x1, y1 + y);
104                         x1 += draw->get_w();
105 TRACE("PatchGUI::reposition 7\n");
106                         mute->reposition_window(x1, y1 + y);
107                         x1 += mute->get_w();
108 TRACE("PatchGUI::reposition 8\n");
110                         if(expand)
111                         {
112 TRACE("PatchGUI::reposition 9\n");
113                                 expand->reposition_window(
114                                         patchbay->get_w() - 10 - mwindow->theme->expandpatch_data[0]->get_w(), 
115                                         y1 + y);
116 TRACE("PatchGUI::reposition 10\n");
117                                 x1 += expand->get_w();
118 TRACE("PatchGUI::reposition 11\n");
119                         }
120                 }
121                 y1 += mwindow->theme->play_h;
122         }
123         else
124         {
125                 y1 += mwindow->theme->title_h;
126                 y1 += mwindow->theme->play_h;
127         }
129         return y1;
132 int PatchGUI::update(int x, int y)
134 //TRACE("PatchGUI::update 1");
135         reposition(x, y);
136 //TRACE("PatchGUI::update 10");
138         int h = track->vertical_span(mwindow->theme);
139         int y1 = 0;
140         int x1 = 0;
141 //printf("PatchGUI::update 10\n");
143         if(title)
144         {
145                 if(h - y1 < 0)
146                 {
147                         delete title;
148                         title = 0;
149                 }
150                 else
151                 {
152                         title->update(track->title);
153                 }
154         }
155         else
156         if(h - y1 >= 0)
157         {
158                 patchbay->add_subwindow(title = new TitlePatch(mwindow, this, x1 + x, y1 + y));
159         }
160         y1 += mwindow->theme->title_h;
162         if(play)
163         {
164                 if(h - y1 < mwindow->theme->play_h)
165                 {
166                         delete play;
167                         delete record;
168                         delete gang;
169                         delete draw;
170                         delete mute;
171                         delete expand;
172                         play = 0;
173                         record = 0;
174                         draw = 0;
175                         mute = 0;
176                         expand = 0;
177                 }
178                 else
179                 {
180                         play->update(track->play);
181                         record->update(track->record);
182                         gang->update(track->gang);
183                         draw->update(track->draw);
184                         mute->update(mute->get_keyframe(mwindow, this)->value);
185                         expand->update(track->expand_view);
186                 }
187         }
188         else
189         if(h - y1 >= mwindow->theme->play_h)
190         {
191                 patchbay->add_subwindow(play = new PlayPatch(mwindow, this, x1 + x, y1 + y));
192 //printf("PatchGUI::update 1 %p %p\n", play, &play->status);
193                 x1 += play->get_w();
194                 patchbay->add_subwindow(record = new RecordPatch(mwindow, this, x1 + x, y1 + y));
195                 x1 += record->get_w();
196                 patchbay->add_subwindow(gang = new GangPatch(mwindow, this, x1 + x, y1 + y));
197                 x1 += gang->get_w();
198                 patchbay->add_subwindow(draw = new DrawPatch(mwindow, this, x1 + x, y1 + y));
199                 x1 += draw->get_w();
200                 patchbay->add_subwindow(mute = new MutePatch(mwindow, this, x1 + x, y1 + y));
201                 x1 += mute->get_w();
204                 patchbay->add_subwindow(expand = new ExpandPatch(mwindow, 
205                         this, 
206                         patchbay->get_w() - 10 - mwindow->theme->expandpatch_data[0]->get_w(), 
207                         y1 + y));
208                 x1 += expand->get_w();
209         }
210         y1 += mwindow->theme->play_h;
212 //UNTRACE
213         return y1;
217 void PatchGUI::toggle_behavior(int type, 
218                 int value,
219                 BC_Toggle *toggle,
220                 int *output)
222         if(toggle->shift_down())
223         {
224                 int total_selected = mwindow->edl->tracks->total_of(type);
226 // nothing previously selected
227                 if(total_selected == 0)
228                 {
229                         mwindow->edl->tracks->select_all(type,
230                                 1);
231                 }
232                 else
233                 if(total_selected == 1)
234                 {
235 // this patch was previously the only one on
236                         if(*output)
237                         {
238                                 mwindow->edl->tracks->select_all(type,
239                                         1);
240                         }
241 // another patch was previously the only one on
242                         else
243                         {
244                                 mwindow->edl->tracks->select_all(type,
245                                         0);
246                                 *output = 1;
247                         }
248                 }
249                 else
250                 if(total_selected > 1)
251                 {
252                         mwindow->edl->tracks->select_all(type,
253                                 0);
254                         *output = 1;
255                 }
256                 toggle->set_value(*output);
257                 patchbay->update();
258                 patchbay->drag_operation = type;
259                 patchbay->new_status = 1;
260                 patchbay->button_down = 1;
261         }
262         else
263         {
264                 *output = value;
265 // Select + drag behavior
266                 patchbay->drag_operation = type;
267                 patchbay->new_status = value;
268                 patchbay->button_down = 1;
269         }
271         if(type == Tracks::PLAY)
272         {
273                 mwindow->gui->unlock_window();
274                 mwindow->restart_brender();
275                 mwindow->sync_parameters(CHANGE_EDL);
276                 mwindow->gui->lock_window("PatchGUI::toggle_behavior 1");
277         }
278         else
279         if(type == Tracks::MUTE)
280         {
281                 mwindow->gui->unlock_window();
282                 mwindow->restart_brender();
283                 mwindow->sync_parameters(CHANGE_PARAMS);
284                 mwindow->gui->lock_window("PatchGUI::toggle_behavior 2");
285         }
287 // Update affected tracks in cwindow
288         if(type == Tracks::RECORD)
289                 mwindow->cwindow->update(0, 1, 1);
293 char* PatchGUI::calculate_nudge_text(int *changed)
295         if(changed) *changed = 0;
296         if(track->edl->session->nudge_seconds)
297         {
298                 sprintf(string_return, "%.4f", track->from_units(track->nudge));
299                 if(changed && nudge && atof(nudge->get_text()) - atof(string_return) != 0)
300                         *changed = 1;
301         }
302         else
303         {
304                 sprintf(string_return, "%d", track->nudge);
305                 if(changed && nudge && atoi(nudge->get_text()) - atoi(string_return) != 0)
306                         *changed = 1;
307         }
308         return string_return;
311 void PatchGUI::set_nudge_value(char *string)
313         if(track->edl->session->nudge_seconds)
314         {
315                 float result;
316                 sscanf(string, "%f", &result);
317                 track->nudge = track->to_units(result, 0);
318 //printf("PatchGUI::set_nudge_value 1 %d %f %s\n", track->nudge, result, string);
319         }
320         else
321         {
322                 int64_t temp;
323                 sscanf(string, "%lld", &temp);
324                 track->nudge = temp;
325 //printf("PatchGUI::set_nudge_value 10 %d\n", track->nudge);
326         }
327 //printf("PatchGUI::set_nudge_value %d\n", track->nudge);
341 PlayPatch::PlayPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
342  : BC_Toggle(x, 
343                 y, 
344                 mwindow->theme->playpatch_data,
345                 patch->track->play, 
346                 "",
347                 0,
348                 0,
349                 0)
351         this->mwindow = mwindow;
352         this->patch = patch;
353         set_tooltip(_("Play track"));
354         set_select_drag(1);
357 int PlayPatch::button_press_event()
359         if(is_event_win() && get_buttonpress() == 1)
360         {
361                 set_status(BC_Toggle::TOGGLE_DOWN);
362                 update(!get_value());
363                 patch->toggle_behavior(Tracks::PLAY,
364                         get_value(),
365                         this,
366                         &patch->track->play);
367                 return 1;
368         }
369         return 0;
372 int PlayPatch::button_release_event()
374         int result = BC_Toggle::button_release_event();
375         if(patch->patchbay->drag_operation != Tracks::NONE)
376         {
377                 patch->patchbay->drag_operation = Tracks::NONE;
378         }
379         return result;
392 RecordPatch::RecordPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
393  : BC_Toggle(x, 
394                 y, 
395                 mwindow->theme->recordpatch_data,
396                 patch->track->record, 
397                 "",
398                 0,
399                 0,
400                 0)
402         this->mwindow = mwindow;
403         this->patch = patch;
404         set_tooltip(_("Arm track"));
405         set_select_drag(1);
408 int RecordPatch::button_press_event()
410         if(is_event_win() && get_buttonpress() == 1)
411         {
412                 set_status(BC_Toggle::TOGGLE_DOWN);
413                 update(!get_value());
414                 patch->toggle_behavior(Tracks::RECORD,
415                         get_value(),
416                         this,
417                         &patch->track->record);
418                 return 1;
419         }
420         return 0;
423 int RecordPatch::button_release_event()
425         int result = BC_Toggle::button_release_event();
426         if(patch->patchbay->drag_operation != Tracks::NONE)
427         {
428                 patch->patchbay->drag_operation = Tracks::NONE;
429         }
430         return result;
443 GangPatch::GangPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
444  : BC_Toggle(x, y, 
445                 mwindow->theme->gangpatch_data,
446                 patch->track->gang, 
447                 "",
448                 0,
449                 0,
450                 0)
452         this->mwindow = mwindow;
453         this->patch = patch;
454         set_tooltip(_("Gang faders"));
455         set_select_drag(1);
458 int GangPatch::button_press_event()
460         if(is_event_win() && get_buttonpress() == 1)
461         {
462                 set_status(BC_Toggle::TOGGLE_DOWN);
463                 update(!get_value());
464                 patch->toggle_behavior(Tracks::GANG,
465                         get_value(),
466                         this,
467                         &patch->track->gang);
468                 return 1;
469         }
470         return 0;
473 int GangPatch::button_release_event()
475         int result = BC_Toggle::button_release_event();
476         if(patch->patchbay->drag_operation != Tracks::NONE)
477         {
478                 patch->patchbay->drag_operation = Tracks::NONE;
479         }
480         return result;
493 DrawPatch::DrawPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
494  : BC_Toggle(x, y, 
495                 mwindow->theme->drawpatch_data,
496                 patch->track->draw, 
497                 "",
498                 0,
499                 0,
500                 0)
502         this->mwindow = mwindow;
503         this->patch = patch;
504         set_tooltip(_("Draw media"));
505         set_select_drag(1);
508 int DrawPatch::button_press_event()
510         if(is_event_win() && get_buttonpress() == 1)
511         {
512                 set_status(BC_Toggle::TOGGLE_DOWN);
513                 update(!get_value());
514                 patch->toggle_behavior(Tracks::DRAW,
515                         get_value(),
516                         this,
517                         &patch->track->draw);
518                 return 1;
519         }
520         return 0;
523 int DrawPatch::button_release_event()
525         int result = BC_Toggle::button_release_event();
526         if(patch->patchbay->drag_operation != Tracks::NONE)
527         {
528                 patch->patchbay->drag_operation = Tracks::NONE;
529         }
530         return result;
542 MutePatch::MutePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
543  : BC_Toggle(x, y, 
544                 mwindow->theme->mutepatch_data,
545                 get_keyframe(mwindow, patch)->value, 
546                 "",
547                 0,
548                 0,
549                 0)
551         this->mwindow = mwindow;
552         this->patch = patch;
553         set_tooltip(_("Don't send to output"));
554         set_select_drag(1);
557 int MutePatch::button_press_event()
559         if(is_event_win() && get_buttonpress() == 1)
560         {
561                 set_status(BC_Toggle::TOGGLE_DOWN);
562                 update(!get_value());
563                 IntAuto *current;
564                 double position = mwindow->edl->local_session->selectionstart;
565                 Autos *mute_autos = patch->track->automation->mute_autos;
567                 mwindow->undo->update_undo_before(_("keyframe"), LOAD_AUTOMATION);
569                 current = (IntAuto*)mute_autos->get_auto_for_editing(position);
570                 current->value = get_value();
572                 patch->toggle_behavior(Tracks::MUTE,
573                         get_value(),
574                         this,
575                         &current->value);
578                 mwindow->undo->update_undo_after();
580                 if(mwindow->edl->session->auto_conf->mute)
581                 {
582                         mwindow->gui->canvas->draw_overlays();
583                         mwindow->gui->canvas->flash();
584                 }
585                 return 1;
586         }
587         return 0;
590 int MutePatch::button_release_event()
592         int result = BC_Toggle::button_release_event();
593         if(patch->patchbay->drag_operation != Tracks::NONE)
594         {
595                 patch->patchbay->drag_operation = Tracks::NONE;
596         }
597         return result;
600 IntAuto* MutePatch::get_keyframe(MWindow *mwindow, PatchGUI *patch)
602         Auto *current = 0;
603         double unit_position = mwindow->edl->local_session->selectionstart;
604         unit_position = mwindow->edl->align_to_frame(unit_position, 0);
605         unit_position = patch->track->to_units(unit_position, 0);
606         return (IntAuto*)patch->track->automation->mute_autos->get_prev_auto(
607                 (long)unit_position, 
608                 PLAY_FORWARD,
609                 current);
623 ExpandPatch::ExpandPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
624  : BC_Toggle(x, 
625                 y, 
626                 mwindow->theme->expandpatch_data,
627                 patch->track->expand_view, 
628                 "",
629                 0,
630                 0,
631                 0)
633         this->mwindow = mwindow;
634         this->patch = patch;
635         set_select_drag(1);
638 int ExpandPatch::button_press_event()
640         if(is_event_win() && get_buttonpress() == 1)
641         {
642                 set_status(BC_Toggle::TOGGLE_DOWN);
643                 update(!get_value());
644                 patch->toggle_behavior(Tracks::EXPAND,
645                         get_value(),
646                         this,
647                         &patch->track->expand_view);
648                 mwindow->trackmovement(mwindow->edl->local_session->track_start);
649                 return 1;
650         }
651         return 0;
654 int ExpandPatch::button_release_event()
656         int result = BC_Toggle::button_release_event();
657         if(patch->patchbay->drag_operation != Tracks::NONE)
658         {
659                 patch->patchbay->drag_operation = Tracks::NONE;
660         }
661         return result;
668 TitlePatch::TitlePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
669  : BC_TextBox(x, 
670                 y, 
671                 patch->patchbay->get_w() - 10, 
672                 1,
673                 patch->track->title)
675         this->mwindow = mwindow;
676         this->patch = patch;
679 int TitlePatch::handle_event()
681         strcpy(patch->track->title, get_text());
682         mwindow->update_plugin_titles();
683         mwindow->gui->canvas->draw_overlays();
684         mwindow->gui->canvas->flash();
685         return 1;
696 NudgePatch::NudgePatch(MWindow *mwindow, 
697         PatchGUI *patch, 
698         int x, 
699         int y, 
700         int w)
701  : BC_TextBox(x,
702         y,
703         w,
704         1,
705         patch->calculate_nudge_text(0))
707         this->mwindow = mwindow;
708         this->patch = patch;
709         set_tooltip(_("Nudge"));
712 int NudgePatch::handle_event()
714         mwindow->undo->update_undo_before("nudge", LOAD_AUTOMATION);
715         patch->set_nudge_value(get_text());
716         mwindow->undo->update_undo_after();
718         if(patch->track->data_type == TRACK_AUDIO)
719         {
720                 mwindow->gui->unlock_window();
721 //              mwindow->sync_parameters(CHANGE_EDL);
722                 mwindow->sync_parameters(CHANGE_PARAMS);
723                 mwindow->gui->lock_window("NudgePatch::handle_event 1");
724         }
725         else
726         {
727                 mwindow->gui->unlock_window();
728                 mwindow->restart_brender();
729                 mwindow->sync_parameters(CHANGE_PARAMS);
730                 mwindow->gui->lock_window("NudgePatch::handle_event 2");
731         }
733         mwindow->session->changes_made = 1;
734         return 1;
737 int NudgePatch::button_press_event()
739         int result;
740         if(get_buttonpress() == 3 &&
741                 is_event_win() &&
742                 cursor_inside())
743         {
744                 patch->patchbay->nudge_popup->activate_menu(patch);
745                 return 1;
746         }
747         else
748                 return BC_TextBox::button_press_event();
752 void NudgePatch::update()
754         int changed;
755         char *string = patch->calculate_nudge_text(&changed);
756         if(changed)
757                 BC_TextBox::update(string);