4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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
22 #include "automation.h"
23 #include "bcsignals.h"
24 #include "cplayback.h"
27 #include "edlsession.h"
31 #include "localsession.h"
32 #include "mainsession.h"
35 #include "mwindowgui.h"
38 #include "playbackengine.h"
41 #include "trackcanvas.h"
43 #include "transportque.h"
48 PatchGUI::PatchGUI(MWindow *mwindow,
54 this->mwindow = mwindow;
55 this->patchbay = patchbay;
72 track_id = track ? track->get_id() : -1;
94 void PatchGUI::create_objects()
99 int PatchGUI::reposition(int x, int y)
101 if( track->is_hidden() ) return 0;
106 if( x != this->x || y != this->y ) {
107 this->x = x; this->y = y;
110 title->reposition_window(title->get_x(), y1 + y, 0);
112 expand->reposition_window(expand->get_x(), y1 + y);
113 y1 += mwindow->theme->title_h;
116 play->reposition_window(play->get_x(), y1 + y);
118 record->reposition_window(record->get_x(), y1 + y);
119 x1 += record->get_w();
120 // automate->reposition_window(x1, y1 + y);
121 // x1 += automate->get_w();
122 draw->reposition_window(draw->get_x(), y1 + y);
124 mute->reposition_window(mute->get_x(), y1 + y);
126 gang->reposition_window(gang->get_x(), y1 + y);
128 master->reposition_window(master->get_x(), y1 + y);
129 x1 += master->get_w();
130 zoom->reposition_window(zoom->get_x(), y1 + y);
131 // x1 += zoom->get_w();
133 y1 += mwindow->theme->play_h;
137 y1 += mwindow->theme->title_h;
139 y1 += mwindow->theme->play_h;
145 int PatchGUI::update(int x, int y)
147 if( track->is_hidden() ) return 0;
148 //TRACE("PatchGUI::update 1");
150 //TRACE("PatchGUI::update 10");
152 int h = track->vertical_span(mwindow->theme);
155 //printf("PatchGUI::update 10\n");
157 int y2 = y1 + mwindow->theme->title_h;
160 delete title; title = 0;
161 delete expand; expand = 0;
164 title->update(track->title);
165 expand->update(track->expand_view);
169 VFrame **expandpatch_data = mwindow->theme->get_image_set("expandpatch_data");
170 int x2 = patchbay->get_w() - expandpatch_data[0]->get_w() - 5;
171 patchbay->add_subwindow(title = new TitlePatch(mwindow, this, x1 + x, y1 + y, x2-x1-5));
172 patchbay->add_subwindow(expand = new ExpandPatch(mwindow, this, x2, y1 + y));
178 y2 = y1 + mwindow->theme->play_h;
181 delete play; play = 0;
182 delete record; record = 0;
183 delete draw; draw = 0;
184 delete mute; mute = 0;
185 delete gang; gang = 0;
186 delete master; master = 0;
187 delete zoom; zoom = 0;
190 play->update(track->play);
191 record->update(track->armed);
192 draw->update(track->draw);
193 mute->update(mwindow->get_int_auto(this, AUTOMATION_MUTE)->value);
194 gang->update(track->ganged);
195 master->update(track->master);
199 patchbay->add_subwindow(play = new PlayPatch(mwindow, this, x1 + x, y1 + y));
200 //printf("PatchGUI::update %d %d\n", __LINE__, play->get_h());
202 patchbay->add_subwindow(record = new RecordPatch(mwindow, this, x1 + x, y1 + y));
203 x1 += record->get_w();
204 patchbay->add_subwindow(draw = new DrawPatch(mwindow, this, x1 + x, y1 + y));
206 patchbay->add_subwindow(mute = new MutePatch(mwindow, this, x1 + x, y1 + y));
208 patchbay->add_subwindow(gang = new GangPatch(mwindow, this, x1 + x, y1 + y));
210 patchbay->add_subwindow(master = new MasterPatch(mwindow, this, x1 + x, y1 + y));
211 x1 += master->get_w();
212 patchbay->add_subwindow(zoom = new ZoomPatch(mwindow, this, x1 + x, y1 + y));
213 // x1 += zoom->get_w();
223 void PatchGUI::toggle_behavior(int type,
228 if(toggle->shift_down()) {
229 int sense = type != Tracks::MUTE ? 1 : 0;
230 // all selected if nothing previously selected or
231 // if this patch was previously the only one selected
232 int total_type = mwindow->edl->tracks->total_of(type);
233 int total_selected = sense ? total_type :
234 mwindow->edl->tracks->total() - total_type;
235 int selected = !total_selected || (total_selected == 1 &&
236 *output == sense ) ? sense : 1-sense;
237 mwindow->edl->tracks->select_all(type, selected);
238 if( selected != sense ) *output = sense;
240 patchbay->drag_operation = type;
241 patchbay->new_status = 1;
246 // Select + drag behavior
247 patchbay->drag_operation = type;
248 patchbay->new_status = value;
254 mwindow->gui->unlock_window();
255 mwindow->restart_brender();
256 mwindow->sync_parameters(CHANGE_EDL);
257 mwindow->gui->lock_window("PatchGUI::toggle_behavior 1");
261 mwindow->gui->unlock_window();
262 mwindow->restart_brender();
263 mwindow->sync_parameters(CHANGE_PARAMS);
264 mwindow->gui->lock_window("PatchGUI::toggle_behavior 2");
267 // Update affected tracks in cwindow
269 mwindow->cwindow->update(0, 1, 1);
276 mwindow->gui->update(0, NORMAL_DRAW, 0, 0, 0, 0, 0);
284 mwindow->gui->update_patchbay();
288 char* PatchGUI::calculate_nudge_text(int *changed)
290 if(changed) *changed = 0;
291 if(track->edl->session->nudge_format)
293 sprintf(string_return, "%.4f", track->from_units(track->nudge));
294 if(changed && nudge && atof(nudge->get_text()) - atof(string_return) != 0)
299 sprintf(string_return, "%jd", track->nudge);
300 if(changed && nudge && atoi(nudge->get_text()) - atoi(string_return) != 0)
303 return string_return;
307 int64_t PatchGUI::calculate_nudge(const char *string)
309 if(mwindow->edl->session->nudge_format)
312 sscanf(string, "%f", &result);
313 return track->to_units(result, 0);
318 sscanf(string, "%jd", &temp);
324 PlayPatch::PlayPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
327 mwindow->theme->get_image_set("playpatch_data"),
334 this->mwindow = mwindow;
336 set_tooltip(_("Play track"));
340 int PlayPatch::button_press_event()
342 if(is_event_win() && get_buttonpress() == 1)
344 mwindow->undo->update_undo_before();
345 set_status(BC_Toggle::TOGGLE_DOWN);
346 update(!get_value());
347 patch->toggle_behavior(Tracks::PLAY,
350 &patch->track->play);
356 int PlayPatch::button_release_event()
358 int result = BC_Toggle::button_release_event();
359 if(patch->patchbay->drag_operation == Tracks::PLAY)
361 mwindow->undo->update_undo_after(_("play patch"), LOAD_PATCHES);
362 patch->patchbay->drag_operation = Tracks::NONE;
377 RecordPatch::RecordPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
380 mwindow->theme->get_image_set("recordpatch_data"),
387 this->mwindow = mwindow;
389 set_tooltip(_("Arm track"));
393 int RecordPatch::button_press_event()
395 if(is_event_win() && get_buttonpress() == 1)
397 mwindow->undo->update_undo_before();
398 set_status(BC_Toggle::TOGGLE_DOWN);
399 update(!get_value());
400 patch->toggle_behavior(Tracks::RECORD,
403 &patch->track->armed);
404 patch->title->set_back_color(patch->track->armed ?
405 get_resources()->text_background :
406 get_resources()->text_background_disarmed);
407 patch->title->set_text_row(0);
408 mwindow->gui->draw_overlays(1);
414 int RecordPatch::button_release_event()
416 int result = BC_Toggle::button_release_event();
417 if(patch->patchbay->drag_operation == Tracks::RECORD)
419 mwindow->undo->update_undo_after(_("record patch"), LOAD_PATCHES);
420 patch->patchbay->drag_operation = Tracks::NONE;
435 GangPatch::GangPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
437 mwindow->theme->get_image_set("gangpatch_data"),
438 patch->track->ganged,
444 this->mwindow = mwindow;
446 set_tooltip(_("Gang faders"));
450 int GangPatch::button_press_event()
452 if(is_event_win() && get_buttonpress() == 1)
454 mwindow->undo->update_undo_before();
455 set_status(BC_Toggle::TOGGLE_DOWN);
456 update(!get_value());
457 patch->toggle_behavior(Tracks::GANG,
460 &patch->track->ganged);
466 int GangPatch::button_release_event()
468 int result = BC_Toggle::button_release_event();
469 if(patch->patchbay->drag_operation == Tracks::GANG)
471 mwindow->undo->update_undo_after(_("gang patch"), LOAD_PATCHES);
472 patch->patchbay->drag_operation = Tracks::NONE;
487 DrawPatch::DrawPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
489 mwindow->theme->get_image_set("drawpatch_data"),
496 this->mwindow = mwindow;
498 set_tooltip(_("Draw media"));
502 int DrawPatch::button_press_event()
504 if(is_event_win() && get_buttonpress() == 1)
506 mwindow->undo->update_undo_before();
507 set_status(BC_Toggle::TOGGLE_DOWN);
508 update(!get_value());
509 patch->toggle_behavior(Tracks::DRAW,
512 &patch->track->draw);
518 int DrawPatch::button_release_event()
520 int result = BC_Toggle::button_release_event();
521 if(patch->patchbay->drag_operation == Tracks::DRAW)
523 mwindow->undo->update_undo_after(_("draw patch"), LOAD_PATCHES);
524 patch->patchbay->drag_operation = Tracks::NONE;
538 MutePatch::MutePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
540 mwindow->theme->get_image_set("mutepatch_data"),
541 mwindow->get_int_auto(patch, AUTOMATION_MUTE)->value,
547 this->mwindow = mwindow;
549 set_tooltip(_("Don't send to output"));
553 int MutePatch::button_press_event()
555 if(is_event_win() && get_buttonpress() == 1)
557 mwindow->undo->update_undo_before();
558 set_status(BC_Toggle::TOGGLE_DOWN);
559 update(!get_value());
561 double position = mwindow->edl->local_session->get_selectionstart(1);
562 Autos *mute_autos = patch->track->automation->autos[AUTOMATION_MUTE];
565 current = (IntAuto*)mute_autos->get_auto_for_editing(position);
566 current->value = get_value();
568 patch->toggle_behavior(Tracks::MUTE,
575 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MUTE])
577 mwindow->gui->draw_overlays(1);
584 int MutePatch::button_release_event()
586 int result = BC_Toggle::button_release_event();
587 if(patch->patchbay->drag_operation == Tracks::MUTE)
589 mwindow->undo->update_undo_after(_("mute patch"), LOAD_PATCHES);
590 patch->patchbay->drag_operation = Tracks::NONE;
596 ZoomPatch::ZoomPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
597 : BC_Tumbler(x, y, mwindow->theme->get_image_set("tumblepatch_data"))
599 this->mwindow = mwindow;
601 set_tooltip(_("Track Data Height"));
604 int ZoomPatch::handle_up_event()
606 patch->track->data_h *= 2;
607 bclamp(patch->track->data_h, MIN_TRACK_ZOOM, MAX_TRACK_ZOOM);
608 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
609 mwindow->gui->draw_trackmovement();
612 int ZoomPatch::handle_down_event()
614 patch->track->data_h /= 2;
615 bclamp(patch->track->data_h, MIN_TRACK_ZOOM, MAX_TRACK_ZOOM);
616 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
617 mwindow->gui->draw_trackmovement();
622 MasterPatch::MasterPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
623 : BC_Toggle(x, y, mwindow->theme->get_image_set("masterpatch_data"),
624 patch->track->master, "", 0, 0, 0)
626 this->mwindow = mwindow;
628 set_tooltip(_("Master Track"));
629 // *** CONTEXT_HELP ***
630 context_help_set_keyword("Displaying tracks: Ganged mode");
633 int MasterPatch::handle_event()
635 patch->track->master = patch->track->master ? 0 : 1;
636 mwindow->draw_trackmovement(); // delayed, can delete *this
641 ExpandPatch::ExpandPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
642 : BC_Toggle(x, y, mwindow->theme->get_image_set("expandpatch_data"),
643 patch->track->expand_view, "", 0, 0, 0)
645 this->mwindow = mwindow;
650 int ExpandPatch::button_press_event()
652 if(is_event_win() && get_buttonpress() == 1)
654 mwindow->undo->update_undo_before();
655 set_status(BC_Toggle::TOGGLE_DOWN);
656 update(!get_value());
657 patch->toggle_behavior(Tracks::EXPAND,
660 &patch->track->expand_view);
661 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
662 mwindow->gui->draw_trackmovement();
668 int ExpandPatch::button_release_event()
670 int result = BC_Toggle::button_release_event();
671 if(patch->patchbay->drag_operation == Tracks::EXPAND)
673 mwindow->undo->update_undo_after(_("expand patch"), LOAD_PATCHES);
674 patch->patchbay->drag_operation = Tracks::NONE;
680 TitlePatch::TitlePatch(MWindow *mwindow, PatchGUI *patch, int x, int y, int w)
681 : BC_TextBox(x, y, w, 1, patch->track->title, 1, MEDIUMFONT, 1)
683 this->mwindow = mwindow;
685 set_back_color(patch->track->armed ?
686 get_resources()->text_background :
687 get_resources()->text_background_disarmed);
690 void TitlePatch::update(const char *text)
692 set_back_color(patch->track->armed ?
693 get_resources()->text_background :
694 get_resources()->text_background_disarmed);
695 BC_TextBox::update(text);
698 int TitlePatch::handle_event()
700 mwindow->undo->update_undo_before(_("track title"), this);
701 strcpy(patch->track->title, get_text());
702 mwindow->update_plugin_titles();
703 mwindow->gui->draw_overlays(1);
704 mwindow->undo->update_undo_after(_("track title"), LOAD_PATCHES);
709 NudgePatch::NudgePatch(MWindow *mwindow,
718 patch->calculate_nudge_text(0))
720 this->mwindow = mwindow;
722 set_tooltip(_("Nudge"));
725 int NudgePatch::handle_event()
727 set_value(patch->calculate_nudge(get_text()));
731 void NudgePatch::set_value(int64_t value)
733 mwindow->undo->update_undo_before(_("nudge."), this);
734 patch->track->nudge = value;
736 if(patch->track->is_ganged() && patch->track->is_armed())
737 patch->patchbay->synchronize_nudge(patch->track->nudge, patch->track);
739 mwindow->undo->update_undo_after(_("nudge."), LOAD_PATCHES);
741 mwindow->gui->unlock_window();
742 if(patch->track->data_type == TRACK_VIDEO)
743 mwindow->restart_brender();
744 mwindow->sync_parameters(CHANGE_PARAMS);
745 mwindow->gui->lock_window("NudgePatch::handle_event 2");
747 mwindow->session->changes_made = 1;
751 int NudgePatch::button_press_event()
755 if(is_event_win() && cursor_inside())
757 if(get_buttonpress() == 4)
759 int value = patch->calculate_nudge(get_text());
760 value += calculate_increment();
766 if(get_buttonpress() == 5)
768 int value = patch->calculate_nudge(get_text());
769 value -= calculate_increment();
775 if(get_buttonpress() == 3)
777 patch->patchbay->nudge_popup->activate_menu(patch);
783 return BC_TextBox::button_press_event();
788 int64_t NudgePatch::calculate_increment()
790 if(patch->track->data_type == TRACK_AUDIO)
792 return (int64_t)ceil(patch->track->edl->session->sample_rate / 10.0);
796 return (int64_t)ceil(1.0 / patch->track->edl->session->frame_rate);
800 void NudgePatch::update()
803 char *string = patch->calculate_nudge_text(&changed);
805 BC_TextBox::update(string);
809 MixPatch::MixPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
810 : BC_Toggle(x, y, mwindow->theme->get_image_set("mixpatch_data"),
811 patch->mixer, "", 0, 0, 0)
813 this->mwindow = mwindow;
817 MixPatch::~MixPatch()
821 int MixPatch::handle_event()
823 int v = patch->track ? get_value() : 0;
824 if( patch->mixer != v ) {
826 mwindow->gui->update_mixers(patch->track, v);
829 mwindow->update_mixer_tracks();
834 void MixPatch::update(int v)
837 BC_Toggle::update(v);