3 #include "automation.h"
11 #include "cwindowgui.h"
12 #include "edithandles.h"
13 #include "editpopup.h"
16 #include "edlsession.h"
17 #include "floatauto.h"
18 #include "floatautos.h"
21 #include "keyframepopup.h"
22 #include "keyframes.h"
24 #include "localsession.h"
25 #include "mainclock.h"
26 #include "maincursor.h"
28 #include "maskautos.h"
32 #include "mwindowgui.h"
36 #include "resourcethread.h"
37 #include "playbackengine.h"
38 #include "playtransport.h"
40 #include "pluginpopup.h"
41 #include "pluginset.h"
42 #include "pluginserver.h"
43 #include "plugintoggles.h"
44 #include "preferences.h"
45 #include "resourcepixmap.h"
46 #include "mainsession.h"
47 #include "transitionhandles.h"
48 #include "transitionpopup.h"
49 #include "transportque.h"
53 #include "trackcanvas.h"
55 #include "transition.h"
57 #include "apatchgui.inc"
58 #include "vpatchgui.inc"
62 TrackCanvas::TrackCanvas(MWindow *mwindow, MWindowGUI *gui)
63 : BC_SubWindow(mwindow->theme->mcanvas_x,
64 mwindow->theme->mcanvas_y,
68 this->mwindow = mwindow;
71 selection_midpoint1 = selection_midpoint2 = 0;
76 translate_selected = 0;
83 resource_timer = new Timer;
84 hourglass_enabled = 0;
85 resource_thread = new ResourceThread(mwindow);
88 TrackCanvas::~TrackCanvas()
90 for(int i = 0; i < resource_pixmaps.total; i++)
91 delete resource_pixmaps.values[i];
92 // delete transition_handles;
94 delete keyframe_pixmap;
95 delete camerakeyframe_pixmap;
96 delete modekeyframe_pixmap;
97 delete pankeyframe_pixmap;
98 delete projectorkeyframe_pixmap;
99 delete maskkeyframe_pixmap;
100 delete background_pixmap;
101 if(temp_picon) delete temp_picon;
102 delete resource_timer;
105 int TrackCanvas::create_objects()
107 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
108 // transition_handles = new TransitionHandles(mwindow, this);
109 edit_handles = new EditHandles(mwindow, this);
110 keyframe_pixmap = new BC_Pixmap(this, mwindow->theme->keyframe_data, PIXMAP_ALPHA);
111 camerakeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->camerakeyframe_data, PIXMAP_ALPHA);
112 modekeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->modekeyframe_data, PIXMAP_ALPHA);
113 pankeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->pankeyframe_data, PIXMAP_ALPHA);
114 projectorkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->projectorkeyframe_data, PIXMAP_ALPHA);
115 maskkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->maskkeyframe_data, PIXMAP_ALPHA);
116 resource_thread->create_objects();
123 void TrackCanvas::resize_event()
125 //printf("TrackCanvas::resize_event 1\n");
128 //printf("TrackCanvas::resize_event 2\n");
131 int TrackCanvas::keypress_event()
139 int TrackCanvas::drag_motion()
141 int cursor_x = get_relative_cursor_x();
142 int cursor_y = get_relative_cursor_y();
143 Track *over_track = 0;
145 PluginSet *over_pluginset = 0;
146 Plugin *over_plugin = 0;
152 drag_popup->cursor_motion_event();
156 // there's no point in drawing highlights has until drag operation has been set
157 if (!mwindow->session->current_operation)
160 if(get_cursor_over_window() &&
163 cursor_x < get_w() &&
166 // Find the edit and track the cursor is over
167 for(Track *track = mwindow->edl->tracks->first; track; track = track->next)
169 int64_t track_x, track_y, track_w, track_h;
170 track_dimensions(track, track_x, track_y, track_w, track_h);
172 if(cursor_y >= track_y &&
173 cursor_y < track_y + track_h)
176 for(Edit *edit = track->edits->first; edit; edit = edit->next)
178 if (mwindow->session->current_operation != DRAG_ATRANSITION &&
179 mwindow->session->current_operation != DRAG_VTRANSITION &&
180 edit == track->edits->last)
182 int64_t edit_x, edit_y, edit_w, edit_h;
183 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
185 if(cursor_x >= edit_x &&
186 cursor_y >= edit_y &&
187 cursor_x < edit_x + edit_w &&
188 cursor_y < edit_y + edit_h)
195 for(int i = 0; i < track->plugin_set.total; i++)
197 PluginSet *pluginset = track->plugin_set.values[i];
201 for(Plugin *plugin = (Plugin*)pluginset->first;
202 plugin != pluginset->last;
203 plugin = (Plugin*)plugin->next)
205 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
206 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
208 if(cursor_y >= plugin_y &&
209 cursor_y < plugin_y + plugin_h)
211 over_pluginset = plugin->plugin_set;
213 if(cursor_x >= plugin_x &&
214 cursor_x < plugin_x + plugin_w)
216 over_plugin = plugin;
227 if (!over_track) // check for pastes from patchbay
228 over_track = mwindow->gui->patchbay->is_over_track();
230 if(mwindow->session->track_highlighted != over_track)
232 mwindow->session->track_highlighted = over_track;
236 if(mwindow->session->edit_highlighted != over_edit)
238 mwindow->session->edit_highlighted = over_edit;
242 if(mwindow->session->pluginset_highlighted != over_pluginset)
244 mwindow->session->pluginset_highlighted = over_pluginset;
248 if(mwindow->session->plugin_highlighted != over_plugin)
250 mwindow->session->plugin_highlighted = over_plugin;
254 if (mwindow->session->current_operation == DRAG_ASSET ||
255 mwindow->session->current_operation == DRAG_EDIT)
262 lock_window("TrackCanvas::drag_motion");
271 int TrackCanvas::drag_start_event()
276 int new_cursor, update_cursor;
278 if(mwindow->session->current_operation != NO_OPERATION) return 0;
282 if(do_plugins(get_drag_x(),
292 if(do_edits(get_drag_x(),
308 int TrackCanvas::drag_motion_event()
310 return drag_motion();
313 int TrackCanvas::cursor_leave_event()
315 // Because drag motion calls get_cursor_over_window we can be sure that
316 // all highlights get deleted now.
317 // This ended up blocking keyboard input from the drag operations.
319 // return drag_motion();
323 int TrackCanvas::drag_stop_event()
325 int result = drag_stop();
336 int TrackCanvas::drag_stop()
338 // In most cases the editing routine redraws and not the drag_stop
339 int result = 0, redraw = 0;
341 int insertion = 0; // used in drag and drop mode
342 switch(mwindow->session->current_operation)
344 case DRAG_VTRANSITION:
345 case DRAG_ATRANSITION:
346 if(mwindow->session->edit_highlighted)
348 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
349 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
350 (mwindow->session->current_operation == DRAG_VTRANSITION &&
351 mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
353 mwindow->session->current_operation = NO_OPERATION;
354 mwindow->paste_transition();
364 // Behavior for dragged plugins is limited by the fact that a shared plugin
365 // can only refer to a standalone plugin that exists in the same position in
366 // time. Dragging a plugin from one point in time to another can't produce
367 // a shared plugin to the original plugin. In this case we relocate the
368 // plugin instead of sharing it.
369 case DRAG_AEFFECT_COPY:
370 case DRAG_VEFFECT_COPY:
371 if(mwindow->session->track_highlighted &&
372 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY &&
373 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
374 (mwindow->session->current_operation == DRAG_VEFFECT_COPY &&
375 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
377 mwindow->session->current_operation = NO_OPERATION;
379 // Insert shared plugin in source
380 // Move source to different location
381 if(mwindow->session->pluginset_highlighted)
383 //printf("TrackCanvas::drag_stop 6\n");
384 if(mwindow->session->plugin_highlighted)
386 mwindow->move_effect(mwindow->session->drag_plugin,
387 mwindow->session->plugin_highlighted->plugin_set,
389 mwindow->session->plugin_highlighted->startproject);
393 mwindow->move_effect(mwindow->session->drag_plugin,
394 mwindow->session->pluginset_highlighted,
396 mwindow->session->pluginset_highlighted->last->startproject);
401 // Move to a new plugin set between two edits
402 if(mwindow->session->edit_highlighted)
404 mwindow->move_effect(mwindow->session->drag_plugin,
406 mwindow->session->track_highlighted,
407 mwindow->session->edit_highlighted->startproject);
411 // Move to a new plugin set
412 if(mwindow->session->track_highlighted)
414 mwindow->move_effect(mwindow->session->drag_plugin,
416 mwindow->session->track_highlighted,
425 if(mwindow->session->track_highlighted &&
426 ((mwindow->session->current_operation == DRAG_AEFFECT &&
427 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
428 (mwindow->session->current_operation == DRAG_VEFFECT &&
429 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
431 // Drop all the effects
432 PluginSet *plugin_set = mwindow->session->pluginset_highlighted;
433 Track *track = mwindow->session->track_highlighted;
435 double length = track->get_length();
437 if(mwindow->session->plugin_highlighted)
439 start = track->from_units(mwindow->session->plugin_highlighted->startproject);
440 length = track->from_units(mwindow->session->plugin_highlighted->length);
441 if(length <= 0) length = track->get_length();
444 if(mwindow->session->pluginset_highlighted)
446 start = track->from_units(plugin_set->last->startproject);
447 length = track->get_length() - start;
448 if(length <= 0) length = track->get_length();
451 if(mwindow->edl->local_session->get_selectionend() >
452 mwindow->edl->local_session->get_selectionstart())
454 start = mwindow->edl->local_session->get_selectionstart();
455 length = mwindow->edl->local_session->get_selectionend() -
456 mwindow->edl->local_session->get_selectionstart();
458 // Move to a point between two edits
460 if(mwindow->session->edit_highlighted)
462 start = mwindow->session->track_highlighted->from_units(
463 mwindow->session->edit_highlighted->startproject);
464 length = mwindow->session->track_highlighted->from_units(
465 mwindow->session->edit_highlighted->length);
468 mwindow->insert_effects_canvas(start, length);
471 if (mwindow->session->track_highlighted)
472 result = 1; // we have to cleanup
476 if(mwindow->session->track_highlighted)
478 float asset_length_float;
479 int64_t asset_length_units;
480 int64_t position = 0;
482 if(mwindow->session->current_operation == DRAG_ASSET &&
483 mwindow->session->drag_assets->total)
485 Asset *asset = mwindow->session->drag_assets->values[0];
486 // we use video if we are over video and audio if we are over audio
487 if (asset->video_data && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
489 // Images have length -1
490 double video_length = asset->video_length;
491 if (video_length < 0)
493 if(mwindow->edl->session->si_useduration)
494 video_length = mwindow->edl->session->si_duration;
496 video_length = 1.0 / mwindow->edl->session->frame_rate ;
498 asset_length_float = video_length / asset->frame_rate;
500 else if (asset->audio_data && mwindow->session->track_highlighted->data_type == TRACK_AUDIO)
501 asset_length_float = asset->audio_length / asset->sample_rate;
505 break; // Do not do anything
508 if(mwindow->session->current_operation == DRAG_ASSET &&
509 mwindow->session->drag_clips->total)
511 EDL *clip = mwindow->session->drag_clips->values[0];
512 asset_length_float = clip->tracks->total_length();
515 printf("DRAG_ASSET error: Asset dropped, but both drag_clips and drag_assets total is zero\n");
518 asset_length_units = mwindow->session->track_highlighted->to_units(asset_length_float, 1);
519 position = get_drop_position (&insertion, NULL, asset_length_units);
523 break; // Do not do anything
526 double position_f = mwindow->session->track_highlighted->from_units(position);
527 Track *track = mwindow->session->track_highlighted;
531 // // FIXME, we should create an mwindow/EDL method that overwrites, without clearing the keyframes and autos
532 // // Unfortunately, this is _a lot_ of work to do right
533 // printf("Problematic insertion\n");
534 // mwindow->edl->tracks->clear(position_f,
535 // position_f + asset_length_float, 0);
537 mwindow->paste_assets(position_f, track, !insertion);
538 result = 1; // need to be one no matter what, since we have track highlited so we have to cleanup....
543 mwindow->session->current_operation = NO_OPERATION;
544 if(mwindow->session->track_highlighted)
546 if(mwindow->session->track_highlighted->data_type == mwindow->session->drag_edit->track->data_type)
548 int64_t position = 0;
550 position = get_drop_position (&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length);
555 break; // Do not do anything
558 double position_f = mwindow->session->track_highlighted->from_units(position);
559 Track *track = mwindow->session->track_highlighted;
560 mwindow->move_edits(mwindow->session->drag_edits,
571 // since we don't have subwindows we have to terminate any drag operation
574 if (mwindow->session->track_highlighted
575 || mwindow->session->edit_highlighted
576 || mwindow->session->plugin_highlighted
577 || mwindow->session->pluginset_highlighted)
579 mwindow->session->track_highlighted = 0;
580 mwindow->session->edit_highlighted = 0;
581 mwindow->session->plugin_highlighted = 0;
582 mwindow->session->pluginset_highlighted = 0;
583 mwindow->session->current_operation = NO_OPERATION;
587 //printf("TrackCanvas::drag_stop %d %d\n", redraw, mwindow->session->current_operation);
590 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
591 gui->get_scrollbars();
593 gui->patchbay->update();
594 gui->cursor->update();
603 int64_t TrackCanvas::get_drop_position (int *is_insertion, Edit *moved_edit, int64_t moved_edit_length)
607 // get the canvas/track position
608 int cursor_x = get_relative_cursor_x();
609 double pos = (double)cursor_x *
610 mwindow->edl->local_session->zoom_sample /
611 mwindow->edl->session->sample_rate +
612 (double)mwindow->edl->local_session->view_start *
613 mwindow->edl->local_session->zoom_sample /
614 mwindow->edl->session->sample_rate;
615 // convert to track's units to operate with them
616 Track *track = mwindow->session->track_highlighted;
617 // cursor relative position - depending on where we started the drag inside the edit
618 int64_t cursor_position;
619 if (moved_edit) // relative cursor position depends upon grab point
620 cursor_position = track->to_units (pos - (mwindow->session->drag_position - moved_edit->track->from_units(moved_edit->startproject)), 1);
621 else // for clips and assets acts as they were grabbed in the middle
622 cursor_position = track->to_units (pos , 1) - moved_edit_length / 2;
624 // we use real cursor position for affinity calculations
625 int64_t real_cursor_position = track->to_units (pos, 0);
626 if (cursor_position < 0) cursor_position = 0;
627 if (real_cursor_position < 0) real_cursor_position = 0;
628 int64_t position = -1;
629 int64_t span_start = 0;
630 int64_t span_length = 0;
632 int last_ignore = 0; // used to make sure we can ignore the last edit if that is what we are dragging
634 if (!track->edits->last)
636 // No edits -> no problems!
637 position = cursor_position;
641 Edit *fake_edit = new Edit(mwindow->edl, track);
642 int last2 = 0; // last2 is a hack that let us make virtual edits at the end so thing works for last edit also
643 // we do this by appending two VERY long virtual edits at the end
645 for (Edit *edit = track->edits->first; edit || last2 < 2; )
648 if (!edit && last_ignore)
650 span_length += 100000000000000LL;
655 ((moved_edit && edit == moved_edit && edit->previous && !edit->previous->asset) ||
656 (moved_edit && edit->previous == moved_edit && !edit->asset)))
658 span_length += edit->length; // our fake edit spans over the edit we are moving
661 { // This is a virtual edit
662 fake_edit->startproject = span_start;
663 fake_edit->length = span_length;
664 int64_t edit_x, edit_y, edit_w, edit_h;
665 edit_dimensions(fake_edit, edit_x, edit_y, edit_w, edit_h);
666 if (labs(edit_x - cursor_x) < HANDLE_W) // cursor is close to the beginning of an edit -> insertion
669 position = span_start;
671 if (labs(edit_x + edit_w - cursor_x) < HANDLE_W) // cursor is close to the end of an edit -> insertion
674 position = span_start + span_length;
677 if (!span_asset && // we have enough empty space to position the edit where user wants
678 span_start <= cursor_position &&
679 span_start + span_length >= cursor_position + moved_edit_length)
681 position = cursor_position;
683 if (!span_asset & // we are inside an empty edit, but cannot push the edit as far as user wants, so 'resist moving it further'
684 real_cursor_position >= span_start &&
685 real_cursor_position < span_start + span_length &&
686 span_length >= moved_edit_length)
688 if (llabs(real_cursor_position - span_start) < llabs(real_cursor_position - span_start - span_length))
689 position = span_start;
691 position = span_start + span_length - moved_edit_length;
693 if (cursor_x > edit_x && cursor_x <= edit_x + edit_w / 2) // we are inside an nonempty edit, - snap to left
696 position = span_start;
698 if (cursor_x > edit_x + edit_w / 2 && cursor_x <= edit_x + edit_w) // we are inside an nonempty edit, - snap to right
701 position = span_start + span_length;
708 // This is the new edit
711 span_length = edit->length;
712 span_start = edit->startproject;
714 if (!edit->asset || (!moved_edit || moved_edit == edit))
716 if (moved_edit && moved_edit == edit)
724 span_start = span_length + span_start;
725 span_length = 100000000000000LL;
740 if (real_cursor_position == 0)
745 // printf("rcp: %lli, position: %lli, insertion: %i\n", real_cursor_position, position, *is_insertion);
751 void TrackCanvas::draw(int mode, int hide_cursor)
753 // Swap pixmap layers
754 if(get_w() != background_pixmap->get_w() ||
755 get_h() != background_pixmap->get_h())
757 delete background_pixmap;
758 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
761 // Cursor disappears after resize when this is called.
762 // Cursor doesn't redraw after editing when this isn't called.
763 if(gui->cursor && hide_cursor) gui->cursor->hide();
764 draw_top_background(get_parent(), 0, 0, get_w(), get_h(), background_pixmap);
765 draw_resources(mode);
769 void TrackCanvas::update_cursor()
771 switch(mwindow->edl->session->editing_mode)
773 case EDITING_ARROW: set_cursor(ARROW_CURSOR); break;
774 case EDITING_IBEAM: set_cursor(IBEAM_CURSOR); break;
779 void TrackCanvas::test_timer()
781 if(resource_timer->get_difference() > 1000 &&
785 hourglass_enabled = 1;
790 void TrackCanvas::draw_indexes(Asset *asset)
792 // Don't redraw raw samples
793 if(asset->index_zoom > mwindow->edl->local_session->zoom_sample)
796 draw_resources(0, 1, asset);
804 void TrackCanvas::draw_resources(int mode,
808 if(!mwindow->edl->session->show_assets) return;
810 if(mode != 3 && !indexes_only)
811 resource_thread->stop_draw(!indexes_only);
813 resource_timer->update();
815 // Age resource pixmaps for deletion
817 for(int i = 0; i < resource_pixmaps.total; i++)
818 resource_pixmaps.values[i]->visible--;
821 resource_pixmaps.remove_all_objects();
825 for(Track *current = mwindow->edl->tracks->first;
829 for(Edit *edit = current->edits->first; edit; edit = edit->next)
831 if(!edit->asset) continue;
834 if(edit->track->data_type != TRACK_AUDIO) continue;
835 if(!edit->asset->test_path(index_asset->path)) continue;
838 int64_t edit_x, edit_y, edit_w, edit_h;
839 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
842 if(MWindowGUI::visible(edit_x, edit_x + edit_w, 0, get_w()) &&
843 MWindowGUI::visible(edit_y, edit_y + edit_h, 0, get_h()))
845 int64_t pixmap_x, pixmap_w, pixmap_h;
847 // Search for existing pixmap containing edit
848 for(int i = 0; i < resource_pixmaps.total; i++)
850 ResourcePixmap* pixmap = resource_pixmaps.values[i];
851 // Same pointer can be different edit if editing took place
852 if(pixmap->edit_id == edit->id)
859 // Get new size, offset of pixmap needed
860 get_pixmap_size(edit,
868 if(pixmap_w && pixmap_h)
870 // Create pixmap if it doesn't exist
871 ResourcePixmap* pixmap = create_pixmap(edit,
876 // Resize it if it's bigger
877 if(pixmap_w > pixmap->pixmap_w ||
878 pixmap_h > pixmap->pixmap_h)
879 pixmap->resize(pixmap_w, pixmap_h);
880 pixmap->draw_data(edit,
888 // Resize it if it's smaller
889 if(pixmap_w < pixmap->pixmap_w ||
890 pixmap_h < pixmap->pixmap_h)
891 pixmap->resize(pixmap_w, pixmap_h);
893 // Copy pixmap to background canvas
894 background_pixmap->draw_pixmap(pixmap,
904 // Delete unused pixmaps
906 for(int i = resource_pixmaps.total - 1; i >= 0; i--)
907 if(resource_pixmaps.values[i]->visible < -5)
909 delete resource_pixmaps.values[i];
910 resource_pixmaps.remove(resource_pixmaps.values[i]);
913 if(hourglass_enabled)
916 hourglass_enabled = 0;
919 if(mode != 3 && !indexes_only)
920 resource_thread->start_draw();
923 ResourcePixmap* TrackCanvas::create_pixmap(Edit *edit,
929 ResourcePixmap *result = 0;
931 for(int i = 0; i < resource_pixmaps.total; i++)
933 //printf("TrackCanvas::create_pixmap 1 %d %d\n", edit->id, resource_pixmaps.values[i]->edit->id);
934 if(resource_pixmaps.values[i]->edit_id == edit->id)
936 result = resource_pixmaps.values[i];
943 //printf("TrackCanvas::create_pixmap 2\n");
944 result = new ResourcePixmap(mwindow,
949 resource_pixmaps.append(result);
952 // result->resize(pixmap_w, pixmap_h);
956 void TrackCanvas::get_pixmap_size(Edit *edit,
964 // Align x on frame boundaries
967 // switch(edit->edits->track->data_type)
979 if(pixmap_x + pixmap_w > get_w())
981 pixmap_w = get_w() - pixmap_x;
988 // int64_t picon_w = (int64_t)(edit->picon_w() + 0.5);
989 // int64_t frame_w = (int64_t)(edit->frame_w() + 0.5);
990 // int64_t pixel_increment = MAX(picon_w, frame_w);
991 // int64_t pixmap_x1 = edit_x;
992 // int64_t pixmap_x2 = edit_x + edit_w;
996 // pixmap_x1 = (int64_t)((double)-edit_x / pixel_increment) *
1001 // if(pixmap_x2 > get_w())
1003 // pixmap_x2 = (int64_t)((double)(get_w() - edit_x) / pixel_increment + 1) *
1004 // pixel_increment +
1007 // pixmap_x = pixmap_x1;
1008 // pixmap_w = pixmap_x2 - pixmap_x1;
1013 pixmap_h = mwindow->edl->local_session->zoom_track;
1014 if(mwindow->edl->session->show_titles) pixmap_h += mwindow->theme->get_image("title_bg_data")->get_h();
1015 //printf("get_pixmap_size %d %d %d %d\n", edit_x, edit_w, pixmap_x, pixmap_w);
1018 void TrackCanvas::edit_dimensions(Edit *edit,
1024 // w = Units::round(edit->track->from_units(edit->length) *
1025 // mwindow->edl->session->sample_rate /
1026 // mwindow->edl->local_session->zoom_sample);
1030 x = Units::round(edit->track->from_units(edit->startproject) *
1031 mwindow->edl->session->sample_rate /
1032 mwindow->edl->local_session->zoom_sample -
1033 mwindow->edl->local_session->view_start);
1035 // Method for calculating w so when edits are together we never get off by one error due to rounding
1036 int64_t x_next = Units::round(edit->track->from_units(edit->startproject + edit->length) *
1037 mwindow->edl->session->sample_rate /
1038 mwindow->edl->local_session->zoom_sample -
1039 mwindow->edl->local_session->view_start);
1042 y = edit->edits->track->y_pixel;
1044 if(mwindow->edl->session->show_titles)
1045 h += mwindow->theme->get_image("title_bg_data")->get_h();
1048 void TrackCanvas::track_dimensions(Track *track, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1053 h = track->vertical_span(mwindow->theme);
1057 void TrackCanvas::draw_paste_destination()
1059 int current_atrack = 0;
1060 int current_vtrack = 0;
1061 int current_aedit = 0;
1062 int current_vedit = 0;
1069 if((mwindow->session->current_operation == DRAG_ASSET &&
1070 (mwindow->session->drag_assets->total ||
1071 mwindow->session->drag_clips->total)) ||
1072 (mwindow->session->current_operation == DRAG_EDIT &&
1073 mwindow->session->drag_edits->total))
1080 if(mwindow->session->current_operation == DRAG_ASSET &&
1081 mwindow->session->drag_assets->total)
1082 asset = mwindow->session->drag_assets->values[0];
1084 if(mwindow->session->current_operation == DRAG_ASSET &&
1085 mwindow->session->drag_clips->total)
1086 clip = mwindow->session->drag_clips->values[0];
1088 // 'Align cursor of frame' lengths calculations
1089 double paste_audio_length, paste_video_length;
1090 int64_t asset_length;
1091 double desta_position = 0;
1092 double destv_position = 0;
1096 double asset_length_ac = asset->total_length_framealigned(mwindow->edl->session->frame_rate);
1097 if (mwindow->edl->session->cursor_on_frames)
1099 paste_video_length = paste_audio_length = asset_length_ac;
1103 paste_audio_length = (double)asset->audio_length / asset->sample_rate;
1104 paste_video_length = (double)asset->video_length / asset->frame_rate;
1107 // Images have length -1 (they are a single image!!)
1108 if (asset->video_data && asset->video_length < 0)
1110 if(mwindow->edl->session->si_useduration)
1111 paste_video_length = mwindow->edl->session->si_duration / asset->frame_rate;
1113 paste_video_length = 1.0 / asset->frame_rate; // bit confused!! (this is 1 frame)
1116 int64_t asset_length = 0;
1118 if(asset->audio_data)
1120 // we use video if we are over video and audio if we are over audio
1121 if(asset->video_data && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
1122 asset_length = mwindow->session->track_highlighted->to_units(paste_video_length, 1);
1124 asset_length = mwindow->session->track_highlighted->to_units(paste_audio_length, 1);
1126 desta_position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1129 if(asset->video_data)
1131 asset_length = mwindow->session->track_highlighted->to_units((double)paste_video_length, 1);
1132 destv_position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1138 if(mwindow->edl->session->cursor_on_frames)
1139 paste_audio_length = paste_video_length = clip->tracks->total_length_framealigned(mwindow->edl->session->frame_rate);
1141 paste_audio_length = paste_video_length = clip->tracks->total_length();
1143 int64_t asset_length;
1145 asset_length = mwindow->session->track_highlighted->to_units((double)clip->tracks->total_length(), 1);
1146 desta_position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1149 // Get destination track
1150 for(Track *dest = mwindow->session->track_highlighted;
1156 // Get source width in pixels
1159 // Use start of highlighted edit
1160 if(mwindow->session->edit_highlighted)
1161 position = mwindow->session->track_highlighted->from_units(
1162 mwindow->session->edit_highlighted->startproject);
1164 // Use end of highlighted track, disregarding effects
1165 position = mwindow->session->track_highlighted->from_units(
1166 mwindow->session->track_highlighted->edits->last->startproject);
1169 if(dest->data_type == TRACK_AUDIO)
1171 if( (asset && current_atrack < asset->channels)
1172 || (clip && current_atrack < clip->tracks->total_audio_tracks()) )
1174 w = Units::to_int64(paste_audio_length *
1175 mwindow->edl->session->sample_rate /
1176 mwindow->edl->local_session->zoom_sample);
1178 position = desta_position;
1188 if(mwindow->session->current_operation == DRAG_EDIT &&
1189 current_aedit < mwindow->session->drag_edits->total)
1192 while(current_aedit < mwindow->session->drag_edits->total &&
1193 mwindow->session->drag_edits->values[current_aedit]->track->data_type != TRACK_AUDIO)
1196 if(current_aedit < mwindow->session->drag_edits->total)
1198 edit = mwindow->session->drag_edits->values[current_aedit];
1199 w = Units::to_int64(edit->length / mwindow->edl->local_session->zoom_sample);
1201 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length));
1213 if(dest->data_type == TRACK_VIDEO)
1215 //printf("draw_paste_destination 1\n");
1216 if( (asset && current_vtrack < asset->layers)
1217 || (clip && current_vtrack < clip->tracks->total_video_tracks()) )
1219 // Images have length -1
1220 w = Units::to_int64((double)paste_video_length *
1221 mwindow->edl->session->sample_rate /
1222 mwindow->edl->local_session->zoom_sample);
1224 position = destv_position;
1234 if(mwindow->session->current_operation == DRAG_EDIT &&
1235 current_vedit < mwindow->session->drag_edits->total)
1238 while(current_vedit < mwindow->session->drag_edits->total &&
1239 mwindow->session->drag_edits->values[current_vedit]->track->data_type != TRACK_VIDEO)
1242 if(current_vedit < mwindow->session->drag_edits->total)
1244 edit = mwindow->session->drag_edits->values[current_vedit];
1245 w = Units::to_int64(edit->track->from_units(edit->length) *
1246 mwindow->edl->session->sample_rate /
1247 mwindow->edl->local_session->zoom_sample);
1249 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length));
1263 // Get the x coordinate
1264 x = Units::to_int64(position *
1265 mwindow->edl->session->sample_rate /
1266 mwindow->edl->local_session->zoom_sample) -
1267 mwindow->edl->local_session->view_start;
1268 int y = dest->y_pixel;
1269 int h = dest->vertical_span(mwindow->theme);
1272 //printf("TrackCanvas::draw_paste_destination 2 %d %d %d %d\n", x, y, w, h);
1274 draw_highlight_insertion(x, y, w, h);
1276 draw_highlight_rectangle(x, y, w, h);
1283 void TrackCanvas::plugin_dimensions(Plugin *plugin, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1285 x = Units::round(plugin->track->from_units(plugin->startproject) *
1286 mwindow->edl->session->sample_rate /
1287 mwindow->edl->local_session->zoom_sample -
1288 mwindow->edl->local_session->view_start);
1289 w = Units::round(plugin->track->from_units(plugin->length) *
1290 mwindow->edl->session->sample_rate /
1291 mwindow->edl->local_session->zoom_sample);
1292 y = plugin->track->y_pixel +
1293 mwindow->edl->local_session->zoom_track +
1294 plugin->plugin_set->get_number() *
1295 mwindow->theme->get_image("plugin_bg_data")->get_h();
1296 if(mwindow->edl->session->show_titles)
1297 y += mwindow->theme->get_image("title_bg_data")->get_h();
1298 h = mwindow->theme->get_image("plugin_bg_data")->get_h();
1301 int TrackCanvas::resource_h()
1303 return mwindow->edl->local_session->zoom_track;
1306 void TrackCanvas::draw_highlight_rectangle(int x, int y, int w, int h)
1309 // if we have to draw a highlighted rectangle completely on the left or completely on the right of the viewport,
1310 // just draw arrows, so user has indication that something is there
1311 // FIXME: get better colors
1315 draw_triangle_left(0, y + h /6, h * 2/3, h * 2/3, BLACK, GREEN, YELLOW, RED, BLUE);
1320 draw_triangle_right(get_w() - h * 2/3, y + h /6, h * 2/3, h * 2/3, BLACK, GREEN, YELLOW, RED, BLUE);
1324 // Fix bug in heroines & cvs version as of 22.8.2005:
1325 // If we grab when zoomed in and zoom out while dragging, when edit gets really narrow strange things start happening
1326 if (w >= 0 && w < 3) {x -= w /2; w = 3;};
1337 w = MIN(w, get_w() + 20);
1338 h = MIN(h, get_h() + 20);
1341 draw_rectangle(x, y, w, h);
1342 draw_rectangle(x + 1, y + 1, w - 2, h - 2);
1344 //printf("TrackCanvas::draw_highlight_rectangle %d %d %d %d\n", x, y, w, h);
1347 void TrackCanvas::draw_highlight_insertion(int x, int y, int w, int h)
1350 // if we have to draw a highlighted rectangle completely on the left or completely on the right of the viewport,
1351 // just draw arrows, so user has indication that something is there
1352 // FIXME: get better colors
1361 /* these don't look so good
1363 draw_line(x, y, x, y+h);
1364 draw_line(x - h2 * 2, y + h1*2, x - h2, y+h1*2);
1365 draw_line(x - h2 * 2, y + h1*2+1, x - h2, y+h1*2+1);
1366 draw_line(x - h2 * 2, y + h1*6, x - h2, y+h1*6);
1367 draw_line(x - h2 * 2, y + h1*6+1, x - h2, y+h1*6+1);
1369 draw_triangle_right(x - h2, y + h1, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1370 draw_triangle_right(x - h2, y + h1*5, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1372 /* draw_line(x + h2 * 2, y + h1*2, x + h2, y+h1*2);
1373 draw_line(x + h2 * 2, y + h1*2+1, x + h2, y+h1*2+1);
1374 draw_line(x + h2 * 2, y + h1*6, x + h2, y+h1*6);
1375 draw_line(x - h2 * 2, y + h1*6+1, x + h2, y+h1*6+1);
1377 draw_triangle_left(x, y + h1, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1378 draw_triangle_left(x, y + h1*5, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1380 // draw the box centred around x
1382 // Fix bug in heroines & cvs version as of 22.8.2005:
1383 // If we grab when zoomed in and zoom out while dragging, when edit gets really narrow strange things start happening
1384 if (w >= 0 && w < 3) {x -= w /2; w = 3;};
1395 w = MIN(w, get_w() + 20);
1396 h = MIN(h, get_h() + 20);
1399 draw_rectangle(x, y, w, h);
1400 draw_rectangle(x + 1, y + 1, w - 2, h - 2);
1402 //printf("TrackCanvas::draw_highlight_insertion %d %d %d %d\n", x, y, w, h);
1405 void TrackCanvas::draw_playback_cursor()
1407 // Called before playback_cursor exists
1408 // if(mwindow->playback_cursor && mwindow->playback_cursor->visible)
1410 // mwindow->playback_cursor->visible = 0;
1411 // mwindow->playback_cursor->draw();
1415 void TrackCanvas::get_handle_coords(Edit *edit, int64_t &x, int64_t &y, int64_t &w, int64_t &h, int side)
1417 int handle_w = mwindow->theme->edithandlein_data[0]->get_w();
1418 int handle_h = mwindow->theme->edithandlein_data[0]->get_h();
1420 edit_dimensions(edit, x, y, w, h);
1422 if(mwindow->edl->session->show_titles)
1424 y += mwindow->theme->get_image("title_bg_data")->get_h();
1431 if(side == EDIT_OUT)
1440 void TrackCanvas::get_transition_coords(int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1442 //printf("TrackCanvas::get_transition_coords 1\n");
1443 // int transition_w = mwindow->theme->transitionhandle_data[0]->get_w();
1444 // int transition_h = mwindow->theme->transitionhandle_data[0]->get_h();
1445 int transition_w = 30;
1446 int transition_h = 30;
1447 //printf("TrackCanvas::get_transition_coords 1\n");
1449 if(mwindow->edl->session->show_titles)
1450 y += mwindow->theme->get_image("title_bg_data")->get_h();
1451 //printf("TrackCanvas::get_transition_coords 2\n");
1453 y += (h - mwindow->theme->get_image("title_bg_data")->get_h()) / 2 - transition_h / 2;
1454 x -= transition_w / 2;
1460 void TrackCanvas::draw_highlighting()
1468 switch(mwindow->session->current_operation)
1470 case DRAG_ATRANSITION:
1471 case DRAG_VTRANSITION:
1472 //printf("TrackCanvas::draw_highlighting 1 %p %p\n",
1473 // mwindow->session->track_highlighted, mwindow->session->edit_highlighted);
1474 if(mwindow->session->edit_highlighted)
1476 //printf("TrackCanvas::draw_highlighting 2\n");
1477 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
1478 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1479 (mwindow->session->current_operation == DRAG_VTRANSITION &&
1480 mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
1482 //printf("TrackCanvas::draw_highlighting 2\n");
1483 edit_dimensions(mwindow->session->edit_highlighted, x, y, w, h);
1484 //printf("TrackCanvas::draw_highlighting 2\n");
1486 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1487 MWindowGUI::visible(y, y + h, 0, get_h()))
1490 get_transition_coords(x, y, w, h);
1492 //printf("TrackCanvas::draw_highlighting 3\n");
1499 // Dragging a new effect from the Resource window
1502 if(mwindow->session->track_highlighted &&
1503 ((mwindow->session->current_operation == DRAG_AEFFECT && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1504 (mwindow->session->current_operation == DRAG_VEFFECT && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
1506 // Put it before another plugin
1507 if(mwindow->session->plugin_highlighted)
1509 plugin_dimensions(mwindow->session->plugin_highlighted,
1514 //printf("TrackCanvas::draw_highlighting 1 %d %d\n", x, w);
1517 // Put it after a plugin set
1518 if(mwindow->session->pluginset_highlighted &&
1519 mwindow->session->pluginset_highlighted->last)
1521 plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last,
1526 //printf("TrackCanvas::draw_highlighting 1 %d %d\n", x, w);
1527 int64_t track_x, track_y, track_w, track_h;
1528 track_dimensions(mwindow->session->track_highlighted,
1536 mwindow->session->track_highlighted->get_length() *
1537 mwindow->edl->session->sample_rate /
1538 mwindow->edl->local_session->zoom_sample -
1539 mwindow->edl->local_session->view_start) -
1541 //printf("TrackCanvas::draw_highlighting 2 %d\n", w);
1542 if(w <= 0) w = track_w;
1546 track_dimensions(mwindow->session->track_highlighted,
1552 //printf("TrackCanvas::draw_highlighting 1 %d %d %d %d\n", x, y, w, h);
1553 // Put it in a new plugin set determined by the selected range
1554 if(mwindow->edl->local_session->get_selectionend() >
1555 mwindow->edl->local_session->get_selectionstart())
1557 x = Units::to_int64(mwindow->edl->local_session->get_selectionstart() *
1558 mwindow->edl->session->sample_rate /
1559 mwindow->edl->local_session->zoom_sample -
1560 mwindow->edl->local_session->view_start);
1561 w = Units::to_int64((mwindow->edl->local_session->get_selectionend() -
1562 mwindow->edl->local_session->get_selectionstart()) *
1563 mwindow->edl->session->sample_rate /
1564 mwindow->edl->local_session->zoom_sample);
1566 // Put it in a new plugin set determined by an edit boundary
1568 if(mwindow->session->edit_highlighted)
1570 int64_t temp_y, temp_h;
1571 edit_dimensions(mwindow->session->edit_highlighted,
1577 // Put it at the beginning of the track in a new plugin set
1580 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1581 MWindowGUI::visible(y, y + h, 0, get_h()))
1583 //printf("TrackCanvas::draw_highlighting 1\n");
1590 if(mwindow->session->track_highlighted)
1592 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1594 if(MWindowGUI::visible(y, y + h, 0, get_h()))
1596 draw_paste_destination();
1601 // Dragging an effect from the timeline
1602 case DRAG_AEFFECT_COPY:
1603 case DRAG_VEFFECT_COPY:
1604 if((mwindow->session->plugin_highlighted || mwindow->session->track_highlighted) &&
1605 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1606 (mwindow->session->current_operation == DRAG_VEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
1608 // Put it before another plugin
1609 if(mwindow->session->plugin_highlighted)
1610 plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
1612 // Put it after a plugin set
1613 if(mwindow->session->pluginset_highlighted &&
1614 mwindow->session->pluginset_highlighted->last)
1616 plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last, x, y, w, h);
1620 if(mwindow->session->track_highlighted)
1622 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1624 // Put it in a new plugin set determined by an edit boundary
1625 if(mwindow->session->edit_highlighted)
1627 int64_t temp_y, temp_h;
1628 edit_dimensions(mwindow->session->edit_highlighted,
1634 // Put it in a new plugin set at the start of the track
1637 // Calculate length of plugin based on data type of track and units
1638 if(mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
1640 w = (int64_t)((double)mwindow->session->drag_plugin->length /
1641 mwindow->edl->session->frame_rate *
1642 mwindow->edl->session->sample_rate /
1643 mwindow->edl->local_session->zoom_sample);
1647 w = (int64_t)mwindow->session->drag_plugin->length /
1648 mwindow->edl->local_session->zoom_sample;
1651 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1652 MWindowGUI::visible(y, y + h, 0, get_h()))
1659 case DRAG_PLUGINKEY:
1660 if(mwindow->session->plugin_highlighted &&
1661 mwindow->session->current_operation == DRAG_PLUGINKEY)
1663 // Just highlight the plugin
1664 plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
1666 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1667 MWindowGUI::visible(y, y + h, 0, get_h()))
1675 if(mwindow->session->track_highlighted)
1677 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1679 if(MWindowGUI::visible(y, y + h, 0, get_h()))
1681 draw_paste_destination();
1690 draw_highlight_rectangle(x, y, w, h);
1694 void TrackCanvas::draw_plugins()
1696 char string[BCTEXTLEN];
1697 int current_toggle = 0;
1699 if(!mwindow->edl->session->show_assets) goto done;
1701 for(int i = 0; i < plugin_on_toggles.total; i++)
1702 plugin_on_toggles.values[i]->in_use = 0;
1703 for(int i = 0; i < plugin_show_toggles.total; i++)
1704 plugin_show_toggles.values[i]->in_use = 0;
1707 for(Track *track = mwindow->edl->tracks->first;
1709 track = track->next)
1711 if(track->expand_view)
1713 for(int i = 0; i < track->plugin_set.total; i++)
1715 PluginSet *pluginset = track->plugin_set.values[i];
1717 for(Plugin *plugin = (Plugin*)pluginset->first; plugin; plugin = (Plugin*)plugin->next)
1719 int64_t total_x, y, total_w, h;
1720 plugin_dimensions(plugin, total_x, y, total_w, h);
1722 if(MWindowGUI::visible(total_x, total_x + total_w, 0, get_w()) &&
1723 MWindowGUI::visible(y, y + h, 0, get_h()) &&
1724 plugin->plugin_type != PLUGIN_NONE)
1726 int x = total_x, w = total_w, left_margin = 5;
1727 int right_margin = 5;
1733 if(w + x > get_w()) w -= (w + x) - get_w();
1740 mwindow->theme->get_image("plugin_bg_data"),
1742 set_color(get_resources()->default_text_color);
1743 set_font(MEDIUMFONT_3D);
1744 plugin->calculate_title(string, 0);
1746 // Truncate string to int64_test visible in background
1747 int len = strlen(string), j;
1748 for(j = len; j >= 0; j--)
1750 if(left_margin + get_text_width(MEDIUMFONT_3D, string) > w)
1758 // Justify the text on the left boundary of the edit if it is visible.
1759 // Otherwise justify it on the left side of the screen.
1760 int text_x = total_x + left_margin;
1761 text_x = MAX(left_margin, text_x);
1763 y + get_text_ascent(MEDIUMFONT_3D) + 2,
1769 // Update plugin toggles
1770 int toggle_x = total_x + total_w;
1771 toggle_x = MIN(get_w() - right_margin, toggle_x);
1772 toggle_x -= PluginOn::calculate_w(mwindow) + 10;
1774 if(current_toggle >= plugin_on_toggles.total)
1776 PluginOn *plugin_on = new PluginOn(mwindow, toggle_x, toggle_y, plugin);
1777 add_subwindow(plugin_on);
1778 plugin_on_toggles.append(plugin_on);
1782 plugin_on_toggles.values[current_toggle]->update(toggle_x, toggle_y, plugin);
1785 toggle_x -= PluginShow::calculate_w(mwindow) + 10;
1786 if(current_toggle >= plugin_show_toggles.total)
1788 PluginShow *plugin_off = new PluginShow(mwindow, toggle_x, toggle_y, plugin);
1789 add_subwindow(plugin_off);
1790 plugin_show_toggles.append(plugin_off);
1794 plugin_show_toggles.values[current_toggle]->update(toggle_x, toggle_y, plugin);
1805 int i = current_toggle;
1806 while(i < plugin_on_toggles.total &&
1807 i < plugin_show_toggles.total)
1809 plugin_on_toggles.remove_object_number(current_toggle);
1810 plugin_show_toggles.remove_object_number(current_toggle);
1814 void TrackCanvas::refresh_plugintoggles()
1816 for(int i = 0; i < plugin_on_toggles.total; i++)
1818 PluginOn *on = plugin_on_toggles.values[i];
1819 on->reposition_window(on->get_x(), on->get_y());
1821 for(int i = 0; i < plugin_show_toggles.total; i++)
1823 PluginShow *show = plugin_show_toggles.values[i];
1824 show->reposition_window(show->get_x(), show->get_y());
1828 void TrackCanvas::draw_inout_points()
1833 void TrackCanvas::draw_drag_handle()
1835 if(mwindow->session->current_operation == DRAG_EDITHANDLE2 ||
1836 mwindow->session->current_operation == DRAG_PLUGINHANDLE2)
1838 //printf("TrackCanvas::draw_drag_handle 1 %ld %ld\n", mwindow->session->drag_sample, mwindow->edl->local_session->view_start);
1839 int64_t pixel1 = Units::round(mwindow->session->drag_position *
1840 mwindow->edl->session->sample_rate /
1841 mwindow->edl->local_session->zoom_sample -
1842 mwindow->edl->local_session->view_start);
1843 //printf("TrackCanvas::draw_drag_handle 2 %d\n", pixel1);
1846 //printf("TrackCanvas::draw_drag_handle 3\n");
1847 draw_line(pixel1, 0, pixel1, get_h());
1849 //printf("TrackCanvas::draw_drag_handle 4\n");
1854 void TrackCanvas::draw_transitions()
1858 if(!mwindow->edl->session->show_assets) return;
1860 for(Track *track = mwindow->edl->tracks->first;
1862 track = track->next)
1864 for(Edit *edit = track->edits->first;
1868 if(edit->transition)
1870 int64_t strip_w, strip_x, strip_y;
1871 edit_dimensions(edit, x, y, w, h);
1874 if(mwindow->edl->session->show_titles)
1875 strip_y += mwindow->theme->get_image("title_bg_data")->get_h();
1877 get_transition_coords(x, y, w, h);
1878 strip_w = Units::round(edit->track->from_units(edit->transition->length) *
1879 mwindow->edl->session->sample_rate /
1880 mwindow->edl->local_session->zoom_sample);
1882 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1883 MWindowGUI::visible(y, y + h, 0, get_h()))
1885 PluginServer *server = mwindow->scan_plugindb(edit->transition->title,
1887 draw_vframe(server->picon,
1894 server->picon->get_w(),
1895 server->picon->get_h());
1897 if(MWindowGUI::visible(strip_x, strip_x + strip_w, 0, get_w()) &&
1898 MWindowGUI::visible(strip_y, strip_y + h, 0, get_h()))
1900 int x = strip_x, w = strip_w, left_margin = 5;
1906 if(w + x > get_w()) w -= (w + x) - get_w();
1914 mwindow->theme->get_image("plugin_bg_data"),
1923 void TrackCanvas::draw_loop_points()
1925 //printf("TrackCanvas::draw_loop_points 1\n");
1926 if(mwindow->edl->local_session->loop_playback)
1928 //printf("TrackCanvas::draw_loop_points 2\n");
1929 int64_t x = Units::round(mwindow->edl->local_session->loop_start *
1930 mwindow->edl->session->sample_rate /
1931 mwindow->edl->local_session->zoom_sample -
1932 mwindow->edl->local_session->view_start);
1933 //printf("TrackCanvas::draw_loop_points 3\n");
1935 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1938 draw_line(x, 0, x, get_h());
1940 //printf("TrackCanvas::draw_loop_points 4\n");
1942 x = Units::round(mwindow->edl->local_session->loop_end *
1943 mwindow->edl->session->sample_rate /
1944 mwindow->edl->local_session->zoom_sample -
1945 mwindow->edl->local_session->view_start);
1946 //printf("TrackCanvas::draw_loop_points 5\n");
1948 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1951 draw_line(x, 0, x, get_h());
1953 //printf("TrackCanvas::draw_loop_points 6\n");
1955 //printf("TrackCanvas::draw_loop_points 7\n");
1958 void TrackCanvas::draw_brender_start()
1960 if(mwindow->preferences->use_brender)
1962 int64_t x = Units::round(mwindow->edl->session->brender_start *
1963 mwindow->edl->session->sample_rate /
1964 mwindow->edl->local_session->zoom_sample -
1965 mwindow->edl->local_session->view_start);
1967 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1970 draw_line(x, 0, x, get_h());
1975 static int auto_colors[] =
1991 // The operations which correspond to each automation type
1992 static int auto_operations[] =
2008 // The buttonpress operations, so nothing changes unless the mouse moves
2009 // a certain amount. This allows the keyframe to be used to position the
2010 // insertion point without moving itself.
2011 static int pre_auto_operations[] =
2028 int TrackCanvas::do_keyframes(int cursor_x,
2036 // Note: button 3 (right mouse button) is not eaten to allow
2037 // track context menu to appear
2038 int current_tool = 0;
2040 EDLSession *session = mwindow->edl->session;
2044 BC_Pixmap *auto_pixmaps[] =
2055 modekeyframe_pixmap,
2056 maskkeyframe_pixmap,
2062 for(Track *track = mwindow->edl->tracks->first;
2064 track = track->next)
2066 Auto *auto_keyframe;
2067 Automation *automation = track->automation;
2070 // Handle float autos
2071 for(int i = 0; i < AUTOMATION_TOTAL && !result; i++)
2073 // Event not trapped and automation visible
2074 Autos *autos = automation->autos[i];
2075 if(!result && session->auto_conf->autos[i] && autos)
2079 case AUTOMATION_MODE:
2080 case AUTOMATION_PAN:
2081 case AUTOMATION_MASK:
2082 result = do_autos(track,
2083 automation->autos[i],
2093 switch(autos->get_type())
2095 case AUTOMATION_TYPE_FLOAT:
2097 Automation *dummy = new Automation(0,track);
2098 int autogrouptype = dummy->autogrouptype(i,track);
2099 result = do_float_autos(track,
2112 case AUTOMATION_TYPE_INT:
2113 result = do_toggle_autos(track,
2130 if(mwindow->session->current_operation == auto_operations[i])
2134 if (buttonpress != 3)
2136 if(i == AUTOMATION_FADE)
2137 synchronize_autos(0,
2139 (FloatAuto*)mwindow->session->drag_auto,
2141 mwindow->session->current_operation = pre_auto_operations[i];
2142 update_drag_caption();
2147 gui->keyframe_menu->update(automation, autos, auto_keyframe);
2148 gui->keyframe_menu->activate_menu();
2149 rerender = 1; // the position changes
2160 session->auto_conf->plugins &&
2161 mwindow->edl->session->show_assets)
2165 result = do_plugin_autos(track,
2172 if(result && mwindow->session->current_operation == DRAG_PLUGINKEY)
2176 if(result && (buttonpress == 1))
2178 mwindow->session->current_operation = DRAG_PLUGINKEY_PRE;
2179 update_drag_caption();
2182 if (result && (buttonpress == 3))
2184 gui->keyframe_menu->update(plugin, keyframe);
2185 gui->keyframe_menu->activate_menu();
2186 rerender = 1; // the position changes
2191 // Final pass to trap event
2192 for(int i = 0; i < AUTOMATION_TOTAL; i++)
2194 if(mwindow->session->current_operation == pre_auto_operations[i] ||
2195 mwindow->session->current_operation == auto_operations[i])
2199 if(mwindow->session->current_operation == DRAG_PLUGINKEY ||
2200 mwindow->session->current_operation == DRAG_PLUGINKEY_PRE)
2208 new_cursor = UPRIGHT_ARROW_CURSOR;
2214 void TrackCanvas::draw_auto(Auto *current,
2222 char string[BCTEXTLEN];
2224 x1 = x - HANDLE_W / 2;
2225 x2 = x + HANDLE_W / 2;
2226 y1 = center_pixel + y - HANDLE_W / 2;
2227 y2 = center_pixel + y + HANDLE_W / 2;
2229 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2230 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2233 draw_box(x1 + 1, y1 + 1, x2 - x1, y2 - y1);
2235 draw_box(x1, y1, x2 - x1, y2 - y1);
2238 void TrackCanvas::draw_floatauto(Auto *current,
2250 int in_x1, in_y1, in_x2, in_y2;
2251 int out_x1, out_y1, out_x2, out_y2;
2252 char string[BCTEXTLEN];
2255 x1 = x - HANDLE_W / 2;
2256 x2 = x + HANDLE_W / 2;
2257 y1 = center_pixel + y - HANDLE_W / 2;
2258 y2 = center_pixel + y + HANDLE_W / 2;
2260 CLAMP(y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2261 CLAMP(y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2266 draw_box(x1 + 1, y1 + 1, x2 - x1, y2 - y1);
2268 draw_box(x1, y1, x2 - x1, y2 - y1);
2272 in_x1 = in_x - HANDLE_W / 2;
2273 in_x2 = in_x + HANDLE_W / 2;
2274 in_y1 = center_pixel + in_y - HANDLE_W / 2;
2275 in_y2 = center_pixel + in_y + HANDLE_W / 2;
2277 CLAMP(in_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2278 CLAMP(in_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2279 CLAMP(in_y, -zoom_track / 2, zoom_track / 2);
2284 draw_line(x + 1, center_pixel + y + 1, in_x + 1, center_pixel + in_y + 1);
2285 draw_box(in_x1 + 1, in_y1 + 1, in_x2 - in_x1, in_y2 - in_y1);
2287 draw_line(x, center_pixel + y, in_x, center_pixel + in_y);
2288 draw_box(in_x1, in_y1, in_x2 - in_x1, in_y2 - in_y1);
2293 out_x1 = out_x - HANDLE_W / 2;
2294 out_x2 = out_x + HANDLE_W / 2;
2295 out_y1 = center_pixel + out_y - HANDLE_W / 2;
2296 out_y2 = center_pixel + out_y + HANDLE_W / 2;
2298 CLAMP(out_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2299 CLAMP(out_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2300 CLAMP(out_y, -zoom_track / 2, zoom_track / 2);
2305 draw_line(x + 1, center_pixel + y + 1, out_x + 1, center_pixel + out_y + 1);
2306 draw_box(out_x1 + 1, out_y1 + 1, out_x2 - out_x1, out_y2 - out_y1);
2308 draw_line(x, center_pixel + y, out_x, center_pixel + out_y);
2309 draw_box(out_x1, out_y1, out_x2 - out_x1, out_y2 - out_y1);
2313 int TrackCanvas::test_auto(Auto *current,
2323 char string[BCTEXTLEN];
2326 x1 = x - HANDLE_W / 2;
2327 x2 = x + HANDLE_W / 2;
2328 y1 = center_pixel + y - HANDLE_W / 2;
2329 y2 = center_pixel + y + HANDLE_W / 2;
2331 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2332 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2334 if(cursor_x >= x1 && cursor_x < x2 && cursor_y >= y1 && cursor_y < y2)
2336 if(buttonpress && buttonpress != 3)
2338 mwindow->session->drag_auto = current;
2339 mwindow->session->drag_start_percentage = current->value_to_percentage();
2340 mwindow->session->drag_start_position = current->position;
2341 mwindow->session->drag_origin_x = cursor_x;
2342 mwindow->session->drag_origin_y = cursor_y;
2350 int TrackCanvas::test_floatauto(Auto *current,
2364 int in_x1, in_y1, in_x2, in_y2;
2365 int out_x1, out_y1, out_x2, out_y2;
2366 char string[BCTEXTLEN];
2369 x1 = x - HANDLE_W / 2;
2370 x2 = x + HANDLE_W / 2;
2371 y1 = center_pixel + y - HANDLE_W / 2;
2372 y2 = center_pixel + y + HANDLE_W / 2;
2374 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2375 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2377 in_x1 = in_x - HANDLE_W / 2;
2378 in_x2 = in_x + HANDLE_W / 2;
2379 in_y1 = center_pixel + in_y - HANDLE_W / 2;
2380 in_y2 = center_pixel + in_y + HANDLE_W / 2;
2382 if(in_y1 < center_pixel + -zoom_track / 2) in_y1 = center_pixel + -zoom_track / 2;
2383 if(in_y2 > center_pixel + zoom_track / 2) in_y2 = center_pixel + zoom_track / 2;
2385 out_x1 = out_x - HANDLE_W / 2;
2386 out_x2 = out_x + HANDLE_W / 2;
2387 out_y1 = center_pixel + out_y - HANDLE_W / 2;
2388 out_y2 = center_pixel + out_y + HANDLE_W / 2;
2390 if(out_y1 < center_pixel + -zoom_track / 2) out_y1 = center_pixel + -zoom_track / 2;
2391 if(out_y2 > center_pixel + zoom_track / 2) out_y2 = center_pixel + zoom_track / 2;
2395 //printf("TrackCanvas::test_floatauto %d %d %d %d %d %d\n", cursor_x, cursor_y, x1, x2, y1, y2);
2403 if(buttonpress && (buttonpress != 3))
2405 mwindow->session->drag_auto = current;
2406 mwindow->session->drag_start_percentage = current->value_to_percentage();
2407 mwindow->session->drag_start_position = current->position;
2408 mwindow->session->drag_origin_x = cursor_x;
2409 mwindow->session->drag_origin_y = cursor_y;
2410 mwindow->session->drag_handle = 0;
2417 cursor_x >= in_x1 &&
2419 cursor_y >= in_y1 &&
2421 current->position > 0)
2423 if(buttonpress && (buttonpress != 3))
2425 mwindow->session->drag_auto = current;
2426 mwindow->session->drag_start_percentage =
2427 current->invalue_to_percentage();
2428 mwindow->session->drag_start_position =
2429 ((FloatAuto*)current)->control_in_position;
2430 mwindow->session->drag_origin_x = cursor_x;
2431 mwindow->session->drag_origin_y = cursor_y;
2432 mwindow->session->drag_handle = 1;
2439 cursor_x >= out_x1 &&
2440 cursor_x < out_x2 &&
2441 cursor_y >= out_y1 &&
2444 if(buttonpress && (buttonpress != 3))
2446 mwindow->session->drag_auto = current;
2447 mwindow->session->drag_start_percentage =
2448 current->outvalue_to_percentage();
2449 mwindow->session->drag_start_position =
2450 ((FloatAuto*)current)->control_out_position;
2451 mwindow->session->drag_origin_x = cursor_x;
2452 mwindow->session->drag_origin_y = cursor_y;
2453 mwindow->session->drag_handle = 2;
2459 // printf("TrackCanvas::test_floatauto 2 drag_handle=%d ctrl_down=%d cursor_x=%d cursor_y=%d x1=%d x2=%d y1=%d y2=%d\n",
2460 // mwindow->session->drag_handle,
2469 void TrackCanvas::draw_floatline(int center_pixel,
2470 FloatAuto *previous,
2483 // Solve bezier equation for either every pixel or a certain large number of
2488 // Not using slope intercept
2495 // Call by reference fails for some reason here
2496 FloatAuto *previous1 = previous, *next1 = next;
2497 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
2498 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
2499 float automation_range = automation_max - automation_min;
2501 for(int x = x1; x < x2; x++)
2503 int64_t position = (int64_t)(unit_start + x * zoom_units);
2504 float value = autos->get_value(position, PLAY_FORWARD, previous1, next1);
2505 AUTOMATIONCLAMPS(value, autogrouptype);
2507 int y = center_pixel +
2508 (int)(((value - automation_min) / automation_range - 0.5) * -yscale);
2511 y >= center_pixel - yscale / 2 &&
2512 y < center_pixel + yscale / 2 - 1)
2515 draw_line(x - 1, prev_y + 1, x, y + 1);
2517 draw_line(x - 1, prev_y, x, y);
2525 void TrackCanvas::synchronize_autos(float change,
2530 // fill mwindow->session->drag_auto_gang
2531 if (fill_gangs == 1 && skip->gang)
2533 for(Track *current = mwindow->edl->tracks->first;
2537 if(current->data_type == skip->data_type &&
2542 FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
2543 double position = skip->from_units(fauto->position);
2544 FloatAuto *previous = 0, *next = 0;
2546 float init_value = fade_autos->get_value(fauto->position, PLAY_FORWARD, previous, next);
2547 FloatAuto *keyframe;
2548 keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position);
2552 // create keyframe at exactly this point in time
2553 keyframe = (FloatAuto*)fade_autos->insert_auto(fauto->position);
2554 keyframe->value = init_value;
2558 // keyframe exists, just change it
2559 keyframe->value += change;
2562 keyframe->position = fauto->position;
2563 keyframe->control_out_position = fauto->control_out_position;
2564 keyframe->control_in_position = fauto->control_in_position;
2565 keyframe->control_out_value = fauto->control_out_value;
2566 keyframe->control_in_value = fauto->control_in_value;
2568 mwindow->session->drag_auto_gang->append((Auto *)keyframe);
2573 if (fill_gangs == 0)
2576 for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
2578 FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
2580 keyframe->value += change;
2581 keyframe->position = fauto->position;
2582 CLAMP(keyframe->value,
2583 mwindow->edl->local_session->automation_mins[keyframe->autos->autogrouptype],
2584 mwindow->edl->local_session->automation_maxs[keyframe->autos->autogrouptype]);
2585 keyframe->control_out_position = fauto->control_out_position;
2586 keyframe->control_in_position = fauto->control_in_position;
2587 keyframe->control_out_value = fauto->control_out_value;
2588 keyframe->control_in_value = fauto->control_in_value;
2594 if (fill_gangs == -1)
2596 for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
2598 FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
2599 keyframe->autos->remove_nonsequential(
2602 mwindow->session->drag_auto_gang->remove_all();
2607 int TrackCanvas::test_floatline(int center_pixel,
2622 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
2623 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
2624 float automation_range = automation_max - automation_min;
2625 int64_t position = (int64_t)(unit_start + cursor_x * zoom_units);
2626 // Call by reference fails for some reason here
2627 FloatAuto *previous = 0, *next = 0;
2628 float value = autos->get_value(position, PLAY_FORWARD, previous, next);
2629 AUTOMATIONCLAMPS(value,autogrouptype);
2630 int y = center_pixel +
2631 (int)(((value - automation_min) / automation_range - 0.5) * -yscale);
2633 if(cursor_x >= x1 &&
2635 cursor_y >= y - HANDLE_W / 2 &&
2636 cursor_y < y + HANDLE_W / 2 &&
2647 current = mwindow->session->drag_auto = autos->insert_auto(position);
2648 ((FloatAuto*)current)->value = value;
2649 mwindow->session->drag_start_percentage = current->value_to_percentage();
2650 mwindow->session->drag_start_position = current->position;
2651 mwindow->session->drag_origin_x = cursor_x;
2652 mwindow->session->drag_origin_y = cursor_y;
2653 mwindow->session->drag_handle = 0;
2662 void TrackCanvas::draw_toggleline(int center_pixel,
2670 draw_line(x1, center_pixel + y1 + 1, x2, center_pixel + y1 + 1);
2672 draw_line(x1, center_pixel + y1, x2, center_pixel + y1);
2677 draw_line(x2 + 1, center_pixel + y1, x2 + 1, center_pixel + y2);
2679 draw_line(x2, center_pixel + y1, x2, center_pixel + y2);
2683 int TrackCanvas::test_toggleline(Autos *autos,
2694 if(cursor_x >= x1 && cursor_x < x2)
2696 int miny = center_pixel + y1 - HANDLE_W / 2;
2697 int maxy = center_pixel + y1 + HANDLE_W / 2;
2698 if(cursor_y >= miny && cursor_y < maxy)
2707 double position = (double)(cursor_x +
2708 mwindow->edl->local_session->view_start) *
2709 mwindow->edl->local_session->zoom_sample /
2710 mwindow->edl->session->sample_rate;
2711 int64_t unit_position = autos->track->to_units(position, 0);
2712 int new_value = (int)((IntAutos*)autos)->get_automation_constant(unit_position, unit_position);
2714 current = mwindow->session->drag_auto = autos->insert_auto(unit_position);
2715 ((IntAuto*)current)->value = new_value;
2716 mwindow->session->drag_start_percentage = current->value_to_percentage();
2717 mwindow->session->drag_start_position = current->position;
2718 mwindow->session->drag_origin_x = cursor_x;
2719 mwindow->session->drag_origin_y = cursor_y;
2727 void TrackCanvas::calculate_viewport(Track *track,
2728 double &view_start, // Seconds
2730 double &view_end, // Seconds
2734 double &zoom_sample,
2737 view_start = (double)mwindow->edl->local_session->view_start *
2738 mwindow->edl->local_session->zoom_sample /
2739 mwindow->edl->session->sample_rate;
2740 unit_start = track->to_doubleunits(view_start);
2741 view_end = (double)(mwindow->edl->local_session->view_start +
2743 mwindow->edl->local_session->zoom_sample /
2744 mwindow->edl->session->sample_rate;
2745 unit_end = track->to_doubleunits(view_end);
2746 yscale = mwindow->edl->local_session->zoom_track;
2747 center_pixel = (int)(track->y_pixel + yscale / 2) +
2748 (mwindow->edl->session->show_titles ?
2749 mwindow->theme->get_image("title_bg_data")->get_h() :
2751 zoom_sample = mwindow->edl->local_session->zoom_sample;
2753 zoom_units = track->to_doubleunits(zoom_sample / mwindow->edl->session->sample_rate);
2756 float TrackCanvas::percentage_to_value(float percentage,
2764 if(percentage > 0.5)
2771 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
2772 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
2773 float automation_range = automation_max - automation_min;
2775 result = percentage * automation_range + automation_min;
2778 FloatAuto *ptr = (FloatAuto*)reference;
2779 result -= ptr->value;
2786 void TrackCanvas::calculate_auto_position(double *x,
2798 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
2799 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
2800 float automation_range = automation_max - automation_min;
2801 FloatAuto *ptr = (FloatAuto*)current;
2802 *x = (double)(ptr->position - unit_start) / zoom_units;
2803 *y = ((ptr->value - automation_min) /
2804 automation_range - 0.5) *
2808 *in_x = (double)(ptr->position +
2809 ptr->control_in_position -
2815 *in_y = (((ptr->value + ptr->control_in_value) -
2817 automation_range - 0.5) *
2822 *out_x = (double)(ptr->position +
2823 ptr->control_out_position -
2829 *out_y = (((ptr->value + ptr->control_out_value) -
2831 automation_range - 0.5) *
2840 int TrackCanvas::do_float_autos(Track *track,
2847 Auto* &auto_instance,
2860 double ax, ay, ax2, ay2;
2861 double in_x2, in_y2, out_x2, out_y2;
2868 calculate_viewport(track,
2880 // Get first auto before start
2883 for(current = autos->last;
2884 current && current->position >= unit_start;
2890 calculate_auto_position(&ax,
2905 current = autos->first ? autos->first : autos->default_auto;
2908 calculate_auto_position(&ax,
2939 calculate_auto_position(&ax2,
2958 slope = (ay2 - ay) / (ax2 - ax);
2964 ay2 = ay + slope * (get_w() - ax);
2969 ay = ay + slope * (0 - ax);
2987 if(current && !result)
2989 if(current != autos->default_auto)
2994 result = test_floatauto(current,
3007 auto_instance = current;
3011 draw_floatauto(current,
3028 // Draw joining line
3033 if(track->record && buttonpress != 3)
3035 result = test_floatline(center_pixel,
3041 // Exclude auto coverage from the end of the line. The auto overlaps
3042 (int)ax2 - HANDLE_W / 2,
3051 draw_floatline(center_pixel,
3052 (FloatAuto*)previous,
3053 (FloatAuto*)current,
3082 current->position <= unit_end &&
3085 //printf("TrackCanvas::do_float_autos 100\n");
3094 if(ax < get_w() && !result)
3100 if(track->record && buttonpress != 3)
3102 result = test_floatline(center_pixel,
3116 draw_floatline(center_pixel,
3117 (FloatAuto*)previous,
3118 (FloatAuto*)current,
3142 int TrackCanvas::do_toggle_autos(Track *track,
3149 Auto * &auto_instance)
3160 double ax, ay, ax2, ay2;
3164 calculate_viewport(track,
3175 double high = -yscale * 0.8 / 2;
3176 double low = yscale * 0.8 / 2;
3178 // Get first auto before start
3180 for(current = autos->last; current && current->position >= unit_start; current = PREVIOUS)
3186 ay = ((IntAuto*)current)->value > 0 ? high : low;
3191 current = autos->first ? autos->first : autos->default_auto;
3195 ay = ((IntAuto*)current)->value > 0 ? high : low;
3208 ax2 = (double)(current->position - unit_start) / zoom_units;
3209 ay2 = ((IntAuto*)current)->value > 0 ? high : low;
3217 if(ax2 > get_w()) ax2 = get_w();
3219 if(current && !result)
3221 if(current != autos->default_auto)
3227 result = test_auto(current,
3236 auto_instance = current;
3255 if(track->record && buttonpress != 3)
3257 result = test_toggleline(autos,
3270 draw_toggleline(center_pixel,
3279 }while(current && current->position <= unit_end && !result);
3281 if(ax < get_w() && !result)
3287 if(track->record && buttonpress != 3)
3289 result = test_toggleline(autos,
3301 draw_toggleline(center_pixel,
3311 int TrackCanvas::do_autos(Track *track,
3318 Auto * &auto_instance)
3331 calculate_viewport(track,
3344 for(current = autos->first; current && !result; current = NEXT)
3346 if(current->position >= unit_start && current->position < unit_end)
3349 x = (int64_t)((double)(current->position - unit_start) /
3350 zoom_units - (pixmap->get_w() / 2 + 0.5));
3351 y = center_pixel - pixmap->get_h() / 2;
3355 if(cursor_x >= x && cursor_y >= y &&
3356 cursor_x < x + pixmap->get_w() &&
3357 cursor_y < y + pixmap->get_h())
3360 auto_instance = current;
3362 if(buttonpress && (buttonpress != 3))
3364 mwindow->session->drag_auto = current;
3365 mwindow->session->drag_start_position = current->position;
3366 mwindow->session->drag_origin_x = cursor_x;
3367 mwindow->session->drag_origin_y = cursor_y;
3369 double position = autos->track->from_units(current->position);
3370 double center = (mwindow->edl->local_session->get_selectionstart(1) +
3371 mwindow->edl->local_session->get_selectionend(1)) /
3376 mwindow->edl->local_session->set_selectionstart(position);
3377 mwindow->edl->local_session->set_selectionend(position);
3380 if(position < center)
3382 mwindow->edl->local_session->set_selectionstart(position);
3385 mwindow->edl->local_session->set_selectionend(position);
3390 draw_pixmap(pixmap, x, y);
3396 // so this means it is always >0 when keyframe is found
3397 int TrackCanvas::do_plugin_autos(Track *track,
3402 Plugin* &keyframe_plugin,
3403 KeyFrame* &keyframe_instance)
3416 if(!track->expand_view) return 0;
3418 calculate_viewport(track,
3430 for(int i = 0; i < track->plugin_set.total && !result; i++)
3432 PluginSet *plugin_set = track->plugin_set.values[i];
3433 int center_pixel = (int)(track->y_pixel +
3434 mwindow->edl->local_session->zoom_track +
3435 (i + 0.5) * mwindow->theme->get_image("plugin_bg_data")->get_h() +
3436 (mwindow->edl->session->show_titles ? mwindow->theme->get_image("title_bg_data")->get_h() : 0));
3438 for(Plugin *plugin = (Plugin*)plugin_set->first;
3440 plugin = (Plugin*)plugin->next)
3442 for(KeyFrame *keyframe = (KeyFrame*)plugin->keyframes->first;
3443 keyframe && !result;
3444 keyframe = (KeyFrame*)keyframe->next)
3446 //printf("TrackCanvas::draw_plugin_autos 3 %d\n", keyframe->position);
3447 if(keyframe->position >= unit_start && keyframe->position < unit_end)
3449 int64_t x = (int64_t)((keyframe->position - unit_start) / zoom_units);
3450 int y = center_pixel - keyframe_pixmap->get_h() / 2;
3452 //printf("TrackCanvas::draw_plugin_autos 4 %d %d\n", x, center_pixel);
3455 if(cursor_x >= x && cursor_y >= y &&
3456 cursor_x < x + keyframe_pixmap->get_w() &&
3457 cursor_y < y + keyframe_pixmap->get_h())
3460 keyframe_plugin = plugin;
3461 keyframe_instance = keyframe;
3465 mwindow->session->drag_auto = keyframe;
3466 mwindow->session->drag_start_position = keyframe->position;
3467 mwindow->session->drag_origin_x = cursor_x;
3468 mwindow->session->drag_origin_y = cursor_y;
3470 double position = track->from_units(keyframe->position);
3471 double center = (mwindow->edl->local_session->get_selectionstart(1) +
3472 mwindow->edl->local_session->get_selectionend(1)) /
3477 mwindow->edl->local_session->set_selectionstart(position);
3478 mwindow->edl->local_session->set_selectionend(position);
3481 if(position < center)
3483 mwindow->edl->local_session->set_selectionstart(position);
3486 mwindow->edl->local_session->set_selectionend(position);
3491 draw_pixmap(keyframe_pixmap,
3498 //printf("TrackCanvas::draw_plugin_autos 5\n");
3502 void TrackCanvas::draw_overlays()
3504 int new_cursor, update_cursor, rerender;
3506 // Move background pixmap to foreground pixmap
3507 draw_pixmap(background_pixmap,
3516 draw_inout_points();
3519 if(mwindow->edl->session->auto_conf->transitions) draw_transitions();
3526 draw_brender_start();
3528 // Highlighted areas
3529 draw_highlighting();
3541 if(gui->cursor) gui->cursor->restore(1);
3547 draw_playback_cursor();
3551 int TrackCanvas::activate()
3555 get_top_level()->deactivate();
3557 set_active_subwindow(this);
3558 gui->cursor->activate();
3563 int TrackCanvas::deactivate()
3568 gui->cursor->deactivate();
3574 void TrackCanvas::update_drag_handle()
3576 double new_position;
3579 (double)(get_cursor_x() + mwindow->edl->local_session->view_start) *
3580 mwindow->edl->local_session->zoom_sample /
3581 mwindow->edl->session->sample_rate;
3583 mwindow->edl->align_to_frame(new_position, 0);
3586 if(new_position != mwindow->session->drag_position)
3588 mwindow->session->drag_position = new_position;
3589 gui->mainclock->update(new_position);
3590 // Que the CWindow. Doesn't do anything if selectionstart and selection end
3592 // mwindow->cwindow->update(1, 0, 0);
3596 int TrackCanvas::update_drag_edit()
3605 #define UPDATE_DRAG_HEAD(do_clamp) \
3607 int x = cursor_x - mwindow->session->drag_origin_x; \
3608 int y = cursor_y - mwindow->session->drag_origin_y; \
3610 if(!current->autos->track->record) return 0; \
3611 double view_start; \
3612 double unit_start; \
3617 double zoom_sample; \
3618 double zoom_units; \
3620 calculate_viewport(current->autos->track, \
3630 float percentage = (float)(mwindow->session->drag_origin_y - cursor_y) / \
3632 mwindow->session->drag_start_percentage; \
3633 if(do_clamp) CLAMP(percentage, 0, 1); \
3635 int64_t position = Units::to_int64(zoom_units * \
3636 (cursor_x - mwindow->session->drag_origin_x) + \
3637 mwindow->session->drag_start_position); \
3639 if((do_clamp) && position < 0) position = 0;
3649 int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y)
3651 FloatAuto *current = (FloatAuto*)mwindow->session->drag_auto;
3653 UPDATE_DRAG_HEAD(mwindow->session->drag_handle == 0);
3658 switch(mwindow->session->drag_handle)
3662 // Snap to nearby values
3663 old_value = current->value;
3671 if(current->previous)
3673 int autogrouptype = current->previous->autos->autogrouptype;
3674 value = percentage_to_value(percentage, 0, 0, autogrouptype);
3675 value1 = ((FloatAuto*)current->previous)->value;
3676 distance1 = fabs(value - value1);
3677 current->value = value1;
3682 int autogrouptype = current->next->autos->autogrouptype;
3683 value = percentage_to_value(percentage, 0, 0, autogrouptype);
3684 value2 = ((FloatAuto*)current->next)->value;
3685 distance2 = fabs(value - value2);
3686 if(!current->previous || distance2 < distance1)
3688 current->value = value2;
3692 if(!current->previous && !current->next)
3694 current->value = ((FloatAutos*)current->autos)->default_;
3696 value = current->value;
3700 int autogrouptype = current->autos->autogrouptype;
3701 value = percentage_to_value(percentage, 0, 0, autogrouptype);
3704 if(value != old_value || position != current->position)
3707 float change = value - old_value;
3708 current->value = value;
3709 current->position = position;
3710 synchronize_autos(change, current->autos->track, current, 0);
3712 char string[BCTEXTLEN], string2[BCTEXTLEN];
3713 Units::totext(string2,
3714 current->autos->track->from_units(current->position),
3715 mwindow->edl->session->time_format,
3716 mwindow->edl->session->sample_rate,
3717 mwindow->edl->session->frame_rate,
3718 mwindow->edl->session->frames_per_foot);
3719 sprintf(string, "%s, %.2f", string2, current->value);
3720 gui->show_message(string);
3727 int autogrouptype = current->autos->autogrouptype;
3728 value = percentage_to_value(percentage, 0, current, autogrouptype);
3729 position = MIN(0, position);
3730 if(value != current->control_in_value ||
3731 position != current->control_in_position)
3734 current->control_in_value = value;
3735 current->control_in_position = position;
3736 synchronize_autos(0, current->autos->track, current, 0);
3738 char string[BCTEXTLEN], string2[BCTEXTLEN];
3739 Units::totext(string2,
3740 current->autos->track->from_units(current->control_in_position),
3741 mwindow->edl->session->time_format,
3742 mwindow->edl->session->sample_rate,
3743 mwindow->edl->session->frame_rate,
3744 mwindow->edl->session->frames_per_foot);
3745 sprintf(string, "%s, %.2f", string2, current->control_in_value);
3746 gui->show_message(string);
3754 int autogrouptype = current->autos->autogrouptype;
3755 value = percentage_to_value(percentage, 0, current, autogrouptype);
3756 position = MAX(0, position);
3757 if(value != current->control_out_value ||
3758 position != current->control_out_position)
3761 current->control_out_value = value;
3762 current->control_out_position = position;
3763 synchronize_autos(0, current->autos->track, current, 0);
3765 char string[BCTEXTLEN], string2[BCTEXTLEN];
3766 Units::totext(string2,
3767 current->autos->track->from_units(
3768 ((FloatAuto*)current)->control_out_position),
3769 mwindow->edl->session->time_format,
3770 mwindow->edl->session->sample_rate,
3771 mwindow->edl->session->frame_rate,
3772 mwindow->edl->session->frames_per_foot);
3773 sprintf(string, "%s, %.2f",
3775 ((FloatAuto*)current)->control_out_value);
3776 gui->show_message(string);
3785 int TrackCanvas::update_drag_toggleauto(int cursor_x, int cursor_y)
3787 IntAuto *current = (IntAuto*)mwindow->session->drag_auto;
3789 UPDATE_DRAG_HEAD(1);
3790 int value = (int)percentage_to_value(percentage, 1, 0, AUTOGROUPTYPE_INT255);
3792 if(value != current->value || position != current->position)
3795 current->value = value;
3796 current->position = position;
3798 char string[BCTEXTLEN], string2[BCTEXTLEN];
3799 Units::totext(string2,
3800 current->autos->track->from_units(current->position),
3801 mwindow->edl->session->time_format,
3802 mwindow->edl->session->sample_rate,
3803 mwindow->edl->session->frame_rate,
3804 mwindow->edl->session->frames_per_foot);
3805 sprintf(string, "%s, %d", string2, current->value);
3806 gui->show_message(string);
3812 // Autos which can't change value through dragging.
3814 int TrackCanvas::update_drag_auto(int cursor_x, int cursor_y)
3816 Auto *current = (Auto*)mwindow->session->drag_auto;
3819 if(position != current->position)
3822 current->position = position;
3824 char string[BCTEXTLEN];
3825 Units::totext(string,
3826 current->autos->track->from_units(current->position),
3827 mwindow->edl->session->time_format,
3828 mwindow->edl->session->sample_rate,
3829 mwindow->edl->session->frame_rate,
3830 mwindow->edl->session->frames_per_foot);
3831 gui->show_message(string);
3833 double position_f = current->autos->track->from_units(current->position);
3834 double center_f = (mwindow->edl->local_session->get_selectionstart(1) +
3835 mwindow->edl->local_session->get_selectionend(1)) /
3839 mwindow->edl->local_session->set_selectionstart(position_f);
3840 mwindow->edl->local_session->set_selectionend(position_f);
3843 if(position_f < center_f)
3845 mwindow->edl->local_session->set_selectionstart(position_f);
3848 mwindow->edl->local_session->set_selectionend(position_f);
3855 int TrackCanvas::update_drag_pluginauto(int cursor_x, int cursor_y)
3857 KeyFrame *current = (KeyFrame*)mwindow->session->drag_auto;
3860 if(position != current->position)
3862 // printf("uida: autos: %p, track: %p ta: %p\n", current->autos, current->autos->track, current->autos->track->automation);
3863 Track *track = current->autos->track;
3864 PluginAutos *pluginautos = (PluginAutos *)current->autos;
3865 PluginSet *pluginset;
3867 // figure out the correct pluginset & correct plugin
3869 for(int i = 0; i < track->plugin_set.total; i++)
3871 pluginset = track->plugin_set.values[i];
3872 for(plugin = (Plugin *)pluginset->first; plugin; plugin = (Plugin *)plugin->next)
3874 KeyFrames *keyframes = plugin->keyframes;
3875 for(KeyFrame *currentkeyframe = (KeyFrame *)keyframes->first; currentkeyframe; currentkeyframe = (KeyFrame *) currentkeyframe->next)
3877 if (currentkeyframe == current)
3889 mwindow->session->plugin_highlighted = plugin;
3890 mwindow->session->track_highlighted = track;
3892 current->position = position;
3894 char string[BCTEXTLEN];
3895 Units::totext(string,
3896 current->autos->track->from_units(current->position),
3897 mwindow->edl->session->time_format,
3898 mwindow->edl->session->sample_rate,
3899 mwindow->edl->session->frame_rate,
3900 mwindow->edl->session->frames_per_foot);
3901 gui->show_message(string);
3903 double position_f = current->autos->track->from_units(current->position);
3904 double center_f = (mwindow->edl->local_session->get_selectionstart(1) +
3905 mwindow->edl->local_session->get_selectionend(1)) /
3909 mwindow->edl->local_session->set_selectionstart(position_f);
3910 mwindow->edl->local_session->set_selectionend(position_f);
3913 if(position_f < center_f)
3915 mwindow->edl->local_session->set_selectionstart(position_f);
3918 mwindow->edl->local_session->set_selectionend(position_f);
3925 void TrackCanvas::update_drag_caption()
3927 switch(mwindow->session->current_operation)
3937 int TrackCanvas::cursor_motion_event()
3939 int result, cursor_x, cursor_y;
3940 int update_clock = 0;
3941 int update_zoom = 0;
3942 int update_scroll = 0;
3943 int update_overlay = 0;
3944 int update_cursor = 0;
3947 double position = 0;
3948 //printf("TrackCanvas::cursor_motion_event 1\n");
3952 switch(mwindow->edl->session->editing_mode)
3954 case EDITING_ARROW: new_cursor = ARROW_CURSOR; break;
3955 case EDITING_IBEAM: new_cursor = IBEAM_CURSOR; break;
3958 switch(mwindow->session->current_operation)
3960 case DRAG_EDITHANDLE1:
3961 // Outside threshold. Upgrade status
3962 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3964 mwindow->session->current_operation = DRAG_EDITHANDLE2;
3969 case DRAG_EDITHANDLE2:
3970 update_drag_handle();
3974 case DRAG_PLUGINHANDLE1:
3975 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3977 mwindow->session->current_operation = DRAG_PLUGINHANDLE2;
3982 case DRAG_PLUGINHANDLE2:
3983 update_drag_handle();
3987 // Rubber band curves
3994 case DRAG_PROJECTOR_X:
3995 case DRAG_PROJECTOR_Y:
3996 case DRAG_PROJECTOR_Z:
3997 rerender = update_overlay = update_drag_floatauto(get_cursor_x(), get_cursor_y());
4001 rerender = update_overlay = update_drag_toggleauto(get_cursor_x(), get_cursor_y());
4005 rerender = update_overlay = update_drag_toggleauto(get_cursor_x(), get_cursor_y());
4008 // Keyframe icons are sticky
4012 case DRAG_PLUGINKEY_PRE:
4013 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
4015 mwindow->session->current_operation++;
4023 rerender = update_overlay =
4024 update_drag_pluginauto(get_cursor_x(), get_cursor_y());
4027 case DRAG_PLUGINKEY:
4028 rerender = update_overlay =
4029 update_drag_pluginauto(get_cursor_x(), get_cursor_y());
4034 cursor_x = get_cursor_x();
4035 cursor_y = get_cursor_y();
4036 position = (double)(cursor_x + mwindow->edl->local_session->view_start) *
4037 mwindow->edl->local_session->zoom_sample /
4038 mwindow->edl->session->sample_rate;
4040 position = mwindow->edl->align_to_frame(position, 0);
4041 position = MAX(position, 0);
4043 if(position < selection_midpoint1)
4045 mwindow->edl->local_session->set_selectionend(selection_midpoint1);
4046 mwindow->edl->local_session->set_selectionstart(position);
4048 gui->unlock_window();
4049 mwindow->cwindow->update(1, 0, 0, 0, 1);
4050 gui->lock_window("TrackCanvas::cursor_motion_event 1");
4051 // Update the faders
4052 mwindow->update_plugin_guis();
4053 gui->patchbay->update();
4057 mwindow->edl->local_session->set_selectionstart(selection_midpoint1);
4058 mwindow->edl->local_session->set_selectionend(position);
4059 // Don't que the CWindow
4062 gui->cursor->hide(0);
4063 gui->cursor->draw(1);
4073 if(is_event_win() && cursor_inside())
4076 cursor_x = get_cursor_x();
4077 position = (double)cursor_x *
4078 (double)mwindow->edl->local_session->zoom_sample /
4079 (double)mwindow->edl->session->sample_rate +
4080 (double)mwindow->edl->local_session->view_start *
4081 (double)mwindow->edl->local_session->zoom_sample /
4082 (double)mwindow->edl->session->sample_rate;
4083 position = mwindow->edl->align_to_frame(position, 0);
4087 if(do_transitions(get_cursor_x(),
4097 if(do_keyframes(get_cursor_x(),
4109 if(do_edit_handles(get_cursor_x(),
4120 // Plugin boundaries
4121 if(do_plugin_handles(get_cursor_x(),
4132 if(do_edits(get_cursor_x(),
4147 //printf("TrackCanvas::cursor_motion_event 1\n");
4148 if(update_cursor && new_cursor != get_cursor())
4150 set_cursor(new_cursor);
4153 //printf("TrackCanvas::cursor_motion_event 1 %d\n", rerender);
4156 mwindow->restart_brender();
4157 mwindow->sync_parameters(CHANGE_PARAMS);
4158 mwindow->update_plugin_guis();
4159 gui->unlock_window();
4160 mwindow->cwindow->update(1, 0, 0, 0, 1);
4161 gui->lock_window("TrackCanvas::cursor_motion_event 2");
4163 gui->patchbay->update();
4169 if(!mwindow->cwindow->playback_engine->is_playing_back)
4170 gui->mainclock->update(position);
4175 gui->zoombar->update();
4181 (cursor_x >= get_w() || cursor_x < 0 || cursor_y >= get_h() || cursor_y < 0))
4185 (cursor_x < get_w() && cursor_x >= 0 && cursor_y < get_h() && cursor_y >= 0))
4196 //printf("TrackCanvas::cursor_motion_event 100\n");
4200 void TrackCanvas::start_dragscroll()
4205 set_repeat(BC_WindowBase::get_resources()->scroll_repeat);
4206 //printf("TrackCanvas::start_dragscroll 1\n");
4210 void TrackCanvas::stop_dragscroll()
4215 unset_repeat(BC_WindowBase::get_resources()->scroll_repeat);
4216 //printf("TrackCanvas::stop_dragscroll 1\n");
4220 int TrackCanvas::repeat_event(int64_t duration)
4222 if(!drag_scroll) return 0;
4223 if(duration != BC_WindowBase::get_resources()->scroll_repeat) return 0;
4225 int sample_movement = 0;
4226 int track_movement = 0;
4227 int64_t x_distance = 0;
4228 int64_t y_distance = 0;
4229 double position = 0;
4232 switch(mwindow->session->current_operation)
4235 //printf("TrackCanvas::repeat_event 1 %d\n", mwindow->edl->local_session->view_start);
4236 if(get_cursor_x() > get_w())
4238 x_distance = get_cursor_x() - get_w();
4239 sample_movement = 1;
4242 if(get_cursor_x() < 0)
4244 x_distance = get_cursor_x();
4245 sample_movement = 1;
4248 if(get_cursor_y() > get_h())
4250 y_distance = get_cursor_y() - get_h();
4254 if(get_cursor_y() < 0)
4256 y_distance = get_cursor_y();
4266 position = (double)(get_cursor_x() +
4267 mwindow->edl->local_session->view_start +
4269 mwindow->edl->local_session->zoom_sample /
4270 mwindow->edl->session->sample_rate;
4271 position = mwindow->edl->align_to_frame(position, 0);
4272 position = MAX(position, 0);
4274 //printf("TrackCanvas::repeat_event 1 %f\n", position);
4275 switch(mwindow->session->current_operation)
4278 if(position < selection_midpoint1)
4280 mwindow->edl->local_session->set_selectionend(selection_midpoint1);
4281 mwindow->edl->local_session->set_selectionstart(position);
4283 gui->unlock_window();
4284 mwindow->cwindow->update(1, 0, 0);
4285 gui->lock_window("TrackCanvas::repeat_event");
4286 // Update the faders
4287 mwindow->update_plugin_guis();
4288 gui->patchbay->update();
4292 mwindow->edl->local_session->set_selectionstart(selection_midpoint1);
4293 mwindow->edl->local_session->set_selectionend(position);
4294 // Don't que the CWindow
4299 mwindow->samplemovement(mwindow->edl->local_session->view_start +
4305 mwindow->trackmovement(mwindow->edl->local_session->track_start +
4312 int TrackCanvas::button_release_event()
4314 int redraw = 0, update_overlay = 0, result = 0;
4316 switch(mwindow->session->current_operation)
4318 case DRAG_EDITHANDLE2:
4319 mwindow->session->current_operation = NO_OPERATION;
4323 end_edithandle_selection();
4326 case DRAG_EDITHANDLE1:
4327 mwindow->session->current_operation = NO_OPERATION;
4332 case DRAG_PLUGINHANDLE2:
4333 mwindow->session->current_operation = NO_OPERATION;
4337 end_pluginhandle_selection();
4340 case DRAG_PLUGINHANDLE1:
4341 mwindow->session->current_operation = NO_OPERATION;
4347 // delete the drag_auto_gang first and remove out of order keys
4348 synchronize_autos(0, 0, 0, -1);
4359 case DRAG_PROJECTOR_X:
4360 case DRAG_PROJECTOR_Y:
4361 case DRAG_PROJECTOR_Z:
4362 case DRAG_PLUGINKEY:
4363 mwindow->session->current_operation = NO_OPERATION;
4364 mwindow->session->drag_handle = 0;
4365 // Remove any out-of-order keyframe
4366 if(mwindow->session->drag_auto)
4368 mwindow->session->drag_auto->autos->remove_nonsequential(
4369 mwindow->session->drag_auto);
4370 // mwindow->session->drag_auto->autos->optimize();
4373 mwindow->undo->update_undo(_("keyframe"), LOAD_AUTOMATION);
4378 case DRAG_AEFFECT_COPY:
4379 case DRAG_VEFFECT_COPY:
4380 // Trap in drag stop
4386 if(mwindow->session->current_operation)
4388 if(mwindow->session->current_operation == SELECT_REGION)
4390 mwindow->undo->update_undo(_("select"), LOAD_SESSION, 0, 0);
4393 mwindow->session->current_operation = NO_OPERATION;
4395 // Traps button release events
4401 cursor_motion_event();
4415 int TrackCanvas::do_edit_handles(int cursor_x,
4419 int &update_overlay,
4423 Edit *edit_result = 0;
4424 int handle_result = 0;
4427 if(!mwindow->edl->session->show_assets) return 0;
4429 for(Track *track = mwindow->edl->tracks->first;
4431 track = track->next)
4433 for(Edit *edit = track->edits->first;
4437 int64_t edit_x, edit_y, edit_w, edit_h;
4438 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
4440 if(cursor_x >= edit_x && cursor_x <= edit_x + edit_w &&
4441 cursor_y >= edit_y && cursor_y < edit_y + edit_h)
4443 if(cursor_x < edit_x + HANDLE_W)
4450 if(cursor_x >= edit_x + edit_w - HANDLE_W)
4468 if(handle_result == 0)
4470 position = edit_result->track->from_units(edit_result->startproject);
4471 new_cursor = LEFT_CURSOR;
4474 if(handle_result == 1)
4476 position = edit_result->track->from_units(edit_result->startproject + edit_result->length);
4477 new_cursor = RIGHT_CURSOR;
4480 // Reposition cursor
4483 mwindow->session->drag_edit = edit_result;
4484 mwindow->session->drag_handle = handle_result;
4485 mwindow->session->drag_button = get_buttonpress() - 1;
4486 mwindow->session->drag_position = position;
4487 mwindow->session->current_operation = DRAG_EDITHANDLE1;
4488 mwindow->session->drag_origin_x = get_cursor_x();
4489 mwindow->session->drag_origin_y = get_cursor_y();
4490 mwindow->session->drag_start = position;
4492 rerender = start_selection(position);
4500 int TrackCanvas::do_plugin_handles(int cursor_x,
4504 int &update_overlay,
4508 Plugin *plugin_result = 0;
4509 int handle_result = 0;
4512 if(!mwindow->edl->session->show_assets) return 0;
4514 for(Track *track = mwindow->edl->tracks->first;
4516 track = track->next)
4518 for(int i = 0; i < track->plugin_set.total && !result; i++)
4520 PluginSet *plugin_set = track->plugin_set.values[i];
4521 for(Plugin *plugin = (Plugin*)plugin_set->first;
4523 plugin = (Plugin*)plugin->next)
4525 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
4526 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
4528 if(cursor_x >= plugin_x && cursor_x <= plugin_x + plugin_w &&
4529 cursor_y >= plugin_y && cursor_y < plugin_y + plugin_h)
4531 if(cursor_x < plugin_x + HANDLE_W)
4533 plugin_result = plugin;
4538 if(cursor_x >= plugin_x + plugin_w - HANDLE_W)
4540 plugin_result = plugin;
4547 if(result && shift_down())
4548 mwindow->session->trim_edits = plugin_set;
4556 if(handle_result == 0)
4558 position = plugin_result->track->from_units(plugin_result->startproject);
4559 new_cursor = LEFT_CURSOR;
4562 if(handle_result == 1)
4564 position = plugin_result->track->from_units(plugin_result->startproject + plugin_result->length);
4565 new_cursor = RIGHT_CURSOR;
4570 mwindow->session->drag_plugin = plugin_result;
4571 mwindow->session->drag_handle = handle_result;
4572 mwindow->session->drag_button = get_buttonpress() - 1;
4573 mwindow->session->drag_position = position;
4574 mwindow->session->current_operation = DRAG_PLUGINHANDLE1;
4575 mwindow->session->drag_origin_x = get_cursor_x();
4576 mwindow->session->drag_origin_y = get_cursor_y();
4577 mwindow->session->drag_start = position;
4579 rerender = start_selection(position);
4588 int TrackCanvas::do_tracks(int cursor_x,
4595 if(!mwindow->edl->session->show_assets) return 0;
4598 for(Track *track = mwindow->edl->tracks->first;
4600 track = track->next)
4602 int64_t track_x, track_y, track_w, track_h;
4603 track_dimensions(track, track_x, track_y, track_w, track_h);
4606 get_buttonpress() == 3 &&
4607 cursor_y >= track_y &&
4608 cursor_y < track_y + track_h)
4610 gui->edit_menu->update(track, 0);
4611 gui->edit_menu->activate_menu();
4618 int TrackCanvas::do_edits(int cursor_x,
4628 int over_edit_handle = 0;
4630 if(!mwindow->edl->session->show_assets) return 0;
4632 for(Track *track = mwindow->edl->tracks->first;
4634 track = track->next)
4636 for(Edit *edit = track->edits->first;
4637 edit != track->edits->last && !result;
4640 int64_t edit_x, edit_y, edit_w, edit_h;
4641 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
4643 // Cursor inside a track
4644 // Cursor inside an edit
4645 if(cursor_x >= edit_x && cursor_x < edit_x + edit_w &&
4646 cursor_y >= edit_y && cursor_y < edit_y + edit_h)
4648 // Select duration of edit
4651 if(get_double_click() && !drag_start)
4653 mwindow->edl->local_session->set_selectionstart(edit->track->from_units(edit->startproject));
4654 mwindow->edl->local_session->set_selectionend(edit->track->from_units(edit->startproject) +
4655 edit->track->from_units(edit->length));
4656 if(mwindow->edl->session->cursor_on_frames)
4658 mwindow->edl->local_session->set_selectionstart(
4659 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionstart(1), 0));
4660 mwindow->edl->local_session->set_selectionend(
4661 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionend(1), 1));
4669 if(drag_start && track->record)
4671 if(mwindow->edl->session->editing_mode == EDITING_ARROW)
4673 // Need to create drag window
4674 mwindow->session->current_operation = DRAG_EDIT;
4675 mwindow->session->drag_edit = edit;
4676 //printf("TrackCanvas::do_edits 2\n");
4678 // Drag only one edit
4681 mwindow->session->drag_edits->remove_all();
4682 mwindow->session->drag_edits->append(edit);
4685 // Construct list of all affected edits
4687 mwindow->edl->tracks->get_affected_edits(
4688 mwindow->session->drag_edits,
4689 edit->track->from_units(edit->startproject),
4692 mwindow->session->drag_origin_x = cursor_x;
4693 mwindow->session->drag_origin_y = cursor_y;
4694 // Where the drag started, so we know relative position inside the edit later
4695 mwindow->session->drag_position = (double)cursor_x *
4696 mwindow->edl->local_session->zoom_sample /
4697 mwindow->edl->session->sample_rate +
4698 (double)mwindow->edl->local_session->view_start *
4699 mwindow->edl->local_session->zoom_sample /
4700 mwindow->edl->session->sample_rate;
4702 drag_popup = new BC_DragWindow(gui,
4703 mwindow->theme->get_image("clip_icon"),
4704 get_abs_cursor_x(0) - mwindow->theme->get_image("clip_icon")->get_w() / 2,
4705 get_abs_cursor_y(0) - mwindow->theme->get_image("clip_icon")->get_h() / 2);
4717 int TrackCanvas::test_resources(int cursor_x, int cursor_y)
4722 int TrackCanvas::do_plugins(int cursor_x,
4736 if(!mwindow->edl->session->show_assets) return 0;
4739 for(track = mwindow->edl->tracks->first;
4741 track = track->next)
4743 if(!track->expand_view) continue;
4746 for(int i = 0; i < track->plugin_set.total && !done; i++)
4748 // first check if plugins are visible at all
4749 if (!track->expand_view)
4751 PluginSet *plugin_set = track->plugin_set.values[i];
4752 for(plugin = (Plugin*)plugin_set->first;
4754 plugin = (Plugin*)plugin->next)
4756 plugin_dimensions(plugin, x, y, w, h);
4757 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
4758 MWindowGUI::visible(y, y + h, 0, get_h()))
4760 if(cursor_x >= x && cursor_x < x + w &&
4761 cursor_y >= y && cursor_y < y + h)
4773 // Start plugin popup
4776 if(get_buttonpress() == 3)
4778 gui->plugin_menu->update(plugin);
4779 gui->plugin_menu->activate_menu();
4783 // Select range of plugin on doubleclick over plugin
4784 if (get_double_click() && !drag_start)
4786 mwindow->edl->local_session->set_selectionstart(plugin->track->from_units(plugin->startproject));
4787 mwindow->edl->local_session->set_selectionend(plugin->track->from_units(plugin->startproject) +
4788 plugin->track->from_units(plugin->length));
4789 if(mwindow->edl->session->cursor_on_frames)
4791 mwindow->edl->local_session->set_selectionstart(
4792 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionstart(1), 0));
4793 mwindow->edl->local_session->set_selectionend(
4794 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionend(1), 1));
4803 if(drag_start && plugin->track->record)
4805 if(mwindow->edl->session->editing_mode == EDITING_ARROW)
4807 if(plugin->track->data_type == TRACK_AUDIO)
4808 mwindow->session->current_operation = DRAG_AEFFECT_COPY;
4810 if(plugin->track->data_type == TRACK_VIDEO)
4811 mwindow->session->current_operation = DRAG_VEFFECT_COPY;
4813 mwindow->session->drag_plugin = plugin;
4820 switch(plugin->plugin_type)
4822 case PLUGIN_STANDALONE:
4824 PluginServer *server = mwindow->scan_plugindb(
4826 plugin->track->data_type);
4829 VFrame *frame = server->picon;
4831 drag_popup = new BC_DragWindow(gui,
4833 get_abs_cursor_x(0) - frame->get_w() / 2,
4834 get_abs_cursor_y(0) - frame->get_h() / 2);
4839 case PLUGIN_SHAREDPLUGIN:
4840 case PLUGIN_SHAREDMODULE:
4841 drag_popup = new BC_DragWindow(gui,
4842 mwindow->theme->get_image("clip_icon"),
4843 get_abs_cursor_x(0) - mwindow->theme->get_image("clip_icon")->get_w() / 2,
4844 get_abs_cursor_y(0) - mwindow->theme->get_image("clip_icon")->get_h() / 2);
4857 int TrackCanvas::do_transitions(int cursor_x,
4863 Transition *transition = 0;
4869 if(!mwindow->edl->session->show_assets ||
4870 !mwindow->edl->session->auto_conf->transitions) return 0;
4874 for(Track *track = mwindow->edl->tracks->first;
4876 track = track->next)
4878 for(Edit *edit = track->edits->first;
4882 if(edit->transition)
4884 edit_dimensions(edit, x, y, w, h);
4885 get_transition_coords(x, y, w, h);
4887 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
4888 MWindowGUI::visible(y, y + h, 0, get_h()))
4890 if(cursor_x >= x && cursor_x < x + w &&
4891 cursor_y >= y && cursor_y < y + h)
4893 transition = edit->transition;
4907 new_cursor = UPRIGHT_ARROW_CURSOR;
4910 if(get_buttonpress() == 3)
4912 gui->transition_menu->update(transition);
4913 gui->transition_menu->activate_menu();
4920 int TrackCanvas::button_press_event()
4923 int cursor_x, cursor_y;
4924 int new_cursor, update_cursor;
4926 cursor_x = get_cursor_x();
4927 cursor_y = get_cursor_y();
4928 mwindow->session->trim_edits = 0;
4930 if(is_event_win() && cursor_inside())
4932 double position = (double)cursor_x *
4933 mwindow->edl->local_session->zoom_sample /
4934 mwindow->edl->session->sample_rate +
4935 (double)mwindow->edl->local_session->view_start *
4936 mwindow->edl->local_session->zoom_sample /
4937 mwindow->edl->session->sample_rate;
4945 if(get_buttonpress() == 1)
4947 gui->unlock_window();
4948 gui->mbuttons->transport->handle_transport(STOP, 1, 0, 0);
4949 gui->lock_window("TrackCanvas::button_press_event");
4952 int update_overlay = 0, update_cursor = 0, rerender = 0;
4954 if(get_buttonpress() == 4)
4957 mwindow->expand_sample();
4959 mwindow->move_up(get_h() / 10);
4963 if(get_buttonpress() == 5)
4966 mwindow->zoom_in_sample();
4968 mwindow->move_down(get_h() / 10);
4972 switch(mwindow->edl->session->editing_mode)
4974 // Test handles and resource boundaries and highlight a track
4979 if(mwindow->edl->session->auto_conf->transitions &&
4980 do_transitions(cursor_x,
4989 if(do_keyframes(cursor_x,
5000 // Test edit boundaries
5001 if(do_edit_handles(cursor_x,
5012 // Test plugin boundaries
5013 if(do_plugin_handles(cursor_x,
5024 if(do_edits(cursor_x, cursor_y, 1, 0, update_cursor, rerender, new_cursor, update_cursor))
5029 if(do_plugins(cursor_x, cursor_y, 0, 1, update_cursor, rerender))
5034 if(test_resources(cursor_x, cursor_y))
5039 if(do_tracks(cursor_x, cursor_y, 1))
5046 // Test handles only and select a region
5049 //printf("TrackCanvas::button_press_event %d\n", position);
5051 if(mwindow->edl->session->auto_conf->transitions &&
5052 do_transitions(cursor_x,
5061 if(do_keyframes(cursor_x,
5073 // Test edit boundaries
5074 if(do_edit_handles(cursor_x,
5085 // Test plugin boundaries
5086 if(do_plugin_handles(cursor_x,
5097 if(do_edits(cursor_x,
5109 if(do_plugins(cursor_x,
5119 if(do_tracks(cursor_x, cursor_y, 1))
5123 // Highlight selection
5127 rerender = start_selection(position);
5129 mwindow->session->current_operation = SELECT_REGION;
5141 gui->unlock_window();
5142 mwindow->cwindow->update(1, 0, 0, 0, 1);
5144 gui->lock_window("TrackCanvas::button_press_event 2");
5146 mwindow->update_plugin_guis();
5147 gui->patchbay->update();
5160 gui->timebar->update_highlights();
5161 gui->cursor->hide();
5162 gui->cursor->show();
5163 gui->zoombar->update();
5175 int TrackCanvas::start_selection(double position)
5178 position = mwindow->edl->align_to_frame(position, 0);
5184 double midpoint = (mwindow->edl->local_session->get_selectionstart(1) +
5185 mwindow->edl->local_session->get_selectionend(1)) / 2;
5187 if(position < midpoint)
5189 mwindow->edl->local_session->set_selectionstart(position);
5190 selection_midpoint1 = mwindow->edl->local_session->get_selectionend(1);
5196 mwindow->edl->local_session->set_selectionend(position);
5197 selection_midpoint1 = mwindow->edl->local_session->get_selectionstart(1);
5198 // Don't que the CWindow for the end
5202 // Start a new selection
5204 //printf("TrackCanvas::start_selection %f\n", position);
5205 mwindow->edl->local_session->set_selectionstart(position);
5206 mwindow->edl->local_session->set_selectionend(position);
5207 selection_midpoint1 = position;
5215 void TrackCanvas::end_edithandle_selection()
5217 mwindow->modify_edithandles();
5220 void TrackCanvas::end_pluginhandle_selection()
5222 mwindow->modify_pluginhandles();
5226 double TrackCanvas::time_visible()
5228 return (double)get_w() *
5229 mwindow->edl->local_session->zoom_sample /
5230 mwindow->edl->session->sample_rate;
5273 void TrackCanvas::draw_automation()
5278 int TrackCanvas::set_index_file(int flash, Asset *asset)
5284 int TrackCanvas::button_release()
5290 int TrackCanvas::auto_reposition(int &cursor_x, int &cursor_y, int64_t cursor_position)
5296 int TrackCanvas::draw_floating_handle(int flash)
5301 int TrackCanvas::draw_loop_point(int64_t position, int flash)
5306 int TrackCanvas::draw_playback_cursor(int pixel, int flash)
5312 int TrackCanvas::update_handle_selection(int64_t cursor_position)
5317 int TrackCanvas::end_translation()