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;
71 track_id = track ? track->get_id() : -1;
90 void PatchGUI::create_objects()
95 int PatchGUI::reposition(int x, int y)
101 if( x != this->x || y != this->y ) {
102 this->x = x; this->y = y;
105 title->reposition_window(title->get_x(), y1 + y, 0);
107 expand->reposition_window(expand->get_x(), y1 + y);
108 y1 += mwindow->theme->title_h;
111 play->reposition_window(play->get_x(), y1 + y);
113 record->reposition_window(record->get_x(), y1 + y);
114 x1 += record->get_w();
115 // automate->reposition_window(x1, y1 + y);
116 // x1 += automate->get_w();
117 gang->reposition_window(gang->get_x(), y1 + y);
119 draw->reposition_window(draw->get_x(), y1 + y);
121 mute->reposition_window(mute->get_x(), y1 + y);
123 zoom->reposition_window(zoom->get_x(), y1 + y);
125 y1 += mwindow->theme->play_h;
129 y1 += mwindow->theme->title_h;
131 y1 += mwindow->theme->play_h;
137 int PatchGUI::update(int x, int y)
139 //TRACE("PatchGUI::update 1");
141 //TRACE("PatchGUI::update 10");
143 int h = track->vertical_span(mwindow->theme);
146 //printf("PatchGUI::update 10\n");
148 int y2 = y1 + mwindow->theme->title_h;
151 delete title; title = 0;
152 delete expand; expand = 0;
155 title->update(track->title);
156 expand->update(track->expand_view);
160 VFrame **expandpatch_data = mwindow->theme->get_image_set("expandpatch_data");
161 int x2 = patchbay->get_w() - expandpatch_data[0]->get_w() - 5;
162 patchbay->add_subwindow(title = new TitlePatch(mwindow, this, x1 + x, y1 + y, x2-x1-5));
163 patchbay->add_subwindow(expand = new ExpandPatch(mwindow, this, x2, y1 + y));
169 y2 = y1 + mwindow->theme->play_h;
172 delete play; play = 0;
173 delete record; record = 0;
174 delete gang; gang = 0;
175 delete draw; draw = 0;
176 delete mute; mute = 0;
177 delete zoom; zoom = 0;
180 play->update(track->play);
181 record->update(track->record);
182 gang->update(track->gang);
183 draw->update(track->draw);
184 mute->update(mwindow->get_int_auto(this, AUTOMATION_MUTE)->value);
188 patchbay->add_subwindow(play = new PlayPatch(mwindow, this, x1 + x, y1 + y));
189 //printf("PatchGUI::update %d %d\n", __LINE__, play->get_h());
191 patchbay->add_subwindow(record = new RecordPatch(mwindow, this, x1 + x, y1 + y));
192 x1 += record->get_w();
193 patchbay->add_subwindow(gang = new GangPatch(mwindow, this, x1 + x, y1 + y));
195 patchbay->add_subwindow(draw = new DrawPatch(mwindow, this, x1 + x, y1 + y));
197 patchbay->add_subwindow(mute = new MutePatch(mwindow, this, x1 + x, y1 + y));
199 patchbay->add_subwindow(zoom = new ZoomPatch(mwindow, this, x1 + x, y1 + y));
209 void PatchGUI::toggle_behavior(int type,
214 if(toggle->shift_down()) {
215 int sense = type != Tracks::MUTE ? 1 : 0;
216 // all selected if nothing previously selected or
217 // if this patch was previously the only one selected
218 int total_type = mwindow->edl->tracks->total_of(type);
219 int total_selected = sense ? total_type :
220 mwindow->edl->tracks->total() - total_type;
221 int selected = !total_selected || (total_selected == 1 &&
222 *output == sense ) ? sense : 1-sense;
223 mwindow->edl->tracks->select_all(type, selected);
224 if( selected != sense ) *output = sense;
226 patchbay->drag_operation = type;
227 patchbay->new_status = 1;
232 // Select + drag behavior
233 patchbay->drag_operation = type;
234 patchbay->new_status = value;
240 mwindow->gui->unlock_window();
241 mwindow->restart_brender();
242 mwindow->sync_parameters(CHANGE_EDL);
243 mwindow->gui->lock_window("PatchGUI::toggle_behavior 1");
247 mwindow->gui->unlock_window();
248 mwindow->restart_brender();
249 mwindow->sync_parameters(CHANGE_PARAMS);
250 mwindow->gui->lock_window("PatchGUI::toggle_behavior 2");
253 // Update affected tracks in cwindow
255 mwindow->cwindow->update(0, 1, 1);
262 mwindow->gui->update(0, NORMAL_DRAW, 0, 0, 0, 0, 0);
270 mwindow->gui->update_patchbay();
274 char* PatchGUI::calculate_nudge_text(int *changed)
276 if(changed) *changed = 0;
277 if(track->edl->session->nudge_format)
279 sprintf(string_return, "%.4f", track->from_units(track->nudge));
280 if(changed && nudge && atof(nudge->get_text()) - atof(string_return) != 0)
285 sprintf(string_return, "%jd", track->nudge);
286 if(changed && nudge && atoi(nudge->get_text()) - atoi(string_return) != 0)
289 return string_return;
293 int64_t PatchGUI::calculate_nudge(const char *string)
295 if(mwindow->edl->session->nudge_format)
298 sscanf(string, "%f", &result);
299 return track->to_units(result, 0);
304 sscanf(string, "%jd", &temp);
310 PlayPatch::PlayPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
313 mwindow->theme->get_image_set("playpatch_data"),
320 this->mwindow = mwindow;
322 set_tooltip(_("Play track"));
326 int PlayPatch::button_press_event()
328 if(is_event_win() && get_buttonpress() == 1)
330 mwindow->undo->update_undo_before();
331 set_status(BC_Toggle::TOGGLE_DOWN);
332 update(!get_value());
333 patch->toggle_behavior(Tracks::PLAY,
336 &patch->track->play);
342 int PlayPatch::button_release_event()
344 int result = BC_Toggle::button_release_event();
345 if(patch->patchbay->drag_operation == Tracks::PLAY)
347 mwindow->undo->update_undo_after(_("play patch"), LOAD_PATCHES);
348 patch->patchbay->drag_operation = Tracks::NONE;
363 RecordPatch::RecordPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
366 mwindow->theme->get_image_set("recordpatch_data"),
367 patch->track->record,
373 this->mwindow = mwindow;
375 set_tooltip(_("Arm track"));
379 int RecordPatch::button_press_event()
381 if(is_event_win() && get_buttonpress() == 1)
383 mwindow->undo->update_undo_before();
384 set_status(BC_Toggle::TOGGLE_DOWN);
385 update(!get_value());
386 patch->toggle_behavior(Tracks::RECORD,
389 &patch->track->record);
390 patch->title->set_back_color(patch->track->record ?
391 get_resources()->text_background :
392 get_resources()->text_background_disarmed);
393 patch->title->set_text_row(0);
394 mwindow->gui->draw_overlays(1);
400 int RecordPatch::button_release_event()
402 int result = BC_Toggle::button_release_event();
403 if(patch->patchbay->drag_operation == Tracks::RECORD)
405 mwindow->undo->update_undo_after(_("record patch"), LOAD_PATCHES);
406 patch->patchbay->drag_operation = Tracks::NONE;
421 GangPatch::GangPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
423 mwindow->theme->get_image_set("gangpatch_data"),
430 this->mwindow = mwindow;
432 set_tooltip(_("Gang faders"));
436 int GangPatch::button_press_event()
438 if(is_event_win() && get_buttonpress() == 1)
440 mwindow->undo->update_undo_before();
441 set_status(BC_Toggle::TOGGLE_DOWN);
442 update(!get_value());
443 patch->toggle_behavior(Tracks::GANG,
446 &patch->track->gang);
452 int GangPatch::button_release_event()
454 int result = BC_Toggle::button_release_event();
455 if(patch->patchbay->drag_operation == Tracks::GANG)
457 mwindow->undo->update_undo_after(_("gang patch"), LOAD_PATCHES);
458 patch->patchbay->drag_operation = Tracks::NONE;
473 DrawPatch::DrawPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
475 mwindow->theme->get_image_set("drawpatch_data"),
482 this->mwindow = mwindow;
484 set_tooltip(_("Draw media"));
488 int DrawPatch::button_press_event()
490 if(is_event_win() && get_buttonpress() == 1)
492 mwindow->undo->update_undo_before();
493 set_status(BC_Toggle::TOGGLE_DOWN);
494 update(!get_value());
495 patch->toggle_behavior(Tracks::DRAW,
498 &patch->track->draw);
504 int DrawPatch::button_release_event()
506 int result = BC_Toggle::button_release_event();
507 if(patch->patchbay->drag_operation == Tracks::DRAW)
509 mwindow->undo->update_undo_after(_("draw patch"), LOAD_PATCHES);
510 patch->patchbay->drag_operation = Tracks::NONE;
524 MutePatch::MutePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
526 mwindow->theme->get_image_set("mutepatch_data"),
527 mwindow->get_int_auto(patch, AUTOMATION_MUTE)->value,
533 this->mwindow = mwindow;
535 set_tooltip(_("Don't send to output"));
539 int MutePatch::button_press_event()
541 if(is_event_win() && get_buttonpress() == 1)
543 mwindow->undo->update_undo_before();
544 set_status(BC_Toggle::TOGGLE_DOWN);
545 update(!get_value());
547 double position = mwindow->edl->local_session->get_selectionstart(1);
548 Autos *mute_autos = patch->track->automation->autos[AUTOMATION_MUTE];
551 current = (IntAuto*)mute_autos->get_auto_for_editing(position);
552 current->value = get_value();
554 patch->toggle_behavior(Tracks::MUTE,
561 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MUTE])
563 mwindow->gui->draw_overlays(1);
570 int MutePatch::button_release_event()
572 int result = BC_Toggle::button_release_event();
573 if(patch->patchbay->drag_operation == Tracks::MUTE)
575 mwindow->undo->update_undo_after(_("mute patch"), LOAD_PATCHES);
576 patch->patchbay->drag_operation = Tracks::NONE;
582 ZoomPatch::ZoomPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
583 : BC_Tumbler(x, y, mwindow->theme->get_image_set("tumblepatch_data"))
585 this->mwindow = mwindow;
587 set_tooltip(_("Track Data Height"));
590 int ZoomPatch::handle_up_event()
592 patch->track->data_h *= 2;
593 bclamp(patch->track->data_h, MIN_TRACK_ZOOM, MAX_TRACK_ZOOM);
594 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
595 mwindow->gui->draw_trackmovement();
598 int ZoomPatch::handle_down_event()
600 patch->track->data_h /= 2;
601 bclamp(patch->track->data_h, MIN_TRACK_ZOOM, MAX_TRACK_ZOOM);
602 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
603 mwindow->gui->draw_trackmovement();
608 ExpandPatch::ExpandPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
611 mwindow->theme->get_image_set("expandpatch_data"),
612 patch->track->expand_view,
618 this->mwindow = mwindow;
623 int ExpandPatch::button_press_event()
625 if(is_event_win() && get_buttonpress() == 1)
627 mwindow->undo->update_undo_before();
628 set_status(BC_Toggle::TOGGLE_DOWN);
629 update(!get_value());
630 patch->toggle_behavior(Tracks::EXPAND,
633 &patch->track->expand_view);
634 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
635 mwindow->gui->draw_trackmovement();
641 int ExpandPatch::button_release_event()
643 int result = BC_Toggle::button_release_event();
644 if(patch->patchbay->drag_operation == Tracks::EXPAND)
646 mwindow->undo->update_undo_after(_("expand patch"), LOAD_PATCHES);
647 patch->patchbay->drag_operation = Tracks::NONE;
653 TitlePatch::TitlePatch(MWindow *mwindow, PatchGUI *patch, int x, int y, int w)
654 : BC_TextBox(x, y, w, 1, patch->track->title, 1, MEDIUMFONT, 1)
656 this->mwindow = mwindow;
658 set_back_color(patch->track->record ?
659 get_resources()->text_background :
660 get_resources()->text_background_disarmed);
663 void TitlePatch::update(const char *text)
665 set_back_color(patch->track->record ?
666 get_resources()->text_background :
667 get_resources()->text_background_disarmed);
668 BC_TextBox::update(text);
671 int TitlePatch::handle_event()
673 mwindow->undo->update_undo_before(_("track title"), this);
674 strcpy(patch->track->title, get_text());
675 mwindow->update_plugin_titles();
676 mwindow->gui->draw_overlays(1);
677 mwindow->undo->update_undo_after(_("track title"), LOAD_PATCHES);
682 NudgePatch::NudgePatch(MWindow *mwindow,
691 patch->calculate_nudge_text(0))
693 this->mwindow = mwindow;
695 set_tooltip(_("Nudge"));
698 int NudgePatch::handle_event()
700 set_value(patch->calculate_nudge(get_text()));
704 void NudgePatch::set_value(int64_t value)
706 mwindow->undo->update_undo_before(_("nudge."), this);
707 patch->track->nudge = value;
709 if(patch->track->gang && patch->track->record)
710 patch->patchbay->synchronize_nudge(patch->track->nudge, patch->track);
712 mwindow->undo->update_undo_after(_("nudge."), LOAD_PATCHES);
714 mwindow->gui->unlock_window();
715 if(patch->track->data_type == TRACK_VIDEO)
716 mwindow->restart_brender();
717 mwindow->sync_parameters(CHANGE_PARAMS);
718 mwindow->gui->lock_window("NudgePatch::handle_event 2");
720 mwindow->session->changes_made = 1;
724 int NudgePatch::button_press_event()
728 if(is_event_win() && cursor_inside())
730 if(get_buttonpress() == 4)
732 int value = patch->calculate_nudge(get_text());
733 value += calculate_increment();
739 if(get_buttonpress() == 5)
741 int value = patch->calculate_nudge(get_text());
742 value -= calculate_increment();
748 if(get_buttonpress() == 3)
750 patch->patchbay->nudge_popup->activate_menu(patch);
756 return BC_TextBox::button_press_event();
761 int64_t NudgePatch::calculate_increment()
763 if(patch->track->data_type == TRACK_AUDIO)
765 return (int64_t)ceil(patch->track->edl->session->sample_rate / 10.0);
769 return (int64_t)ceil(1.0 / patch->track->edl->session->frame_rate);
773 void NudgePatch::update()
776 char *string = patch->calculate_nudge_text(&changed);
778 BC_TextBox::update(string);
782 MixPatch::MixPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
783 : BC_Toggle(x, y, mwindow->theme->get_image_set("mixpatch_data"),
784 patch->mixer, "", 0, 0, 0)
786 this->mwindow = mwindow;
790 MixPatch::~MixPatch()
794 int MixPatch::handle_event()
796 int v = patch->track ? get_value() : 0;
797 if( patch->mixer != v ) {
799 mwindow->gui->update_mixers(patch->track, v);
802 mwindow->update_mixer_tracks();
807 void MixPatch::update(int v)
810 BC_Toggle::update(v);