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;
70 track_id = track ? track->get_id() : -1;
88 void PatchGUI::create_objects()
93 int PatchGUI::reposition(int x, int y)
99 if(x != this->x || y != this->y)
106 TRACE("PatchGUI::reposition 1\n");
107 title->reposition_window(title->get_x(), y1 + y, 0);
108 TRACE("PatchGUI::reposition 2\n");
110 y1 += mwindow->theme->title_h;
114 TRACE("PatchGUI::reposition 3\n");
115 play->reposition_window(play->get_x(), y1 + y);
117 TRACE("PatchGUI::reposition 4\n");
118 record->reposition_window(record->get_x(), y1 + y);
119 x1 += record->get_w();
120 TRACE("PatchGUI::reposition 5\n");
121 // automate->reposition_window(x1, y1 + y);
122 // x1 += automate->get_w();
123 gang->reposition_window(gang->get_x(), y1 + y);
125 TRACE("PatchGUI::reposition 6\n");
126 draw->reposition_window(draw->get_x(), y1 + y);
128 TRACE("PatchGUI::reposition 7\n");
129 mute->reposition_window(mute->get_x(), y1 + y);
131 TRACE("PatchGUI::reposition 8\n");
135 TRACE("PatchGUI::reposition 9\n");
136 // VFrame **expandpatch_data = mwindow->theme->get_image_set("expandpatch_data");
137 // int x = patchbay->get_w() - 10 - expandpatch_data[0]->get_w();
138 expand->reposition_window(
141 TRACE("PatchGUI::reposition 10\n");
142 x1 += expand->get_w();
143 TRACE("PatchGUI::reposition 11\n");
146 y1 += mwindow->theme->play_h;
150 y1 += mwindow->theme->title_h;
151 y1 += mwindow->theme->play_h;
157 int PatchGUI::update(int x, int y)
159 //TRACE("PatchGUI::update 1");
161 //TRACE("PatchGUI::update 10");
163 int h = track->vertical_span(mwindow->theme);
166 //printf("PatchGUI::update 10\n");
177 title->update(track->title);
183 patchbay->add_subwindow(title = new TitlePatch(mwindow, this, x1 + x, y1 + y));
185 y1 += mwindow->theme->title_h;
189 if(h - y1 < mwindow->theme->play_h)
191 delete play; play = 0;
192 delete record; record = 0;
193 delete gang; gang = 0;
194 delete draw; draw = 0;
195 delete mute; mute = 0;
196 delete expand; expand = 0;
200 play->update(track->play);
201 record->update(track->record);
202 gang->update(track->gang);
203 draw->update(track->draw);
204 mute->update(mwindow->get_int_auto(this, AUTOMATION_MUTE)->value);
205 expand->update(track->expand_view);
209 if(h - y1 >= mwindow->theme->play_h)
211 patchbay->add_subwindow(play = new PlayPatch(mwindow, this, x1 + x, y1 + y));
212 //printf("PatchGUI::update %d %d\n", __LINE__, play->get_h());
214 patchbay->add_subwindow(record = new RecordPatch(mwindow, this, x1 + x, y1 + y));
215 x1 += record->get_w();
216 patchbay->add_subwindow(gang = new GangPatch(mwindow, this, x1 + x, y1 + y));
218 patchbay->add_subwindow(draw = new DrawPatch(mwindow, this, x1 + x, y1 + y));
220 patchbay->add_subwindow(mute = new MutePatch(mwindow, this, x1 + x, y1 + y));
223 VFrame **expandpatch_data = mwindow->theme->get_image_set("expandpatch_data");
224 patchbay->add_subwindow(expand = new ExpandPatch(mwindow,
226 patchbay->get_w() - 10 - expandpatch_data[0]->get_w(),
228 x1 += expand->get_w();
230 y1 += mwindow->theme->play_h;
237 void PatchGUI::toggle_behavior(int type,
242 if(toggle->shift_down()) {
243 int sense = type != Tracks::MUTE ? 1 : 0;
244 // all selected if nothing previously selected or
245 // if this patch was previously the only one selected
246 int total_type = mwindow->edl->tracks->total_of(type);
247 int total_selected = sense ? total_type :
248 mwindow->edl->tracks->total() - total_type;
249 int selected = !total_selected || (total_selected == 1 &&
250 *output == sense ) ? sense : 1-sense;
251 mwindow->edl->tracks->select_all(type, selected);
252 if( selected != sense ) *output = sense;
254 patchbay->drag_operation = type;
255 patchbay->new_status = 1;
260 // Select + drag behavior
261 patchbay->drag_operation = type;
262 patchbay->new_status = value;
268 mwindow->gui->unlock_window();
269 mwindow->restart_brender();
270 mwindow->sync_parameters(CHANGE_EDL);
271 mwindow->gui->lock_window("PatchGUI::toggle_behavior 1");
275 mwindow->gui->unlock_window();
276 mwindow->restart_brender();
277 mwindow->sync_parameters(CHANGE_PARAMS);
278 mwindow->gui->lock_window("PatchGUI::toggle_behavior 2");
281 // Update affected tracks in cwindow
283 mwindow->cwindow->update(0, 1, 1);
290 mwindow->gui->update(0, 1, 0, 0, 0, 0, 0);
298 mwindow->gui->update_patchbay();
302 char* PatchGUI::calculate_nudge_text(int *changed)
304 if(changed) *changed = 0;
305 if(track->edl->session->nudge_format)
307 sprintf(string_return, "%.4f", track->from_units(track->nudge));
308 if(changed && nudge && atof(nudge->get_text()) - atof(string_return) != 0)
313 sprintf(string_return, "%jd", track->nudge);
314 if(changed && nudge && atoi(nudge->get_text()) - atoi(string_return) != 0)
317 return string_return;
321 int64_t PatchGUI::calculate_nudge(const char *string)
323 if(mwindow->edl->session->nudge_format)
326 sscanf(string, "%f", &result);
327 return track->to_units(result, 0);
332 sscanf(string, "%jd", &temp);
348 PlayPatch::PlayPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
351 mwindow->theme->get_image_set("playpatch_data"),
358 this->mwindow = mwindow;
360 set_tooltip(_("Play track"));
364 int PlayPatch::button_press_event()
366 if(is_event_win() && get_buttonpress() == 1)
368 mwindow->undo->update_undo_before();
369 set_status(BC_Toggle::TOGGLE_DOWN);
370 update(!get_value());
371 patch->toggle_behavior(Tracks::PLAY,
374 &patch->track->play);
380 int PlayPatch::button_release_event()
382 int result = BC_Toggle::button_release_event();
383 if(patch->patchbay->drag_operation == Tracks::PLAY)
385 mwindow->undo->update_undo_after(_("play patch"), LOAD_PATCHES);
386 patch->patchbay->drag_operation = Tracks::NONE;
401 RecordPatch::RecordPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
404 mwindow->theme->get_image_set("recordpatch_data"),
405 patch->track->record,
411 this->mwindow = mwindow;
413 set_tooltip(_("Arm track"));
417 int RecordPatch::button_press_event()
419 if(is_event_win() && get_buttonpress() == 1)
421 mwindow->undo->update_undo_before();
422 set_status(BC_Toggle::TOGGLE_DOWN);
423 update(!get_value());
424 patch->toggle_behavior(Tracks::RECORD,
427 &patch->track->record);
428 patch->title->set_back_color(patch->track->record ?
429 get_resources()->text_background :
430 get_resources()->text_background_disarmed);
431 patch->title->set_text_row(0);
437 int RecordPatch::button_release_event()
439 int result = BC_Toggle::button_release_event();
440 if(patch->patchbay->drag_operation == Tracks::RECORD)
442 mwindow->undo->update_undo_after(_("record patch"), LOAD_PATCHES);
443 patch->patchbay->drag_operation = Tracks::NONE;
458 GangPatch::GangPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
460 mwindow->theme->get_image_set("gangpatch_data"),
467 this->mwindow = mwindow;
469 set_tooltip(_("Gang faders"));
473 int GangPatch::button_press_event()
475 if(is_event_win() && get_buttonpress() == 1)
477 mwindow->undo->update_undo_before();
478 set_status(BC_Toggle::TOGGLE_DOWN);
479 update(!get_value());
480 patch->toggle_behavior(Tracks::GANG,
483 &patch->track->gang);
489 int GangPatch::button_release_event()
491 int result = BC_Toggle::button_release_event();
492 if(patch->patchbay->drag_operation == Tracks::GANG)
494 mwindow->undo->update_undo_after(_("gang patch"), LOAD_PATCHES);
495 patch->patchbay->drag_operation = Tracks::NONE;
510 DrawPatch::DrawPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
512 mwindow->theme->get_image_set("drawpatch_data"),
519 this->mwindow = mwindow;
521 set_tooltip(_("Draw media"));
525 int DrawPatch::button_press_event()
527 if(is_event_win() && get_buttonpress() == 1)
529 mwindow->undo->update_undo_before();
530 set_status(BC_Toggle::TOGGLE_DOWN);
531 update(!get_value());
532 patch->toggle_behavior(Tracks::DRAW,
535 &patch->track->draw);
541 int DrawPatch::button_release_event()
543 int result = BC_Toggle::button_release_event();
544 if(patch->patchbay->drag_operation == Tracks::DRAW)
546 mwindow->undo->update_undo_after(_("draw patch"), LOAD_PATCHES);
547 patch->patchbay->drag_operation = Tracks::NONE;
561 MutePatch::MutePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
563 mwindow->theme->get_image_set("mutepatch_data"),
564 mwindow->get_int_auto(patch, AUTOMATION_MUTE)->value,
570 this->mwindow = mwindow;
572 set_tooltip(_("Don't send to output"));
576 int MutePatch::button_press_event()
578 if(is_event_win() && get_buttonpress() == 1)
580 mwindow->undo->update_undo_before();
581 set_status(BC_Toggle::TOGGLE_DOWN);
582 update(!get_value());
584 double position = mwindow->edl->local_session->get_selectionstart(1);
585 Autos *mute_autos = patch->track->automation->autos[AUTOMATION_MUTE];
588 current = (IntAuto*)mute_autos->get_auto_for_editing(position);
589 current->value = get_value();
591 patch->toggle_behavior(Tracks::MUTE,
598 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MUTE])
600 mwindow->gui->draw_overlays(1);
607 int MutePatch::button_release_event()
609 int result = BC_Toggle::button_release_event();
610 if(patch->patchbay->drag_operation == Tracks::MUTE)
612 mwindow->undo->update_undo_after(_("mute patch"), LOAD_PATCHES);
613 patch->patchbay->drag_operation = Tracks::NONE;
620 ExpandPatch::ExpandPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
623 mwindow->theme->get_image_set("expandpatch_data"),
624 patch->track->expand_view,
630 this->mwindow = mwindow;
635 int ExpandPatch::button_press_event()
637 if(is_event_win() && get_buttonpress() == 1)
639 mwindow->undo->update_undo_before();
640 set_status(BC_Toggle::TOGGLE_DOWN);
641 update(!get_value());
642 patch->toggle_behavior(Tracks::EXPAND,
645 &patch->track->expand_view);
646 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
647 mwindow->gui->draw_trackmovement();
653 int ExpandPatch::button_release_event()
655 int result = BC_Toggle::button_release_event();
656 if(patch->patchbay->drag_operation == Tracks::EXPAND)
658 mwindow->undo->update_undo_after(_("expand patch"), LOAD_PATCHES);
659 patch->patchbay->drag_operation = Tracks::NONE;
665 TitlePatch::TitlePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
666 : BC_TextBox(x, y, patch->patchbay->get_w() - 10, 1,
667 patch->track->title, 1, MEDIUMFONT, 1)
669 this->mwindow = mwindow;
671 set_back_color(patch->track->record ?
672 get_resources()->text_background :
673 get_resources()->text_background_disarmed);
676 void TitlePatch::update(const char *text)
678 set_back_color(patch->track->record ?
679 get_resources()->text_background :
680 get_resources()->text_background_disarmed);
681 BC_TextBox::update(text);
684 int TitlePatch::handle_event()
686 mwindow->undo->update_undo_before(_("track title"), this);
687 strcpy(patch->track->title, get_text());
688 mwindow->update_plugin_titles();
689 mwindow->gui->draw_overlays(1);
690 mwindow->undo->update_undo_after(_("track title"), LOAD_PATCHES);
695 NudgePatch::NudgePatch(MWindow *mwindow,
704 patch->calculate_nudge_text(0))
706 this->mwindow = mwindow;
708 set_tooltip(_("Nudge"));
711 int NudgePatch::handle_event()
713 set_value(patch->calculate_nudge(get_text()));
717 void NudgePatch::set_value(int64_t value)
719 mwindow->undo->update_undo_before(_("nudge."), this);
720 patch->track->nudge = value;
722 if(patch->track->gang && patch->track->record)
723 patch->patchbay->synchronize_nudge(patch->track->nudge, patch->track);
725 mwindow->undo->update_undo_after(_("nudge."), LOAD_PATCHES);
727 mwindow->gui->unlock_window();
728 if(patch->track->data_type == TRACK_VIDEO)
729 mwindow->restart_brender();
730 mwindow->sync_parameters(CHANGE_PARAMS);
731 mwindow->gui->lock_window("NudgePatch::handle_event 2");
733 mwindow->session->changes_made = 1;
737 int NudgePatch::button_press_event()
741 if(is_event_win() && cursor_inside())
743 if(get_buttonpress() == 4)
745 int value = patch->calculate_nudge(get_text());
746 value += calculate_increment();
752 if(get_buttonpress() == 5)
754 int value = patch->calculate_nudge(get_text());
755 value -= calculate_increment();
761 if(get_buttonpress() == 3)
763 patch->patchbay->nudge_popup->activate_menu(patch);
769 return BC_TextBox::button_press_event();
774 int64_t NudgePatch::calculate_increment()
776 if(patch->track->data_type == TRACK_AUDIO)
778 return (int64_t)ceil(patch->track->edl->session->sample_rate / 10.0);
782 return (int64_t)ceil(1.0 / patch->track->edl->session->frame_rate);
786 void NudgePatch::update()
789 char *string = patch->calculate_nudge_text(&changed);
791 BC_TextBox::update(string);
795 MixPatch::MixPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
796 : BC_Toggle(x, y, mwindow->theme->get_image_set("mixpatch_data"),
797 patch->mixer, "", 0, 0, 0)
799 this->mwindow = mwindow;
803 MixPatch::~MixPatch()
807 int MixPatch::handle_event()
809 int v = patch->track ? get_value() : 0;
810 if( patch->mixer != v ) {
812 mwindow->gui->update_mixers(patch->track, v);
815 mwindow->update_mixer_tracks();
820 void MixPatch::update(int v)
823 BC_Toggle::update(v);