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 if(track) track_id = track->get_id();
75 if(title) delete title;
76 if(record) delete record;
78 // if(automate) delete automate;
82 if(expand) delete expand;
83 if(nudge) delete nudge;
86 void PatchGUI::create_objects()
91 int PatchGUI::reposition(int x, int y)
97 if(x != this->x || y != this->y)
104 TRACE("PatchGUI::reposition 1\n");
105 title->reposition_window(title->get_x(), y1 + y, 0);
106 TRACE("PatchGUI::reposition 2\n");
108 y1 += mwindow->theme->title_h;
112 TRACE("PatchGUI::reposition 3\n");
113 play->reposition_window(play->get_x(), y1 + y);
115 TRACE("PatchGUI::reposition 4\n");
116 record->reposition_window(record->get_x(), y1 + y);
117 x1 += record->get_w();
118 TRACE("PatchGUI::reposition 5\n");
119 // automate->reposition_window(x1, y1 + y);
120 // x1 += automate->get_w();
121 gang->reposition_window(gang->get_x(), y1 + y);
123 TRACE("PatchGUI::reposition 6\n");
124 draw->reposition_window(draw->get_x(), y1 + y);
126 TRACE("PatchGUI::reposition 7\n");
127 mute->reposition_window(mute->get_x(), y1 + y);
129 TRACE("PatchGUI::reposition 8\n");
133 TRACE("PatchGUI::reposition 9\n");
134 // VFrame **expandpatch_data = mwindow->theme->get_image_set("expandpatch_data");
135 // int x = patchbay->get_w() - 10 - expandpatch_data[0]->get_w();
136 expand->reposition_window(
139 TRACE("PatchGUI::reposition 10\n");
140 x1 += expand->get_w();
141 TRACE("PatchGUI::reposition 11\n");
144 y1 += mwindow->theme->play_h;
148 y1 += mwindow->theme->title_h;
149 y1 += mwindow->theme->play_h;
155 int PatchGUI::update(int x, int y)
157 //TRACE("PatchGUI::update 1");
159 //TRACE("PatchGUI::update 10");
161 int h = track->vertical_span(mwindow->theme);
164 //printf("PatchGUI::update 10\n");
175 title->update(track->title);
181 patchbay->add_subwindow(title = new TitlePatch(mwindow, this, x1 + x, y1 + y));
183 y1 += mwindow->theme->title_h;
187 if(h - y1 < mwindow->theme->play_h)
189 delete play; play = 0;
190 delete record; record = 0;
191 delete gang; gang = 0;
192 delete draw; draw = 0;
193 delete mute; mute = 0;
194 delete expand; expand = 0;
198 play->update(track->play);
199 record->update(track->record);
200 gang->update(track->gang);
201 draw->update(track->draw);
202 mute->update(mute->get_keyframe(mwindow, this)->value);
203 expand->update(track->expand_view);
207 if(h - y1 >= mwindow->theme->play_h)
209 patchbay->add_subwindow(play = new PlayPatch(mwindow, this, x1 + x, y1 + y));
210 //printf("PatchGUI::update %d %d\n", __LINE__, play->get_h());
212 patchbay->add_subwindow(record = new RecordPatch(mwindow, this, x1 + x, y1 + y));
213 x1 += record->get_w();
214 patchbay->add_subwindow(gang = new GangPatch(mwindow, this, x1 + x, y1 + y));
216 patchbay->add_subwindow(draw = new DrawPatch(mwindow, this, x1 + x, y1 + y));
218 patchbay->add_subwindow(mute = new MutePatch(mwindow, this, x1 + x, y1 + y));
221 VFrame **expandpatch_data = mwindow->theme->get_image_set("expandpatch_data");
222 patchbay->add_subwindow(expand = new ExpandPatch(mwindow,
224 patchbay->get_w() - 10 - expandpatch_data[0]->get_w(),
226 x1 += expand->get_w();
228 y1 += mwindow->theme->play_h;
235 void PatchGUI::toggle_behavior(int type,
240 if(toggle->shift_down())
242 // all selected if nothing previously selected or
243 // if this patch was previously the only one selected
245 case Tracks::MUTE: { // negative logic for normally off
246 int total_selected = mwindow->edl->tracks->total() -
247 mwindow->edl->tracks->total_of(type);
248 int current_output = *output;
249 int selected = !total_selected || (total_selected == 1 &&
250 !current_output ) ? 0 : 1;
251 mwindow->edl->tracks->select_all(type, selected);
252 if( selected ) *output = 0;
255 int total_selected = mwindow->edl->tracks->total_of(type);
256 int current_output = *output;
257 int selected = !total_selected || (total_selected == 1 &&
258 current_output ) ? 1 : 0;
259 mwindow->edl->tracks->select_all(type, selected);
260 if( !selected ) *output = 1;
264 patchbay->drag_operation = type;
265 patchbay->new_status = 1;
270 // Select + drag behavior
271 patchbay->drag_operation = type;
272 patchbay->new_status = value;
278 mwindow->gui->unlock_window();
279 mwindow->restart_brender();
280 mwindow->sync_parameters(CHANGE_EDL);
281 mwindow->gui->lock_window("PatchGUI::toggle_behavior 1");
285 mwindow->gui->unlock_window();
286 mwindow->restart_brender();
287 mwindow->sync_parameters(CHANGE_PARAMS);
288 mwindow->gui->lock_window("PatchGUI::toggle_behavior 2");
291 // Update affected tracks in cwindow
293 mwindow->cwindow->update(0, 1, 1);
300 mwindow->gui->update(0, 1, 0, 0, 0, 0, 0);
308 mwindow->gui->update_patchbay();
312 char* PatchGUI::calculate_nudge_text(int *changed)
314 if(changed) *changed = 0;
315 if(track->edl->session->nudge_format)
317 sprintf(string_return, "%.4f", track->from_units(track->nudge));
318 if(changed && nudge && atof(nudge->get_text()) - atof(string_return) != 0)
323 sprintf(string_return, "%jd", track->nudge);
324 if(changed && nudge && atoi(nudge->get_text()) - atoi(string_return) != 0)
327 return string_return;
331 int64_t PatchGUI::calculate_nudge(const char *string)
333 if(mwindow->edl->session->nudge_format)
336 sscanf(string, "%f", &result);
337 return track->to_units(result, 0);
342 sscanf(string, "%jd", &temp);
358 PlayPatch::PlayPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
361 mwindow->theme->get_image_set("playpatch_data"),
368 this->mwindow = mwindow;
370 set_tooltip(_("Play track"));
374 int PlayPatch::button_press_event()
376 if(is_event_win() && get_buttonpress() == 1)
378 mwindow->undo->update_undo_before();
379 set_status(BC_Toggle::TOGGLE_DOWN);
380 update(!get_value());
381 patch->toggle_behavior(Tracks::PLAY,
384 &patch->track->play);
390 int PlayPatch::button_release_event()
392 int result = BC_Toggle::button_release_event();
393 if(patch->patchbay->drag_operation == Tracks::PLAY)
395 mwindow->undo->update_undo_after(_("play patch"), LOAD_PATCHES);
396 patch->patchbay->drag_operation = Tracks::NONE;
411 RecordPatch::RecordPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
414 mwindow->theme->get_image_set("recordpatch_data"),
415 patch->track->record,
421 this->mwindow = mwindow;
423 set_tooltip(_("Arm track"));
427 int RecordPatch::button_press_event()
429 if(is_event_win() && get_buttonpress() == 1)
431 mwindow->undo->update_undo_before();
432 set_status(BC_Toggle::TOGGLE_DOWN);
433 update(!get_value());
434 patch->toggle_behavior(Tracks::RECORD,
437 &patch->track->record);
443 int RecordPatch::button_release_event()
445 int result = BC_Toggle::button_release_event();
446 if(patch->patchbay->drag_operation == Tracks::RECORD)
448 mwindow->undo->update_undo_after(_("record patch"), LOAD_PATCHES);
449 patch->patchbay->drag_operation = Tracks::NONE;
464 GangPatch::GangPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
466 mwindow->theme->get_image_set("gangpatch_data"),
473 this->mwindow = mwindow;
475 set_tooltip(_("Gang faders"));
479 int GangPatch::button_press_event()
481 if(is_event_win() && get_buttonpress() == 1)
483 mwindow->undo->update_undo_before();
484 set_status(BC_Toggle::TOGGLE_DOWN);
485 update(!get_value());
486 patch->toggle_behavior(Tracks::GANG,
489 &patch->track->gang);
495 int GangPatch::button_release_event()
497 int result = BC_Toggle::button_release_event();
498 if(patch->patchbay->drag_operation == Tracks::GANG)
500 mwindow->undo->update_undo_after(_("gang patch"), LOAD_PATCHES);
501 patch->patchbay->drag_operation = Tracks::NONE;
516 DrawPatch::DrawPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
518 mwindow->theme->get_image_set("drawpatch_data"),
525 this->mwindow = mwindow;
527 set_tooltip(_("Draw media"));
531 int DrawPatch::button_press_event()
533 if(is_event_win() && get_buttonpress() == 1)
535 mwindow->undo->update_undo_before();
536 set_status(BC_Toggle::TOGGLE_DOWN);
537 update(!get_value());
538 patch->toggle_behavior(Tracks::DRAW,
541 &patch->track->draw);
547 int DrawPatch::button_release_event()
549 int result = BC_Toggle::button_release_event();
550 if(patch->patchbay->drag_operation == Tracks::DRAW)
552 mwindow->undo->update_undo_after(_("draw patch"), LOAD_PATCHES);
553 patch->patchbay->drag_operation = Tracks::NONE;
567 MutePatch::MutePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
569 mwindow->theme->get_image_set("mutepatch_data"),
570 get_keyframe(mwindow, patch)->value,
576 this->mwindow = mwindow;
578 set_tooltip(_("Don't send to output"));
582 int MutePatch::button_press_event()
584 if(is_event_win() && get_buttonpress() == 1)
586 mwindow->undo->update_undo_before();
587 set_status(BC_Toggle::TOGGLE_DOWN);
588 update(!get_value());
590 double position = mwindow->edl->local_session->get_selectionstart(1);
591 Autos *mute_autos = patch->track->automation->autos[AUTOMATION_MUTE];
594 current = (IntAuto*)mute_autos->get_auto_for_editing(position);
595 current->value = get_value();
597 patch->toggle_behavior(Tracks::MUTE,
604 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MUTE])
606 mwindow->gui->draw_overlays(1);
613 int MutePatch::button_release_event()
615 int result = BC_Toggle::button_release_event();
616 if(patch->patchbay->drag_operation == Tracks::MUTE)
618 mwindow->undo->update_undo_after(_("mute patch"), LOAD_PATCHES);
619 patch->patchbay->drag_operation = Tracks::NONE;
624 IntAuto* MutePatch::get_keyframe(MWindow *mwindow, PatchGUI *patch)
627 double unit_position = mwindow->edl->local_session->get_selectionstart(1);
628 unit_position = mwindow->edl->align_to_frame(unit_position, 0);
629 unit_position = patch->track->to_units(unit_position, 0);
630 return (IntAuto*)patch->track->automation->autos[AUTOMATION_MUTE]->get_prev_auto(
631 (int64_t)unit_position,
647 ExpandPatch::ExpandPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
650 mwindow->theme->get_image_set("expandpatch_data"),
651 patch->track->expand_view,
657 this->mwindow = mwindow;
662 int ExpandPatch::button_press_event()
664 if(is_event_win() && get_buttonpress() == 1)
666 mwindow->undo->update_undo_before();
667 set_status(BC_Toggle::TOGGLE_DOWN);
668 update(!get_value());
669 patch->toggle_behavior(Tracks::EXPAND,
672 &patch->track->expand_view);
673 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
674 mwindow->gui->draw_trackmovement();
680 int ExpandPatch::button_release_event()
682 int result = BC_Toggle::button_release_event();
683 if(patch->patchbay->drag_operation == Tracks::EXPAND)
685 mwindow->undo->update_undo_after(_("expand patch"), LOAD_PATCHES);
686 patch->patchbay->drag_operation = Tracks::NONE;
695 TitlePatch::TitlePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
698 patch->patchbay->get_w() - 10,
703 this->mwindow = mwindow;
707 int TitlePatch::handle_event()
709 mwindow->undo->update_undo_before(_("track title"), this);
710 strcpy(patch->track->title, get_text());
711 mwindow->update_plugin_titles();
712 mwindow->gui->draw_overlays(1);
713 mwindow->undo->update_undo_after(_("track title"), LOAD_PATCHES);
725 NudgePatch::NudgePatch(MWindow *mwindow,
734 patch->calculate_nudge_text(0))
736 this->mwindow = mwindow;
738 set_tooltip(_("Nudge"));
741 int NudgePatch::handle_event()
743 set_value(patch->calculate_nudge(get_text()));
747 void NudgePatch::set_value(int64_t value)
749 mwindow->undo->update_undo_before(_("nudge"), this);
750 patch->track->nudge = value;
752 if(patch->track->gang && patch->track->record)
753 patch->patchbay->synchronize_nudge(patch->track->nudge, patch->track);
755 mwindow->undo->update_undo_after(_("nudge"), LOAD_PATCHES);
757 mwindow->gui->unlock_window();
758 if(patch->track->data_type == TRACK_VIDEO)
759 mwindow->restart_brender();
760 mwindow->sync_parameters(CHANGE_PARAMS);
761 mwindow->gui->lock_window("NudgePatch::handle_event 2");
763 mwindow->session->changes_made = 1;
767 int NudgePatch::button_press_event()
771 if(is_event_win() && cursor_inside())
773 if(get_buttonpress() == 4)
775 int value = patch->calculate_nudge(get_text());
776 value += calculate_increment();
782 if(get_buttonpress() == 5)
784 int value = patch->calculate_nudge(get_text());
785 value -= calculate_increment();
791 if(get_buttonpress() == 3)
793 patch->patchbay->nudge_popup->activate_menu(patch);
799 return BC_TextBox::button_press_event();
804 int64_t NudgePatch::calculate_increment()
806 if(patch->track->data_type == TRACK_AUDIO)
808 return (int64_t)ceil(patch->track->edl->session->sample_rate / 10.0);
812 return (int64_t)ceil(1.0 / patch->track->edl->session->frame_rate);
816 void NudgePatch::update()
819 char *string = patch->calculate_nudge_text(&changed);
821 BC_TextBox::update(string);