4 * Copyright (C) 1997-2014 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 "apatchgui.h"
23 #include "automation.h"
24 #include "floatauto.h"
25 #include "floatautos.h"
28 #include "edlsession.h"
33 #include "localsession.h"
36 #include "mwindowgui.h"
39 #include "mainsession.h"
42 #include "timelinepane.h"
44 #include "trackcanvas.h"
46 #include "vpatchgui.h"
53 NudgePopup::NudgePopup(MWindow *mwindow, PatchBay *patchbay)
60 this->mwindow = mwindow;
61 this->patchbay = patchbay;
64 NudgePopup::~NudgePopup()
69 void NudgePopup::create_objects()
71 add_item(seconds_item = new NudgePopupSeconds(this));
72 add_item(native_item = new NudgePopupNative(this));
75 void NudgePopup::activate_menu(PatchGUI *gui)
78 seconds_item->set_checked(mwindow->edl->session->nudge_format ? 1 : 0);
79 native_item->set_checked(mwindow->edl->session->nudge_format ? 0 : 1);
81 // Set native units to track format
82 native_item->set_text(gui->track->data_type == TRACK_AUDIO ?
87 BC_PopupMenu::activate_menu();
92 NudgePopupSeconds::NudgePopupSeconds(NudgePopup *popup)
93 : BC_MenuItem(_("Seconds"))
98 int NudgePopupSeconds::handle_event()
100 popup->mwindow->edl->session->nudge_format = 1;
101 popup->mwindow->gui->update_patchbay();
109 NudgePopupNative::NudgePopupNative(NudgePopup *popup)
115 int NudgePopupNative::handle_event()
117 popup->mwindow->edl->session->nudge_format = 0;
118 popup->mwindow->gui->update_patchbay();
130 PatchBay::PatchBay(MWindow *mwindow, MWindowGUI *gui)
131 : BC_SubWindow(mwindow->theme->patchbay_x,
132 mwindow->theme->patchbay_y,
133 mwindow->theme->patchbay_w,
134 mwindow->theme->patchbay_h)
136 this->mwindow = mwindow;
139 drag_operation = Tracks::NONE;
140 for(int i = 0; i < TRANSFER_TYPES; i++) mode_icons[i] = 0;
143 PatchBay::PatchBay(MWindow *mwindow,
154 this->mwindow = mwindow;
155 this->gui = mwindow->gui;
157 drag_operation = Tracks::NONE;
158 for(int i = 0; i < TRANSFER_TYPES; i++) mode_icons[i] = 0;
159 // printf("PatchBay::PatchBay %d %d %d %d %d\n",
167 PatchBay::~PatchBay()
169 delete_all_patches();
170 for(int i = 0; i < TRANSFER_TYPES; i++) delete mode_icons[i];
174 int PatchBay::delete_all_patches()
176 patches.remove_all_objects();
180 void PatchBay::create_objects()
182 draw_top_background(get_parent(), 0, 0, get_w(), get_h());
185 // Create icons for mode types
186 static const char *mode_types[] = {
218 for( int mode=0; mode<TRANSFER_TYPES; ++mode ) {
219 mode_icons[mode] = new BC_Pixmap(this,
220 mwindow->theme->get_image(mode_types[mode]),
224 add_subwindow(nudge_popup = new NudgePopup(mwindow, this));
225 nudge_popup->create_objects();
229 BC_Pixmap* PatchBay::mode_to_icon(int mode)
231 return mode_icons[mode];
234 int PatchBay::icon_to_mode(BC_Pixmap *icon)
236 for(int i = 0; i < TRANSFER_TYPES; i++)
237 if(icon == mode_icons[i]) return i;
238 return TRANSFER_NORMAL;
241 void PatchBay::resize_event()
243 reposition_window(mwindow->theme->patchbay_x,
244 mwindow->theme->patchbay_y,
245 mwindow->theme->patchbay_w,
246 mwindow->theme->patchbay_h);
247 draw_top_background(get_parent(), 0, 0, get_w(), get_h());
252 void PatchBay::resize_event(int x, int y, int w, int h)
258 draw_top_background(get_parent(), 0, 0, w, h);
263 int PatchBay::button_press_event()
266 // Too much junk to support the wheel
270 int PatchBay::cursor_motion_event()
272 //int cursor_x = get_relative_cursor_x();
273 int cursor_y = get_relative_cursor_y();
276 if(drag_operation != Tracks::NONE)
281 // Get track we're inside of
282 for(Track *track = mwindow->edl->tracks->first;
286 if( track->is_hidden() ) continue;
287 int y = track->y_pixel - mwindow->edl->local_session->track_start[pane->number];
288 int h = track->vertical_span(mwindow->theme);
289 if(cursor_y >= y && cursor_y < y + h)
291 switch(drag_operation)
294 if(track->play != new_status)
296 track->play = new_status;
297 mwindow->gui->unlock_window();
298 mwindow->restart_brender();
299 mwindow->sync_parameters(CHANGE_EDL);
300 mwindow->gui->lock_window();
305 if(track->armed != new_status)
307 track->armed = new_status;
312 if(track->ganged != new_status)
314 track->ganged = new_status;
319 if(track->draw != new_status)
321 track->draw = new_status;
326 if(track->expand_view != new_status)
328 track->expand_view = new_status;
329 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
330 gui->draw_trackmovement();
336 IntAuto *current = 0;
338 double position = mwindow->edl->local_session->get_selectionstart(1);
339 Autos *mute_autos = track->automation->autos[AUTOMATION_MUTE];
341 current = (IntAuto*)mute_autos->get_prev_auto(PLAY_FORWARD,
344 if(current->value != new_status)
347 // mwindow->undo->update_undo_before(_("keyframe"), this);
348 current = (IntAuto*)mute_autos->get_auto_for_editing(position);
350 current->value = new_status;
352 // mwindow->undo->update_undo_after(_("keyframe"), LOAD_AUTOMATION);
354 mwindow->gui->unlock_window();
355 mwindow->restart_brender();
356 mwindow->sync_parameters(CHANGE_PARAMS);
357 mwindow->gui->lock_window();
359 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MUTE])
361 gui->draw_overlays(1);
375 gui->update_patchbay();
380 void PatchBay::set_meter_format(int mode, int min, int max)
382 for(int i = 0; i < patches.total; i++)
384 PatchGUI *patchgui = patches.values[i];
385 if(patchgui->data_type == TRACK_AUDIO)
387 APatchGUI *apatchgui = (APatchGUI*)patchgui;
390 apatchgui->meter->change_format(mode, min, max);
396 void PatchBay::update_meters(ArrayList<double> *module_levels)
398 for(int level_number = 0, patch_number = 0;
399 patch_number < patches.total && level_number < module_levels->total;
402 APatchGUI *patchgui = (APatchGUI*)patches.values[patch_number];
404 if(patchgui->data_type == TRACK_AUDIO)
408 double level = module_levels->values[level_number];
409 patchgui->meter->update(level, level > 1);
417 void PatchBay::reset_meters()
419 for(int patch_number = 0;
420 patch_number < patches.total;
423 APatchGUI *patchgui = (APatchGUI*)patches.values[patch_number];
424 if(patchgui->data_type == TRACK_AUDIO && patchgui->meter)
426 patchgui->meter->reset_over();
431 void PatchBay::stop_meters()
433 for(int patch_number = 0;
434 patch_number < patches.total;
437 APatchGUI *patchgui = (APatchGUI*)patches.values[patch_number];
438 if(patchgui->data_type == TRACK_AUDIO && patchgui->meter)
440 patchgui->meter->reset();
448 int PatchBay::update()
452 // Every patch has a GUI regardless of whether or not it is visible.
453 // Make sure GUI's are allocated for every patch and deleted for non-existant
455 for(Track *current = mwindow->edl->tracks->first; current; current = NEXT)
457 if( current->is_hidden() ) continue;
458 PatchGUI *patchgui = 0;
459 int y = current->y_pixel;
460 y -= mwindow->edl->local_session->track_start[pane->number];
462 //printf("PatchBay::update %d %d\n", __LINE__, y);
463 if(patches.total > patch_count)
465 if(patches.values[patch_count]->track_id != current->get_id())
467 delete patches.values[patch_count];
469 switch(current->data_type)
472 patchgui = patches.values[patch_count] = new APatchGUI(mwindow, this, (ATrack*)current, PATCH_X, y);
475 patchgui = patches.values[patch_count] = new VPatchGUI(mwindow, this, (VTrack*)current, PATCH_X, y);
478 patchgui = patches.values[patch_count] = new SPatchGUI(mwindow, this, (STrack*)current, PATCH_X, y);
481 patchgui->create_objects();
485 patches.values[patch_count]->update(PATCH_X, y);
490 switch(current->data_type)
493 patchgui = new APatchGUI(mwindow, this, (ATrack*)current, PATCH_X, y);
496 patchgui = new VPatchGUI(mwindow, this, (VTrack*)current, PATCH_X, y);
499 patchgui = new SPatchGUI(mwindow, this, (STrack*)current, PATCH_X, y);
502 patches.append(patchgui);
503 patchgui->create_objects();
508 while(patches.total > patch_count)
510 delete patches.values[patches.total - 1];
511 patches.remove_number(patches.total - 1);
518 void PatchBay::synchronize_faders(float change, int data_type, Track *skip)
520 for(Track *current = mwindow->edl->tracks->first;
524 if(current->data_type == data_type &&
525 current->armed_gang(skip) &&
526 current->is_armed() &&
529 FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
530 double position = mwindow->edl->local_session->get_selectionstart(1);
533 FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_for_editing(position);
535 float new_value = keyframe->get_value() + change;
536 if(data_type == TRACK_AUDIO)
538 mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_AUDIO_FADE],
539 mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_AUDIO_FADE]);
542 mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_VIDEO_FADE],
543 mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_VIDEO_FADE]);
545 keyframe->set_value(new_value);
547 PatchGUI *patch = get_patch_of(current);
548 if(patch) patch->update(patch->x, patch->y);
553 void PatchBay::synchronize_nudge(int64_t value, Track *skip)
555 Track *current = mwindow->edl->tracks->first;
556 for( ; current; current = NEXT ) {
557 if( current->data_type == skip->data_type &&
558 current->armed_gang(skip) && current->is_armed() &&
560 current->nudge = value;
561 PatchGUI *patch = get_patch_of(current);
562 if(patch) patch->update(patch->x, patch->y);
567 PatchGUI* PatchBay::get_patch_of(Track *track)
569 for(int i = 0; i < patches.total; i++)
571 if(patches.values[i]->track == track)
572 return patches.values[i];
577 int PatchBay::resize_event(int top, int bottom)
579 reposition_window(mwindow->theme->patchbay_x,
580 mwindow->theme->patchbay_y,
581 mwindow->theme->patchbay_w,
582 mwindow->theme->patchbay_h);