r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / patchgui.C
blob372529ffa3374731d925ecebcaaa247977acd28e
1 #include "automation.h"
2 #include "cplayback.h"
3 #include "cwindow.h"
4 #include "edl.h"
5 #include "edlsession.h"
6 #include "intauto.h"
7 #include "intautos.h"
8 #include "localsession.h"
9 #include "mainundo.h"
10 #include "mwindow.h"
11 #include "mwindowgui.h"
12 #include "patchbay.h"
13 #include "patchgui.h"
14 #include "playbackengine.h"
15 #include "theme.h"
16 #include "track.h"
17 #include "trackcanvas.h"
18 #include "tracks.h"
19 #include "transportque.h"
20 #include "vframe.h"
22 #include <libintl.h>
23 #define _(String) gettext(String)
24 #define gettext_noop(String) String
25 #define N_(String) gettext_noop (String)
28 PatchGUI::PatchGUI(MWindow *mwindow, 
29                 PatchBay *patchbay, 
30                 Track *track, 
31                 int x, 
32                 int y)
34         this->mwindow = mwindow;
35         this->patchbay = patchbay;
36         this->track = track;
37         this->x = x;
38         this->y = y;
39         title = 0;
40         record = 0;
41         play = 0;
42 //      automate = 0;
43         gang = 0;
44         draw = 0;
45         mute = 0;
46         expand = 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;
64 int PatchGUI::create_objects()
66         return update(x, y);
69 int PatchGUI::reposition(int x, int y)
71         int x1 = 0;
72         int y1 = 0;
75         if(x != this->x || y != this->y)
76         {
77                 this->x = x;
78                 this->y = y;
80                 if(title)
81                 {
82                         title->reposition_window(x1, y1 + y);
83                 }
84                 y1 += mwindow->theme->title_h;
86                 if(play)
87                 {
88                         play->reposition_window(x1, y1 + y);
89                         x1 += play->get_w();
90                         record->reposition_window(x1, y1 + y);
91                         x1 += record->get_w();
92 //                      automate->reposition_window(x1, y1 + y);
93 //                      x1 += automate->get_w();
94                         gang->reposition_window(x1, y1 + y);
95                         x1 += gang->get_w();
96                         draw->reposition_window(x1, y1 + y);
97                         x1 += draw->get_w();
98                         mute->reposition_window(x1, y1 + y);
99                         x1 += mute->get_w();
101                         expand->reposition_window(
102                                 patchbay->get_w() - 10 - mwindow->theme->expandpatch_data[0]->get_w(), 
103                                 y1 + y);
104                         x1 += expand->get_w();
105                 }
106                 y1 += mwindow->theme->play_h;
107         }
108         else
109         {
110                 y1 += mwindow->theme->title_h;
111                 y1 += mwindow->theme->play_h;
112         }
114         return y1;
117 int PatchGUI::update(int x, int y)
119         reposition(x, y);
121         int h = track->vertical_span(mwindow->theme);
122         int y1 = 0;
123         int x1 = 0;
125         if(title)
126         {
127                 if(h - y1 < 0)
128                 {
129                         delete title;
130                         title = 0;
131                 }
132                 else
133                 {
134                         title->update(track->title);
135                 }
136         }
137         else
138         if(h - y1 >= 0)
139         {
140                 patchbay->add_subwindow(title = new TitlePatch(mwindow, this, x1 + x, y1 + y));
141         }
142         y1 += mwindow->theme->title_h;
144         if(play)
145         {
146                 if(h - y1 < mwindow->theme->play_h)
147                 {
148                         delete play;
149                         delete record;
150                         delete gang;
151                         delete draw;
152                         delete mute;
153                         delete expand;
154                         play = 0;
155                         record = 0;
156                         draw = 0;
157                         mute = 0;
158                         expand = 0;
159                 }
160                 else
161                 {
162                         play->update(track->play);
163                         record->update(track->record);
164                         gang->update(track->gang);
165                         draw->update(track->draw);
166                         mute->update(mute->get_keyframe(mwindow, this)->value);
167                         expand->update(track->expand_view);
168                 }
169         }
170         else
171         if(h - y1 >= mwindow->theme->play_h)
172         {
173                 patchbay->add_subwindow(play = new PlayPatch(mwindow, this, x1 + x, y1 + y));
174                 x1 += play->get_w();
175                 patchbay->add_subwindow(record = new RecordPatch(mwindow, this, x1 + x, y1 + y));
176                 x1 += record->get_w();
177                 patchbay->add_subwindow(gang = new GangPatch(mwindow, this, x1 + x, y1 + y));
178                 x1 += gang->get_w();
179                 patchbay->add_subwindow(draw = new DrawPatch(mwindow, this, x1 + x, y1 + y));
180                 x1 += draw->get_w();
181                 patchbay->add_subwindow(mute = new MutePatch(mwindow, this, x1 + x, y1 + y));
182                 x1 += mute->get_w();
185                 patchbay->add_subwindow(expand = new ExpandPatch(mwindow, 
186                         this, 
187                         patchbay->get_w() - 10 - mwindow->theme->expandpatch_data[0]->get_w(), 
188                         y1 + y));
189                 x1 += expand->get_w();
190         }
191         y1 += mwindow->theme->play_h;
193         return y1;
197 void PatchGUI::toggle_behavior(int type, 
198                 int value,
199                 BC_Toggle *toggle,
200                 int *output)
202         if(toggle->shift_down())
203         {
204                 int total_selected = mwindow->edl->tracks->total_of(type);
206 // nothing previously selected
207                 if(total_selected == 0)
208                 {
209                         mwindow->edl->tracks->select_all(type,
210                                 1);
211                 }
212                 else
213                 if(total_selected == 1)
214                 {
215 // this patch was previously the only one on
216                         if(*output)
217                         {
218                                 mwindow->edl->tracks->select_all(type,
219                                         1);
220                         }
221 // another patch was previously the only one on
222                         else
223                         {
224                                 mwindow->edl->tracks->select_all(type,
225                                         0);
226                                 *output = 1;
227                         }
228                 }
229                 else
230                 if(total_selected > 1)
231                 {
232                         mwindow->edl->tracks->select_all(type,
233                                 0);
234                         *output = 1;
235                 }
236                 toggle->set_value(*output);
237                 patchbay->update();
238         }
239         else
240         {
241                 *output = value;
242 // Select + drag behavior
243                 patchbay->drag_operation = type;
244                 patchbay->new_status = value;
245                 patchbay->button_down = 1;
246         }
248         if(type == Tracks::PLAY)
249         {
250                 mwindow->gui->unlock_window();
251                 mwindow->restart_brender();
252                 mwindow->sync_parameters(CHANGE_EDL);
253                 mwindow->gui->lock_window();
254         }
255         else
256         if(type == Tracks::MUTE)
257         {
258                 mwindow->gui->unlock_window();
259                 mwindow->restart_brender();
260                 mwindow->sync_parameters(CHANGE_PARAMS);
261                 mwindow->gui->lock_window();
262         }
263         
264 // Update affected tracks in cwindow
265         if(type == Tracks::RECORD)
266                 mwindow->cwindow->update(0, 1, 1);
280 PlayPatch::PlayPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
281  : BC_Toggle(x, 
282                 y, 
283                 mwindow->theme->playpatch_data,
284                 patch->track->play, 
285                 "",
286                 0,
287                 0,
288                 0)
290         this->mwindow = mwindow;
291         this->patch = patch;
292         set_tooltip(_("Play track"));
293         set_select_drag(1);
296 int PlayPatch::button_press_event()
298         if(is_event_win() && get_buttonpress() == 1)
299         {
300                 update(!get_value());
301                 patch->toggle_behavior(Tracks::PLAY,
302                         get_value(),
303                         this,
304                         &patch->track->play);
305                 return 1;
306         }
307         return 0;
310 int PlayPatch::button_release_event()
312         if(patch->patchbay->drag_operation != Tracks::NONE)
313         {
314                 patch->patchbay->drag_operation = Tracks::NONE;
315                 return 1;
316         }
317         return 0;
330 RecordPatch::RecordPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
331  : BC_Toggle(x, 
332                 y, 
333                 mwindow->theme->recordpatch_data,
334                 patch->track->record, 
335                 "",
336                 0,
337                 0,
338                 0)
340         this->mwindow = mwindow;
341         this->patch = patch;
342         set_tooltip(_("Arm track"));
343         set_select_drag(1);
346 int RecordPatch::button_press_event()
348         if(is_event_win() && get_buttonpress() == 1)
349         {
350                 update(!get_value());
351                 patch->toggle_behavior(Tracks::RECORD,
352                         get_value(),
353                         this,
354                         &patch->track->record);
355                 return 1;
356         }
357         return 0;
360 int RecordPatch::button_release_event()
362         if(patch->patchbay->drag_operation != Tracks::NONE)
363         {
364                 patch->patchbay->drag_operation = Tracks::NONE;
365                 return 1;
366         }
367         return 0;
379 TitlePatch::TitlePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
380  : BC_TextBox(x, 
381                 y, 
382                 patch->patchbay->get_w() - 10, 
383                 1,
384                 patch->track->title)
386         this->mwindow = mwindow;
387         this->patch = patch;
390 int TitlePatch::handle_event()
392         strcpy(patch->track->title, get_text());
393         mwindow->update_plugin_titles();
394         mwindow->gui->canvas->draw_overlays();
395         mwindow->gui->canvas->flash();
396         return 1;
409 GangPatch::GangPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
410  : BC_Toggle(x, y, 
411                 mwindow->theme->gangpatch_data,
412                 patch->track->gang, 
413                 "",
414                 0,
415                 0,
416                 0)
418         this->mwindow = mwindow;
419         this->patch = patch;
420         set_tooltip(_("Gang faders"));
421         set_select_drag(1);
424 int GangPatch::button_press_event()
426         if(is_event_win() && get_buttonpress() == 1)
427         {
428                 update(!get_value());
429                 patch->toggle_behavior(Tracks::GANG,
430                         get_value(),
431                         this,
432                         &patch->track->gang);
433                 return 1;
434         }
435         return 0;
438 int GangPatch::button_release_event()
440         if(patch->patchbay->drag_operation != Tracks::NONE)
441         {
442                 patch->patchbay->drag_operation = Tracks::NONE;
443                 return 1;
444         }
445         return 0;
458 DrawPatch::DrawPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
459  : BC_Toggle(x, y, 
460                 mwindow->theme->drawpatch_data,
461                 patch->track->draw, 
462                 "",
463                 0,
464                 0,
465                 0)
467         this->mwindow = mwindow;
468         this->patch = patch;
469         set_tooltip(_("Draw media"));
470         set_select_drag(1);
473 int DrawPatch::button_press_event()
475         if(is_event_win() && get_buttonpress() == 1)
476         {
477                 update(!get_value());
478                 patch->toggle_behavior(Tracks::DRAW,
479                         get_value(),
480                         this,
481                         &patch->track->draw);
482                 return 1;
483         }
484         return 0;
487 int DrawPatch::button_release_event()
489         if(patch->patchbay->drag_operation != Tracks::NONE)
490         {
491                 patch->patchbay->drag_operation = Tracks::NONE;
492                 return 1;
493         }
494         return 0;
506 MutePatch::MutePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
507  : BC_Toggle(x, y, 
508                 mwindow->theme->mutepatch_data,
509                 get_keyframe(mwindow, patch)->value, 
510                 "",
511                 0,
512                 0,
513                 0)
515         this->mwindow = mwindow;
516         this->patch = patch;
517         set_tooltip(_("Don't send to output"));
518         set_select_drag(1);
521 int MutePatch::button_press_event()
523         if(is_event_win() && get_buttonpress() == 1)
524         {
525                 update(!get_value());
526                 IntAuto *current;
527                 double position = mwindow->edl->local_session->selectionstart;
528                 Autos *mute_autos = patch->track->automation->mute_autos;
530                 mwindow->undo->update_undo_before(_("keyframe"), LOAD_AUTOMATION);
532                 current = (IntAuto*)mute_autos->get_auto_for_editing(position);
533                 current->value = get_value();
535                 patch->toggle_behavior(Tracks::MUTE,
536                         get_value(),
537                         this,
538                         &current->value);
541                 mwindow->undo->update_undo_after();
543                 if(mwindow->edl->session->auto_conf->mute)
544                 {
545                         mwindow->gui->canvas->draw_overlays();
546                         mwindow->gui->canvas->flash();
547                 }
548                 return 1;
549         }
550         return 0;
553 int MutePatch::button_release_event()
555         if(patch->patchbay->drag_operation != Tracks::NONE)
556         {
557                 patch->patchbay->drag_operation = Tracks::NONE;
558                 return 1;
559         }
560         return 0;
563 IntAuto* MutePatch::get_keyframe(MWindow *mwindow, PatchGUI *patch)
565         Auto *current = 0;
566         double unit_position = mwindow->edl->local_session->selectionstart;
567         unit_position = mwindow->edl->align_to_frame(unit_position, 0);
568         unit_position = patch->track->to_units(unit_position, 0);
569         return (IntAuto*)patch->track->automation->mute_autos->get_prev_auto(
570                 (long)unit_position, 
571                 PLAY_FORWARD,
572                 current);
586 ExpandPatch::ExpandPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
587  : BC_Toggle(x, 
588                 y, 
589                 mwindow->theme->expandpatch_data,
590                 patch->track->expand_view, 
591                 "",
592                 0,
593                 0,
594                 0)
596         this->mwindow = mwindow;
597         this->patch = patch;
598         set_select_drag(1);
601 int ExpandPatch::button_press_event()
603         if(is_event_win() && get_buttonpress() == 1)
604         {
605                 update(!get_value());
606                 patch->toggle_behavior(Tracks::EXPAND,
607                         get_value(),
608                         this,
609                         &patch->track->expand_view);
610                 mwindow->trackmovement(mwindow->edl->local_session->track_start);
611                 return 1;
612         }
613         return 0;
616 int ExpandPatch::button_release_event()
618         if(patch->patchbay->drag_operation != Tracks::NONE)
619         {
620                 patch->patchbay->drag_operation = Tracks::NONE;
621                 return 1;
622         }
623         return 0;