00001 #include "asset.h"
00002 #include "autoconf.h"
00003 #include "automation.h"
00004 #include "bcsignals.h"
00005 #include "bctimer.h"
00006 #include "clip.h"
00007 #include "colors.h"
00008 #include "cplayback.h"
00009 #include "cursors.h"
00010 #include "cwindow.h"
00011 #include "cwindowgui.h"
00012 #include "edithandles.h"
00013 #include "editpopup.h"
00014 #include "edits.h"
00015 #include "edl.h"
00016 #include "edlsession.h"
00017 #include "floatauto.h"
00018 #include "floatautos.h"
00019 #include "intauto.h"
00020 #include "keyframe.h"
00021 #include "keyframepopup.h"
00022 #include "keyframes.h"
00023 #include "keys.h"
00024 #include "localsession.h"
00025 #include "mainclock.h"
00026 #include "maincursor.h"
00027 #include "mainundo.h"
00028 #include "maskautos.h"
00029 #include "mbuttons.h"
00030 #include "mtimebar.h"
00031 #include "mwindow.h"
00032 #include "mwindowgui.h"
00033 #include "patchbay.h"
00034 #include "tracking.h"
00035 #include "panautos.h"
00036 #include "resourcethread.h"
00037 #include "playbackengine.h"
00038 #include "playtransport.h"
00039 #include "plugin.h"
00040 #include "pluginpopup.h"
00041 #include "pluginset.h"
00042 #include "pluginserver.h"
00043 #include "plugintoggles.h"
00044 #include "preferences.h"
00045 #include "resourcepixmap.h"
00046 #include "mainsession.h"
00047 #include "transitionhandles.h"
00048 #include "transitionpopup.h"
00049 #include "transportque.h"
00050 #include "zoombar.h"
00051 #include "theme.h"
00052 #include "intautos.h"
00053 #include "trackcanvas.h"
00054 #include "tracks.h"
00055 #include "transition.h"
00056 #include "vframe.h"
00057 #include "apatchgui.inc"
00058 #include "vpatchgui.inc"
00059
00060 #include <string.h>
00061
00062 TrackCanvas::TrackCanvas(MWindow *mwindow, MWindowGUI *gui)
00063 : BC_SubWindow(mwindow->theme->mcanvas_x,
00064 mwindow->theme->mcanvas_y,
00065 gui->view_w,
00066 gui->view_h)
00067 {
00068 this->mwindow = mwindow;
00069 this->gui = gui;
00070 current_end = 0;
00071 selection_midpoint1 = selection_midpoint2 = 0;
00072 selection_type = 0;
00073 region_selected = 0;
00074 handle_selected = 0;
00075 auto_selected = 0;
00076 translate_selected = 0;
00077 which_handle = 0;
00078 handle_pixel = 0;
00079 drag_scroll = 0;
00080 drag_popup = 0;
00081 active = 0;
00082 temp_picon = 0;
00083 resource_timer = new Timer;
00084 hourglass_enabled = 0;
00085 resource_thread = new ResourceThread(mwindow);
00086 }
00087
00088 TrackCanvas::~TrackCanvas()
00089 {
00090 for(int i = 0; i < resource_pixmaps.total; i++)
00091 delete resource_pixmaps.values[i];
00092
00093 delete edit_handles;
00094 delete keyframe_pixmap;
00095 delete camerakeyframe_pixmap;
00096 delete modekeyframe_pixmap;
00097 delete pankeyframe_pixmap;
00098 delete projectorkeyframe_pixmap;
00099 delete maskkeyframe_pixmap;
00100 delete background_pixmap;
00101 if(temp_picon) delete temp_picon;
00102 delete resource_timer;
00103 }
00104
00105 int TrackCanvas::create_objects()
00106 {
00107 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
00108
00109 edit_handles = new EditHandles(mwindow, this);
00110 keyframe_pixmap = new BC_Pixmap(this, mwindow->theme->keyframe_data, PIXMAP_ALPHA);
00111 camerakeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->camerakeyframe_data, PIXMAP_ALPHA);
00112 modekeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->modekeyframe_data, PIXMAP_ALPHA);
00113 pankeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->pankeyframe_data, PIXMAP_ALPHA);
00114 projectorkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->projectorkeyframe_data, PIXMAP_ALPHA);
00115 maskkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->maskkeyframe_data, PIXMAP_ALPHA);
00116 resource_thread->create_objects();
00117 draw();
00118 update_cursor();
00119 flash();
00120 return 0;
00121 }
00122
00123 void TrackCanvas::resize_event()
00124 {
00125
00126 draw(0, 0);
00127 flash();
00128
00129 }
00130
00131 int TrackCanvas::keypress_event()
00132 {
00133 int result = 0;
00134
00135
00136 return result;
00137 }
00138
00139 int TrackCanvas::drag_motion()
00140 {
00141 int cursor_x = get_relative_cursor_x();
00142 int cursor_y = get_relative_cursor_y();
00143 Track *over_track = 0;
00144 Edit *over_edit = 0;
00145 PluginSet *over_pluginset = 0;
00146 Plugin *over_plugin = 0;
00147 int redraw = 0;
00148
00149
00150 if(drag_popup)
00151 {
00152 drag_popup->cursor_motion_event();
00153 }
00154
00155
00156
00157 if (!mwindow->session->current_operation)
00158 return 0;
00159
00160 if(get_cursor_over_window() &&
00161 cursor_x >= 0 &&
00162 cursor_y >= 0 &&
00163 cursor_x < get_w() &&
00164 cursor_y < get_h())
00165 {
00166
00167 for(Track *track = mwindow->edl->tracks->first; track; track = track->next)
00168 {
00169 int64_t track_x, track_y, track_w, track_h;
00170 track_dimensions(track, track_x, track_y, track_w, track_h);
00171
00172 if(cursor_y >= track_y &&
00173 cursor_y < track_y + track_h)
00174 {
00175 over_track = track;
00176 for(Edit *edit = track->edits->first; edit; edit = edit->next)
00177 {
00178 if (mwindow->session->current_operation != DRAG_ATRANSITION &&
00179 mwindow->session->current_operation != DRAG_VTRANSITION &&
00180 edit == track->edits->last)
00181 break;
00182 int64_t edit_x, edit_y, edit_w, edit_h;
00183 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
00184
00185 if(cursor_x >= edit_x &&
00186 cursor_y >= edit_y &&
00187 cursor_x < edit_x + edit_w &&
00188 cursor_y < edit_y + edit_h)
00189 {
00190 over_edit = edit;
00191 break;
00192 }
00193 }
00194
00195 for(int i = 0; i < track->plugin_set.total; i++)
00196 {
00197 PluginSet *pluginset = track->plugin_set.values[i];
00198
00199
00200
00201 for(Plugin *plugin = (Plugin*)pluginset->first;
00202 plugin != pluginset->last;
00203 plugin = (Plugin*)plugin->next)
00204 {
00205 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
00206 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
00207
00208 if(cursor_y >= plugin_y &&
00209 cursor_y < plugin_y + plugin_h)
00210 {
00211 over_pluginset = plugin->plugin_set;
00212
00213 if(cursor_x >= plugin_x &&
00214 cursor_x < plugin_x + plugin_w)
00215 {
00216 over_plugin = plugin;
00217 break;
00218 }
00219 }
00220 }
00221 }
00222 break;
00223 }
00224 }
00225 }
00226
00227 if (!over_track)
00228 over_track = mwindow->gui->patchbay->is_over_track();
00229
00230 if(mwindow->session->track_highlighted != over_track)
00231 {
00232 mwindow->session->track_highlighted = over_track;
00233 redraw = 1;
00234 }
00235
00236 if(mwindow->session->edit_highlighted != over_edit)
00237 {
00238 mwindow->session->edit_highlighted = over_edit;
00239 redraw = 1;
00240 }
00241
00242 if(mwindow->session->pluginset_highlighted != over_pluginset)
00243 {
00244 mwindow->session->pluginset_highlighted = over_pluginset;
00245 redraw = 1;
00246 }
00247
00248 if(mwindow->session->plugin_highlighted != over_plugin)
00249 {
00250 mwindow->session->plugin_highlighted = over_plugin;
00251 redraw = 1;
00252 }
00253
00254 if (mwindow->session->current_operation == DRAG_ASSET ||
00255 mwindow->session->current_operation == DRAG_EDIT)
00256 {
00257 redraw = 1;
00258 }
00259
00260 if(redraw)
00261 {
00262 lock_window("TrackCanvas::drag_motion");
00263 draw_overlays();
00264 flash();
00265 unlock_window();
00266 }
00267
00268 return 0;
00269 }
00270
00271 int TrackCanvas::drag_start_event()
00272 {
00273 int result = 0;
00274 int redraw = 0;
00275 int rerender = 0;
00276 int new_cursor, update_cursor;
00277
00278 if(mwindow->session->current_operation != NO_OPERATION) return 0;
00279
00280 if(is_event_win())
00281 {
00282 if(do_plugins(get_drag_x(),
00283 get_drag_y(),
00284 1,
00285 0,
00286 redraw,
00287 rerender))
00288 {
00289 result = 1;
00290 }
00291 else
00292 if(do_edits(get_drag_x(),
00293 get_drag_y(),
00294 0,
00295 1,
00296 redraw,
00297 rerender,
00298 new_cursor,
00299 update_cursor))
00300 {
00301 result = 1;
00302 }
00303 }
00304
00305 return result;
00306 }
00307
00308 int TrackCanvas::drag_motion_event()
00309 {
00310 return drag_motion();
00311 }
00312
00313 int TrackCanvas::cursor_leave_event()
00314 {
00315
00316
00317
00318 return 0;
00319
00320 }
00321
00322
00323 int TrackCanvas::drag_stop_event()
00324 {
00325 int result = drag_stop();
00326
00327 if(drag_popup)
00328 {
00329 delete drag_popup;
00330 drag_popup = 0;
00331 }
00332 return result;
00333 }
00334
00335
00336 int TrackCanvas::drag_stop()
00337 {
00338
00339 int result = 0, redraw = 0;
00340
00341 int insertion = 0;
00342 switch(mwindow->session->current_operation)
00343 {
00344 case DRAG_VTRANSITION:
00345 case DRAG_ATRANSITION:
00346 if(mwindow->session->edit_highlighted)
00347 {
00348 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
00349 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
00350 (mwindow->session->current_operation == DRAG_VTRANSITION &&
00351 mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
00352 {
00353 mwindow->session->current_operation = NO_OPERATION;
00354 mwindow->paste_transition();
00355 result = 1;
00356 }
00357 }
00358 redraw = 1;
00359 break;
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 case DRAG_AEFFECT_COPY:
00370 case DRAG_VEFFECT_COPY:
00371 if(mwindow->session->track_highlighted &&
00372 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY &&
00373 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
00374 (mwindow->session->current_operation == DRAG_VEFFECT_COPY &&
00375 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
00376 {
00377 mwindow->session->current_operation = NO_OPERATION;
00378
00379
00380
00381 if(mwindow->session->pluginset_highlighted)
00382 {
00383
00384 if(mwindow->session->plugin_highlighted)
00385 {
00386 mwindow->move_effect(mwindow->session->drag_plugin,
00387 mwindow->session->plugin_highlighted->plugin_set,
00388 0,
00389 mwindow->session->plugin_highlighted->startproject);
00390 }
00391 else
00392 {
00393 mwindow->move_effect(mwindow->session->drag_plugin,
00394 mwindow->session->pluginset_highlighted,
00395 0,
00396 mwindow->session->pluginset_highlighted->last->startproject);
00397 }
00398 result = 1;
00399 }
00400 else
00401
00402 if(mwindow->session->edit_highlighted)
00403 {
00404 mwindow->move_effect(mwindow->session->drag_plugin,
00405 0,
00406 mwindow->session->track_highlighted,
00407 mwindow->session->edit_highlighted->startproject);
00408 result = 1;
00409 }
00410 else
00411
00412 if(mwindow->session->track_highlighted)
00413 {
00414 mwindow->move_effect(mwindow->session->drag_plugin,
00415 0,
00416 mwindow->session->track_highlighted,
00417 0);
00418 result = 1;
00419 }
00420 }
00421 break;
00422
00423 case DRAG_AEFFECT:
00424 case DRAG_VEFFECT:
00425 if(mwindow->session->track_highlighted &&
00426 ((mwindow->session->current_operation == DRAG_AEFFECT &&
00427 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
00428 (mwindow->session->current_operation == DRAG_VEFFECT &&
00429 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
00430 {
00431
00432 PluginSet *plugin_set = mwindow->session->pluginset_highlighted;
00433 Track *track = mwindow->session->track_highlighted;
00434 double start = 0;
00435 double length = track->get_length();
00436
00437 if(mwindow->session->plugin_highlighted)
00438 {
00439 start = track->from_units(mwindow->session->plugin_highlighted->startproject);
00440 length = track->from_units(mwindow->session->plugin_highlighted->length);
00441 if(length <= 0) length = track->get_length();
00442 }
00443 else
00444 if(mwindow->session->pluginset_highlighted)
00445 {
00446 start = track->from_units(plugin_set->last->startproject);
00447 length = track->get_length() - start;
00448 if(length <= 0) length = track->get_length();
00449 }
00450 else
00451 if(mwindow->edl->local_session->get_selectionend() >
00452 mwindow->edl->local_session->get_selectionstart())
00453 {
00454 start = mwindow->edl->local_session->get_selectionstart();
00455 length = mwindow->edl->local_session->get_selectionend() -
00456 mwindow->edl->local_session->get_selectionstart();
00457 }
00458
00459 else
00460 if(mwindow->session->edit_highlighted)
00461 {
00462 start = mwindow->session->track_highlighted->from_units(
00463 mwindow->session->edit_highlighted->startproject);
00464 length = mwindow->session->track_highlighted->from_units(
00465 mwindow->session->edit_highlighted->length);
00466 }
00467
00468 mwindow->insert_effects_canvas(start, length);
00469 redraw = 1;
00470 }
00471 if (mwindow->session->track_highlighted)
00472 result = 1;
00473 break;
00474
00475 case DRAG_ASSET:
00476 if(mwindow->session->track_highlighted)
00477 {
00478 float asset_length_float;
00479 int64_t asset_length_units;
00480 int64_t position = 0;
00481
00482 if(mwindow->session->current_operation == DRAG_ASSET &&
00483 mwindow->session->drag_assets->total)
00484 {
00485 Asset *asset = mwindow->session->drag_assets->values[0];
00486
00487 if (asset->video_data && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
00488 {
00489
00490 double video_length = asset->video_length;
00491 if (video_length < 0)
00492 {
00493 if(mwindow->edl->session->si_useduration)
00494 video_length = mwindow->edl->session->si_duration;
00495 else
00496 video_length = 1.0 / mwindow->edl->session->frame_rate ;
00497 }
00498 asset_length_float = video_length / asset->frame_rate;
00499 }
00500 else if (asset->audio_data && mwindow->session->track_highlighted->data_type == TRACK_AUDIO)
00501 asset_length_float = asset->audio_length / asset->sample_rate;
00502 else
00503 {
00504 result = 1;
00505 break;
00506 }
00507 } else
00508 if(mwindow->session->current_operation == DRAG_ASSET &&
00509 mwindow->session->drag_clips->total)
00510 {
00511 EDL *clip = mwindow->session->drag_clips->values[0];
00512 asset_length_float = clip->tracks->total_length();
00513 } else
00514 {
00515 printf("DRAG_ASSET error: Asset dropped, but both drag_clips and drag_assets total is zero\n");
00516 }
00517
00518 asset_length_units = mwindow->session->track_highlighted->to_units(asset_length_float, 1);
00519 position = get_drop_position (&insertion, NULL, asset_length_units);
00520 if (position == -1)
00521 {
00522 result = 1;
00523 break;
00524 }
00525
00526 double position_f = mwindow->session->track_highlighted->from_units(position);
00527 Track *track = mwindow->session->track_highlighted;
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 mwindow->paste_assets(position_f, track, !insertion);
00538 result = 1;
00539 }
00540 break;
00541
00542 case DRAG_EDIT:
00543 mwindow->session->current_operation = NO_OPERATION;
00544 if(mwindow->session->track_highlighted)
00545 {
00546 if(mwindow->session->track_highlighted->data_type == mwindow->session->drag_edit->track->data_type)
00547 {
00548 int64_t position = 0;
00549
00550 position = get_drop_position (&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length);
00551
00552 if (position == -1)
00553 {
00554 result = 1;
00555 break;
00556 }
00557
00558 double position_f = mwindow->session->track_highlighted->from_units(position);
00559 Track *track = mwindow->session->track_highlighted;
00560 mwindow->move_edits(mwindow->session->drag_edits,
00561 track,
00562 position_f,
00563 !insertion);
00564 }
00565
00566 result = 1;
00567 }
00568 break;
00569 }
00570
00571
00572 if(result)
00573 {
00574 if (mwindow->session->track_highlighted
00575 || mwindow->session->edit_highlighted
00576 || mwindow->session->plugin_highlighted
00577 || mwindow->session->pluginset_highlighted)
00578 redraw = 1;
00579 mwindow->session->track_highlighted = 0;
00580 mwindow->session->edit_highlighted = 0;
00581 mwindow->session->plugin_highlighted = 0;
00582 mwindow->session->pluginset_highlighted = 0;
00583 mwindow->session->current_operation = NO_OPERATION;
00584 }
00585
00586
00587
00588 if(redraw)
00589 {
00590 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
00591 gui->get_scrollbars();
00592 draw();
00593 gui->patchbay->update();
00594 gui->cursor->update();
00595 flash();
00596 flush();
00597 }
00598
00599 return result;
00600 }
00601
00602
00603 int64_t TrackCanvas::get_drop_position (int *is_insertion, Edit *moved_edit, int64_t moved_edit_length)
00604 {
00605 *is_insertion = 0;
00606
00607
00608 int cursor_x = get_relative_cursor_x();
00609 double pos = (double)cursor_x *
00610 mwindow->edl->local_session->zoom_sample /
00611 mwindow->edl->session->sample_rate +
00612 (double)mwindow->edl->local_session->view_start *
00613 mwindow->edl->local_session->zoom_sample /
00614 mwindow->edl->session->sample_rate;
00615
00616 Track *track = mwindow->session->track_highlighted;
00617
00618 int64_t cursor_position;
00619 if (moved_edit)
00620 cursor_position = track->to_units (pos - (mwindow->session->drag_position - moved_edit->track->from_units(moved_edit->startproject)), 1);
00621 else
00622 cursor_position = track->to_units (pos , 1) - moved_edit_length / 2;
00623
00624
00625 int64_t real_cursor_position = track->to_units (pos, 0);
00626 if (cursor_position < 0) cursor_position = 0;
00627 if (real_cursor_position < 0) real_cursor_position = 0;
00628 int64_t position = -1;
00629 int64_t span_start = 0;
00630 int64_t span_length = 0;
00631 int span_asset = 0;
00632 int last_ignore = 0;
00633
00634 if (!track->edits->last)
00635 {
00636
00637 position = cursor_position;
00638 }
00639 else
00640 {
00641 Edit *fake_edit = new Edit(mwindow->edl, track);
00642 int last2 = 0;
00643
00644
00645 for (Edit *edit = track->edits->first; edit || last2 < 2; )
00646 {
00647
00648 if (!edit && last_ignore)
00649 {
00650 span_length += 100000000000000LL;
00651 last_ignore = 0;
00652 span_asset = 0;
00653 } else
00654 if (edit &&
00655 ((moved_edit && edit == moved_edit && edit->previous && !edit->previous->asset) ||
00656 (moved_edit && edit->previous == moved_edit && !edit->asset)))
00657 {
00658 span_length += edit->length;
00659 last_ignore = 1;
00660 } else
00661 {
00662 fake_edit->startproject = span_start;
00663 fake_edit->length = span_length;
00664 int64_t edit_x, edit_y, edit_w, edit_h;
00665 edit_dimensions(fake_edit, edit_x, edit_y, edit_w, edit_h);
00666 if (labs(edit_x - cursor_x) < HANDLE_W)
00667 {
00668 *is_insertion = 1;
00669 position = span_start;
00670 } else
00671 if (labs(edit_x + edit_w - cursor_x) < HANDLE_W)
00672 {
00673 *is_insertion = 1;
00674 position = span_start + span_length;
00675
00676 } else
00677 if (!span_asset &&
00678 span_start <= cursor_position &&
00679 span_start + span_length >= cursor_position + moved_edit_length)
00680 {
00681 position = cursor_position;
00682 } else
00683 if (!span_asset &
00684 real_cursor_position >= span_start &&
00685 real_cursor_position < span_start + span_length &&
00686 span_length >= moved_edit_length)
00687 {
00688 if (llabs(real_cursor_position - span_start) < llabs(real_cursor_position - span_start - span_length))
00689 position = span_start;
00690 else
00691 position = span_start + span_length - moved_edit_length;
00692 } else
00693 if (cursor_x > edit_x && cursor_x <= edit_x + edit_w / 2)
00694 {
00695 *is_insertion = 1;
00696 position = span_start;
00697 } else
00698 if (cursor_x > edit_x + edit_w / 2 && cursor_x <= edit_x + edit_w)
00699 {
00700 *is_insertion = 1;
00701 position = span_start + span_length;
00702 }
00703
00704
00705 if (position != -1)
00706 break;
00707
00708
00709 if (edit)
00710 {
00711 span_length = edit->length;
00712 span_start = edit->startproject;
00713 last_ignore = 0;
00714 if (!edit->asset || (!moved_edit || moved_edit == edit))
00715 {
00716 if (moved_edit && moved_edit == edit)
00717 last_ignore = 1;
00718
00719 span_asset = 0;
00720 } else
00721 span_asset = 1;
00722 } else
00723 {
00724 span_start = span_length + span_start;
00725 span_length = 100000000000000LL;
00726 span_asset = 0;
00727 };
00728
00729
00730 }
00731 if (edit)
00732 edit = edit->next;
00733 else
00734 last2++;
00735
00736 }
00737 delete fake_edit;
00738
00739 }
00740 if (real_cursor_position == 0)
00741 {
00742 position = 0;
00743 *is_insertion = 1;
00744 }
00745
00746 return position;
00747
00748
00749 }
00750
00751 void TrackCanvas::draw(int mode, int hide_cursor)
00752 {
00753
00754 if(get_w() != background_pixmap->get_w() ||
00755 get_h() != background_pixmap->get_h())
00756 {
00757 delete background_pixmap;
00758 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
00759 }
00760
00761
00762
00763 if(gui->cursor && hide_cursor) gui->cursor->hide();
00764 draw_top_background(get_parent(), 0, 0, get_w(), get_h(), background_pixmap);
00765 draw_resources(mode);
00766 draw_overlays();
00767 }
00768
00769 void TrackCanvas::update_cursor()
00770 {
00771 switch(mwindow->edl->session->editing_mode)
00772 {
00773 case EDITING_ARROW: set_cursor(ARROW_CURSOR); break;
00774 case EDITING_IBEAM: set_cursor(IBEAM_CURSOR); break;
00775 }
00776 }
00777
00778
00779 void TrackCanvas::test_timer()
00780 {
00781 if(resource_timer->get_difference() > 1000 &&
00782 !hourglass_enabled)
00783 {
00784 start_hourglass();
00785 hourglass_enabled = 1;
00786 }
00787 }
00788
00789
00790 void TrackCanvas::draw_indexes(Asset *asset)
00791 {
00792
00793 if(asset->index_zoom > mwindow->edl->local_session->zoom_sample)
00794 return;
00795
00796 draw_resources(0, 1, asset);
00797
00798 draw_overlays();
00799 draw_automation();
00800 flash();
00801 flush();
00802 }
00803
00804 void TrackCanvas::draw_resources(int mode,
00805 int indexes_only,
00806 Asset *index_asset)
00807 {
00808 if(!mwindow->edl->session->show_assets) return;
00809
00810 if(mode != 3 && !indexes_only)
00811 resource_thread->stop_draw(!indexes_only);
00812
00813 resource_timer->update();
00814
00815
00816 if(!indexes_only)
00817 for(int i = 0; i < resource_pixmaps.total; i++)
00818 resource_pixmaps.values[i]->visible--;
00819
00820 if(mode == 2)
00821 resource_pixmaps.remove_all_objects();
00822
00823
00824
00825 for(Track *current = mwindow->edl->tracks->first;
00826 current;
00827 current = NEXT)
00828 {
00829 for(Edit *edit = current->edits->first; edit; edit = edit->next)
00830 {
00831 if(!edit->asset) continue;
00832 if(indexes_only)
00833 {
00834 if(edit->track->data_type != TRACK_AUDIO) continue;
00835 if(!edit->asset->test_path(index_asset->path)) continue;
00836 }
00837
00838 int64_t edit_x, edit_y, edit_w, edit_h;
00839 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
00840
00841
00842 if(MWindowGUI::visible(edit_x, edit_x + edit_w, 0, get_w()) &&
00843 MWindowGUI::visible(edit_y, edit_y + edit_h, 0, get_h()))
00844 {
00845 int64_t pixmap_x, pixmap_w, pixmap_h;
00846
00847
00848 for(int i = 0; i < resource_pixmaps.total; i++)
00849 {
00850 ResourcePixmap* pixmap = resource_pixmaps.values[i];
00851
00852 if(pixmap->edit_id == edit->id)
00853 {
00854 pixmap->visible = 1;
00855 break;
00856 }
00857 }
00858
00859
00860 get_pixmap_size(edit,
00861 edit_x,
00862 edit_w,
00863 pixmap_x,
00864 pixmap_w,
00865 pixmap_h);
00866
00867
00868 if(pixmap_w && pixmap_h)
00869 {
00870
00871 ResourcePixmap* pixmap = create_pixmap(edit,
00872 edit_x,
00873 pixmap_x,
00874 pixmap_w,
00875 pixmap_h);
00876
00877 if(pixmap_w > pixmap->pixmap_w ||
00878 pixmap_h > pixmap->pixmap_h)
00879 pixmap->resize(pixmap_w, pixmap_h);
00880 pixmap->draw_data(edit,
00881 edit_x,
00882 edit_w,
00883 pixmap_x,
00884 pixmap_w,
00885 pixmap_h,
00886 mode,
00887 indexes_only);
00888
00889 if(pixmap_w < pixmap->pixmap_w ||
00890 pixmap_h < pixmap->pixmap_h)
00891 pixmap->resize(pixmap_w, pixmap_h);
00892
00893
00894 background_pixmap->draw_pixmap(pixmap,
00895 pixmap->pixmap_x,
00896 current->y_pixel,
00897 pixmap->pixmap_w,
00898 edit_h);
00899 }
00900 }
00901 }
00902 }
00903
00904
00905 if(!indexes_only)
00906 for(int i = resource_pixmaps.total - 1; i >= 0; i--)
00907 if(resource_pixmaps.values[i]->visible < -5)
00908 {
00909 delete resource_pixmaps.values[i];
00910 resource_pixmaps.remove(resource_pixmaps.values[i]);
00911 }
00912
00913 if(hourglass_enabled)
00914 {
00915 stop_hourglass();
00916 hourglass_enabled = 0;
00917 }
00918
00919 if(mode != 3 && !indexes_only)
00920 resource_thread->start_draw();
00921 }
00922
00923 ResourcePixmap* TrackCanvas::create_pixmap(Edit *edit,
00924 int64_t edit_x,
00925 int64_t pixmap_x,
00926 int64_t pixmap_w,
00927 int64_t pixmap_h)
00928 {
00929 ResourcePixmap *result = 0;
00930
00931 for(int i = 0; i < resource_pixmaps.total; i++)
00932 {
00933
00934 if(resource_pixmaps.values[i]->edit_id == edit->id)
00935 {
00936 result = resource_pixmaps.values[i];
00937 break;
00938 }
00939 }
00940
00941 if(!result)
00942 {
00943
00944 result = new ResourcePixmap(mwindow,
00945 this,
00946 edit,
00947 pixmap_w,
00948 pixmap_h);
00949 resource_pixmaps.append(result);
00950 }
00951
00952
00953 return result;
00954 }
00955
00956 void TrackCanvas::get_pixmap_size(Edit *edit,
00957 int64_t edit_x,
00958 int64_t edit_w,
00959 int64_t &pixmap_x,
00960 int64_t &pixmap_w,
00961 int64_t &pixmap_h)
00962 {
00963
00964
00965
00966
00967
00968
00969
00970
00971 pixmap_x = edit_x;
00972 pixmap_w = edit_w;
00973 if(pixmap_x < 0)
00974 {
00975 pixmap_w -= -edit_x;
00976 pixmap_x = 0;
00977 }
00978
00979 if(pixmap_x + pixmap_w > get_w())
00980 {
00981 pixmap_w = get_w() - pixmap_x;
00982 }
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013 pixmap_h = mwindow->edl->local_session->zoom_track;
01014 if(mwindow->edl->session->show_titles) pixmap_h += mwindow->theme->get_image("title_bg_data")->get_h();
01015
01016 }
01017
01018 void TrackCanvas::edit_dimensions(Edit *edit,
01019 int64_t &x,
01020 int64_t &y,
01021 int64_t &w,
01022 int64_t &h)
01023 {
01024
01025
01026
01027
01028 h = resource_h();
01029
01030 x = Units::round(edit->track->from_units(edit->startproject) *
01031 mwindow->edl->session->sample_rate /
01032 mwindow->edl->local_session->zoom_sample -
01033 mwindow->edl->local_session->view_start);
01034
01035
01036 int64_t x_next = Units::round(edit->track->from_units(edit->startproject + edit->length) *
01037 mwindow->edl->session->sample_rate /
01038 mwindow->edl->local_session->zoom_sample -
01039 mwindow->edl->local_session->view_start);
01040 w = x_next - x;
01041
01042 y = edit->edits->track->y_pixel;
01043
01044 if(mwindow->edl->session->show_titles)
01045 h += mwindow->theme->get_image("title_bg_data")->get_h();
01046 }
01047
01048 void TrackCanvas::track_dimensions(Track *track, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
01049 {
01050 x = 0;
01051 w = get_w();
01052 y = track->y_pixel;
01053 h = track->vertical_span(mwindow->theme);
01054 }
01055
01056
01057 void TrackCanvas::draw_paste_destination()
01058 {
01059 int current_atrack = 0;
01060 int current_vtrack = 0;
01061 int current_aedit = 0;
01062 int current_vedit = 0;
01063 int64_t w = 0;
01064 int64_t x;
01065 double position;
01066 int insertion = 0;
01067
01068
01069 if((mwindow->session->current_operation == DRAG_ASSET &&
01070 (mwindow->session->drag_assets->total ||
01071 mwindow->session->drag_clips->total)) ||
01072 (mwindow->session->current_operation == DRAG_EDIT &&
01073 mwindow->session->drag_edits->total))
01074 {
01075
01076 Asset *asset = 0;
01077 EDL *clip = 0;
01078 int draw_box = 0;
01079
01080 if(mwindow->session->current_operation == DRAG_ASSET &&
01081 mwindow->session->drag_assets->total)
01082 asset = mwindow->session->drag_assets->values[0];
01083
01084 if(mwindow->session->current_operation == DRAG_ASSET &&
01085 mwindow->session->drag_clips->total)
01086 clip = mwindow->session->drag_clips->values[0];
01087
01088
01089 double paste_audio_length, paste_video_length;
01090 int64_t asset_length;
01091 double desta_position = 0;
01092 double destv_position = 0;
01093
01094 if (asset)
01095 {
01096 double asset_length_ac = asset->total_length_framealigned(mwindow->edl->session->frame_rate);
01097 if (mwindow->edl->session->cursor_on_frames)
01098 {
01099 paste_video_length = paste_audio_length = asset_length_ac;
01100 }
01101 else
01102 {
01103 paste_audio_length = (double)asset->audio_length / asset->sample_rate;
01104 paste_video_length = (double)asset->video_length / asset->frame_rate;
01105 }
01106
01107
01108 if (asset->video_data && asset->video_length < 0)
01109 {
01110 if(mwindow->edl->session->si_useduration)
01111 paste_video_length = mwindow->edl->session->si_duration / asset->frame_rate;
01112 else
01113 paste_video_length = 1.0 / asset->frame_rate;
01114 }
01115
01116 int64_t asset_length = 0;
01117
01118 if(asset->audio_data)
01119 {
01120
01121 if(asset->video_data && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
01122 asset_length = mwindow->session->track_highlighted->to_units(paste_video_length, 1);
01123 else
01124 asset_length = mwindow->session->track_highlighted->to_units(paste_audio_length, 1);
01125
01126 desta_position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
01127 }
01128
01129 if(asset->video_data)
01130 {
01131 asset_length = mwindow->session->track_highlighted->to_units((double)paste_video_length, 1);
01132 destv_position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
01133 }
01134 }
01135
01136 if(clip)
01137 {
01138 if(mwindow->edl->session->cursor_on_frames)
01139 paste_audio_length = paste_video_length = clip->tracks->total_length_framealigned(mwindow->edl->session->frame_rate);
01140 else
01141 paste_audio_length = paste_video_length = clip->tracks->total_length();
01142
01143 int64_t asset_length;
01144
01145 asset_length = mwindow->session->track_highlighted->to_units((double)clip->tracks->total_length(), 1);
01146 desta_position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
01147 }
01148
01149
01150 for(Track *dest = mwindow->session->track_highlighted;
01151 dest;
01152 dest = dest->next)
01153 {
01154 if(dest->record)
01155 {
01156
01157 w = -1;
01158
01159
01160 if(mwindow->session->edit_highlighted)
01161 position = mwindow->session->track_highlighted->from_units(
01162 mwindow->session->edit_highlighted->startproject);
01163 else
01164
01165 position = mwindow->session->track_highlighted->from_units(
01166 mwindow->session->track_highlighted->edits->last->startproject);
01167
01168
01169 if(dest->data_type == TRACK_AUDIO)
01170 {
01171 if( (asset && current_atrack < asset->channels)
01172 || (clip && current_atrack < clip->tracks->total_audio_tracks()) )
01173 {
01174 w = Units::to_int64(paste_audio_length *
01175 mwindow->edl->session->sample_rate /
01176 mwindow->edl->local_session->zoom_sample);
01177
01178 position = desta_position;
01179 if (position < 0)
01180 w = -1;
01181 else
01182 {
01183 current_atrack++;
01184 draw_box = 1;
01185 }
01186 }
01187 else
01188 if(mwindow->session->current_operation == DRAG_EDIT &&
01189 current_aedit < mwindow->session->drag_edits->total)
01190 {
01191 Edit *edit;
01192 while(current_aedit < mwindow->session->drag_edits->total &&
01193 mwindow->session->drag_edits->values[current_aedit]->track->data_type != TRACK_AUDIO)
01194 current_aedit++;
01195
01196 if(current_aedit < mwindow->session->drag_edits->total)
01197 {
01198 edit = mwindow->session->drag_edits->values[current_aedit];
01199 w = Units::to_int64(edit->length / mwindow->edl->local_session->zoom_sample);
01200
01201 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length));
01202 if (position < 0)
01203 w = -1;
01204 else
01205 {
01206 current_aedit++;
01207 draw_box = 1;
01208 }
01209 }
01210 }
01211 }
01212 else
01213 if(dest->data_type == TRACK_VIDEO)
01214 {
01215
01216 if( (asset && current_vtrack < asset->layers)
01217 || (clip && current_vtrack < clip->tracks->total_video_tracks()) )
01218 {
01219
01220 w = Units::to_int64((double)paste_video_length *
01221 mwindow->edl->session->sample_rate /
01222 mwindow->edl->local_session->zoom_sample);
01223
01224 position = destv_position;
01225 if (position < 0)
01226 w = -1;
01227 else
01228 {
01229 current_vtrack++;
01230 draw_box = 1;
01231 }
01232 }
01233 else
01234 if(mwindow->session->current_operation == DRAG_EDIT &&
01235 current_vedit < mwindow->session->drag_edits->total)
01236 {
01237 Edit *edit;
01238 while(current_vedit < mwindow->session->drag_edits->total &&
01239 mwindow->session->drag_edits->values[current_vedit]->track->data_type != TRACK_VIDEO)
01240 current_vedit++;
01241
01242 if(current_vedit < mwindow->session->drag_edits->total)
01243 {
01244 edit = mwindow->session->drag_edits->values[current_vedit];
01245 w = Units::to_int64(edit->track->from_units(edit->length) *
01246 mwindow->edl->session->sample_rate /
01247 mwindow->edl->local_session->zoom_sample);
01248
01249 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length));
01250 if (position < 0)
01251 w = -1;
01252 else
01253 {
01254 current_vedit++;
01255 draw_box = 1;
01256 }
01257 }
01258 }
01259 }
01260
01261 if(w >= 0)
01262 {
01263
01264 x = Units::to_int64(position *
01265 mwindow->edl->session->sample_rate /
01266 mwindow->edl->local_session->zoom_sample) -
01267 mwindow->edl->local_session->view_start;
01268 int y = dest->y_pixel;
01269 int h = dest->vertical_span(mwindow->theme);
01270
01271
01272
01273 if (insertion)
01274 draw_highlight_insertion(x, y, w, h);
01275 else
01276 draw_highlight_rectangle(x, y, w, h);
01277 }
01278 }
01279 }
01280 }
01281 }
01282
01283 void TrackCanvas::plugin_dimensions(Plugin *plugin, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
01284 {
01285 x = Units::round(plugin->track->from_units(plugin->startproject) *
01286 mwindow->edl->session->sample_rate /
01287 mwindow->edl->local_session->zoom_sample -
01288 mwindow->edl->local_session->view_start);
01289 w = Units::round(plugin->track->from_units(plugin->length) *
01290 mwindow->edl->session->sample_rate /
01291 mwindow->edl->local_session->zoom_sample);
01292 y = plugin->track->y_pixel +
01293 mwindow->edl->local_session->zoom_track +
01294 plugin->plugin_set->get_number() *
01295 mwindow->theme->get_image("plugin_bg_data")->get_h();
01296 if(mwindow->edl->session->show_titles)
01297 y += mwindow->theme->get_image("title_bg_data")->get_h();
01298 h = mwindow->theme->get_image("plugin_bg_data")->get_h();
01299 }
01300
01301 int TrackCanvas::resource_h()
01302 {
01303 return mwindow->edl->local_session->zoom_track;
01304 }
01305
01306 void TrackCanvas::draw_highlight_rectangle(int x, int y, int w, int h)
01307 {
01308
01309
01310
01311
01312
01313 if (x + w <= 0)
01314 {
01315 draw_triangle_left(0, y + h /6, h * 2/3, h * 2/3, BLACK, GREEN, YELLOW, RED, BLUE);
01316 return;
01317 } else
01318 if (x >= get_w())
01319 {
01320 draw_triangle_right(get_w() - h * 2/3, y + h /6, h * 2/3, h * 2/3, BLACK, GREEN, YELLOW, RED, BLUE);
01321 return;
01322 }
01323
01324
01325
01326 if (w >= 0 && w < 3) {x -= w /2; w = 3;};
01327 if(x < -10)
01328 {
01329 w += x - -10;
01330 x = -10;
01331 }
01332 if(y < -10)
01333 {
01334 h += y - -10;
01335 y = -10;
01336 }
01337 w = MIN(w, get_w() + 20);
01338 h = MIN(h, get_h() + 20);
01339 set_color(WHITE);
01340 set_inverse();
01341 draw_rectangle(x, y, w, h);
01342 draw_rectangle(x + 1, y + 1, w - 2, h - 2);
01343 set_opaque();
01344
01345 }
01346
01347 void TrackCanvas::draw_highlight_insertion(int x, int y, int w, int h)
01348 {
01349
01350
01351
01352
01353
01354
01355
01356 int h1 = h / 8;
01357 int h2 = h / 4;
01358
01359 set_inverse();
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369 draw_triangle_right(x - h2, y + h1, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
01370 draw_triangle_right(x - h2, y + h1*5, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
01371
01372
01373
01374
01375
01376
01377 draw_triangle_left(x, y + h1, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
01378 draw_triangle_left(x, y + h1*5, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
01379
01380
01381 x -= w / 2;
01382
01383
01384 if (w >= 0 && w < 3) {x -= w /2; w = 3;};
01385 if(x < -10)
01386 {
01387 w += x - -10;
01388 x = -10;
01389 }
01390 if(y < -10)
01391 {
01392 h += y - -10;
01393 y = -10;
01394 }
01395 w = MIN(w, get_w() + 20);
01396 h = MIN(h, get_h() + 20);
01397 set_color(WHITE);
01398 set_inverse();
01399 draw_rectangle(x, y, w, h);
01400 draw_rectangle(x + 1, y + 1, w - 2, h - 2);
01401 set_opaque();
01402
01403 }
01404
01405 void TrackCanvas::draw_playback_cursor()
01406 {
01407
01408
01409
01410
01411
01412
01413 }
01414
01415 void TrackCanvas::get_handle_coords(Edit *edit, int64_t &x, int64_t &y, int64_t &w, int64_t &h, int side)
01416 {
01417 int handle_w = mwindow->theme->edithandlein_data[0]->get_w();
01418 int handle_h = mwindow->theme->edithandlein_data[0]->get_h();
01419
01420 edit_dimensions(edit, x, y, w, h);
01421
01422 if(mwindow->edl->session->show_titles)
01423 {
01424 y += mwindow->theme->get_image("title_bg_data")->get_h();
01425 }
01426 else
01427 {
01428 y = 0;
01429 }
01430
01431 if(side == EDIT_OUT)
01432 {
01433 x += w - handle_w;
01434 }
01435
01436 h = handle_h;
01437 w = handle_w;
01438 }
01439
01440 void TrackCanvas::get_transition_coords(int64_t &x, int64_t &y, int64_t &w, int64_t &h)
01441 {
01442
01443
01444
01445 int transition_w = 30;
01446 int transition_h = 30;
01447
01448
01449 if(mwindow->edl->session->show_titles)
01450 y += mwindow->theme->get_image("title_bg_data")->get_h();
01451
01452
01453 y += (h - mwindow->theme->get_image("title_bg_data")->get_h()) / 2 - transition_h / 2;
01454 x -= transition_w / 2;
01455
01456 h = transition_h;
01457 w = transition_w;
01458 }
01459
01460 void TrackCanvas::draw_highlighting()
01461 {
01462 int64_t x, y, w, h;
01463 int draw_box = 0;
01464
01465
01466
01467
01468 switch(mwindow->session->current_operation)
01469 {
01470 case DRAG_ATRANSITION:
01471 case DRAG_VTRANSITION:
01472
01473
01474 if(mwindow->session->edit_highlighted)
01475 {
01476
01477 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
01478 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
01479 (mwindow->session->current_operation == DRAG_VTRANSITION &&
01480 mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
01481 {
01482
01483 edit_dimensions(mwindow->session->edit_highlighted, x, y, w, h);
01484
01485
01486 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
01487 MWindowGUI::visible(y, y + h, 0, get_h()))
01488 {
01489 draw_box = 1;
01490 get_transition_coords(x, y, w, h);
01491 }
01492
01493 }
01494 }
01495 break;
01496
01497
01498
01499
01500 case DRAG_AEFFECT:
01501 case DRAG_VEFFECT:
01502 if(mwindow->session->track_highlighted &&
01503 ((mwindow->session->current_operation == DRAG_AEFFECT && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
01504 (mwindow->session->current_operation == DRAG_VEFFECT && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
01505 {
01506
01507 if(mwindow->session->plugin_highlighted)
01508 {
01509 plugin_dimensions(mwindow->session->plugin_highlighted,
01510 x,
01511 y,
01512 w,
01513 h);
01514
01515 }
01516 else
01517
01518 if(mwindow->session->pluginset_highlighted &&
01519 mwindow->session->pluginset_highlighted->last)
01520 {
01521 plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last,
01522 x,
01523 y,
01524 w,
01525 h);
01526
01527 int64_t track_x, track_y, track_w, track_h;
01528 track_dimensions(mwindow->session->track_highlighted,
01529 track_x,
01530 track_y,
01531 track_w,
01532 track_h);
01533
01534 x += w;
01535 w = Units::round(
01536 mwindow->session->track_highlighted->get_length() *
01537 mwindow->edl->session->sample_rate /
01538 mwindow->edl->local_session->zoom_sample -
01539 mwindow->edl->local_session->view_start) -
01540 x;
01541
01542 if(w <= 0) w = track_w;
01543 }
01544 else
01545 {
01546 track_dimensions(mwindow->session->track_highlighted,
01547 x,
01548 y,
01549 w,
01550 h);
01551
01552
01553
01554 if(mwindow->edl->local_session->get_selectionend() >
01555 mwindow->edl->local_session->get_selectionstart())
01556 {
01557 x = Units::to_int64(mwindow->edl->local_session->get_selectionstart() *
01558 mwindow->edl->session->sample_rate /
01559 mwindow->edl->local_session->zoom_sample -
01560 mwindow->edl->local_session->view_start);
01561 w = Units::to_int64((mwindow->edl->local_session->get_selectionend() -
01562 mwindow->edl->local_session->get_selectionstart()) *
01563 mwindow->edl->session->sample_rate /
01564 mwindow->edl->local_session->zoom_sample);
01565 }
01566
01567 else
01568 if(mwindow->session->edit_highlighted)
01569 {
01570 int64_t temp_y, temp_h;
01571 edit_dimensions(mwindow->session->edit_highlighted,
01572 x,
01573 temp_y,
01574 w,
01575 temp_h);
01576 }
01577
01578 }
01579
01580 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
01581 MWindowGUI::visible(y, y + h, 0, get_h()))
01582 {
01583
01584 draw_box = 1;
01585 }
01586 }
01587 break;
01588
01589 case DRAG_ASSET:
01590 if(mwindow->session->track_highlighted)
01591 {
01592 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
01593
01594 if(MWindowGUI::visible(y, y + h, 0, get_h()))
01595 {
01596 draw_paste_destination();
01597 }
01598 }
01599 break;
01600
01601
01602 case DRAG_AEFFECT_COPY:
01603 case DRAG_VEFFECT_COPY:
01604 if((mwindow->session->plugin_highlighted || mwindow->session->track_highlighted) &&
01605 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
01606 (mwindow->session->current_operation == DRAG_VEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
01607 {
01608
01609 if(mwindow->session->plugin_highlighted)
01610 plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
01611 else
01612
01613 if(mwindow->session->pluginset_highlighted &&
01614 mwindow->session->pluginset_highlighted->last)
01615 {
01616 plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last, x, y, w, h);
01617 x += w;
01618 }
01619 else
01620 if(mwindow->session->track_highlighted)
01621 {
01622 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
01623
01624
01625 if(mwindow->session->edit_highlighted)
01626 {
01627 int64_t temp_y, temp_h;
01628 edit_dimensions(mwindow->session->edit_highlighted,
01629 x,
01630 temp_y,
01631 w,
01632 temp_h);
01633 }
01634
01635 }
01636
01637
01638 if(mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
01639 {
01640 w = (int64_t)((double)mwindow->session->drag_plugin->length /
01641 mwindow->edl->session->frame_rate *
01642 mwindow->edl->session->sample_rate /
01643 mwindow->edl->local_session->zoom_sample);
01644 }
01645 else
01646 {
01647 w = (int64_t)mwindow->session->drag_plugin->length /
01648 mwindow->edl->local_session->zoom_sample;
01649 }
01650
01651 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
01652 MWindowGUI::visible(y, y + h, 0, get_h()))
01653 {
01654 draw_box = 1;
01655 }
01656 }
01657 break;
01658
01659 case DRAG_PLUGINKEY:
01660 if(mwindow->session->plugin_highlighted &&
01661 mwindow->session->current_operation == DRAG_PLUGINKEY)
01662 {
01663
01664 plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
01665
01666 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
01667 MWindowGUI::visible(y, y + h, 0, get_h()))
01668 {
01669 draw_box = 1;
01670 }
01671 }
01672 break;
01673
01674 case DRAG_EDIT:
01675 if(mwindow->session->track_highlighted)
01676 {
01677 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
01678
01679 if(MWindowGUI::visible(y, y + h, 0, get_h()))
01680 {
01681 draw_paste_destination();
01682 }
01683 }
01684 break;
01685 }
01686
01687
01688 if(draw_box)
01689 {
01690 draw_highlight_rectangle(x, y, w, h);
01691 }
01692 }
01693
01694 void TrackCanvas::draw_plugins()
01695 {
01696 char string[BCTEXTLEN];
01697 int current_toggle = 0;
01698
01699 if(!mwindow->edl->session->show_assets) goto done;
01700
01701 for(int i = 0; i < plugin_on_toggles.total; i++)
01702 plugin_on_toggles.values[i]->in_use = 0;
01703 for(int i = 0; i < plugin_show_toggles.total; i++)
01704 plugin_show_toggles.values[i]->in_use = 0;
01705
01706
01707 for(Track *track = mwindow->edl->tracks->first;
01708 track;
01709 track = track->next)
01710 {
01711 if(track->expand_view)
01712 {
01713 for(int i = 0; i < track->plugin_set.total; i++)
01714 {
01715 PluginSet *pluginset = track->plugin_set.values[i];
01716
01717 for(Plugin *plugin = (Plugin*)pluginset->first; plugin; plugin = (Plugin*)plugin->next)
01718 {
01719 int64_t total_x, y, total_w, h;
01720 plugin_dimensions(plugin, total_x, y, total_w, h);
01721
01722 if(MWindowGUI::visible(total_x, total_x + total_w, 0, get_w()) &&
01723 MWindowGUI::visible(y, y + h, 0, get_h()) &&
01724 plugin->plugin_type != PLUGIN_NONE)
01725 {
01726 int x = total_x, w = total_w, left_margin = 5;
01727 int right_margin = 5;
01728 if(x < 0)
01729 {
01730 w -= -x;
01731 x = 0;
01732 }
01733 if(w + x > get_w()) w -= (w + x) - get_w();
01734
01735 draw_3segmenth(x,
01736 y,
01737 w,
01738 total_x,
01739 total_w,
01740 mwindow->theme->get_image("plugin_bg_data"),
01741 0);
01742 set_color(get_resources()->default_text_color);
01743 set_font(MEDIUMFONT_3D);
01744 plugin->calculate_title(string, 0);
01745
01746
01747 int len = strlen(string), j;
01748 for(j = len; j >= 0; j--)
01749 {
01750 if(left_margin + get_text_width(MEDIUMFONT_3D, string) > w)
01751 {
01752 string[j] = 0;
01753 }
01754 else
01755 break;
01756 }
01757
01758
01759
01760 int text_x = total_x + left_margin;
01761 text_x = MAX(left_margin, text_x);
01762 draw_text(text_x,
01763 y + get_text_ascent(MEDIUMFONT_3D) + 2,
01764 string,
01765 strlen(string),
01766 0);
01767
01768
01769
01770 int toggle_x = total_x + total_w;
01771 toggle_x = MIN(get_w() - right_margin, toggle_x);
01772 toggle_x -= PluginOn::calculate_w(mwindow) + 10;
01773 int toggle_y = y;
01774 if(current_toggle >= plugin_on_toggles.total)
01775 {
01776 PluginOn *plugin_on = new PluginOn(mwindow, toggle_x, toggle_y, plugin);
01777 add_subwindow(plugin_on);
01778 plugin_on_toggles.append(plugin_on);
01779 }
01780 else
01781 {
01782 plugin_on_toggles.values[current_toggle]->update(toggle_x, toggle_y, plugin);
01783 }
01784
01785 toggle_x -= PluginShow::calculate_w(mwindow) + 10;
01786 if(current_toggle >= plugin_show_toggles.total)
01787 {
01788 PluginShow *plugin_off = new PluginShow(mwindow, toggle_x, toggle_y, plugin);
01789 add_subwindow(plugin_off);
01790 plugin_show_toggles.append(plugin_off);
01791 }
01792 else
01793 {
01794 plugin_show_toggles.values[current_toggle]->update(toggle_x, toggle_y, plugin);
01795 }
01796 current_toggle++;
01797 }
01798 }
01799 }
01800 }
01801 }
01802
01803
01804 done:
01805 int i = current_toggle;
01806 while(i < plugin_on_toggles.total &&
01807 i < plugin_show_toggles.total)
01808 {
01809 plugin_on_toggles.remove_object_number(current_toggle);
01810 plugin_show_toggles.remove_object_number(current_toggle);
01811 }
01812 }
01813
01814 void TrackCanvas::refresh_plugintoggles()
01815 {
01816 for(int i = 0; i < plugin_on_toggles.total; i++)
01817 {
01818 PluginOn *on = plugin_on_toggles.values[i];
01819 on->reposition_window(on->get_x(), on->get_y());
01820 }
01821 for(int i = 0; i < plugin_show_toggles.total; i++)
01822 {
01823 PluginShow *show = plugin_show_toggles.values[i];
01824 show->reposition_window(show->get_x(), show->get_y());
01825 }
01826 }
01827
01828 void TrackCanvas::draw_inout_points()
01829 {
01830 }
01831
01832
01833 void TrackCanvas::draw_drag_handle()
01834 {
01835 if(mwindow->session->current_operation == DRAG_EDITHANDLE2 ||
01836 mwindow->session->current_operation == DRAG_PLUGINHANDLE2)
01837 {
01838
01839 int64_t pixel1 = Units::round(mwindow->session->drag_position *
01840 mwindow->edl->session->sample_rate /
01841 mwindow->edl->local_session->zoom_sample -
01842 mwindow->edl->local_session->view_start);
01843
01844 set_color(GREEN);
01845 set_inverse();
01846
01847 draw_line(pixel1, 0, pixel1, get_h());
01848 set_opaque();
01849
01850 }
01851 }
01852
01853
01854 void TrackCanvas::draw_transitions()
01855 {
01856 int64_t x, y, w, h;
01857
01858 if(!mwindow->edl->session->show_assets) return;
01859
01860 for(Track *track = mwindow->edl->tracks->first;
01861 track;
01862 track = track->next)
01863 {
01864 for(Edit *edit = track->edits->first;
01865 edit;
01866 edit = edit->next)
01867 {
01868 if(edit->transition)
01869 {
01870 int64_t strip_w, strip_x, strip_y;
01871 edit_dimensions(edit, x, y, w, h);
01872 strip_x = x ;
01873 strip_y = y;
01874 if(mwindow->edl->session->show_titles)
01875 strip_y += mwindow->theme->get_image("title_bg_data")->get_h();
01876
01877 get_transition_coords(x, y, w, h);
01878 strip_w = Units::round(edit->track->from_units(edit->transition->length) *
01879 mwindow->edl->session->sample_rate /
01880 mwindow->edl->local_session->zoom_sample);
01881
01882 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
01883 MWindowGUI::visible(y, y + h, 0, get_h()))
01884 {
01885 PluginServer *server = mwindow->scan_plugindb(edit->transition->title,
01886 track->data_type);
01887 draw_vframe(server->picon,
01888 x,
01889 y,
01890 w,
01891 h,
01892 0,
01893 0,
01894 server->picon->get_w(),
01895 server->picon->get_h());
01896 }
01897 if(MWindowGUI::visible(strip_x, strip_x + strip_w, 0, get_w()) &&
01898 MWindowGUI::visible(strip_y, strip_y + h, 0, get_h()))
01899 {
01900 int x = strip_x, w = strip_w, left_margin = 5;
01901 if(x < 0)
01902 {
01903 w -= -x;
01904 x = 0;
01905 }
01906 if(w + x > get_w()) w -= (w + x) - get_w();
01907
01908 draw_3segmenth(
01909 x,
01910 strip_y,
01911 w,
01912 strip_x,
01913 strip_w,
01914 mwindow->theme->get_image("plugin_bg_data"),
01915 0);
01916
01917 }
01918 }
01919 }
01920 }
01921 }
01922
01923 void TrackCanvas::draw_loop_points()
01924 {
01925
01926 if(mwindow->edl->local_session->loop_playback)
01927 {
01928
01929 int64_t x = Units::round(mwindow->edl->local_session->loop_start *
01930 mwindow->edl->session->sample_rate /
01931 mwindow->edl->local_session->zoom_sample -
01932 mwindow->edl->local_session->view_start);
01933
01934
01935 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
01936 {
01937 set_color(GREEN);
01938 draw_line(x, 0, x, get_h());
01939 }
01940
01941
01942 x = Units::round(mwindow->edl->local_session->loop_end *
01943 mwindow->edl->session->sample_rate /
01944 mwindow->edl->local_session->zoom_sample -
01945 mwindow->edl->local_session->view_start);
01946
01947
01948 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
01949 {
01950 set_color(GREEN);
01951 draw_line(x, 0, x, get_h());
01952 }
01953
01954 }
01955
01956 }
01957
01958 void TrackCanvas::draw_brender_start()
01959 {
01960 if(mwindow->preferences->use_brender)
01961 {
01962 int64_t x = Units::round(mwindow->edl->session->brender_start *
01963 mwindow->edl->session->sample_rate /
01964 mwindow->edl->local_session->zoom_sample -
01965 mwindow->edl->local_session->view_start);
01966
01967 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
01968 {
01969 set_color(RED);
01970 draw_line(x, 0, x, get_h());
01971 }
01972 }
01973 }
01974
01975 static int auto_colors[] =
01976 {
01977 BLUE,
01978 RED,
01979 GREEN,
01980 BLUE,
01981 RED,
01982 GREEN,
01983 BLUE,
01984 WHITE,
01985 0,
01986 0,
01987 0,
01988 0
01989 };
01990
01991
01992 static int auto_operations[] =
01993 {
01994 DRAG_MUTE,
01995 DRAG_CAMERA_X,
01996 DRAG_CAMERA_Y,
01997 DRAG_CAMERA_Z,
01998 DRAG_PROJECTOR_X,
01999 DRAG_PROJECTOR_Y,
02000 DRAG_PROJECTOR_Z,
02001 DRAG_FADE,
02002 DRAG_PAN,
02003 DRAG_MODE,
02004 DRAG_MASK,
02005 DRAG_NUDGE
02006 };
02007
02008
02009
02010
02011 static int pre_auto_operations[] =
02012 {
02013 DRAG_MUTE,
02014 DRAG_CAMERA_X,
02015 DRAG_CAMERA_Y,
02016 DRAG_CAMERA_Z,
02017 DRAG_PROJECTOR_X,
02018 DRAG_PROJECTOR_Y,
02019 DRAG_PROJECTOR_Z,
02020 DRAG_FADE,
02021 DRAG_PAN_PRE,
02022 DRAG_MODE_PRE,
02023 DRAG_MASK_PRE,
02024 DRAG_NUDGE
02025 };
02026
02027
02028 int TrackCanvas::do_keyframes(int cursor_x,
02029 int cursor_y,
02030 int draw,
02031 int buttonpress,
02032 int &new_cursor,
02033 int &update_cursor,
02034 int &rerender)
02035 {
02036
02037
02038 int current_tool = 0;
02039 int result = 0;
02040 EDLSession *session = mwindow->edl->session;
02041
02042
02043
02044 BC_Pixmap *auto_pixmaps[] =
02045 {
02046 0,
02047 0,
02048 0,
02049 0,
02050 0,
02051 0,
02052 0,
02053 0,
02054 pankeyframe_pixmap,
02055 modekeyframe_pixmap,
02056 maskkeyframe_pixmap,
02057 0,
02058 };
02059
02060
02061
02062 for(Track *track = mwindow->edl->tracks->first;
02063 track && !result;
02064 track = track->next)
02065 {
02066 Auto *auto_keyframe;
02067 Automation *automation = track->automation;
02068
02069
02070
02071 for(int i = 0; i < AUTOMATION_TOTAL && !result; i++)
02072 {
02073
02074 Autos *autos = automation->autos[i];
02075 if(!result && session->auto_conf->autos[i] && autos)
02076 {
02077 switch(i)
02078 {
02079 case AUTOMATION_MODE:
02080 case AUTOMATION_PAN:
02081 case AUTOMATION_MASK:
02082 result = do_autos(track,
02083 automation->autos[i],
02084 cursor_x,
02085 cursor_y,
02086 draw,
02087 buttonpress,
02088 auto_pixmaps[i],
02089 auto_keyframe);
02090 break;
02091
02092 default:
02093 switch(autos->get_type())
02094 {
02095 case AUTOMATION_TYPE_FLOAT:
02096 {
02097 Automation *dummy = new Automation(0,track);
02098 int autogrouptype = dummy->autogrouptype(i,track);
02099 result = do_float_autos(track,
02100 autos,
02101 cursor_x,
02102 cursor_y,
02103 draw,
02104 buttonpress,
02105 auto_colors[i],
02106 auto_keyframe,
02107 autogrouptype);
02108 delete dummy;
02109 }
02110 break;
02111
02112 case AUTOMATION_TYPE_INT:
02113 result = do_toggle_autos(track,
02114 autos,
02115 cursor_x,
02116 cursor_y,
02117 draw,
02118 buttonpress,
02119 auto_colors[i],
02120 auto_keyframe);
02121 break;
02122 }
02123 break;
02124 }
02125
02126
02127
02128 if(result)
02129 {
02130 if(mwindow->session->current_operation == auto_operations[i])
02131 rerender = 1;
02132 if(buttonpress)
02133 {
02134 if (buttonpress != 3)
02135 {
02136 if(i == AUTOMATION_FADE)
02137 synchronize_autos(0,
02138 track,
02139 (FloatAuto*)mwindow->session->drag_auto,
02140 1);
02141 mwindow->session->current_operation = pre_auto_operations[i];
02142 update_drag_caption();
02143 rerender = 1;
02144 }
02145 else
02146 {
02147 gui->keyframe_menu->update(automation, autos, auto_keyframe);
02148 gui->keyframe_menu->activate_menu();
02149 rerender = 1;
02150 }
02151 }
02152 }
02153 }
02154 }
02155
02156
02157
02158
02159 if(!result &&
02160 session->auto_conf->plugins &&
02161 mwindow->edl->session->show_assets)
02162 {
02163 Plugin *plugin;
02164 KeyFrame *keyframe;
02165 result = do_plugin_autos(track,
02166 cursor_x,
02167 cursor_y,
02168 draw,
02169 buttonpress,
02170 plugin,
02171 keyframe);
02172 if(result && mwindow->session->current_operation == DRAG_PLUGINKEY)
02173 {
02174 rerender = 1;
02175 }
02176 if(result && (buttonpress == 1))
02177 {
02178 mwindow->session->current_operation = DRAG_PLUGINKEY_PRE;
02179 update_drag_caption();
02180 rerender = 1;
02181 } else
02182 if (result && (buttonpress == 3))
02183 {
02184 gui->keyframe_menu->update(plugin, keyframe);
02185 gui->keyframe_menu->activate_menu();
02186 rerender = 1;
02187 }
02188 }
02189 }
02190
02191
02192 for(int i = 0; i < AUTOMATION_TOTAL; i++)
02193 {
02194 if(mwindow->session->current_operation == pre_auto_operations[i] ||
02195 mwindow->session->current_operation == auto_operations[i])
02196 result = 1;
02197 }
02198
02199 if(mwindow->session->current_operation == DRAG_PLUGINKEY ||
02200 mwindow->session->current_operation == DRAG_PLUGINKEY_PRE)
02201 {
02202 result = 1;
02203 }
02204
02205 update_cursor = 1;
02206 if(result)
02207 {
02208 new_cursor = UPRIGHT_ARROW_CURSOR;
02209 }
02210
02211 return result;
02212 }
02213
02214 void TrackCanvas::draw_auto(Auto *current,
02215 int x,
02216 int y,
02217 int center_pixel,
02218 int zoom_track,
02219 int color)
02220 {
02221 int x1, y1, x2, y2;
02222 char string[BCTEXTLEN];
02223
02224 x1 = x - HANDLE_W / 2;
02225 x2 = x + HANDLE_W / 2;
02226 y1 = center_pixel + y - HANDLE_W / 2;
02227 y2 = center_pixel + y + HANDLE_W / 2;
02228
02229 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
02230 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
02231
02232 set_color(BLACK);
02233 draw_box(x1 + 1, y1 + 1, x2 - x1, y2 - y1);
02234 set_color(color);
02235 draw_box(x1, y1, x2 - x1, y2 - y1);
02236 }
02237
02238 void TrackCanvas::draw_floatauto(Auto *current,
02239 int x,
02240 int y,
02241 int in_x,
02242 int in_y,
02243 int out_x,
02244 int out_y,
02245 int center_pixel,
02246 int zoom_track,
02247 int color)
02248 {
02249 int x1, y1, x2, y2;
02250 int in_x1, in_y1, in_x2, in_y2;
02251 int out_x1, out_y1, out_x2, out_y2;
02252 char string[BCTEXTLEN];
02253
02254
02255 x1 = x - HANDLE_W / 2;
02256 x2 = x + HANDLE_W / 2;
02257 y1 = center_pixel + y - HANDLE_W / 2;
02258 y2 = center_pixel + y + HANDLE_W / 2;
02259
02260 CLAMP(y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
02261 CLAMP(y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
02262
02263 if(y2 - 1 > y1)
02264 {
02265 set_color(BLACK);
02266 draw_box(x1 + 1, y1 + 1, x2 - x1, y2 - y1);
02267 set_color(color);
02268 draw_box(x1, y1, x2 - x1, y2 - y1);
02269 }
02270
02271
02272 in_x1 = in_x - HANDLE_W / 2;
02273 in_x2 = in_x + HANDLE_W / 2;
02274 in_y1 = center_pixel + in_y - HANDLE_W / 2;
02275 in_y2 = center_pixel + in_y + HANDLE_W / 2;
02276
02277 CLAMP(in_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
02278 CLAMP(in_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
02279 CLAMP(in_y, -zoom_track / 2, zoom_track / 2);
02280
02281 if(in_y2 > in_y1)
02282 {
02283 set_color(BLACK);
02284 draw_line(x + 1, center_pixel + y + 1, in_x + 1, center_pixel + in_y + 1);
02285 draw_box(in_x1 + 1, in_y1 + 1, in_x2 - in_x1, in_y2 - in_y1);
02286 set_color(color);
02287 draw_line(x, center_pixel + y, in_x, center_pixel + in_y);
02288 draw_box(in_x1, in_y1, in_x2 - in_x1, in_y2 - in_y1);
02289 }
02290
02291
02292
02293 out_x1 = out_x - HANDLE_W / 2;
02294 out_x2 = out_x + HANDLE_W / 2;
02295 out_y1 = center_pixel + out_y - HANDLE_W / 2;
02296 out_y2 = center_pixel + out_y + HANDLE_W / 2;
02297
02298 CLAMP(out_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
02299 CLAMP(out_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
02300 CLAMP(out_y, -zoom_track / 2, zoom_track / 2);
02301
02302 if(out_y2 > out_y1)
02303 {
02304 set_color(BLACK);
02305 draw_line(x + 1, center_pixel + y + 1, out_x + 1, center_pixel + out_y + 1);
02306 draw_box(out_x1 + 1, out_y1 + 1, out_x2 - out_x1, out_y2 - out_y1);
02307 set_color(color);
02308 draw_line(x, center_pixel + y, out_x, center_pixel + out_y);
02309 draw_box(out_x1, out_y1, out_x2 - out_x1, out_y2 - out_y1);
02310 }
02311 }
02312
02313 int TrackCanvas::test_auto(Auto *current,
02314 int x,
02315 int y,
02316 int center_pixel,
02317 int zoom_track,
02318 int cursor_x,
02319 int cursor_y,
02320 int buttonpress)
02321 {
02322 int x1, y1, x2, y2;
02323 char string[BCTEXTLEN];
02324 int result = 0;
02325
02326 x1 = x - HANDLE_W / 2;
02327 x2 = x + HANDLE_W / 2;
02328 y1 = center_pixel + y - HANDLE_W / 2;
02329 y2 = center_pixel + y + HANDLE_W / 2;
02330
02331 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
02332 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
02333
02334 if(cursor_x >= x1 && cursor_x < x2 && cursor_y >= y1 && cursor_y < y2)
02335 {
02336 if(buttonpress && buttonpress != 3)
02337 {
02338 mwindow->session->drag_auto = current;
02339 mwindow->session->drag_start_percentage = current->value_to_percentage();
02340 mwindow->session->drag_start_position = current->position;
02341 mwindow->session->drag_origin_x = cursor_x;
02342 mwindow->session->drag_origin_y = cursor_y;
02343 }
02344 result = 1;
02345 }
02346
02347 return result;
02348 }
02349
02350 int TrackCanvas::test_floatauto(Auto *current,
02351 int x,
02352 int y,
02353 int in_x,
02354 int in_y,
02355 int out_x,
02356 int out_y,
02357 int center_pixel,
02358 int zoom_track,
02359 int cursor_x,
02360 int cursor_y,
02361 int buttonpress)
02362 {
02363 int x1, y1, x2, y2;
02364 int in_x1, in_y1, in_x2, in_y2;
02365 int out_x1, out_y1, out_x2, out_y2;
02366 char string[BCTEXTLEN];
02367 int result = 0;
02368
02369 x1 = x - HANDLE_W / 2;
02370 x2 = x + HANDLE_W / 2;
02371 y1 = center_pixel + y - HANDLE_W / 2;
02372 y2 = center_pixel + y + HANDLE_W / 2;
02373
02374 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
02375 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
02376
02377 in_x1 = in_x - HANDLE_W / 2;
02378 in_x2 = in_x + HANDLE_W / 2;
02379 in_y1 = center_pixel + in_y - HANDLE_W / 2;
02380 in_y2 = center_pixel + in_y + HANDLE_W / 2;
02381
02382 if(in_y1 < center_pixel + -zoom_track / 2) in_y1 = center_pixel + -zoom_track / 2;
02383 if(in_y2 > center_pixel + zoom_track / 2) in_y2 = center_pixel + zoom_track / 2;
02384
02385 out_x1 = out_x - HANDLE_W / 2;
02386 out_x2 = out_x + HANDLE_W / 2;
02387 out_y1 = center_pixel + out_y - HANDLE_W / 2;
02388 out_y2 = center_pixel + out_y + HANDLE_W / 2;
02389
02390 if(out_y1 < center_pixel + -zoom_track / 2) out_y1 = center_pixel + -zoom_track / 2;
02391 if(out_y2 > center_pixel + zoom_track / 2) out_y2 = center_pixel + zoom_track / 2;
02392
02393
02394
02395
02396
02397 if(!ctrl_down() &&
02398 cursor_x >= x1 &&
02399 cursor_x < x2 &&
02400 cursor_y >= y1 &&
02401 cursor_y < y2)
02402 {
02403 if(buttonpress && (buttonpress != 3))
02404 {
02405 mwindow->session->drag_auto = current;
02406 mwindow->session->drag_start_percentage = current->value_to_percentage();
02407 mwindow->session->drag_start_position = current->position;
02408 mwindow->session->drag_origin_x = cursor_x;
02409 mwindow->session->drag_origin_y = cursor_y;
02410 mwindow->session->drag_handle = 0;
02411 }
02412 result = 1;
02413 }
02414 else
02415
02416 if(ctrl_down() &&
02417 cursor_x >= in_x1 &&
02418 cursor_x < in_x2 &&
02419 cursor_y >= in_y1 &&
02420 cursor_y < in_y2 &&
02421 current->position > 0)
02422 {
02423 if(buttonpress && (buttonpress != 3))
02424 {
02425 mwindow->session->drag_auto = current;
02426 mwindow->session->drag_start_percentage =
02427 current->invalue_to_percentage();
02428 mwindow->session->drag_start_position =
02429 ((FloatAuto*)current)->control_in_position;
02430 mwindow->session->drag_origin_x = cursor_x;
02431 mwindow->session->drag_origin_y = cursor_y;
02432 mwindow->session->drag_handle = 1;
02433 }
02434 result = 1;
02435 }
02436 else
02437
02438 if(ctrl_down() &&
02439 cursor_x >= out_x1 &&
02440 cursor_x < out_x2 &&
02441 cursor_y >= out_y1 &&
02442 cursor_y < out_y2)
02443 {
02444 if(buttonpress && (buttonpress != 3))
02445 {
02446 mwindow->session->drag_auto = current;
02447 mwindow->session->drag_start_percentage =
02448 current->outvalue_to_percentage();
02449 mwindow->session->drag_start_position =
02450 ((FloatAuto*)current)->control_out_position;
02451 mwindow->session->drag_origin_x = cursor_x;
02452 mwindow->session->drag_origin_y = cursor_y;
02453 mwindow->session->drag_handle = 2;
02454 }
02455 result = 1;
02456 }
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466 return result;
02467 }
02468
02469 void TrackCanvas::draw_floatline(int center_pixel,
02470 FloatAuto *previous,
02471 FloatAuto *next,
02472 FloatAutos *autos,
02473 double unit_start,
02474 double zoom_units,
02475 double yscale,
02476 int x1,
02477 int y1,
02478 int x2,
02479 int y2,
02480 int color,
02481 int autogrouptype)
02482 {
02483
02484
02485
02486
02487
02488
02489 x1 = MAX(0, x1);
02490
02491
02492
02493
02494 int prev_y;
02495
02496 FloatAuto *previous1 = previous, *next1 = next;
02497 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
02498 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
02499 float automation_range = automation_max - automation_min;
02500
02501 for(int x = x1; x < x2; x++)
02502 {
02503 int64_t position = (int64_t)(unit_start + x * zoom_units);
02504 float value = autos->get_value(position, PLAY_FORWARD, previous1, next1);
02505 AUTOMATIONCLAMPS(value, autogrouptype);
02506
02507 int y = center_pixel +
02508 (int)(((value - automation_min) / automation_range - 0.5) * -yscale);
02509
02510 if(x > x1 &&
02511 y >= center_pixel - yscale / 2 &&
02512 y < center_pixel + yscale / 2 - 1)
02513 {
02514 set_color(BLACK);
02515 draw_line(x - 1, prev_y + 1, x, y + 1);
02516 set_color(color);
02517 draw_line(x - 1, prev_y, x, y);
02518 }
02519 prev_y = y;
02520 }
02521
02522
02523 }
02524
02525 void TrackCanvas::synchronize_autos(float change,
02526 Track *skip,
02527 FloatAuto *fauto,
02528 int fill_gangs)
02529 {
02530
02531 if (fill_gangs == 1 && skip->gang)
02532 {
02533 for(Track *current = mwindow->edl->tracks->first;
02534 current;
02535 current = NEXT)
02536 {
02537 if(current->data_type == skip->data_type &&
02538 current->gang &&
02539 current->record &&
02540 current != skip)
02541 {
02542 FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
02543 double position = skip->from_units(fauto->position);
02544 FloatAuto *previous = 0, *next = 0;
02545
02546 float init_value = fade_autos->get_value(fauto->position, PLAY_FORWARD, previous, next);
02547 FloatAuto *keyframe;
02548 keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position);
02549
02550 if (!keyframe)
02551 {
02552
02553 keyframe = (FloatAuto*)fade_autos->insert_auto(fauto->position);
02554 keyframe->value = init_value;
02555 }
02556 else
02557 {
02558
02559 keyframe->value += change;
02560 }
02561
02562 keyframe->position = fauto->position;
02563 keyframe->control_out_position = fauto->control_out_position;
02564 keyframe->control_in_position = fauto->control_in_position;
02565 keyframe->control_out_value = fauto->control_out_value;
02566 keyframe->control_in_value = fauto->control_in_value;
02567
02568 mwindow->session->drag_auto_gang->append((Auto *)keyframe);
02569 }
02570 }
02571 } else
02572
02573 if (fill_gangs == 0)
02574 {
02575
02576 for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
02577 {
02578 FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
02579
02580 keyframe->value += change;
02581 keyframe->position = fauto->position;
02582 CLAMP(keyframe->value,
02583 mwindow->edl->local_session->automation_mins[keyframe->autos->autogrouptype],
02584 mwindow->edl->local_session->automation_maxs[keyframe->autos->autogrouptype]);
02585 keyframe->control_out_position = fauto->control_out_position;
02586 keyframe->control_in_position = fauto->control_in_position;
02587 keyframe->control_out_value = fauto->control_out_value;
02588 keyframe->control_in_value = fauto->control_in_value;
02589 }
02590
02591 }
02592 else
02593
02594 if (fill_gangs == -1)
02595 {
02596 for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
02597 {
02598 FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
02599 keyframe->autos->remove_nonsequential(
02600 keyframe);
02601 }
02602 mwindow->session->drag_auto_gang->remove_all();
02603 }
02604 }
02605
02606
02607 int TrackCanvas::test_floatline(int center_pixel,
02608 FloatAutos *autos,
02609 double unit_start,
02610 double zoom_units,
02611 double yscale,
02612 int x1,
02613 int x2,
02614 int cursor_x,
02615 int cursor_y,
02616 int buttonpress,
02617 int autogrouptype)
02618 {
02619 int result = 0;
02620
02621
02622 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
02623 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
02624 float automation_range = automation_max - automation_min;
02625 int64_t position = (int64_t)(unit_start + cursor_x * zoom_units);
02626
02627 FloatAuto *previous = 0, *next = 0;
02628 float value = autos->get_value(position, PLAY_FORWARD, previous, next);
02629 AUTOMATIONCLAMPS(value,autogrouptype);
02630 int y = center_pixel +
02631 (int)(((value - automation_min) / automation_range - 0.5) * -yscale);
02632
02633 if(cursor_x >= x1 &&
02634 cursor_x < x2 &&
02635 cursor_y >= y - HANDLE_W / 2 &&
02636 cursor_y < y + HANDLE_W / 2 &&
02637 !ctrl_down())
02638 {
02639 result = 1;
02640
02641
02642 if(buttonpress)
02643 {
02644
02645
02646 Auto *current;
02647 current = mwindow->session->drag_auto = autos->insert_auto(position);
02648 ((FloatAuto*)current)->value = value;
02649 mwindow->session->drag_start_percentage = current->value_to_percentage();
02650 mwindow->session->drag_start_position = current->position;
02651 mwindow->session->drag_origin_x = cursor_x;
02652 mwindow->session->drag_origin_y = cursor_y;
02653 mwindow->session->drag_handle = 0;
02654
02655 }
02656 }
02657
02658
02659 return result;
02660 }
02661
02662 void TrackCanvas::draw_toggleline(int center_pixel,
02663 int x1,
02664 int y1,
02665 int x2,
02666 int y2,
02667 int color)
02668 {
02669 set_color(BLACK);
02670 draw_line(x1, center_pixel + y1 + 1, x2, center_pixel + y1 + 1);
02671 set_color(color);
02672 draw_line(x1, center_pixel + y1, x2, center_pixel + y1);
02673
02674 if(y2 != y1)
02675 {
02676 set_color(BLACK);
02677 draw_line(x2 + 1, center_pixel + y1, x2 + 1, center_pixel + y2);
02678 set_color(color);
02679 draw_line(x2, center_pixel + y1, x2, center_pixel + y2);
02680 }
02681 }
02682
02683 int TrackCanvas::test_toggleline(Autos *autos,
02684 int center_pixel,
02685 int x1,
02686 int y1,
02687 int x2,
02688 int y2,
02689 int cursor_x,
02690 int cursor_y,
02691 int buttonpress)
02692 {
02693 int result = 0;
02694 if(cursor_x >= x1 && cursor_x < x2)
02695 {
02696 int miny = center_pixel + y1 - HANDLE_W / 2;
02697 int maxy = center_pixel + y1 + HANDLE_W / 2;
02698 if(cursor_y >= miny && cursor_y < maxy)
02699 {
02700 result = 1;
02701
02702 if(buttonpress)
02703 {
02704
02705
02706 Auto *current;
02707 double position = (double)(cursor_x +
02708 mwindow->edl->local_session->view_start) *
02709 mwindow->edl->local_session->zoom_sample /
02710 mwindow->edl->session->sample_rate;
02711 int64_t unit_position = autos->track->to_units(position, 0);
02712 int new_value = (int)((IntAutos*)autos)->get_automation_constant(unit_position, unit_position);
02713
02714 current = mwindow->session->drag_auto = autos->insert_auto(unit_position);
02715 ((IntAuto*)current)->value = new_value;
02716 mwindow->session->drag_start_percentage = current->value_to_percentage();
02717 mwindow->session->drag_start_position = current->position;
02718 mwindow->session->drag_origin_x = cursor_x;
02719 mwindow->session->drag_origin_y = cursor_y;
02720
02721 }
02722 }
02723 };
02724 return result;
02725 }
02726
02727 void TrackCanvas::calculate_viewport(Track *track,
02728 double &view_start,
02729 double &unit_start,
02730 double &view_end,
02731 double &unit_end,
02732 double &yscale,
02733 int ¢er_pixel,
02734 double &zoom_sample,
02735 double &zoom_units)
02736 {
02737 view_start = (double)mwindow->edl->local_session->view_start *
02738 mwindow->edl->local_session->zoom_sample /
02739 mwindow->edl->session->sample_rate;
02740 unit_start = track->to_doubleunits(view_start);
02741 view_end = (double)(mwindow->edl->local_session->view_start +
02742 get_w()) *
02743 mwindow->edl->local_session->zoom_sample /
02744 mwindow->edl->session->sample_rate;
02745 unit_end = track->to_doubleunits(view_end);
02746 yscale = mwindow->edl->local_session->zoom_track;
02747 center_pixel = (int)(track->y_pixel + yscale / 2) +
02748 (mwindow->edl->session->show_titles ?
02749 mwindow->theme->get_image("title_bg_data")->get_h() :
02750 0);
02751 zoom_sample = mwindow->edl->local_session->zoom_sample;
02752
02753 zoom_units = track->to_doubleunits(zoom_sample / mwindow->edl->session->sample_rate);
02754 }
02755
02756 float TrackCanvas::percentage_to_value(float percentage,
02757 int is_toggle,
02758 Auto *reference,
02759 int autogrouptype)
02760 {
02761 float result;
02762 if(is_toggle)
02763 {
02764 if(percentage > 0.5)
02765 result = 1;
02766 else
02767 result = 0;
02768 }
02769 else
02770 {
02771 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
02772 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
02773 float automation_range = automation_max - automation_min;
02774
02775 result = percentage * automation_range + automation_min;
02776 if(reference)
02777 {
02778 FloatAuto *ptr = (FloatAuto*)reference;
02779 result -= ptr->value;
02780 }
02781 }
02782 return result;
02783 }
02784
02785
02786 void TrackCanvas::calculate_auto_position(double *x,
02787 double *y,
02788 double *in_x,
02789 double *in_y,
02790 double *out_x,
02791 double *out_y,
02792 Auto *current,
02793 double unit_start,
02794 double zoom_units,
02795 double yscale,
02796 int autogrouptype)
02797 {
02798 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
02799 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
02800 float automation_range = automation_max - automation_min;
02801 FloatAuto *ptr = (FloatAuto*)current;
02802 *x = (double)(ptr->position - unit_start) / zoom_units;
02803 *y = ((ptr->value - automation_min) /
02804 automation_range - 0.5) *
02805 -yscale;
02806 if(in_x)
02807 {
02808 *in_x = (double)(ptr->position +
02809 ptr->control_in_position -
02810 unit_start) /
02811 zoom_units;
02812 }
02813 if(in_y)
02814 {
02815 *in_y = (((ptr->value + ptr->control_in_value) -
02816 automation_min) /
02817 automation_range - 0.5) *
02818 -yscale;
02819 }
02820 if(out_x)
02821 {
02822 *out_x = (double)(ptr->position +
02823 ptr->control_out_position -
02824 unit_start) /
02825 zoom_units;
02826 }
02827 if(out_y)
02828 {
02829 *out_y = (((ptr->value + ptr->control_out_value) -
02830 automation_min) /
02831 automation_range - 0.5) *
02832 -yscale;
02833 }
02834 }
02835
02836
02837
02838
02839
02840 int TrackCanvas::do_float_autos(Track *track,
02841 Autos *autos,
02842 int cursor_x,
02843 int cursor_y,
02844 int draw,
02845 int buttonpress,
02846 int color,
02847 Auto* &auto_instance,
02848 int autogrouptype)
02849 {
02850 int result = 0;
02851
02852 double view_start;
02853 double unit_start;
02854 double view_end;
02855 double unit_end;
02856 double yscale;
02857 int center_pixel;
02858 double zoom_sample;
02859 double zoom_units;
02860 double ax, ay, ax2, ay2;
02861 double in_x2, in_y2, out_x2, out_y2;
02862 int draw_auto;
02863 double slope;
02864 int skip = 0;
02865
02866 auto_instance = 0;
02867
02868 calculate_viewport(track,
02869 view_start,
02870 unit_start,
02871 view_end,
02872 unit_end,
02873 yscale,
02874 center_pixel,
02875 zoom_sample,
02876 zoom_units);
02877
02878
02879
02880
02881 Auto *current = 0;
02882 Auto *previous = 0;
02883 for(current = autos->last;
02884 current && current->position >= unit_start;
02885 current = PREVIOUS)
02886 ;
02887
02888 if(current)
02889 {
02890 calculate_auto_position(&ax,
02891 &ay,
02892 0,
02893 0,
02894 0,
02895 0,
02896 current,
02897 unit_start,
02898 zoom_units,
02899 yscale,
02900 autogrouptype);
02901 current = NEXT;
02902 }
02903 else
02904 {
02905 current = autos->first ? autos->first : autos->default_auto;
02906 if(current)
02907 {
02908 calculate_auto_position(&ax,
02909 &ay,
02910 0,
02911 0,
02912 0,
02913 0,
02914 current,
02915 unit_start,
02916 zoom_units,
02917 yscale,
02918 autogrouptype);
02919 ax = 0;
02920 }
02921 else
02922 {
02923 ax = 0;
02924 ay = 0;
02925 }
02926 }
02927
02928
02929
02930
02931
02932 do
02933 {
02934 skip = 0;
02935 draw_auto = 1;
02936
02937 if(current)
02938 {
02939 calculate_auto_position(&ax2,
02940 &ay2,
02941 &in_x2,
02942 &in_y2,
02943 &out_x2,
02944 &out_y2,
02945 current,
02946 unit_start,
02947 zoom_units,
02948 yscale,
02949 autogrouptype);
02950 }
02951 else
02952 {
02953 ax2 = get_w();
02954 ay2 = ay;
02955 skip = 1;
02956 }
02957
02958 slope = (ay2 - ay) / (ax2 - ax);
02959
02960 if(ax2 > get_w())
02961 {
02962 draw_auto = 0;
02963 ax2 = get_w();
02964 ay2 = ay + slope * (get_w() - ax);
02965 }
02966
02967 if(ax < 0)
02968 {
02969 ay = ay + slope * (0 - ax);
02970 ax = 0;
02971 }
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987 if(current && !result)
02988 {
02989 if(current != autos->default_auto)
02990 {
02991 if(!draw)
02992 {
02993 if(track->record)
02994 result = test_floatauto(current,
02995 (int)ax2,
02996 (int)ay2,
02997 (int)in_x2,
02998 (int)in_y2,
02999 (int)out_x2,
03000 (int)out_y2,
03001 (int)center_pixel,
03002 (int)yscale,
03003 cursor_x,
03004 cursor_y,
03005 buttonpress);
03006 if (result)
03007 auto_instance = current;
03008 }
03009 else
03010 if(draw_auto)
03011 draw_floatauto(current,
03012 (int)ax2,
03013 (int)ay2,
03014 (int)in_x2,
03015 (int)in_y2,
03016 (int)out_x2,
03017 (int)out_y2,
03018 (int)center_pixel,
03019 (int)yscale,
03020 color);
03021 }
03022 }
03023
03024
03025
03026
03027
03028
03029 if(!draw)
03030 {
03031 if(!result)
03032 {
03033 if(track->record && buttonpress != 3)
03034 {
03035 result = test_floatline(center_pixel,
03036 (FloatAutos*)autos,
03037 unit_start,
03038 zoom_units,
03039 yscale,
03040 (int)ax,
03041
03042 (int)ax2 - HANDLE_W / 2,
03043 cursor_x,
03044 cursor_y,
03045 buttonpress,
03046 autogrouptype);
03047 }
03048 }
03049 }
03050 else
03051 draw_floatline(center_pixel,
03052 (FloatAuto*)previous,
03053 (FloatAuto*)current,
03054 (FloatAutos*)autos,
03055 unit_start,
03056 zoom_units,
03057 yscale,
03058 (int)ax,
03059 (int)ay,
03060 (int)ax2,
03061 (int)ay2,
03062 color,
03063 autogrouptype);
03064
03065
03066
03067
03068
03069
03070
03071 if(current)
03072 {
03073 previous = current;
03074 current = NEXT;
03075 }
03076
03077
03078
03079 ax = ax2;
03080 ay = ay2;
03081 }while(current &&
03082 current->position <= unit_end &&
03083 !result);
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094 if(ax < get_w() && !result)
03095 {
03096 ax2 = get_w();
03097 ay2 = ay;
03098 if(!draw)
03099 {
03100 if(track->record && buttonpress != 3)
03101 {
03102 result = test_floatline(center_pixel,
03103 (FloatAutos*)autos,
03104 unit_start,
03105 zoom_units,
03106 yscale,
03107 (int)ax,
03108 (int)ax2,
03109 cursor_x,
03110 cursor_y,
03111 buttonpress,
03112 autogrouptype);
03113 }
03114 }
03115 else
03116 draw_floatline(center_pixel,
03117 (FloatAuto*)previous,
03118 (FloatAuto*)current,
03119 (FloatAutos*)autos,
03120 unit_start,
03121 zoom_units,
03122 yscale,
03123 (int)ax,
03124 (int)ay,
03125 (int)ax2,
03126 (int)ay2,
03127 color,
03128 autogrouptype);
03129 }
03130
03131
03132
03133
03134
03135
03136
03137
03138 return result;
03139 }
03140
03141
03142 int TrackCanvas::do_toggle_autos(Track *track,
03143 Autos *autos,
03144 int cursor_x,
03145 int cursor_y,
03146 int draw,
03147 int buttonpress,
03148 int color,
03149 Auto * &auto_instance)
03150 {
03151 int result = 0;
03152 double view_start;
03153 double unit_start;
03154 double view_end;
03155 double unit_end;
03156 double yscale;
03157 int center_pixel;
03158 double zoom_sample;
03159 double zoom_units;
03160 double ax, ay, ax2, ay2;
03161
03162 auto_instance = 0;
03163
03164 calculate_viewport(track,
03165 view_start,
03166 unit_start,
03167 view_end,
03168 unit_end,
03169 yscale,
03170 center_pixel,
03171 zoom_sample,
03172 zoom_units);
03173
03174
03175 double high = -yscale * 0.8 / 2;
03176 double low = yscale * 0.8 / 2;
03177
03178
03179 Auto *current;
03180 for(current = autos->last; current && current->position >= unit_start; current = PREVIOUS)
03181 ;
03182
03183 if(current)
03184 {
03185 ax = 0;
03186 ay = ((IntAuto*)current)->value > 0 ? high : low;
03187 current = NEXT;
03188 }
03189 else
03190 {
03191 current = autos->first ? autos->first : autos->default_auto;
03192 if(current)
03193 {
03194 ax = 0;
03195 ay = ((IntAuto*)current)->value > 0 ? high : low;
03196 }
03197 else
03198 {
03199 ax = 0;
03200 ay = yscale;
03201 }
03202 }
03203
03204 do
03205 {
03206 if(current)
03207 {
03208 ax2 = (double)(current->position - unit_start) / zoom_units;
03209 ay2 = ((IntAuto*)current)->value > 0 ? high : low;
03210 }
03211 else
03212 {
03213 ax2 = get_w();
03214 ay2 = ay;
03215 }
03216
03217 if(ax2 > get_w()) ax2 = get_w();
03218
03219 if(current && !result)
03220 {
03221 if(current != autos->default_auto)
03222 {
03223 if(!draw)
03224 {
03225 if(track->record)
03226 {
03227 result = test_auto(current,
03228 (int)ax2,
03229 (int)ay2,
03230 (int)center_pixel,
03231 (int)yscale,
03232 cursor_x,
03233 cursor_y,
03234 buttonpress);
03235 if (result)
03236 auto_instance = current;
03237 }
03238 }
03239 else
03240 draw_auto(current,
03241 (int)ax2,
03242 (int)ay2,
03243 (int)center_pixel,
03244 (int)yscale,
03245 color);
03246 }
03247
03248 current = NEXT;
03249 }
03250
03251 if(!draw)
03252 {
03253 if(!result)
03254 {
03255 if(track->record && buttonpress != 3)
03256 {
03257 result = test_toggleline(autos,
03258 center_pixel,
03259 (int)ax,
03260 (int)ay,
03261 (int)ax2,
03262 (int)ay2,
03263 cursor_x,
03264 cursor_y,
03265 buttonpress);
03266 }
03267 }
03268 }
03269 else
03270 draw_toggleline(center_pixel,
03271 (int)ax,
03272 (int)ay,
03273 (int)ax2,
03274 (int)ay2,
03275 color);
03276
03277 ax = ax2;
03278 ay = ay2;
03279 }while(current && current->position <= unit_end && !result);
03280
03281 if(ax < get_w() && !result)
03282 {
03283 ax2 = get_w();
03284 ay2 = ay;
03285 if(!draw)
03286 {
03287 if(track->record && buttonpress != 3)
03288 {
03289 result = test_toggleline(autos,
03290 center_pixel,
03291 (int)ax,
03292 (int)ay,
03293 (int)ax2,
03294 (int)ay2,
03295 cursor_x,
03296 cursor_y,
03297 buttonpress);
03298 }
03299 }
03300 else
03301 draw_toggleline(center_pixel,
03302 (int)ax,
03303 (int)ay,
03304 (int)ax2,
03305 (int)ay2,
03306 color);
03307 }
03308 return result;
03309 }
03310
03311 int TrackCanvas::do_autos(Track *track,
03312 Autos *autos,
03313 int cursor_x,
03314 int cursor_y,
03315 int draw,
03316 int buttonpress,
03317 BC_Pixmap *pixmap,
03318 Auto * &auto_instance)
03319 {
03320 int result = 0;
03321
03322 double view_start;
03323 double unit_start;
03324 double view_end;
03325 double unit_end;
03326 double yscale;
03327 int center_pixel;
03328 double zoom_sample;
03329 double zoom_units;
03330
03331 calculate_viewport(track,
03332 view_start,
03333 unit_start,
03334 view_end,
03335 unit_end,
03336 yscale,
03337 center_pixel,
03338 zoom_sample,
03339 zoom_units);
03340
03341 Auto *current;
03342 auto_instance = 0;
03343
03344 for(current = autos->first; current && !result; current = NEXT)
03345 {
03346 if(current->position >= unit_start && current->position < unit_end)
03347 {
03348 int64_t x, y;
03349 x = (int64_t)((double)(current->position - unit_start) /
03350 zoom_units - (pixmap->get_w() / 2 + 0.5));
03351 y = center_pixel - pixmap->get_h() / 2;
03352
03353 if(!draw)
03354 {
03355 if(cursor_x >= x && cursor_y >= y &&
03356 cursor_x < x + pixmap->get_w() &&
03357 cursor_y < y + pixmap->get_h())
03358 {
03359 result = 1;
03360 auto_instance = current;
03361
03362 if(buttonpress && (buttonpress != 3))
03363 {
03364 mwindow->session->drag_auto = current;
03365 mwindow->session->drag_start_position = current->position;
03366 mwindow->session->drag_origin_x = cursor_x;
03367 mwindow->session->drag_origin_y = cursor_y;
03368
03369 double position = autos->track->from_units(current->position);
03370 double center = (mwindow->edl->local_session->get_selectionstart(1) +
03371 mwindow->edl->local_session->get_selectionend(1)) /
03372 2;
03373
03374 if(!shift_down())
03375 {
03376 mwindow->edl->local_session->set_selectionstart(position);
03377 mwindow->edl->local_session->set_selectionend(position);
03378 }
03379 else
03380 if(position < center)
03381 {
03382 mwindow->edl->local_session->set_selectionstart(position);
03383 }
03384 else
03385 mwindow->edl->local_session->set_selectionend(position);
03386 }
03387 }
03388 }
03389 else
03390 draw_pixmap(pixmap, x, y);
03391 }
03392 }
03393 return result;
03394 }
03395
03396
03397 int TrackCanvas::do_plugin_autos(Track *track,
03398 int cursor_x,
03399 int cursor_y,
03400 int draw,
03401 int buttonpress,
03402 Plugin* &keyframe_plugin,
03403 KeyFrame* &keyframe_instance)
03404 {
03405 int result = 0;
03406
03407 double view_start;
03408 double unit_start;
03409 double view_end;
03410 double unit_end;
03411 double yscale;
03412 int center_pixel;
03413 double zoom_sample;
03414 double zoom_units;
03415
03416 if(!track->expand_view) return 0;
03417
03418 calculate_viewport(track,
03419 view_start,
03420 unit_start,
03421 view_end,
03422 unit_end,
03423 yscale,
03424 center_pixel,
03425 zoom_sample,
03426 zoom_units);
03427
03428
03429
03430 for(int i = 0; i < track->plugin_set.total && !result; i++)
03431 {
03432 PluginSet *plugin_set = track->plugin_set.values[i];
03433 int center_pixel = (int)(track->y_pixel +
03434 mwindow->edl->local_session->zoom_track +
03435 (i + 0.5) * mwindow->theme->get_image("plugin_bg_data")->get_h() +
03436 (mwindow->edl->session->show_titles ? mwindow->theme->get_image("title_bg_data")->get_h() : 0));
03437
03438 for(Plugin *plugin = (Plugin*)plugin_set->first;
03439 plugin && !result;
03440 plugin = (Plugin*)plugin->next)
03441 {
03442 for(KeyFrame *keyframe = (KeyFrame*)plugin->keyframes->first;
03443 keyframe && !result;
03444 keyframe = (KeyFrame*)keyframe->next)
03445 {
03446
03447 if(keyframe->position >= unit_start && keyframe->position < unit_end)
03448 {
03449 int64_t x = (int64_t)((keyframe->position - unit_start) / zoom_units);
03450 int y = center_pixel - keyframe_pixmap->get_h() / 2;
03451
03452
03453 if(!draw)
03454 {
03455 if(cursor_x >= x && cursor_y >= y &&
03456 cursor_x < x + keyframe_pixmap->get_w() &&
03457 cursor_y < y + keyframe_pixmap->get_h())
03458 {
03459 result = 1;
03460 keyframe_plugin = plugin;
03461 keyframe_instance = keyframe;
03462
03463 if(buttonpress)
03464 {
03465 mwindow->session->drag_auto = keyframe;
03466 mwindow->session->drag_start_position = keyframe->position;
03467 mwindow->session->drag_origin_x = cursor_x;
03468 mwindow->session->drag_origin_y = cursor_y;
03469
03470 double position = track->from_units(keyframe->position);
03471 double center = (mwindow->edl->local_session->get_selectionstart(1) +
03472 mwindow->edl->local_session->get_selectionend(1)) /
03473 2;
03474
03475 if(!shift_down())
03476 {
03477 mwindow->edl->local_session->set_selectionstart(position);
03478 mwindow->edl->local_session->set_selectionend(position);
03479 }
03480 else
03481 if(position < center)
03482 {
03483 mwindow->edl->local_session->set_selectionstart(position);
03484 }
03485 else
03486 mwindow->edl->local_session->set_selectionend(position);
03487 }
03488 }
03489 }
03490 else
03491 draw_pixmap(keyframe_pixmap,
03492 x,
03493 y);
03494 }
03495 }
03496 }
03497 }
03498
03499 return result;
03500 }
03501
03502 void TrackCanvas::draw_overlays()
03503 {
03504 int new_cursor, update_cursor, rerender;
03505
03506
03507 draw_pixmap(background_pixmap,
03508 0,
03509 0,
03510 get_w(),
03511 get_h(),
03512 0,
03513 0);
03514
03515
03516 draw_inout_points();
03517
03518
03519 if(mwindow->edl->session->auto_conf->transitions) draw_transitions();
03520
03521
03522 draw_plugins();
03523
03524
03525 draw_loop_points();
03526 draw_brender_start();
03527
03528
03529 draw_highlighting();
03530
03531
03532 do_keyframes(0,
03533 0,
03534 1,
03535 0,
03536 new_cursor,
03537 update_cursor,
03538 rerender);
03539
03540
03541 if(gui->cursor) gui->cursor->restore(1);
03542
03543
03544 draw_drag_handle();
03545
03546
03547 draw_playback_cursor();
03548
03549 }
03550
03551 int TrackCanvas::activate()
03552 {
03553 if(!active)
03554 {
03555 get_top_level()->deactivate();
03556 active = 1;
03557 set_active_subwindow(this);
03558 gui->cursor->activate();
03559 }
03560 return 0;
03561 }
03562
03563 int TrackCanvas::deactivate()
03564 {
03565 if(active)
03566 {
03567 active = 0;
03568 gui->cursor->deactivate();
03569 }
03570 return 0;
03571 }
03572
03573
03574 void TrackCanvas::update_drag_handle()
03575 {
03576 double new_position;
03577
03578 new_position =
03579 (double)(get_cursor_x() + mwindow->edl->local_session->view_start) *
03580 mwindow->edl->local_session->zoom_sample /
03581 mwindow->edl->session->sample_rate;
03582 new_position =
03583 mwindow->edl->align_to_frame(new_position, 0);
03584
03585
03586 if(new_position != mwindow->session->drag_position)
03587 {
03588 mwindow->session->drag_position = new_position;
03589 gui->mainclock->update(new_position);
03590
03591
03592
03593 }
03594 }
03595
03596 int TrackCanvas::update_drag_edit()
03597 {
03598 int result = 0;
03599
03600
03601
03602 return result;
03603 }
03604
03605 #define UPDATE_DRAG_HEAD(do_clamp) \
03606 int result = 0; \
03607 int x = cursor_x - mwindow->session->drag_origin_x; \
03608 int y = cursor_y - mwindow->session->drag_origin_y; \
03609 \
03610 if(!current->autos->track->record) return 0; \
03611 double view_start; \
03612 double unit_start; \
03613 double view_end; \
03614 double unit_end; \
03615 double yscale; \
03616 int center_pixel; \
03617 double zoom_sample; \
03618 double zoom_units; \
03619 \
03620 calculate_viewport(current->autos->track, \
03621 view_start, \
03622 unit_start, \
03623 view_end, \
03624 unit_end, \
03625 yscale, \
03626 center_pixel, \
03627 zoom_sample, \
03628 zoom_units); \
03629 \
03630 float percentage = (float)(mwindow->session->drag_origin_y - cursor_y) / \
03631 yscale + \
03632 mwindow->session->drag_start_percentage; \
03633 if(do_clamp) CLAMP(percentage, 0, 1); \
03634 \
03635 int64_t position = Units::to_int64(zoom_units * \
03636 (cursor_x - mwindow->session->drag_origin_x) + \
03637 mwindow->session->drag_start_position); \
03638 \
03639 if((do_clamp) && position < 0) position = 0;
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649 int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y)
03650 {
03651 FloatAuto *current = (FloatAuto*)mwindow->session->drag_auto;
03652
03653 UPDATE_DRAG_HEAD(mwindow->session->drag_handle == 0);
03654
03655 float value;
03656 float old_value;
03657
03658 switch(mwindow->session->drag_handle)
03659 {
03660
03661 case 0:
03662
03663 old_value = current->value;
03664 if(shift_down())
03665 {
03666 double value1;
03667 double distance1;
03668 double value2;
03669 double distance2;
03670
03671 if(current->previous)
03672 {
03673 int autogrouptype = current->previous->autos->autogrouptype;
03674 value = percentage_to_value(percentage, 0, 0, autogrouptype);
03675 value1 = ((FloatAuto*)current->previous)->value;
03676 distance1 = fabs(value - value1);
03677 current->value = value1;
03678 }
03679
03680 if(current->next)
03681 {
03682 int autogrouptype = current->next->autos->autogrouptype;
03683 value = percentage_to_value(percentage, 0, 0, autogrouptype);
03684 value2 = ((FloatAuto*)current->next)->value;
03685 distance2 = fabs(value - value2);
03686 if(!current->previous || distance2 < distance1)
03687 {
03688 current->value = value2;
03689 }
03690 }
03691
03692 if(!current->previous && !current->next)
03693 {
03694 current->value = ((FloatAutos*)current->autos)->default_;
03695 }
03696 value = current->value;
03697 }
03698 else
03699 {
03700 int autogrouptype = current->autos->autogrouptype;
03701 value = percentage_to_value(percentage, 0, 0, autogrouptype);
03702 }
03703
03704