Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

patchbay.C

Go to the documentation of this file.
00001 #include "apatchgui.h"
00002 #include "automation.h"
00003 #include "floatauto.h"
00004 #include "floatautos.h"
00005 #include "clip.h"
00006 #include "edl.h"
00007 #include "edlsession.h"
00008 #include "filexml.h"
00009 #include "intauto.h"
00010 #include "intautos.h"
00011 #include "language.h"
00012 #include "localsession.h"
00013 #include "mainundo.h"
00014 #include "mwindow.h"
00015 #include "mwindowgui.h"
00016 #include "patchbay.h"
00017 #include "patchgui.h"
00018 #include "mainsession.h"
00019 #include "theme.h"
00020 #include "track.h"
00021 #include "trackcanvas.h"
00022 #include "tracks.h"
00023 #include "vpatchgui.h"
00024 
00025 
00026 
00027 
00028 
00029 
00030 NudgePopup::NudgePopup(MWindow *mwindow, PatchBay *patchbay)
00031  : BC_PopupMenu(0, 
00032                 0, 
00033                 0, 
00034                 "", 
00035                 0)
00036 {
00037         this->mwindow = mwindow;
00038         this->patchbay = patchbay;
00039 }
00040 
00041 NudgePopup::~NudgePopup()
00042 {
00043 }
00044 
00045 
00046 void NudgePopup::create_objects()
00047 {
00048         add_item(seconds_item = new NudgePopupSeconds(this));
00049         add_item(native_item = new NudgePopupNative(this));
00050 }
00051 
00052 void NudgePopup::activate_menu(PatchGUI *gui)
00053 {
00054 // Set checked status
00055         seconds_item->set_checked(mwindow->edl->session->nudge_seconds ? 1 : 0);
00056         native_item->set_checked(mwindow->edl->session->nudge_seconds ? 0 : 1);
00057 
00058 // Set native units to track format
00059         native_item->set_text(gui->track->data_type == TRACK_AUDIO ? 
00060                 (char*)"Samples" : 
00061                 (char*)"Frames");
00062 
00063 // Show it
00064         BC_PopupMenu::activate_menu();
00065 }
00066 
00067 
00068 
00069 NudgePopupSeconds::NudgePopupSeconds(NudgePopup *popup)
00070  : BC_MenuItem("Seconds")
00071 {
00072         this->popup = popup;
00073 }
00074 
00075 int NudgePopupSeconds::handle_event()
00076 {
00077         popup->mwindow->edl->session->nudge_seconds = 1;
00078         popup->patchbay->update();
00079         return 1;
00080 }
00081 
00082 
00083 
00084 
00085 
00086 NudgePopupNative::NudgePopupNative(NudgePopup *popup)
00087  : BC_MenuItem("")
00088 {
00089         this->popup = popup;
00090 }
00091 
00092 int NudgePopupNative::handle_event()
00093 {
00094         popup->mwindow->edl->session->nudge_seconds = 0;
00095         popup->patchbay->update();
00096         return 1;
00097 }
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 PatchBay::PatchBay(MWindow *mwindow, MWindowGUI *gui)
00108  : BC_SubWindow(mwindow->theme->patchbay_x,
00109         mwindow->theme->patchbay_y,
00110         mwindow->theme->patchbay_w,
00111         mwindow->theme->patchbay_h)
00112 {
00113         this->mwindow = mwindow;
00114         this->gui = gui;
00115         button_down = 0;
00116         reconfigure_trigger = 0;
00117         drag_operation = Tracks::NONE;
00118 }
00119 
00120 PatchBay::~PatchBay() 
00121 {
00122 }
00123 
00124 
00125 int PatchBay::delete_all_patches()
00126 {
00127     patches.remove_all_objects();
00128     return 0;
00129 }
00130 
00131 int PatchBay::create_objects()
00132 {
00133         draw_top_background(get_parent(), 0, 0, get_w(), get_h());
00134         flash();
00135 
00136 // Create icons for mode types
00137         mode_icons[TRANSFER_NORMAL] = new BC_Pixmap(this, 
00138                 mwindow->theme->get_image("mode_normal"),
00139                 PIXMAP_ALPHA);
00140         mode_icons[TRANSFER_ADDITION] = new BC_Pixmap(this, 
00141                 mwindow->theme->get_image("mode_add"),
00142                 PIXMAP_ALPHA);
00143         mode_icons[TRANSFER_SUBTRACT] = new BC_Pixmap(this, 
00144                 mwindow->theme->get_image("mode_subtract"),
00145                 PIXMAP_ALPHA);
00146         mode_icons[TRANSFER_MULTIPLY] = new BC_Pixmap(this, 
00147                 mwindow->theme->get_image("mode_multiply"),
00148                 PIXMAP_ALPHA);
00149         mode_icons[TRANSFER_DIVIDE] = new BC_Pixmap(this, 
00150                 mwindow->theme->get_image("mode_divide"),
00151                 PIXMAP_ALPHA);
00152         mode_icons[TRANSFER_REPLACE] = new BC_Pixmap(this, 
00153                 mwindow->theme->get_image("mode_replace"),
00154                 PIXMAP_ALPHA);
00155         
00156         add_subwindow(nudge_popup = new NudgePopup(mwindow, this));
00157         nudge_popup->create_objects();
00158 
00159         return 0;
00160 }
00161 
00162 BC_Pixmap* PatchBay::mode_to_icon(int mode)
00163 {
00164         return mode_icons[mode];
00165 }
00166 
00167 int PatchBay::icon_to_mode(BC_Pixmap *icon)
00168 {
00169         for(int i = 0; i < TRANSFER_TYPES; i++)
00170                 if(icon == mode_icons[i]) return i;
00171         return TRANSFER_NORMAL;
00172 }
00173 
00174 void PatchBay::resize_event()
00175 {
00176         reposition_window(mwindow->theme->patchbay_x,
00177                 mwindow->theme->patchbay_y,
00178                 mwindow->theme->patchbay_w,
00179                 mwindow->theme->patchbay_h);
00180         draw_top_background(get_parent(), 0, 0, get_w(), get_h());
00181         update();
00182         flash();
00183 }
00184 
00185 int PatchBay::button_press_event()
00186 {
00187         int result = 0;
00188 // Too much junk to support the wheel
00189         return result;
00190 }
00191 
00192 
00193 Track *PatchBay::is_over_track()     // called from mwindow
00194 {
00195         int cursor_x = get_relative_cursor_x();
00196         int cursor_y = get_relative_cursor_y();
00197         Track *over_track = 0;
00198 
00199         if(get_cursor_over_window() &&
00200                 cursor_x >= 0 && 
00201                 cursor_y >= 0 && 
00202                 cursor_x < get_w() && 
00203                 cursor_y < get_h())
00204         {
00205 // Get track we're inside of
00206                 for(Track *track = mwindow->edl->tracks->first;
00207                         track;
00208                         track = track->next)
00209                 {
00210                         int y = track->y_pixel;
00211                         int h = track->vertical_span(mwindow->theme);
00212                         if(cursor_y >= y && cursor_y < y + h)
00213                         {       
00214                                 over_track = track;
00215                         }
00216                 }
00217         }                               
00218         return (over_track);
00219 
00220 }
00221 
00222 int PatchBay::cursor_motion_event()
00223 {
00224         int cursor_x = get_relative_cursor_x();
00225         int cursor_y = get_relative_cursor_y();
00226         int update_gui = 0;
00227 
00228         if(drag_operation != Tracks::NONE)
00229         {
00230                 if(cursor_y >= 0 &&
00231                         cursor_y < get_h())
00232                 {
00233 // Get track we're inside of
00234                         for(Track *track = mwindow->edl->tracks->first;
00235                                 track;
00236                                 track = track->next)
00237                         {
00238                                 int y = track->y_pixel;
00239                                 int h = track->vertical_span(mwindow->theme);
00240                                 if(cursor_y >= y && cursor_y < y + h)
00241                                 {
00242                                         switch(drag_operation)
00243                                         {
00244                                                 case Tracks::PLAY:
00245                                                         if(track->play != new_status)
00246                                                         {
00247                                                                 track->play = new_status;
00248                                                                 mwindow->gui->unlock_window();
00249                                                                 mwindow->restart_brender();
00250                                                                 mwindow->sync_parameters(CHANGE_EDL);
00251                                                                 mwindow->gui->lock_window();
00252                                                                 update_gui = 1;
00253                                                         }
00254                                                         break;
00255                                                 case Tracks::RECORD:
00256                                                         if(track->record != new_status)
00257                                                         {
00258                                                                 track->record = new_status;
00259                                                                 update_gui = 1;
00260                                                         }
00261                                                         break;
00262                                                 case Tracks::GANG:
00263                                                         if(track->gang != new_status)
00264                                                         {
00265                                                                 track->gang = new_status;
00266                                                                 update_gui = 1;
00267                                                         }
00268                                                         break;
00269                                                 case Tracks::DRAW:
00270                                                         if(track->draw != new_status)
00271                                                         {
00272                                                                 track->draw = new_status;
00273                                                                 update_gui = 1;
00274                                                         }
00275                                                         break;
00276                                                 case Tracks::EXPAND:
00277                                                         if(track->expand_view != new_status)
00278                                                         {
00279                                                                 track->expand_view = new_status;
00280                                                                 mwindow->trackmovement(mwindow->edl->local_session->track_start);
00281                                                                 update_gui = 0;
00282                                                         }
00283                                                         break;
00284                                                 case Tracks::MUTE:
00285                                                 {
00286                                                         IntAuto *current = 0;
00287                                                         Auto *keyframe = 0;
00288                                                         double position = mwindow->edl->local_session->get_selectionstart(1);
00289                                                         Autos *mute_autos = track->automation->autos[AUTOMATION_MUTE];
00290 
00291                                                         current = (IntAuto*)mute_autos->get_prev_auto(PLAY_FORWARD, 
00292                                                                 keyframe);
00293 
00294                                                         if(current->value != new_status)
00295                                                         {
00296 
00297                                                                 current = (IntAuto*)mute_autos->get_auto_for_editing(position);
00298 
00299                                                                 current->value = new_status;
00300 
00301                                                                 mwindow->undo->update_undo(_("keyframe"), LOAD_AUTOMATION);
00302 
00303                                                                 mwindow->gui->unlock_window();
00304                                                                 mwindow->restart_brender();
00305                                                                 mwindow->sync_parameters(CHANGE_PARAMS);
00306                                                                 mwindow->gui->lock_window();
00307 
00308                                                                 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MUTE])
00309                                                                 {
00310                                                                         mwindow->gui->canvas->draw_overlays();
00311                                                                         mwindow->gui->canvas->flash();
00312                                                                 }
00313                                                                 update_gui = 1;
00314                                                         }
00315                                                         break;
00316                                                 }
00317                                         }
00318                                 }
00319                         }
00320                 }
00321         }
00322 
00323         if(update_gui)
00324         {
00325                 update();
00326         }
00327         return 0;
00328 }
00329 
00330 void PatchBay::change_meter_format(int mode, int min, int max)
00331 {
00332         for(int i = 0; i < patches.total; i++)
00333         {
00334                 PatchGUI *patchgui = patches.values[i];
00335                 if(patchgui->data_type == TRACK_AUDIO)
00336                 {
00337                         APatchGUI *apatchgui = (APatchGUI*)patchgui;
00338                         if(apatchgui->meter)
00339                         {
00340                                 apatchgui->meter->change_format(mode, min, max);
00341                         }
00342                 }
00343         }
00344 }
00345 
00346 void PatchBay::update_meters(ArrayList<double> *module_levels)
00347 {
00348         for(int level_number = 0, patch_number = 0;
00349                 patch_number < patches.total && level_number < module_levels->total;
00350                 patch_number++)
00351         {
00352                 APatchGUI *patchgui = (APatchGUI*)patches.values[patch_number];
00353 
00354                 if(patchgui->data_type == TRACK_AUDIO)
00355                 {
00356                         if(patchgui->meter)
00357                         {
00358                                 double level = module_levels->values[level_number];
00359                                 patchgui->meter->update(level, level > 1);
00360                         }
00361 
00362                         level_number++;
00363                 }
00364         }
00365 }
00366 
00367 void PatchBay::reset_meters()
00368 {
00369         for(int patch_number = 0;
00370                 patch_number < patches.total;
00371                 patch_number++)
00372         {
00373                 APatchGUI *patchgui = (APatchGUI*)patches.values[patch_number];
00374                 if(patchgui->data_type == TRACK_AUDIO && patchgui->meter)
00375                 {
00376                         patchgui->meter->reset_over();
00377                 }
00378         }
00379 }
00380 
00381 void PatchBay::stop_meters()
00382 {
00383         for(int patch_number = 0;
00384                 patch_number < patches.total;
00385                 patch_number++)
00386         {
00387                 APatchGUI *patchgui = (APatchGUI*)patches.values[patch_number];
00388                 if(patchgui->data_type == TRACK_AUDIO && patchgui->meter)
00389                 {
00390                         patchgui->meter->reset();
00391                 }
00392         }
00393 }
00394 
00395 
00396 #define PATCH_X 3
00397 
00398 int PatchBay::update()
00399 {
00400         int patch_count = 0;
00401 
00402 // Every patch has a GUI regardless of whether or not it is visible.
00403 // Make sure GUI's are allocated for every patch and deleted for non-existant
00404 // patches.
00405         for(Track *current = mwindow->edl->tracks->first;
00406                 current;
00407                 current = NEXT, patch_count++)
00408         {
00409                 PatchGUI *patchgui;
00410                 int y = current->y_pixel;
00411 
00412                 if(patches.total > patch_count)
00413                 {
00414                         if(patches.values[patch_count]->track_id != current->get_id())
00415                         {
00416                                 delete patches.values[patch_count];
00417 
00418                                 switch(current->data_type)
00419                                 {
00420                                         case TRACK_AUDIO:
00421                                                 patchgui = patches.values[patch_count] = new APatchGUI(mwindow, this, (ATrack*)current, PATCH_X, y);
00422                                                 break;
00423                                         case TRACK_VIDEO:
00424                                                 patchgui = patches.values[patch_count] = new VPatchGUI(mwindow, this, (VTrack*)current, PATCH_X, y);
00425                                                 break;
00426                                 }
00427                                 patchgui->create_objects();
00428                         }
00429                         else
00430                         {
00431                                 patches.values[patch_count]->update(PATCH_X, y);
00432                         }
00433                 }
00434                 else
00435                 {
00436                         switch(current->data_type)
00437                         {
00438                                 case TRACK_AUDIO:
00439                                         patchgui = new APatchGUI(mwindow, this, (ATrack*)current, PATCH_X, y);
00440                                         break;
00441                                 case TRACK_VIDEO:
00442                                         patchgui = new VPatchGUI(mwindow, this, (VTrack*)current, PATCH_X, y);
00443                                         break;
00444                         }
00445                         patches.append(patchgui);
00446                         patchgui->create_objects();
00447                 }
00448         }
00449 
00450         while(patches.total > patch_count)
00451         {
00452                 delete patches.values[patches.total - 1];
00453                 patches.remove_number(patches.total - 1);
00454         }
00455 
00456         return 0;
00457 }
00458 
00459 void PatchBay::synchronize_faders(float change, int data_type, Track *skip)
00460 {
00461         for(Track *current = mwindow->edl->tracks->first;
00462                 current;
00463                 current = NEXT)
00464         {
00465                 if(current->data_type == data_type &&
00466                         current->gang && 
00467                         current->record && 
00468                         current != skip)
00469                 {
00470                         FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
00471                         double position = mwindow->edl->local_session->get_selectionstart(1);
00472 
00473 
00474                         FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_for_editing(position);
00475 
00476                         keyframe->value += change;
00477                         if(data_type == TRACK_AUDIO)
00478                                 CLAMP(keyframe->value, INFINITYGAIN, MAX_AUDIO_FADE);
00479                         else
00480                                 CLAMP(keyframe->value, 0, MAX_VIDEO_FADE);
00481 
00482 
00483                         PatchGUI *patch = get_patch_of(current);
00484                         if(patch) patch->update(patch->x, patch->y);
00485                 }
00486         }
00487 }
00488 
00489 void PatchBay::synchronize_nudge(int64_t value, Track *skip)
00490 {
00491         for(Track *current = mwindow->edl->tracks->first;
00492                 current;
00493                 current = NEXT)
00494         {
00495                 if(current->data_type == skip->data_type &&
00496                         current->gang &&
00497                         current->record &&
00498                         current != skip)
00499                 {
00500                         current->nudge = value;
00501                         PatchGUI *patch = get_patch_of(current);
00502                         if(patch) patch->update(patch->x, patch->y);
00503                 }
00504         }
00505 }
00506 
00507 PatchGUI* PatchBay::get_patch_of(Track *track)
00508 {
00509         for(int i = 0; i < patches.total; i++)
00510         {
00511                 if(patches.values[i]->track == track)
00512                         return patches.values[i];
00513         }
00514         return 0;
00515 }
00516 
00517 int PatchBay::resize_event(int top, int bottom)
00518 {
00519         reposition_window(mwindow->theme->patchbay_x,
00520                 mwindow->theme->patchbay_y,
00521                 mwindow->theme->patchbay_w,
00522                 mwindow->theme->patchbay_h);
00523         return 0;
00524 }
00525 
00526 

Generated on Sun Jan 8 13:38:58 2006 for Cinelerra-svn by  doxygen 1.4.4