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 "playbackengine.h"
37 #include "playtransport.h"
39 #include "pluginpopup.h"
40 #include "pluginset.h"
41 #include "pluginserver.h"
42 #include "preferences.h"
43 #include "resourcepixmap.h"
44 #include "mainsession.h"
45 #include "transitionhandles.h"
46 #include "transitionpopup.h"
47 #include "transportque.h"
51 #include "trackcanvas.h"
53 #include "transition.h"
55 #include "apatchgui.inc"
56 #include "vpatchgui.inc"
60 TrackCanvas::TrackCanvas(MWindow *mwindow, MWindowGUI *gui)
61 : BC_SubWindow(mwindow->theme->mcanvas_x,
62 mwindow->theme->mcanvas_y,
66 this->mwindow = mwindow;
69 selection_midpoint1 = selection_midpoint2 = 0;
74 translate_selected = 0;
81 resource_timer = new Timer;
82 hourglass_enabled = 0;
85 TrackCanvas::~TrackCanvas()
87 for(int i = 0; i < resource_pixmaps.total; i++)
88 delete resource_pixmaps.values[i];
89 // delete transition_handles;
91 delete keyframe_pixmap;
92 delete camerakeyframe_pixmap;
93 delete modekeyframe_pixmap;
94 delete pankeyframe_pixmap;
95 delete projectorkeyframe_pixmap;
96 delete maskkeyframe_pixmap;
97 delete background_pixmap;
98 if(temp_picon) delete temp_picon;
99 delete resource_timer;
102 int TrackCanvas::create_objects()
104 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
105 // transition_handles = new TransitionHandles(mwindow, this);
106 edit_handles = new EditHandles(mwindow, this);
107 keyframe_pixmap = new BC_Pixmap(this, mwindow->theme->keyframe_data, PIXMAP_ALPHA);
108 camerakeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->camerakeyframe_data, PIXMAP_ALPHA);
109 modekeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->modekeyframe_data, PIXMAP_ALPHA);
110 pankeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->pankeyframe_data, PIXMAP_ALPHA);
111 projectorkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->projectorkeyframe_data, PIXMAP_ALPHA);
112 maskkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->maskkeyframe_data, PIXMAP_ALPHA);
119 void TrackCanvas::resize_event()
121 //printf("TrackCanvas::resize_event 1\n");
124 //printf("TrackCanvas::resize_event 2\n");
127 int TrackCanvas::keypress_event()
135 int TrackCanvas::drag_motion()
137 int cursor_x = get_relative_cursor_x();
138 int cursor_y = get_relative_cursor_y();
139 Track *over_track = 0;
141 PluginSet *over_pluginset = 0;
142 Plugin *over_plugin = 0;
148 drag_popup->cursor_motion_event();
152 // there's no point in drawing highlights has until drag operation has been set
153 if (!mwindow->session->current_operation)
156 if(get_cursor_over_window() &&
159 cursor_x < get_w() &&
162 //printf("drag motion 1 %d\n", ctrl_down());
163 if(mwindow->session->free_drag) redraw = 1;
167 mwindow->session->free_drag = 1;
171 mwindow->session->free_drag = 0;
174 // Find the edit and track the cursor is over
175 for(Track *track = mwindow->edl->tracks->first; track; track = track->next)
177 int64_t track_x, track_y, track_w, track_h;
178 track_dimensions(track, track_x, track_y, track_w, track_h);
180 if(cursor_y >= track_y &&
181 cursor_y < track_y + track_h)
184 for(Edit *edit = track->edits->first; edit; edit = edit->next)
186 int64_t edit_x, edit_y, edit_w, edit_h;
187 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
189 if(cursor_x >= edit_x &&
190 cursor_y >= edit_y &&
191 cursor_x < edit_x + edit_w &&
192 cursor_y < edit_y + edit_h)
199 for(int i = 0; i < track->plugin_set.total; i++)
201 PluginSet *pluginset = track->plugin_set.values[i];
205 for(Plugin *plugin = (Plugin*)pluginset->first;
207 plugin = (Plugin*)plugin->next)
209 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
210 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
212 if(cursor_y >= plugin_y &&
213 cursor_y < plugin_y + plugin_h)
215 over_pluginset = plugin->plugin_set;
217 if(cursor_x >= plugin_x &&
218 cursor_x < plugin_x + plugin_w)
220 over_plugin = plugin;
231 if (!over_track) // check for pastes from patchbay
232 over_track = mwindow->gui->patchbay->is_over_track();
234 if(mwindow->session->track_highlighted != over_track)
236 mwindow->session->track_highlighted = over_track;
240 if(mwindow->session->edit_highlighted != over_edit)
242 mwindow->session->edit_highlighted = over_edit;
246 if(mwindow->session->pluginset_highlighted != over_pluginset)
248 mwindow->session->pluginset_highlighted = over_pluginset;
252 if(mwindow->session->plugin_highlighted != over_plugin)
254 mwindow->session->plugin_highlighted = over_plugin;
258 if (mwindow->session->current_operation == DRAG_ASSET ||
259 mwindow->session->current_operation == DRAG_EDIT)
265 //printf("TrackCanvas::drag_motion 2 %p\n", mwindow->session->track_highlighted);
268 lock_window("TrackCanvas::drag_motion");
277 int TrackCanvas::drag_start_event()
282 int new_cursor, update_cursor;
284 if(mwindow->session->current_operation != NO_OPERATION) return 0;
288 if(do_plugins(get_drag_x(),
298 if(do_edits(get_drag_x(),
311 if(result) mwindow->session->free_drag = ctrl_down();
316 int TrackCanvas::drag_motion_event()
318 return drag_motion();
321 int TrackCanvas::cursor_leave_event()
323 // Because drag motion calls get_cursor_over_window we can be sure that
324 // all highlights get deleted now.
325 // This ended up blocking keyboard input from the drag operations.
327 // return drag_motion();
331 int TrackCanvas::drag_stop_event()
333 int result = drag_stop();
344 int TrackCanvas::drag_stop()
346 // In most cases the editing routine redraws and not the drag_stop
347 int result = 0, redraw = 0;
349 int insertion = 0; // used in drag and drop mode
350 switch(mwindow->session->current_operation)
352 case DRAG_VTRANSITION:
353 case DRAG_ATRANSITION:
354 if(mwindow->session->edit_highlighted)
356 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
357 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
358 (mwindow->session->current_operation == DRAG_VTRANSITION &&
359 mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
361 mwindow->session->current_operation = NO_OPERATION;
362 mwindow->paste_transition();
372 // Behavior for dragged plugins is limited by the fact that a shared plugin
373 // can only refer to a standalone plugin that exists in the same position in
374 // time. Dragging a plugin from one point in time to another can't produce
375 // a shared plugin to the original plugin. In this case we relocate the
376 // plugin instead of sharing it.
377 case DRAG_AEFFECT_COPY:
378 case DRAG_VEFFECT_COPY:
379 if(mwindow->session->track_highlighted &&
380 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY &&
381 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
382 (mwindow->session->current_operation == DRAG_VEFFECT_COPY &&
383 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
385 mwindow->session->current_operation = NO_OPERATION;
387 // Insert shared plugin in source
388 if(mwindow->session->track_highlighted != mwindow->session->drag_plugin->track &&
389 !mwindow->session->plugin_highlighted &&
390 !mwindow->session->pluginset_highlighted)
392 // Move plugin if different startproject
393 mwindow->move_effect(mwindow->session->drag_plugin,
395 mwindow->session->track_highlighted,
400 // Move source to different location
401 if(mwindow->session->pluginset_highlighted)
403 //printf("TrackCanvas::drag_stop 6\n");
404 if(mwindow->session->plugin_highlighted)
406 mwindow->move_effect(mwindow->session->drag_plugin,
407 mwindow->session->plugin_highlighted->plugin_set,
409 mwindow->session->plugin_highlighted->startproject);
413 mwindow->move_effect(mwindow->session->drag_plugin,
414 mwindow->session->pluginset_highlighted,
416 mwindow->session->pluginset_highlighted->length());
421 // Move to a new plugin set between two edits
422 if(mwindow->session->edit_highlighted)
424 mwindow->move_effect(mwindow->session->drag_plugin,
426 mwindow->session->track_highlighted,
427 mwindow->session->edit_highlighted->startproject);
431 // Move to a new plugin set
432 if(mwindow->session->track_highlighted)
434 mwindow->move_effect(mwindow->session->drag_plugin,
436 mwindow->session->track_highlighted,
445 if(mwindow->session->track_highlighted &&
446 ((mwindow->session->current_operation == DRAG_AEFFECT &&
447 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
448 (mwindow->session->current_operation == DRAG_VEFFECT &&
449 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
451 // Drop all the effects
452 PluginSet *plugin_set = mwindow->session->pluginset_highlighted;
453 Track *track = mwindow->session->track_highlighted;
455 double length = track->get_length();
457 if(mwindow->session->plugin_highlighted)
459 start = track->from_units(mwindow->session->plugin_highlighted->startproject);
460 length = track->from_units(mwindow->session->plugin_highlighted->length);
461 if(length <= 0) length = track->get_length();
464 if(mwindow->session->pluginset_highlighted)
466 start = track->from_units(plugin_set->length());
467 length = track->get_length() - start;
468 if(length <= 0) length = track->get_length();
471 if(mwindow->edl->local_session->get_selectionend() >
472 mwindow->edl->local_session->get_selectionstart())
474 start = mwindow->edl->local_session->get_selectionstart();
475 length = mwindow->edl->local_session->get_selectionend() -
476 mwindow->edl->local_session->get_selectionstart();
478 // Move to a point between two edits
480 if(mwindow->session->edit_highlighted)
482 start = mwindow->session->track_highlighted->from_units(
483 mwindow->session->edit_highlighted->startproject);
484 length = mwindow->session->track_highlighted->from_units(
485 mwindow->session->edit_highlighted->length);
488 mwindow->insert_effects_canvas(start, length);
491 if (mwindow->session->track_highlighted)
492 result = 1; // we have to cleanup
496 if(mwindow->session->track_highlighted)
498 float asset_length_float;
499 int64_t asset_length_units;
500 int64_t position = 0;
502 if(mwindow->session->current_operation == DRAG_ASSET &&
503 mwindow->session->drag_assets->total)
505 Asset *asset = mwindow->session->drag_assets->values[0];
507 // we use video if we are over video and audio if we are over audio
508 if (asset->video_data && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
509 asset_length_float = asset->video_length / asset->frame_rate;
511 asset_length_float = asset->audio_length / asset->sample_rate;
513 if(mwindow->session->current_operation == DRAG_ASSET &&
514 mwindow->session->drag_clips->total)
516 EDL *clip = mwindow->session->drag_clips->values[0];
517 asset_length_float = clip->tracks->total_length();
520 asset_length_units = mwindow->session->track_highlighted->to_units(asset_length_float, 0);
521 position = get_drop_position (&insertion, NULL, asset_length_units);
525 break; // Do not do anything
528 double position_f = mwindow->session->track_highlighted->from_units(position);
529 Track *track = mwindow->session->track_highlighted;
533 // FIXME, we should create an mwindow/EDL method that overwrites, without clearing the keyframes and autos
534 // Unfortunately, this is _a lot_ of work to do right
535 mwindow->edl->tracks->clear(position_f,
536 position_f + asset_length_float, 0);
538 mwindow->paste_assets(position_f, track);
539 result = 1; // need to be one no matter what, since we have track highlited so we have to cleanup....
544 mwindow->session->current_operation = NO_OPERATION;
545 if(mwindow->session->track_highlighted)
547 if(mwindow->session->track_highlighted->data_type == mwindow->session->drag_edit->track->data_type)
549 int64_t position = 0;
551 position = get_drop_position (&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length);
556 break; // Do not do anything
560 if(mwindow->session->free_drag)
561 position_f = (double)(get_cursor_x() + mwindow->edl->local_session->view_start) *
562 mwindow->edl->local_session->zoom_sample /
563 mwindow->edl->session->sample_rate;
566 position = mwindow->session->edit_highlighted ?
567 mwindow->session->edit_highlighted->startproject :
568 mwindow->session->track_highlighted->edits->length();
569 position_f = mwindow->session->track_highlighted->from_units(position);
571 Track *track = mwindow->session->track_highlighted;
572 mwindow->move_edits(mwindow->session->drag_edits,
583 // since we don't have subwindows we have to terminate any drag operation
586 if (mwindow->session->track_highlighted
587 || mwindow->session->edit_highlighted
588 || mwindow->session->plugin_highlighted
589 || mwindow->session->pluginset_highlighted)
591 mwindow->session->track_highlighted = 0;
592 mwindow->session->edit_highlighted = 0;
593 mwindow->session->plugin_highlighted = 0;
594 mwindow->session->pluginset_highlighted = 0;
595 mwindow->session->current_operation = NO_OPERATION;
599 //printf("TrackCanvas::drag_stop %d %d\n", redraw, mwindow->session->current_operation);
602 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
603 gui->get_scrollbars();
605 gui->patchbay->update();
606 gui->cursor->update();
615 int64_t TrackCanvas::get_drop_position (int *is_insertion, Edit *moved_edit, int64_t moved_edit_length)
619 // get the canvas/track position
620 int cursor_x = get_relative_cursor_x();
621 double pos = (double)cursor_x *
622 mwindow->edl->local_session->zoom_sample /
623 mwindow->edl->session->sample_rate +
624 (double)mwindow->edl->local_session->view_start *
625 mwindow->edl->local_session->zoom_sample /
626 mwindow->edl->session->sample_rate;
627 // convert to track's units to operate with them
628 Track *track = mwindow->session->track_highlighted;
629 // cursor relative position - depending on where we started the drag inside the edit
630 int64_t cursor_position;
631 if (moved_edit) // relative cursor position depends upon grab point
632 cursor_position = track->to_units (pos - (mwindow->session->drag_position - moved_edit->track->from_units(moved_edit->startproject)), 1);
633 else // for clips and assets acts as they were grabbed in the middle
634 cursor_position = track->to_units (pos , 1) - moved_edit_length / 2;
636 // we use real cursor position for affinity calculations
637 int64_t real_cursor_position = track->to_units (pos, 0);
638 if (cursor_position < 0) cursor_position = 0;
639 if (real_cursor_position < 0) real_cursor_position = 0;
640 int64_t position = -1;
641 int64_t span_start = 0;
642 int64_t span_length = 0;
644 int last_ignore = 0; // used to make sure we can ignore the last edit if that is what we are dragging
646 if (!track->edits->last)
648 // No edits -> no problems!
649 position = cursor_position;
653 Edit *fake_edit = new Edit(mwindow->edl, track);
654 int last2 = 0; // last2 is a hack that let us make virtual edits at the end so thing works for last edit also
655 // we do this by appending two VERY long virtual edits at the end
657 for (Edit *edit = track->edits->first; edit || last2 < 2; )
660 if (!edit && last_ignore)
662 span_length += 100000000000000LL;
667 ((moved_edit && edit == moved_edit && edit->previous && !edit->previous->asset) ||
668 (moved_edit && edit->previous == moved_edit && !edit->asset)))
670 span_length += edit->length; // our fake edit spans over the edit we are moving
673 { // This is a virtual edit
674 fake_edit->startproject = span_start;
675 fake_edit->length = span_length;
676 int64_t edit_x, edit_y, edit_w, edit_h;
677 edit_dimensions(fake_edit, edit_x, edit_y, edit_w, edit_h);
678 if (labs(edit_x - cursor_x) < HANDLE_W) // cursor is close to the beginning of an edit -> insertion
681 position = span_start;
683 if (labs(edit_x + edit_w - cursor_x) < HANDLE_W) // cursor is close to the end of an edit -> insertion
686 position = span_start + span_length;
689 if (!span_asset && // we have enough empty space to position the edit where user wants
690 span_start <= cursor_position &&
691 span_start + span_length >= cursor_position + moved_edit_length)
693 position = cursor_position;
695 if (!span_asset & // we are inside an empty edit, but cannot push the edit as far as user wants, so 'resist moving it further'
696 real_cursor_position >= span_start &&
697 real_cursor_position < span_start + span_length &&
698 span_length >= moved_edit_length)
700 if (llabs(real_cursor_position - span_start) < llabs(real_cursor_position - span_start - span_length))
701 position = span_start;
703 position = span_start + span_length - moved_edit_length;
705 if (cursor_x > edit_x && cursor_x <= edit_x + edit_w / 2) // we are inside an nonempty edit, - snap to left
708 position = span_start;
710 if (cursor_x > edit_x + edit_w / 2 && cursor_x <= edit_x + edit_w) // we are inside an nonempty edit, - snap to right
713 position = span_start + span_length;
720 // This is the new edit
723 span_length = edit->length;
724 span_start = edit->startproject;
726 if (!edit->asset || (!moved_edit || moved_edit == edit))
728 if (moved_edit && moved_edit == edit)
736 span_start = span_length + span_start;
737 span_length = 100000000000000LL;
752 if (real_cursor_position == 0)
757 // printf("rcp: %lli, position: %lli, insertion: %i\n", real_cursor_position, position, *is_insertion);
763 void TrackCanvas::draw(int force, int hide_cursor)
765 // Swap pixmap layers
766 TRACE("TrackCanvas::draw 1")
767 if(get_w() != background_pixmap->get_w() ||
768 get_h() != background_pixmap->get_h())
770 delete background_pixmap;
771 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
774 TRACE("TrackCanvas::draw 10")
775 // Cursor disappears after resize when this is called.
776 // Cursor doesn't redraw after editing when this isn't called.
777 if(gui->cursor && hide_cursor) gui->cursor->hide();
778 TRACE("TrackCanvas::draw 20")
779 draw_top_background(get_parent(), 0, 0, get_w(), get_h(), background_pixmap);
780 TRACE("TrackCanvas::draw 30")
781 draw_resources(force);
782 TRACE("TrackCanvas::draw 40")
787 void TrackCanvas::update_cursor()
789 switch(mwindow->edl->session->editing_mode)
791 case EDITING_ARROW: set_cursor(ARROW_CURSOR); break;
792 case EDITING_IBEAM: set_cursor(IBEAM_CURSOR); break;
797 void TrackCanvas::test_timer()
799 if(resource_timer->get_difference() > 1000 &&
803 hourglass_enabled = 1;
808 void TrackCanvas::draw_indexes(Asset *asset)
810 // Don't redraw raw samples
811 if(asset->index_zoom > mwindow->edl->local_session->zoom_sample)
814 draw_resources(0, 1, asset);
822 void TrackCanvas::draw_resources(int force,
826 if(!mwindow->edl->session->show_assets) return;
828 resource_timer->update();
830 // Age resource pixmaps for deletion
832 for(int i = 0; i < resource_pixmaps.total; i++)
833 resource_pixmaps.values[i]->visible--;
836 resource_pixmaps.remove_all_objects();
840 for(Track *current = mwindow->edl->tracks->first;
844 for(Edit *edit = current->edits->first; edit; edit = edit->next)
846 if(!edit->asset) continue;
849 if(edit->track->data_type != TRACK_AUDIO) continue;
850 if(!edit->asset->test_path(index_asset->path)) continue;
853 int64_t edit_x, edit_y, edit_w, edit_h;
854 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
857 if(MWindowGUI::visible(edit_x, edit_x + edit_w, 0, get_w()) &&
858 MWindowGUI::visible(edit_y, edit_y + edit_h, 0, get_h()))
860 int64_t pixmap_x, pixmap_w, pixmap_h;
862 // Search for existing pixmap containing edit
863 for(int i = 0; i < resource_pixmaps.total; i++)
865 ResourcePixmap* pixmap = resource_pixmaps.values[i];
866 // Same pointer can be different edit if editing took place
867 if(pixmap->edit_id == edit->id)
874 // Get new size, offset of pixmap needed
875 get_pixmap_size(edit,
883 if(pixmap_w && pixmap_h)
885 // Create pixmap if it doesn't exist
886 ResourcePixmap* pixmap = create_pixmap(edit,
891 // Resize it if it's bigger
892 if(pixmap_w > pixmap->pixmap_w ||
893 pixmap_h > pixmap->pixmap_h)
894 pixmap->resize(pixmap_w, pixmap_h);
895 pixmap->draw_data(edit,
903 // Resize it if it's smaller
904 if(pixmap_w < pixmap->pixmap_w ||
905 pixmap_h < pixmap->pixmap_h)
906 pixmap->resize(pixmap_w, pixmap_h);
907 // Copy pixmap to background canvas
908 background_pixmap->draw_pixmap(pixmap,
918 // Delete unused pixmaps
920 for(int i = resource_pixmaps.total - 1; i >= 0; i--)
921 if(resource_pixmaps.values[i]->visible < -5)
923 delete resource_pixmaps.values[i];
924 resource_pixmaps.remove(resource_pixmaps.values[i]);
927 if(hourglass_enabled)
930 hourglass_enabled = 0;
934 ResourcePixmap* TrackCanvas::create_pixmap(Edit *edit,
940 ResourcePixmap *result = 0;
942 for(int i = 0; i < resource_pixmaps.total; i++)
944 //printf("TrackCanvas::create_pixmap 1 %d %d\n", edit->id, resource_pixmaps.values[i]->edit->id);
945 if(resource_pixmaps.values[i]->edit_id == edit->id)
947 result = resource_pixmaps.values[i];
954 //printf("TrackCanvas::create_pixmap 2\n");
955 result = new ResourcePixmap(mwindow,
960 resource_pixmaps.append(result);
963 // result->resize(pixmap_w, pixmap_h);
967 void TrackCanvas::get_pixmap_size(Edit *edit,
975 // Align x on frame boundaries
978 // switch(edit->edits->track->data_type)
990 if(pixmap_x + pixmap_w > get_w())
992 pixmap_w = get_w() - pixmap_x;
999 // int64_t picon_w = (int64_t)(edit->picon_w() + 0.5);
1000 // int64_t frame_w = (int64_t)(edit->frame_w() + 0.5);
1001 // int64_t pixel_increment = MAX(picon_w, frame_w);
1002 // int64_t pixmap_x1 = edit_x;
1003 // int64_t pixmap_x2 = edit_x + edit_w;
1005 // if(pixmap_x1 < 0)
1007 // pixmap_x1 = (int64_t)((double)-edit_x / pixel_increment) *
1008 // pixel_increment +
1012 // if(pixmap_x2 > get_w())
1014 // pixmap_x2 = (int64_t)((double)(get_w() - edit_x) / pixel_increment + 1) *
1015 // pixel_increment +
1018 // pixmap_x = pixmap_x1;
1019 // pixmap_w = pixmap_x2 - pixmap_x1;
1024 pixmap_h = mwindow->edl->local_session->zoom_track;
1025 if(mwindow->edl->session->show_titles) pixmap_h += mwindow->theme->title_bg_data->get_h();
1026 //printf("get_pixmap_size %d %d %d %d\n", edit_x, edit_w, pixmap_x, pixmap_w);
1029 void TrackCanvas::edit_dimensions(Edit *edit,
1035 // w = Units::round(edit->track->from_units(edit->length) *
1036 // mwindow->edl->session->sample_rate /
1037 // mwindow->edl->local_session->zoom_sample);
1041 x = Units::round(edit->track->from_units(edit->startproject) *
1042 mwindow->edl->session->sample_rate /
1043 mwindow->edl->local_session->zoom_sample -
1044 mwindow->edl->local_session->view_start);
1046 // Method for calculating w so when edits are together we never get off by one error due to rounding
1047 int64_t x_next = Units::round(edit->track->from_units(edit->startproject + edit->length) *
1048 mwindow->edl->session->sample_rate /
1049 mwindow->edl->local_session->zoom_sample -
1050 mwindow->edl->local_session->view_start);
1053 y = edit->edits->track->y_pixel;
1055 if(mwindow->edl->session->show_titles)
1056 h += mwindow->theme->title_bg_data->get_h();
1059 void TrackCanvas::track_dimensions(Track *track, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1064 h = track->vertical_span(mwindow->theme);
1068 void TrackCanvas::draw_paste_destination()
1070 int current_atrack = 0;
1071 int current_vtrack = 0;
1072 int current_aedit = 0;
1073 int current_vedit = 0;
1080 if((mwindow->session->current_operation == DRAG_ASSET &&
1081 (mwindow->session->drag_assets->total ||
1082 mwindow->session->drag_clips->total)) ||
1083 (mwindow->session->current_operation == DRAG_EDIT &&
1084 mwindow->session->drag_edits->total))
1091 if(mwindow->session->current_operation == DRAG_ASSET &&
1092 mwindow->session->drag_assets->total)
1093 asset = mwindow->session->drag_assets->values[0];
1095 if(mwindow->session->current_operation == DRAG_ASSET &&
1096 mwindow->session->drag_clips->total)
1097 clip = mwindow->session->drag_clips->values[0];
1099 // Get destination track
1100 for(Track *dest = mwindow->session->track_highlighted;
1106 // Get source width in pixels
1109 // Use current cursor position
1110 if(mwindow->session->free_drag)
1111 position = (double)(get_cursor_x() + mwindow->edl->local_session->view_start) *
1112 mwindow->edl->local_session->zoom_sample /
1113 mwindow->edl->session->sample_rate;
1115 // Use start of highlighted edit
1116 if(mwindow->session->edit_highlighted)
1117 position = mwindow->session->track_highlighted->from_units(
1118 mwindow->session->edit_highlighted->startproject);
1120 // Use end of highlighted track, disregarding effects
1121 position = mwindow->session->track_highlighted->from_units(
1122 mwindow->session->track_highlighted->edits->length());
1125 if(dest->data_type == TRACK_AUDIO)
1127 if(asset && current_atrack < asset->channels)
1130 w = Units::to_int64((double)asset->audio_length /
1131 asset->sample_rate *
1132 mwindow->edl->session->sample_rate /
1133 mwindow->edl->local_session->zoom_sample);
1135 // FIXME: more obvious, get_drop_position should be called only ONCE - for highlighted track
1136 int64_t asset_length;
1137 // we use video if we are over video and audio if we are over audio
1138 if (asset->video_data && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
1139 asset_length = mwindow->session->track_highlighted->to_units(asset->video_length / asset->frame_rate, 0);
1141 asset_length = mwindow->session->track_highlighted->to_units(asset->audio_length / asset->sample_rate, 0);
1143 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1153 if(clip && current_atrack < clip->tracks->total_audio_tracks())
1155 w = Units::to_int64((double)clip->tracks->total_length() *
1156 mwindow->edl->session->sample_rate /
1157 mwindow->edl->local_session->zoom_sample);
1158 //printf("draw_paste_destination %d\n", x);
1159 int64_t asset_length = mwindow->session->track_highlighted->to_units((double)clip->tracks->total_length(), 0);
1161 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1171 if(mwindow->session->current_operation == DRAG_EDIT &&
1172 current_aedit < mwindow->session->drag_edits->total)
1175 while(current_aedit < mwindow->session->drag_edits->total &&
1176 mwindow->session->drag_edits->values[current_aedit]->track->data_type != TRACK_AUDIO)
1179 if(current_aedit < mwindow->session->drag_edits->total)
1181 edit = mwindow->session->drag_edits->values[current_aedit];
1182 w = Units::to_int64(edit->length / mwindow->edl->local_session->zoom_sample);
1184 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length));
1197 if(dest->data_type == TRACK_VIDEO)
1199 //printf("draw_paste_destination 1\n");
1200 if(asset && current_vtrack < asset->layers)
1202 w = Units::to_int64((double)asset->video_length /
1204 mwindow->edl->session->sample_rate /
1205 mwindow->edl->local_session->zoom_sample);
1206 int64_t asset_length = mwindow->session->track_highlighted->to_units((double)asset->video_length /
1207 asset->frame_rate, 0);
1209 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1219 if(clip && current_vtrack < clip->tracks->total_video_tracks())
1221 w = Units::to_int64(clip->tracks->total_length() *
1222 mwindow->edl->session->sample_rate /
1223 mwindow->edl->local_session->zoom_sample);
1224 int64_t asset_length = mwindow->session->track_highlighted->to_units((double)clip->tracks->total_length(), 0);
1226 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1236 if(mwindow->session->current_operation == DRAG_EDIT &&
1237 current_vedit < mwindow->session->drag_edits->total)
1240 while(current_vedit < mwindow->session->drag_edits->total &&
1241 mwindow->session->drag_edits->values[current_vedit]->track->data_type != TRACK_VIDEO)
1244 if(current_vedit < mwindow->session->drag_edits->total)
1246 edit = mwindow->session->drag_edits->values[current_vedit];
1247 w = Units::to_int64(edit->track->from_units(edit->length) *
1248 mwindow->edl->session->sample_rate /
1249 mwindow->edl->local_session->zoom_sample);
1251 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length));
1266 // Get the x coordinate
1267 x = Units::to_int64(position *
1268 mwindow->edl->session->sample_rate /
1269 mwindow->edl->local_session->zoom_sample) -
1270 mwindow->edl->local_session->view_start;
1271 int y = dest->y_pixel;
1272 int h = dest->vertical_span(mwindow->theme);
1275 //printf("TrackCanvas::draw_paste_destination 2 %d %d %d %d\n", x, y, w, h);
1277 draw_highlight_insertion(x, y, w, h);
1279 draw_highlight_rectangle(x, y, w, h);
1288 void TrackCanvas::plugin_dimensions(Plugin *plugin, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1290 x = Units::round(plugin->track->from_units(plugin->startproject) *
1291 mwindow->edl->session->sample_rate /
1292 mwindow->edl->local_session->zoom_sample -
1293 mwindow->edl->local_session->view_start);
1294 w = Units::round(plugin->track->from_units(plugin->length) *
1295 mwindow->edl->session->sample_rate /
1296 mwindow->edl->local_session->zoom_sample);
1297 y = plugin->track->y_pixel +
1298 mwindow->edl->local_session->zoom_track +
1299 plugin->plugin_set->get_number() *
1300 mwindow->theme->plugin_bg_data->get_h();
1301 if(mwindow->edl->session->show_titles)
1302 y += mwindow->theme->title_bg_data->get_h();
1303 h = mwindow->theme->plugin_bg_data->get_h();
1306 int TrackCanvas::resource_h()
1308 return mwindow->edl->local_session->zoom_track;
1311 void TrackCanvas::draw_highlight_rectangle(int x, int y, int w, int h)
1314 // if we have to draw a highlighted rectangle completely on the left or completely on the right of the viewport,
1315 // just draw arrows, so user has indication that something is there
1316 // FIXME: get better colors
1320 draw_triangle_left(0, y + h /6, h * 2/3, h * 2/3, BLACK, GREEN, YELLOW, RED, BLUE);
1325 draw_triangle_right(get_w() - h * 2/3, y + h /6, h * 2/3, h * 2/3, BLACK, GREEN, YELLOW, RED, BLUE);
1329 // Fix bug in heroines & cvs version as of 22.8.2005:
1330 // If we grab when zoomed in and zoom out while dragging, when edit gets really narrow strange things start happening
1331 if (w >= 0 && w < 3) {x -= w /2; w = 3;};
1342 w = MIN(w, get_w() + 20);
1343 h = MIN(h, get_h() + 20);
1346 draw_rectangle(x, y, w, h);
1347 draw_rectangle(x + 1, y + 1, w - 2, h - 2);
1349 //printf("TrackCanvas::draw_highlight_rectangle %d %d %d %d\n", x, y, w, h);
1352 void TrackCanvas::draw_highlight_insertion(int x, int y, int w, int h)
1355 // if we have to draw a highlighted rectangle completely on the left or completely on the right of the viewport,
1356 // just draw arrows, so user has indication that something is there
1357 // FIXME: get better colors
1366 /* these don't look so good
1368 draw_line(x, y, x, y+h);
1369 draw_line(x - h2 * 2, y + h1*2, x - h2, y+h1*2);
1370 draw_line(x - h2 * 2, y + h1*2+1, x - h2, y+h1*2+1);
1371 draw_line(x - h2 * 2, y + h1*6, x - h2, y+h1*6);
1372 draw_line(x - h2 * 2, y + h1*6+1, x - h2, y+h1*6+1);
1374 draw_triangle_right(x - h2, y + h1, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1375 draw_triangle_right(x - h2, y + h1*5, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1377 /* draw_line(x + h2 * 2, y + h1*2, x + h2, y+h1*2);
1378 draw_line(x + h2 * 2, y + h1*2+1, x + h2, y+h1*2+1);
1379 draw_line(x + h2 * 2, y + h1*6, x + h2, y+h1*6);
1380 draw_line(x - h2 * 2, y + h1*6+1, x + h2, y+h1*6+1);
1382 draw_triangle_left(x, y + h1, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1383 draw_triangle_left(x, y + h1*5, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1385 // draw the box centred around x
1387 // Fix bug in heroines & cvs version as of 22.8.2005:
1388 // If we grab when zoomed in and zoom out while dragging, when edit gets really narrow strange things start happening
1389 if (w >= 0 && w < 3) {x -= w /2; w = 3;};
1400 w = MIN(w, get_w() + 20);
1401 h = MIN(h, get_h() + 20);
1404 draw_rectangle(x, y, w, h);
1405 draw_rectangle(x + 1, y + 1, w - 2, h - 2);
1407 //printf("TrackCanvas::draw_highlight_insertion %d %d %d %d\n", x, y, w, h);
1410 void TrackCanvas::draw_playback_cursor()
1412 // Called before playback_cursor exists
1413 // if(mwindow->playback_cursor && mwindow->playback_cursor->visible)
1415 // mwindow->playback_cursor->visible = 0;
1416 // mwindow->playback_cursor->draw();
1420 void TrackCanvas::get_handle_coords(Edit *edit, int64_t &x, int64_t &y, int64_t &w, int64_t &h, int side)
1422 int handle_w = mwindow->theme->edithandlein_data[0]->get_w();
1423 int handle_h = mwindow->theme->edithandlein_data[0]->get_h();
1425 edit_dimensions(edit, x, y, w, h);
1427 if(mwindow->edl->session->show_titles)
1429 y += mwindow->theme->title_bg_data->get_h();
1436 if(side == EDIT_OUT)
1445 void TrackCanvas::get_transition_coords(int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1447 //printf("TrackCanvas::get_transition_coords 1\n");
1448 // int transition_w = mwindow->theme->transitionhandle_data[0]->get_w();
1449 // int transition_h = mwindow->theme->transitionhandle_data[0]->get_h();
1450 int transition_w = 30;
1451 int transition_h = 30;
1452 //printf("TrackCanvas::get_transition_coords 1\n");
1454 if(mwindow->edl->session->show_titles)
1455 y += mwindow->theme->title_bg_data->get_h();
1456 //printf("TrackCanvas::get_transition_coords 2\n");
1458 y += (h - mwindow->theme->title_bg_data->get_h()) / 2 - transition_h / 2;
1459 x -= transition_w / 2;
1465 void TrackCanvas::draw_highlighting()
1473 switch(mwindow->session->current_operation)
1475 case DRAG_ATRANSITION:
1476 case DRAG_VTRANSITION:
1477 //printf("TrackCanvas::draw_highlighting 1 %p %p\n",
1478 // mwindow->session->track_highlighted, mwindow->session->edit_highlighted);
1479 if(mwindow->session->edit_highlighted)
1481 //printf("TrackCanvas::draw_highlighting 2\n");
1482 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
1483 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1484 (mwindow->session->current_operation == DRAG_VTRANSITION &&
1485 mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
1487 //printf("TrackCanvas::draw_highlighting 2\n");
1488 edit_dimensions(mwindow->session->edit_highlighted, x, y, w, h);
1489 //printf("TrackCanvas::draw_highlighting 2\n");
1491 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1492 MWindowGUI::visible(y, y + h, 0, get_h()))
1495 get_transition_coords(x, y, w, h);
1497 //printf("TrackCanvas::draw_highlighting 3\n");
1504 // Dragging a new effect from the Resource window
1507 if(mwindow->session->track_highlighted &&
1508 ((mwindow->session->current_operation == DRAG_AEFFECT && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1509 (mwindow->session->current_operation == DRAG_VEFFECT && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
1511 // Put it before another plugin
1512 if(mwindow->session->plugin_highlighted)
1514 plugin_dimensions(mwindow->session->plugin_highlighted,
1519 //printf("TrackCanvas::draw_highlighting 1 %d %d\n", x, w);
1522 // Put it after a plugin set
1523 if(mwindow->session->pluginset_highlighted &&
1524 mwindow->session->pluginset_highlighted->last)
1526 plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last,
1531 //printf("TrackCanvas::draw_highlighting 1 %d %d\n", x, w);
1532 int64_t track_x, track_y, track_w, track_h;
1533 track_dimensions(mwindow->session->track_highlighted,
1541 mwindow->session->track_highlighted->get_length() *
1542 mwindow->edl->session->sample_rate /
1543 mwindow->edl->local_session->zoom_sample -
1544 mwindow->edl->local_session->view_start) -
1546 //printf("TrackCanvas::draw_highlighting 2 %d\n", w);
1547 if(w <= 0) w = track_w;
1551 track_dimensions(mwindow->session->track_highlighted,
1557 //printf("TrackCanvas::draw_highlighting 1 %d %d %d %d\n", x, y, w, h);
1558 // Put it in a new plugin set determined by the selected range
1559 if(mwindow->edl->local_session->get_selectionend() >
1560 mwindow->edl->local_session->get_selectionstart())
1562 x = Units::to_int64(mwindow->edl->local_session->get_selectionstart() *
1563 mwindow->edl->session->sample_rate /
1564 mwindow->edl->local_session->zoom_sample -
1565 mwindow->edl->local_session->view_start);
1566 w = Units::to_int64((mwindow->edl->local_session->get_selectionend() -
1567 mwindow->edl->local_session->get_selectionstart()) *
1568 mwindow->edl->session->sample_rate /
1569 mwindow->edl->local_session->zoom_sample);
1571 // Put it in a new plugin set determined by an edit boundary
1573 if(mwindow->session->edit_highlighted)
1575 int64_t temp_y, temp_h;
1576 edit_dimensions(mwindow->session->edit_highlighted,
1582 // Put it at the beginning of the track in a new plugin set
1585 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1586 MWindowGUI::visible(y, y + h, 0, get_h()))
1588 //printf("TrackCanvas::draw_highlighting 1\n");
1595 if(mwindow->session->track_highlighted)
1597 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1599 if(MWindowGUI::visible(y, y + h, 0, get_h()))
1601 draw_paste_destination();
1606 // Dragging an effect from the timeline
1607 case DRAG_AEFFECT_COPY:
1608 case DRAG_VEFFECT_COPY:
1609 if((mwindow->session->plugin_highlighted || mwindow->session->track_highlighted) &&
1610 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1611 (mwindow->session->current_operation == DRAG_VEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
1613 // Put it before another plugin
1614 if(mwindow->session->plugin_highlighted)
1615 plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
1617 // Put it after a plugin set
1618 if(mwindow->session->pluginset_highlighted &&
1619 mwindow->session->pluginset_highlighted->last)
1621 plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last, x, y, w, h);
1625 if(mwindow->session->track_highlighted)
1627 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1629 // Put it in a new plugin set determined by an edit boundary
1630 if(mwindow->session->edit_highlighted)
1632 int64_t temp_y, temp_h;
1633 edit_dimensions(mwindow->session->edit_highlighted,
1639 // Put it in a new plugin set at the start of the track
1642 // Calculate length of plugin based on data type of track and units
1643 if(mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
1645 w = (int64_t)((double)mwindow->session->drag_plugin->length /
1646 mwindow->edl->session->frame_rate *
1647 mwindow->edl->session->sample_rate /
1648 mwindow->edl->local_session->zoom_sample);
1652 w = (int64_t)mwindow->session->drag_plugin->length /
1653 mwindow->edl->local_session->zoom_sample;
1656 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1657 MWindowGUI::visible(y, y + h, 0, get_h()))
1664 case DRAG_PLUGINKEY:
1665 if(mwindow->session->plugin_highlighted &&
1666 mwindow->session->current_operation == DRAG_PLUGINKEY)
1668 // Just highlight the plugin
1669 plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
1671 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1672 MWindowGUI::visible(y, y + h, 0, get_h()))
1680 if(mwindow->session->track_highlighted)
1682 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1684 if(MWindowGUI::visible(y, y + h, 0, get_h()))
1686 draw_paste_destination();
1695 draw_highlight_rectangle(x, y, w, h);
1699 void TrackCanvas::draw_plugins()
1701 char string[BCTEXTLEN];
1703 if(!mwindow->edl->session->show_assets) return;
1705 for(Track *track = mwindow->edl->tracks->first;
1707 track = track->next)
1709 if(track->expand_view)
1711 for(int i = 0; i < track->plugin_set.total; i++)
1713 PluginSet *pluginset = track->plugin_set.values[i];
1715 for(Plugin *plugin = (Plugin*)pluginset->first; plugin; plugin = (Plugin*)plugin->next)
1717 int64_t total_x, y, total_w, h;
1718 plugin_dimensions(plugin, total_x, y, total_w, h);
1720 if(MWindowGUI::visible(total_x, total_x + total_w, 0, get_w()) &&
1721 MWindowGUI::visible(y, y + h, 0, get_h()) &&
1722 plugin->plugin_type != PLUGIN_NONE)
1724 int x = total_x, w = total_w, left_margin = 5;
1730 if(w + x > get_w()) w -= (w + x) - get_w();
1737 mwindow->theme->plugin_bg_data,
1740 set_font(MEDIUMFONT_3D);
1741 plugin->calculate_title(string, 0);
1743 // Truncate string to int64_test visible in background
1744 int len = strlen(string), j;
1745 for(j = len; j >= 0; j--)
1747 if(left_margin + get_text_width(MEDIUMFONT_3D, string) > w)
1755 // Justify the text on the left boundary of the edit if it is visible.
1756 // Otherwise justify it on the left side of the screen.
1757 int text_x = total_x + left_margin;
1758 text_x = MAX(left_margin, text_x);
1760 y + get_text_ascent(MEDIUMFONT_3D) + 2,
1772 void TrackCanvas::draw_inout_points()
1777 void TrackCanvas::draw_drag_handle()
1779 if(mwindow->session->current_operation == DRAG_EDITHANDLE2 ||
1780 mwindow->session->current_operation == DRAG_PLUGINHANDLE2)
1782 //printf("TrackCanvas::draw_drag_handle 1 %ld %ld\n", mwindow->session->drag_sample, mwindow->edl->local_session->view_start);
1783 int64_t pixel1 = Units::round(mwindow->session->drag_position *
1784 mwindow->edl->session->sample_rate /
1785 mwindow->edl->local_session->zoom_sample -
1786 mwindow->edl->local_session->view_start);
1787 //printf("TrackCanvas::draw_drag_handle 2 %d\n", pixel1);
1790 //printf("TrackCanvas::draw_drag_handle 3\n");
1791 draw_line(pixel1, 0, pixel1, get_h());
1793 //printf("TrackCanvas::draw_drag_handle 4\n");
1798 void TrackCanvas::draw_transitions()
1802 if(!mwindow->edl->session->show_assets) return;
1804 for(Track *track = mwindow->edl->tracks->first;
1806 track = track->next)
1808 for(Edit *edit = track->edits->first;
1812 if(edit->transition)
1814 int64_t strip_w, strip_x, strip_y;
1815 edit_dimensions(edit, x, y, w, h);
1818 if(mwindow->edl->session->show_titles)
1819 strip_y += mwindow->theme->title_bg_data->get_h();
1821 get_transition_coords(x, y, w, h);
1822 strip_w = Units::round(edit->track->from_units(edit->transition->length) *
1823 mwindow->edl->session->sample_rate /
1824 mwindow->edl->local_session->zoom_sample);
1826 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1827 MWindowGUI::visible(y, y + h, 0, get_h()))
1829 PluginServer *server = mwindow->scan_plugindb(edit->transition->title,
1831 draw_vframe(server->picon,
1838 server->picon->get_w(),
1839 server->picon->get_h());
1841 if(MWindowGUI::visible(strip_x, strip_x + strip_w, 0, get_w()) &&
1842 MWindowGUI::visible(strip_y, strip_y + h, 0, get_h()))
1844 int x = strip_x, w = strip_w, left_margin = 5;
1850 if(w + x > get_w()) w -= (w + x) - get_w();
1858 mwindow->theme->plugin_bg_data,
1867 void TrackCanvas::draw_loop_points()
1869 //printf("TrackCanvas::draw_loop_points 1\n");
1870 if(mwindow->edl->local_session->loop_playback)
1872 //printf("TrackCanvas::draw_loop_points 2\n");
1873 int64_t x = Units::round(mwindow->edl->local_session->loop_start *
1874 mwindow->edl->session->sample_rate /
1875 mwindow->edl->local_session->zoom_sample -
1876 mwindow->edl->local_session->view_start);
1877 //printf("TrackCanvas::draw_loop_points 3\n");
1879 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1882 draw_line(x, 0, x, get_h());
1884 //printf("TrackCanvas::draw_loop_points 4\n");
1886 x = Units::round(mwindow->edl->local_session->loop_end *
1887 mwindow->edl->session->sample_rate /
1888 mwindow->edl->local_session->zoom_sample -
1889 mwindow->edl->local_session->view_start);
1890 //printf("TrackCanvas::draw_loop_points 5\n");
1892 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1895 draw_line(x, 0, x, get_h());
1897 //printf("TrackCanvas::draw_loop_points 6\n");
1899 //printf("TrackCanvas::draw_loop_points 7\n");
1902 void TrackCanvas::draw_brender_start()
1904 if(mwindow->preferences->use_brender)
1906 int64_t x = Units::round(mwindow->edl->session->brender_start *
1907 mwindow->edl->session->sample_rate /
1908 mwindow->edl->local_session->zoom_sample -
1909 mwindow->edl->local_session->view_start);
1911 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1914 draw_line(x, 0, x, get_h());
1919 static int auto_colors[] =
1935 // The operations which correspond to each automation type
1936 static int auto_operations[] =
1952 // The buttonpress operations, so nothing changes unless the mouse moves
1953 // a certain amount. This allows the keyframe to be used to position the
1954 // insertion point without moving itself.
1955 static int pre_auto_operations[] =
1972 int TrackCanvas::do_keyframes(int cursor_x,
1980 // Note: button 3 (right mouse button) is not eaten to allow
1981 // track context menu to appear
1982 int current_tool = 0;
1984 EDLSession *session = mwindow->edl->session;
1987 if(buttonpress == 3)
1995 BC_Pixmap *auto_pixmaps[] =
2006 modekeyframe_pixmap,
2007 maskkeyframe_pixmap,
2013 for(Track *track = mwindow->edl->tracks->first;
2015 track = track->next)
2017 Auto *auto_keyframe;
2018 Automation *automation = track->automation;
2021 // Handle float autos
2022 for(int i = 0; i < AUTOMATION_TOTAL && !result; i++)
2024 // Event not trapped and automation visible
2025 Autos *autos = automation->autos[i];
2026 if(!result && session->auto_conf->autos[i] && autos)
2030 case AUTOMATION_MODE:
2031 result = do_autos(track,
2032 automation->autos[i],
2042 switch(autos->get_type())
2044 case AUTOMATION_TYPE_FLOAT:
2045 result = do_float_autos(track,
2055 case AUTOMATION_TYPE_INT:
2056 result = do_toggle_autos(track,
2073 if(mwindow->session->current_operation == auto_operations[i])
2077 if(i == AUTOMATION_FADE)
2078 synchronize_autos(0,
2080 (FloatAuto*)mwindow->session->drag_auto,
2082 mwindow->session->current_operation = pre_auto_operations[i];
2083 update_drag_caption();
2093 session->auto_conf->plugins &&
2094 mwindow->edl->session->show_assets)
2098 result = do_plugin_autos(track,
2105 if(result && mwindow->session->current_operation == DRAG_PLUGINKEY)
2109 if(result && (buttonpress == 1))
2111 mwindow->session->current_operation = DRAG_PLUGINKEY_PRE;
2112 update_drag_caption();
2115 if (result && (buttonpress == 3))
2117 gui->keyframe_menu->update(plugin, keyframe);
2118 gui->keyframe_menu->activate_menu();
2119 rerender = 1; // the position changes
2124 // Final pass to trap event
2125 for(int i = 0; i < AUTOMATION_TOTAL; i++)
2127 if(mwindow->session->current_operation == pre_auto_operations[i] ||
2128 mwindow->session->current_operation == auto_operations[i])
2132 if(mwindow->session->current_operation == DRAG_PLUGINKEY ||
2133 mwindow->session->current_operation == DRAG_PLUGINKEY_PRE)
2141 new_cursor = UPRIGHT_ARROW_CURSOR;
2147 void TrackCanvas::draw_auto(Auto *current,
2155 char string[BCTEXTLEN];
2157 x1 = x - HANDLE_W / 2;
2158 x2 = x + HANDLE_W / 2;
2159 y1 = center_pixel + y - HANDLE_W / 2;
2160 y2 = center_pixel + y + HANDLE_W / 2;
2162 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2163 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2166 draw_box(x1 + 1, y1 + 1, x2 - x1, y2 - y1);
2168 draw_box(x1, y1, x2 - x1, y2 - y1);
2171 void TrackCanvas::draw_floatauto(Auto *current,
2183 int in_x1, in_y1, in_x2, in_y2;
2184 int out_x1, out_y1, out_x2, out_y2;
2185 char string[BCTEXTLEN];
2188 x1 = x - HANDLE_W / 2;
2189 x2 = x + HANDLE_W / 2;
2190 y1 = center_pixel + y - HANDLE_W / 2;
2191 y2 = center_pixel + y + HANDLE_W / 2;
2193 CLAMP(y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2194 CLAMP(y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2199 draw_box(x1 + 1, y1 + 1, x2 - x1, y2 - y1);
2201 draw_box(x1, y1, x2 - x1, y2 - y1);
2205 in_x1 = in_x - HANDLE_W / 2;
2206 in_x2 = in_x + HANDLE_W / 2;
2207 in_y1 = center_pixel + in_y - HANDLE_W / 2;
2208 in_y2 = center_pixel + in_y + HANDLE_W / 2;
2210 CLAMP(in_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2211 CLAMP(in_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2212 CLAMP(in_y, -zoom_track / 2, zoom_track / 2);
2217 draw_line(x + 1, center_pixel + y + 1, in_x + 1, center_pixel + in_y + 1);
2218 draw_box(in_x1 + 1, in_y1 + 1, in_x2 - in_x1, in_y2 - in_y1);
2220 draw_line(x, center_pixel + y, in_x, center_pixel + in_y);
2221 draw_box(in_x1, in_y1, in_x2 - in_x1, in_y2 - in_y1);
2226 out_x1 = out_x - HANDLE_W / 2;
2227 out_x2 = out_x + HANDLE_W / 2;
2228 out_y1 = center_pixel + out_y - HANDLE_W / 2;
2229 out_y2 = center_pixel + out_y + HANDLE_W / 2;
2231 CLAMP(out_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2232 CLAMP(out_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2233 CLAMP(out_y, -zoom_track / 2, zoom_track / 2);
2238 draw_line(x + 1, center_pixel + y + 1, out_x + 1, center_pixel + out_y + 1);
2239 draw_box(out_x1 + 1, out_y1 + 1, out_x2 - out_x1, out_y2 - out_y1);
2241 draw_line(x, center_pixel + y, out_x, center_pixel + out_y);
2242 draw_box(out_x1, out_y1, out_x2 - out_x1, out_y2 - out_y1);
2246 int TrackCanvas::test_auto(Auto *current,
2256 char string[BCTEXTLEN];
2259 x1 = x - HANDLE_W / 2;
2260 x2 = x + HANDLE_W / 2;
2261 y1 = center_pixel + y - HANDLE_W / 2;
2262 y2 = center_pixel + y + HANDLE_W / 2;
2264 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2265 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2267 if(cursor_x >= x1 && cursor_x < x2 && cursor_y >= y1 && cursor_y < y2)
2271 mwindow->session->drag_auto = current;
2272 mwindow->session->drag_start_percentage = current->value_to_percentage();
2273 mwindow->session->drag_start_position = current->position;
2274 mwindow->session->drag_origin_x = cursor_x;
2275 mwindow->session->drag_origin_y = cursor_y;
2283 int TrackCanvas::test_floatauto(Auto *current,
2297 int in_x1, in_y1, in_x2, in_y2;
2298 int out_x1, out_y1, out_x2, out_y2;
2299 char string[BCTEXTLEN];
2302 x1 = x - HANDLE_W / 2;
2303 x2 = x + HANDLE_W / 2;
2304 y1 = center_pixel + y - HANDLE_W / 2;
2305 y2 = center_pixel + y + HANDLE_W / 2;
2307 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2308 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2310 in_x1 = in_x - HANDLE_W / 2;
2311 in_x2 = in_x + HANDLE_W / 2;
2312 in_y1 = center_pixel + in_y - HANDLE_W / 2;
2313 in_y2 = center_pixel + in_y + HANDLE_W / 2;
2315 if(in_y1 < center_pixel + -zoom_track / 2) in_y1 = center_pixel + -zoom_track / 2;
2316 if(in_y2 > center_pixel + zoom_track / 2) in_y2 = center_pixel + zoom_track / 2;
2318 out_x1 = out_x - HANDLE_W / 2;
2319 out_x2 = out_x + HANDLE_W / 2;
2320 out_y1 = center_pixel + out_y - HANDLE_W / 2;
2321 out_y2 = center_pixel + out_y + HANDLE_W / 2;
2323 if(out_y1 < center_pixel + -zoom_track / 2) out_y1 = center_pixel + -zoom_track / 2;
2324 if(out_y2 > center_pixel + zoom_track / 2) out_y2 = center_pixel + zoom_track / 2;
2328 //printf("TrackCanvas::test_floatauto %d %d %d %d %d %d\n", cursor_x, cursor_y, x1, x2, y1, 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;
2343 mwindow->session->drag_handle = 0;
2350 cursor_x >= in_x1 &&
2352 cursor_y >= in_y1 &&
2354 current->position > 0)
2356 if(buttonpress && (buttonpress != 3))
2358 mwindow->session->drag_auto = current;
2359 mwindow->session->drag_start_percentage =
2360 current->invalue_to_percentage();
2361 mwindow->session->drag_start_position =
2362 ((FloatAuto*)current)->control_in_position;
2363 mwindow->session->drag_origin_x = cursor_x;
2364 mwindow->session->drag_origin_y = cursor_y;
2365 mwindow->session->drag_handle = 1;
2372 cursor_x >= out_x1 &&
2373 cursor_x < out_x2 &&
2374 cursor_y >= out_y1 &&
2377 if(buttonpress && (buttonpress != 3))
2379 mwindow->session->drag_auto = current;
2380 mwindow->session->drag_start_percentage =
2381 current->outvalue_to_percentage();
2382 mwindow->session->drag_start_position =
2383 ((FloatAuto*)current)->control_out_position;
2384 mwindow->session->drag_origin_x = cursor_x;
2385 mwindow->session->drag_origin_y = cursor_y;
2386 mwindow->session->drag_handle = 2;
2392 // 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",
2393 // mwindow->session->drag_handle,
2402 void TrackCanvas::draw_floatline(int center_pixel,
2403 FloatAuto *previous,
2415 // Solve bezier equation for either every pixel or a certain large number of
2420 // Not using slope intercept
2427 // Call by reference fails for some reason here
2428 FloatAuto *previous1 = previous, *next1 = next;
2429 float automation_min = mwindow->edl->local_session->automation_min;
2430 float automation_max = mwindow->edl->local_session->automation_max;
2431 float automation_range = automation_max - automation_min;
2433 for(int x = x1; x < x2; x++)
2435 int64_t position = (int64_t)(unit_start + x * zoom_units);
2436 float value = autos->get_value(position, PLAY_FORWARD, previous1, next1);
2438 int y = center_pixel +
2439 (int)(((value - automation_min) / automation_range - 0.5) * -yscale);
2442 y >= center_pixel - yscale / 2 &&
2443 y < center_pixel + yscale / 2 - 1)
2446 draw_line(x - 1, prev_y + 1, x, y + 1);
2448 draw_line(x - 1, prev_y, x, y);
2456 void TrackCanvas::synchronize_autos(float change,
2461 // fill mwindow->session->drag_auto_gang
2462 if (fill_gangs == 1 && skip->gang)
2464 for(Track *current = mwindow->edl->tracks->first;
2468 if(current->data_type == skip->data_type &&
2473 FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
2474 double position = skip->from_units(fauto->position);
2475 FloatAuto *previous = 0, *next = 0;
2477 float init_value = fade_autos->get_value(fauto->position, PLAY_FORWARD, previous, next);
2478 FloatAuto *keyframe;
2479 keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position);
2483 // create keyframe at exactly this point in time
2484 keyframe = (FloatAuto*)fade_autos->insert_auto(fauto->position);
2485 keyframe->value = init_value;
2489 // keyframe exists, just change it
2490 keyframe->value += change;
2493 keyframe->position = fauto->position;
2494 keyframe->control_out_position = fauto->control_out_position;
2495 keyframe->control_in_position = fauto->control_in_position;
2496 keyframe->control_out_value = fauto->control_out_value;
2497 keyframe->control_in_value = fauto->control_in_value;
2499 mwindow->session->drag_auto_gang->append((Auto *)keyframe);
2504 if (fill_gangs == 0)
2507 for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
2509 FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
2511 keyframe->value += change;
2512 keyframe->position = fauto->position;
2513 if(skip->data_type == TRACK_AUDIO)
2514 CLAMP(keyframe->value, INFINITYGAIN, MAX_AUDIO_FADE);
2516 CLAMP(keyframe->value, 0, MAX_VIDEO_FADE);
2517 keyframe->control_out_position = fauto->control_out_position;
2518 keyframe->control_in_position = fauto->control_in_position;
2519 keyframe->control_out_value = fauto->control_out_value;
2520 keyframe->control_in_value = fauto->control_in_value;
2526 if (fill_gangs == -1)
2528 for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
2530 FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
2531 keyframe->autos->remove_nonsequential(
2534 mwindow->session->drag_auto_gang->remove_all();
2539 int TrackCanvas::test_floatline(int center_pixel,
2553 float automation_min = mwindow->edl->local_session->automation_min;
2554 float automation_max = mwindow->edl->local_session->automation_max;
2555 float automation_range = automation_max - automation_min;
2556 int64_t position = (int64_t)(unit_start + cursor_x * zoom_units);
2557 // Call by reference fails for some reason here
2558 FloatAuto *previous = 0, *next = 0;
2559 float value = autos->get_value(position, PLAY_FORWARD, previous, next);
2560 int y = center_pixel +
2561 (int)(((value - automation_min) / automation_range - 0.5) * -yscale);
2563 if(cursor_x >= x1 &&
2565 cursor_y >= y - HANDLE_W / 2 &&
2566 cursor_y < y + HANDLE_W / 2 &&
2577 current = mwindow->session->drag_auto = autos->insert_auto(position);
2578 ((FloatAuto*)current)->value = value;
2579 mwindow->session->drag_start_percentage = current->value_to_percentage();
2580 mwindow->session->drag_start_position = current->position;
2581 mwindow->session->drag_origin_x = cursor_x;
2582 mwindow->session->drag_origin_y = cursor_y;
2583 mwindow->session->drag_handle = 0;
2592 void TrackCanvas::draw_toggleline(int center_pixel,
2600 draw_line(x1, center_pixel + y1 + 1, x2, center_pixel + y1 + 1);
2602 draw_line(x1, center_pixel + y1, x2, center_pixel + y1);
2607 draw_line(x2 + 1, center_pixel + y1, x2 + 1, center_pixel + y2);
2609 draw_line(x2, center_pixel + y1, x2, center_pixel + y2);
2613 int TrackCanvas::test_toggleline(Autos *autos,
2624 if(cursor_x >= x1 && cursor_x < x2)
2626 int miny = center_pixel + y1 - HANDLE_W / 2;
2627 int maxy = center_pixel + y1 + HANDLE_W / 2;
2628 if(cursor_y >= miny && cursor_y < maxy)
2637 double position = (double)(cursor_x +
2638 mwindow->edl->local_session->view_start) *
2639 mwindow->edl->local_session->zoom_sample /
2640 mwindow->edl->session->sample_rate;
2641 int64_t unit_position = autos->track->to_units(position, 0);
2642 int new_value = (int)((IntAutos*)autos)->get_automation_constant(unit_position, unit_position);
2644 current = mwindow->session->drag_auto = autos->insert_auto(unit_position);
2645 ((IntAuto*)current)->value = new_value;
2646 mwindow->session->drag_start_percentage = current->value_to_percentage();
2647 mwindow->session->drag_start_position = current->position;
2648 mwindow->session->drag_origin_x = cursor_x;
2649 mwindow->session->drag_origin_y = cursor_y;
2657 void TrackCanvas::calculate_viewport(Track *track,
2658 double &view_start, // Seconds
2660 double &view_end, // Seconds
2664 double &zoom_sample,
2667 view_start = (double)mwindow->edl->local_session->view_start *
2668 mwindow->edl->local_session->zoom_sample /
2669 mwindow->edl->session->sample_rate;
2670 unit_start = track->to_doubleunits(view_start);
2671 view_end = (double)(mwindow->edl->local_session->view_start +
2673 mwindow->edl->local_session->zoom_sample /
2674 mwindow->edl->session->sample_rate;
2675 unit_end = track->to_doubleunits(view_end);
2676 yscale = mwindow->edl->local_session->zoom_track;
2677 center_pixel = (int)(track->y_pixel + yscale / 2) +
2678 (mwindow->edl->session->show_titles ?
2679 mwindow->theme->title_bg_data->get_h() :
2681 zoom_sample = mwindow->edl->local_session->zoom_sample;
2683 zoom_units = track->to_doubleunits(zoom_sample / mwindow->edl->session->sample_rate);
2686 float TrackCanvas::percentage_to_value(float percentage,
2693 if(percentage > 0.5)
2700 float automation_min = mwindow->edl->local_session->automation_min;
2701 float automation_max = mwindow->edl->local_session->automation_max;
2702 float automation_range = automation_max - automation_min;
2704 result = percentage * automation_range + automation_min;
2707 FloatAuto *ptr = (FloatAuto*)reference;
2708 result -= ptr->value;
2715 void TrackCanvas::calculate_auto_position(double *x,
2726 float automation_min = mwindow->edl->local_session->automation_min;
2727 float automation_max = mwindow->edl->local_session->automation_max;
2728 float automation_range = automation_max - automation_min;
2729 FloatAuto *ptr = (FloatAuto*)current;
2730 *x = (double)(ptr->position - unit_start) / zoom_units;
2731 *y = ((ptr->value - automation_min) /
2732 automation_range - 0.5) *
2736 *in_x = (double)(ptr->position +
2737 ptr->control_in_position -
2743 *in_y = (((ptr->value + ptr->control_in_value) -
2745 automation_range - 0.5) *
2750 *out_x = (double)(ptr->position +
2751 ptr->control_out_position -
2757 *out_y = (((ptr->value + ptr->control_out_value) -
2759 automation_range - 0.5) *
2768 int TrackCanvas::do_float_autos(Track *track,
2775 Auto * &auto_instance)
2787 double ax, ay, ax2, ay2;
2788 double in_x2, in_y2, out_x2, out_y2;
2795 calculate_viewport(track,
2807 // Get first auto before start
2810 for(current = autos->last;
2811 current && current->position >= unit_start;
2817 calculate_auto_position(&ax,
2831 current = autos->first ? autos->first : autos->default_auto;
2834 calculate_auto_position(&ax,
2864 calculate_auto_position(&ax2,
2882 slope = (ay2 - ay) / (ax2 - ax);
2888 ay2 = ay + slope * (get_w() - ax);
2893 ay = ay + slope * (0 - ax);
2911 if(current && !result)
2913 if(current != autos->default_auto)
2918 result = test_floatauto(current,
2931 auto_instance = current;
2935 draw_floatauto(current,
2952 // Draw joining line
2957 if(track->record && buttonpress != 3)
2959 result = test_floatline(center_pixel,
2965 // Exclude auto coverage from the end of the line. The auto overlaps
2966 (int)ax2 - HANDLE_W / 2,
2974 draw_floatline(center_pixel,
2975 (FloatAuto*)previous,
2976 (FloatAuto*)current,
3004 current->position <= unit_end &&
3007 //printf("TrackCanvas::do_float_autos 100\n");
3016 if(ax < get_w() && !result)
3022 if(track->record && buttonpress != 3)
3024 result = test_floatline(center_pixel,
3037 draw_floatline(center_pixel,
3038 (FloatAuto*)previous,
3039 (FloatAuto*)current,
3062 int TrackCanvas::do_toggle_autos(Track *track,
3069 Auto * &auto_instance)
3080 double ax, ay, ax2, ay2;
3084 calculate_viewport(track,
3095 double high = -yscale * 0.8 / 2;
3096 double low = yscale * 0.8 / 2;
3098 // Get first auto before start
3100 for(current = autos->last; current && current->position >= unit_start; current = PREVIOUS)
3106 ay = ((IntAuto*)current)->value > 0 ? high : low;
3111 current = autos->first ? autos->first : autos->default_auto;
3115 ay = ((IntAuto*)current)->value > 0 ? high : low;
3128 ax2 = (double)(current->position - unit_start) / zoom_units;
3129 ay2 = ((IntAuto*)current)->value > 0 ? high : low;
3137 if(ax2 > get_w()) ax2 = get_w();
3139 if(current && !result)
3141 if(current != autos->default_auto)
3147 result = test_auto(current,
3156 auto_instance = current;
3175 if(track->record && buttonpress != 3)
3177 result = test_toggleline(autos,
3190 draw_toggleline(center_pixel,
3199 }while(current && current->position <= unit_end && !result);
3201 if(ax < get_w() && !result)
3207 if(track->record && buttonpress != 3)
3209 result = test_toggleline(autos,
3221 draw_toggleline(center_pixel,
3231 int TrackCanvas::do_autos(Track *track,
3238 Auto * &auto_instance)
3251 calculate_viewport(track,
3264 for(current = autos->first; current && !result; current = NEXT)
3266 if(current->position >= unit_start && current->position < unit_end)
3269 x = (int64_t)((double)(current->position - unit_start) /
3270 zoom_units - (pixmap->get_w() / 2 + 0.5));
3271 y = center_pixel - pixmap->get_h() / 2;
3275 if(cursor_x >= x && cursor_y >= y &&
3276 cursor_x < x + pixmap->get_w() &&
3277 cursor_y < y + pixmap->get_h())
3280 auto_instance = current;
3282 if(buttonpress && (buttonpress != 3))
3284 mwindow->session->drag_auto = current;
3285 mwindow->session->drag_start_position = current->position;
3286 mwindow->session->drag_origin_x = cursor_x;
3287 mwindow->session->drag_origin_y = cursor_y;
3289 double position = autos->track->from_units(current->position);
3290 double center = (mwindow->edl->local_session->get_selectionstart(1) +
3291 mwindow->edl->local_session->get_selectionend(1)) /
3296 mwindow->edl->local_session->set_selectionstart(position);
3297 mwindow->edl->local_session->set_selectionend(position);
3300 if(position < center)
3302 mwindow->edl->local_session->set_selectionstart(position);
3305 mwindow->edl->local_session->set_selectionend(position);
3310 draw_pixmap(pixmap, x, y);
3316 // so this means it is always >0 when keyframe is found
3317 int TrackCanvas::do_plugin_autos(Track *track,
3322 Plugin* &keyframe_plugin,
3323 KeyFrame* &keyframe_instance)
3336 if(!track->expand_view) return 0;
3338 calculate_viewport(track,
3350 for(int i = 0; i < track->plugin_set.total && !result; i++)
3352 PluginSet *plugin_set = track->plugin_set.values[i];
3353 int center_pixel = (int)(track->y_pixel +
3354 mwindow->edl->local_session->zoom_track +
3355 (i + 0.5) * mwindow->theme->plugin_bg_data->get_h() +
3356 (mwindow->edl->session->show_titles ? mwindow->theme->title_bg_data->get_h() : 0));
3358 for(Plugin *plugin = (Plugin*)plugin_set->first;
3360 plugin = (Plugin*)plugin->next)
3362 for(KeyFrame *keyframe = (KeyFrame*)plugin->keyframes->first;
3363 keyframe && !result;
3364 keyframe = (KeyFrame*)keyframe->next)
3366 //printf("TrackCanvas::draw_plugin_autos 3 %d\n", keyframe->position);
3367 if(keyframe->position >= unit_start && keyframe->position < unit_end)
3369 int64_t x = (int64_t)((keyframe->position - unit_start) / zoom_units);
3370 int y = center_pixel - keyframe_pixmap->get_h() / 2;
3372 //printf("TrackCanvas::draw_plugin_autos 4 %d %d\n", x, center_pixel);
3375 if(cursor_x >= x && cursor_y >= y &&
3376 cursor_x < x + keyframe_pixmap->get_w() &&
3377 cursor_y < y + keyframe_pixmap->get_h())
3380 keyframe_plugin = plugin;
3381 keyframe_instance = keyframe;
3385 mwindow->session->drag_auto = keyframe;
3386 mwindow->session->drag_start_position = keyframe->position;
3387 mwindow->session->drag_origin_x = cursor_x;
3388 mwindow->session->drag_origin_y = cursor_y;
3390 double position = track->from_units(keyframe->position);
3391 double center = (mwindow->edl->local_session->get_selectionstart(1) +
3392 mwindow->edl->local_session->get_selectionend(1)) /
3397 mwindow->edl->local_session->set_selectionstart(position);
3398 mwindow->edl->local_session->set_selectionend(position);
3401 if(position < center)
3403 mwindow->edl->local_session->set_selectionstart(position);
3406 mwindow->edl->local_session->set_selectionend(position);
3411 draw_pixmap(keyframe_pixmap,
3418 //printf("TrackCanvas::draw_plugin_autos 5\n");
3422 void TrackCanvas::draw_overlays()
3424 int new_cursor, update_cursor, rerender;
3425 //TRACE("TrackCanvas::draw_overlays 1")
3427 // Move background pixmap to foreground pixmap
3428 draw_pixmap(background_pixmap,
3435 //TRACE("TrackCanvas::draw_overlays 10")
3438 draw_inout_points();
3440 //TRACE("TrackCanvas::draw_overlays 11");
3442 if(mwindow->edl->session->auto_conf->transitions) draw_transitions();
3444 //TRACE("TrackCanvas::draw_overlays 12");
3448 //TRACE("TrackCanvas::draw_overlays 13");
3451 draw_brender_start();
3453 //TRACE("TrackCanvas::draw_overlays 14");
3454 // Highlighted areas
3455 draw_highlighting();
3457 //TRACE("TrackCanvas::draw_overlays 15");
3467 //TRACE("TrackCanvas::draw_overlays 16\n");
3469 if(gui->cursor) gui->cursor->restore();
3471 //TRACE("TrackCanvas::draw_overlays 17\n");
3475 //TRACE("TrackCanvas::draw_overlays 20");
3477 draw_playback_cursor();
3481 int TrackCanvas::activate()
3485 get_top_level()->deactivate();
3487 set_active_subwindow(this);
3488 gui->cursor->activate();
3493 int TrackCanvas::deactivate()
3498 gui->cursor->deactivate();
3504 void TrackCanvas::update_drag_handle()
3506 double new_position;
3509 (double)(get_cursor_x() + mwindow->edl->local_session->view_start) *
3510 mwindow->edl->local_session->zoom_sample /
3511 mwindow->edl->session->sample_rate;
3513 mwindow->edl->align_to_frame(new_position, 0);
3516 if(new_position != mwindow->session->drag_position)
3518 mwindow->session->drag_position = new_position;
3519 gui->mainclock->update(new_position);
3520 // Que the CWindow. Doesn't do anything if selectionstart and selection end
3522 // mwindow->cwindow->update(1, 0, 0);
3526 int TrackCanvas::update_drag_edit()
3535 #define UPDATE_DRAG_HEAD(do_clamp) \
3537 int x = cursor_x - mwindow->session->drag_origin_x; \
3538 int y = cursor_y - mwindow->session->drag_origin_y; \
3540 if(!current->autos->track->record) return 0; \
3541 double view_start; \
3542 double unit_start; \
3547 double zoom_sample; \
3548 double zoom_units; \
3550 calculate_viewport(current->autos->track, \
3560 float percentage = (float)(mwindow->session->drag_origin_y - cursor_y) / \
3562 mwindow->session->drag_start_percentage; \
3563 if(do_clamp) CLAMP(percentage, 0, 1); \
3565 int64_t position = Units::to_int64(zoom_units * \
3566 (cursor_x - mwindow->session->drag_origin_x) + \
3567 mwindow->session->drag_start_position); \
3569 if((do_clamp) && position < 0) position = 0;
3579 int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y)
3581 FloatAuto *current = (FloatAuto*)mwindow->session->drag_auto;
3583 UPDATE_DRAG_HEAD(mwindow->session->drag_handle == 0);
3588 switch(mwindow->session->drag_handle)
3592 // Snap to nearby values
3593 old_value = current->value;
3600 value = percentage_to_value(percentage, 0, 0);
3602 if(current->previous)
3604 value1 = ((FloatAuto*)current->previous)->value;
3605 distance1 = fabs(value - value1);
3606 current->value = value1;
3611 value2 = ((FloatAuto*)current->next)->value;
3612 distance2 = fabs(value - value2);
3613 if(!current->previous || distance2 < distance1)
3615 current->value = value2;
3619 if(!current->previous && !current->next)
3621 current->value = ((FloatAutos*)current->autos)->default_;
3623 value = current->value;
3626 value = percentage_to_value(percentage, 0, 0);
3628 if(value != old_value || position != current->position)
3631 float change = value - old_value;
3632 current->value = value;
3633 current->position = position;
3634 synchronize_autos(change, current->autos->track, current, 0);
3636 char string[BCTEXTLEN], string2[BCTEXTLEN];
3637 Units::totext(string2,
3638 current->autos->track->from_units(current->position),
3639 mwindow->edl->session->time_format,
3640 mwindow->edl->session->sample_rate,
3641 mwindow->edl->session->frame_rate,
3642 mwindow->edl->session->frames_per_foot);
3643 sprintf(string, "%s, %.2f", string2, current->value);
3644 gui->show_message(string);
3650 value = percentage_to_value(percentage, 0, current);
3651 position = MIN(0, position);
3652 if(value != current->control_in_value ||
3653 position != current->control_in_position)
3656 current->control_in_value = value;
3657 current->control_in_position = position;
3658 synchronize_autos(0, current->autos->track, current, 0);
3660 char string[BCTEXTLEN], string2[BCTEXTLEN];
3661 Units::totext(string2,
3662 current->autos->track->from_units(current->control_in_position),
3663 mwindow->edl->session->time_format,
3664 mwindow->edl->session->sample_rate,
3665 mwindow->edl->session->frame_rate,
3666 mwindow->edl->session->frames_per_foot);
3667 sprintf(string, "%s, %.2f", string2, current->control_in_value);
3668 gui->show_message(string);
3674 value = percentage_to_value(percentage, 0, current);
3675 position = MAX(0, position);
3676 if(value != current->control_out_value ||
3677 position != current->control_out_position)
3680 current->control_out_value = value;
3681 current->control_out_position = position;
3682 synchronize_autos(0, current->autos->track, current, 0);
3684 char string[BCTEXTLEN], string2[BCTEXTLEN];
3685 Units::totext(string2,
3686 current->autos->track->from_units(
3687 ((FloatAuto*)current)->control_out_position),
3688 mwindow->edl->session->time_format,
3689 mwindow->edl->session->sample_rate,
3690 mwindow->edl->session->frame_rate,
3691 mwindow->edl->session->frames_per_foot);
3692 sprintf(string, "%s, %.2f",
3694 ((FloatAuto*)current)->control_out_value);
3695 gui->show_message(string);
3703 int TrackCanvas::update_drag_toggleauto(int cursor_x, int cursor_y)
3705 IntAuto *current = (IntAuto*)mwindow->session->drag_auto;
3707 UPDATE_DRAG_HEAD(1);
3709 int value = (int)percentage_to_value(percentage, 1, 0);
3711 if(value != current->value || position != current->position)
3714 current->value = value;
3715 current->position = position;
3717 char string[BCTEXTLEN], string2[BCTEXTLEN];
3718 Units::totext(string2,
3719 current->autos->track->from_units(current->position),
3720 mwindow->edl->session->time_format,
3721 mwindow->edl->session->sample_rate,
3722 mwindow->edl->session->frame_rate,
3723 mwindow->edl->session->frames_per_foot);
3724 sprintf(string, "%s, %d", string2, current->value);
3725 gui->show_message(string);
3731 // Autos which can't change value through dragging.
3733 int TrackCanvas::update_drag_auto(int cursor_x, int cursor_y)
3735 Auto *current = (Auto*)mwindow->session->drag_auto;
3738 if(position != current->position)
3741 current->position = position;
3743 char string[BCTEXTLEN];
3744 Units::totext(string,
3745 current->autos->track->from_units(current->position),
3746 mwindow->edl->session->time_format,
3747 mwindow->edl->session->sample_rate,
3748 mwindow->edl->session->frame_rate,
3749 mwindow->edl->session->frames_per_foot);
3750 gui->show_message(string);
3752 double position_f = current->autos->track->from_units(current->position);
3753 double center_f = (mwindow->edl->local_session->get_selectionstart(1) +
3754 mwindow->edl->local_session->get_selectionend(1)) /
3758 mwindow->edl->local_session->set_selectionstart(position_f);
3759 mwindow->edl->local_session->set_selectionend(position_f);
3762 if(position_f < center_f)
3764 mwindow->edl->local_session->set_selectionstart(position_f);
3767 mwindow->edl->local_session->set_selectionend(position_f);
3774 int TrackCanvas::update_drag_pluginauto(int cursor_x, int cursor_y)
3776 KeyFrame *current = (KeyFrame*)mwindow->session->drag_auto;
3779 if(position != current->position)
3781 // printf("uida: autos: %p, track: %p ta: %p\n", current->autos, current->autos->track, current->autos->track->automation);
3782 Track *track = current->autos->track;
3783 PluginAutos *pluginautos = (PluginAutos *)current->autos;
3784 PluginSet *pluginset;
3786 // figure out the correct pluginset & correct plugin
3788 for(int i = 0; i < track->plugin_set.total; i++)
3790 pluginset = track->plugin_set.values[i];
3791 for(plugin = (Plugin *)pluginset->first; plugin; plugin = (Plugin *)plugin->next)
3793 KeyFrames *keyframes = plugin->keyframes;
3794 for(KeyFrame *currentkeyframe = (KeyFrame *)keyframes->first; currentkeyframe; currentkeyframe = (KeyFrame *) currentkeyframe->next)
3796 if (currentkeyframe == current)
3808 mwindow->session->plugin_highlighted = plugin;
3809 mwindow->session->track_highlighted = track;
3811 current->position = position;
3813 char string[BCTEXTLEN];
3814 Units::totext(string,
3815 current->autos->track->from_units(current->position),
3816 mwindow->edl->session->time_format,
3817 mwindow->edl->session->sample_rate,
3818 mwindow->edl->session->frame_rate,
3819 mwindow->edl->session->frames_per_foot);
3820 gui->show_message(string);
3822 double position_f = current->autos->track->from_units(current->position);
3823 double center_f = (mwindow->edl->local_session->get_selectionstart(1) +
3824 mwindow->edl->local_session->get_selectionend(1)) /
3828 mwindow->edl->local_session->set_selectionstart(position_f);
3829 mwindow->edl->local_session->set_selectionend(position_f);
3832 if(position_f < center_f)
3834 mwindow->edl->local_session->set_selectionstart(position_f);
3837 mwindow->edl->local_session->set_selectionend(position_f);
3844 void TrackCanvas::update_drag_caption()
3846 switch(mwindow->session->current_operation)
3856 int TrackCanvas::cursor_motion_event()
3858 int result, cursor_x, cursor_y;
3859 int update_clock = 0;
3860 int update_zoom = 0;
3861 int update_scroll = 0;
3862 int update_overlay = 0;
3863 int update_cursor = 0;
3866 double position = 0;
3867 //printf("TrackCanvas::cursor_motion_event 1\n");
3871 switch(mwindow->edl->session->editing_mode)
3873 case EDITING_ARROW: new_cursor = ARROW_CURSOR; break;
3874 case EDITING_IBEAM: new_cursor = IBEAM_CURSOR; break;
3877 switch(mwindow->session->current_operation)
3879 case DRAG_EDITHANDLE1:
3880 // Outside threshold. Upgrade status
3881 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3883 mwindow->session->current_operation = DRAG_EDITHANDLE2;
3888 case DRAG_EDITHANDLE2:
3889 update_drag_handle();
3893 case DRAG_PLUGINHANDLE1:
3894 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3896 mwindow->session->current_operation = DRAG_PLUGINHANDLE2;
3901 case DRAG_PLUGINHANDLE2:
3902 update_drag_handle();
3906 // Rubber band curves
3913 case DRAG_PROJECTOR_X:
3914 case DRAG_PROJECTOR_Y:
3915 case DRAG_PROJECTOR_Z:
3916 rerender = update_overlay = update_drag_floatauto(get_cursor_x(), get_cursor_y());
3920 rerender = update_overlay = update_drag_toggleauto(get_cursor_x(), get_cursor_y());
3924 rerender = update_overlay = update_drag_toggleauto(get_cursor_x(), get_cursor_y());
3927 // Keyframe icons are sticky
3931 case DRAG_PLUGINKEY_PRE:
3932 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3934 mwindow->session->current_operation++;
3942 case DRAG_PLUGINKEY:
3943 rerender = update_overlay =
3944 update_drag_pluginauto(get_cursor_x(), get_cursor_y());
3949 cursor_x = get_cursor_x();
3950 cursor_y = get_cursor_y();
3951 position = (double)(cursor_x + mwindow->edl->local_session->view_start) *
3952 mwindow->edl->local_session->zoom_sample /
3953 mwindow->edl->session->sample_rate;
3955 position = mwindow->edl->align_to_frame(position, 0);
3956 position = MAX(position, 0);
3958 if(position < selection_midpoint1)
3960 mwindow->edl->local_session->set_selectionend(selection_midpoint1);
3961 mwindow->edl->local_session->set_selectionstart(position);
3963 gui->unlock_window();
3964 mwindow->cwindow->update(1, 0, 0, 0, 1);
3965 gui->lock_window("TrackCanvas::cursor_motion_event 1");
3966 // Update the faders
3967 mwindow->update_plugin_guis();
3968 gui->patchbay->update();
3972 mwindow->edl->local_session->set_selectionstart(selection_midpoint1);
3973 mwindow->edl->local_session->set_selectionend(position);
3974 // Don't que the CWindow
3977 gui->cursor->hide();
3978 gui->cursor->draw();
3988 if(is_event_win() && cursor_inside())
3991 cursor_x = get_cursor_x();
3992 position = (double)cursor_x *
3993 (double)mwindow->edl->local_session->zoom_sample /
3994 (double)mwindow->edl->session->sample_rate +
3995 (double)mwindow->edl->local_session->view_start *
3996 (double)mwindow->edl->local_session->zoom_sample /
3997 (double)mwindow->edl->session->sample_rate;
3998 position = mwindow->edl->align_to_frame(position, 0);
4002 if(do_transitions(get_cursor_x(),
4012 if(do_keyframes(get_cursor_x(),
4024 if(do_edit_handles(get_cursor_x(),
4033 // Plugin boundaries
4034 if(do_plugin_handles(get_cursor_x(),
4043 if(do_edits(get_cursor_x(),
4058 //printf("TrackCanvas::cursor_motion_event 1\n");
4059 if(update_cursor && new_cursor != get_cursor())
4061 set_cursor(new_cursor);
4064 //printf("TrackCanvas::cursor_motion_event 1 %d\n", rerender);
4067 mwindow->restart_brender();
4068 mwindow->sync_parameters(CHANGE_PARAMS);
4069 mwindow->update_plugin_guis();
4070 gui->unlock_window();
4071 mwindow->cwindow->update(1, 0, 0, 0, 1);
4072 gui->lock_window("TrackCanvas::cursor_motion_event 2");
4074 gui->patchbay->update();
4080 if(!mwindow->cwindow->playback_engine->is_playing_back)
4081 gui->mainclock->update(position);
4086 gui->zoombar->update();
4092 (cursor_x >= get_w() || cursor_x < 0 || cursor_y >= get_h() || cursor_y < 0))
4096 (cursor_x < get_w() && cursor_x >= 0 && cursor_y < get_h() && cursor_y >= 0))
4107 //printf("TrackCanvas::cursor_motion_event 100\n");
4111 void TrackCanvas::start_dragscroll()
4116 set_repeat(BC_WindowBase::get_resources()->scroll_repeat);
4117 //printf("TrackCanvas::start_dragscroll 1\n");
4121 void TrackCanvas::stop_dragscroll()
4126 unset_repeat(BC_WindowBase::get_resources()->scroll_repeat);
4127 //printf("TrackCanvas::stop_dragscroll 1\n");
4131 int TrackCanvas::repeat_event(int64_t duration)
4133 if(!drag_scroll) return 0;
4134 if(duration != BC_WindowBase::get_resources()->scroll_repeat) return 0;
4136 int sample_movement = 0;
4137 int track_movement = 0;
4138 int64_t x_distance = 0;
4139 int64_t y_distance = 0;
4140 double position = 0;
4143 switch(mwindow->session->current_operation)
4146 //printf("TrackCanvas::repeat_event 1 %d\n", mwindow->edl->local_session->view_start);
4147 if(get_cursor_x() > get_w())
4149 x_distance = get_cursor_x() - get_w();
4150 sample_movement = 1;
4153 if(get_cursor_x() < 0)
4155 x_distance = get_cursor_x();
4156 sample_movement = 1;
4159 if(get_cursor_y() > get_h())
4161 y_distance = get_cursor_y() - get_h();
4165 if(get_cursor_y() < 0)
4167 y_distance = get_cursor_y();
4177 position = (double)(get_cursor_x() +
4178 mwindow->edl->local_session->view_start +
4180 mwindow->edl->local_session->zoom_sample /
4181 mwindow->edl->session->sample_rate;
4182 position = mwindow->edl->align_to_frame(position, 0);
4183 position = MAX(position, 0);
4185 //printf("TrackCanvas::repeat_event 1 %f\n", position);
4186 switch(mwindow->session->current_operation)
4189 if(position < selection_midpoint1)
4191 mwindow->edl->local_session->set_selectionend(selection_midpoint1);
4192 mwindow->edl->local_session->set_selectionstart(position);
4194 gui->unlock_window();
4195 mwindow->cwindow->update(1, 0, 0);
4196 gui->lock_window("TrackCanvas::repeat_event");
4197 // Update the faders
4198 mwindow->update_plugin_guis();
4199 gui->patchbay->update();
4203 mwindow->edl->local_session->set_selectionstart(selection_midpoint1);
4204 mwindow->edl->local_session->set_selectionend(position);
4205 // Don't que the CWindow
4210 mwindow->samplemovement(mwindow->edl->local_session->view_start +
4216 mwindow->trackmovement(mwindow->edl->local_session->track_start +
4223 int TrackCanvas::button_release_event()
4225 int redraw = 0, update_overlay = 0, result = 0;
4227 switch(mwindow->session->current_operation)
4229 case DRAG_EDITHANDLE2:
4230 mwindow->session->current_operation = NO_OPERATION;
4234 end_edithandle_selection();
4237 case DRAG_EDITHANDLE1:
4238 mwindow->session->current_operation = NO_OPERATION;
4243 case DRAG_PLUGINHANDLE2:
4244 mwindow->session->current_operation = NO_OPERATION;
4248 end_pluginhandle_selection();
4251 case DRAG_PLUGINHANDLE1:
4252 mwindow->session->current_operation = NO_OPERATION;
4258 // delete the drag_auto_gang first and remove out of order keys
4259 synchronize_autos(0, 0, 0, -1);
4270 case DRAG_PROJECTOR_X:
4271 case DRAG_PROJECTOR_Y:
4272 case DRAG_PROJECTOR_Z:
4273 case DRAG_PLUGINKEY:
4274 mwindow->session->current_operation = NO_OPERATION;
4275 mwindow->session->drag_handle = 0;
4276 // Remove any out-of-order keyframe
4277 if(mwindow->session->drag_auto)
4279 mwindow->session->drag_auto->autos->remove_nonsequential(
4280 mwindow->session->drag_auto);
4281 // mwindow->session->drag_auto->autos->optimize();
4284 mwindow->undo->update_undo(_("keyframe"), LOAD_AUTOMATION);
4289 case DRAG_AEFFECT_COPY:
4290 case DRAG_VEFFECT_COPY:
4291 // Trap in drag stop
4297 if(mwindow->session->current_operation)
4299 if(mwindow->session->current_operation == SELECT_REGION)
4301 mwindow->undo->update_undo(_("select"), LOAD_SESSION, 0, 0);
4304 mwindow->session->current_operation = NO_OPERATION;
4306 // Traps button release events
4312 cursor_motion_event();
4328 int TrackCanvas::do_edit_handles(int cursor_x,
4334 Edit *edit_result = 0;
4335 int handle_result = 0;
4338 if(!mwindow->edl->session->show_assets) return 0;
4340 for(Track *track = mwindow->edl->tracks->first;
4342 track = track->next)
4344 for(Edit *edit = track->edits->first;
4348 int64_t edit_x, edit_y, edit_w, edit_h;
4349 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
4351 if(cursor_x >= edit_x && cursor_x <= edit_x + edit_w &&
4352 cursor_y >= edit_y && cursor_y < edit_y + edit_h)
4354 if(cursor_x < edit_x + HANDLE_W)
4361 if(cursor_x >= edit_x + edit_w - HANDLE_W)
4379 if(handle_result == 0)
4381 position = edit_result->track->from_units(edit_result->startproject);
4382 new_cursor = LEFT_CURSOR;
4385 if(handle_result == 1)
4387 position = edit_result->track->from_units(edit_result->startproject + edit_result->length);
4388 new_cursor = RIGHT_CURSOR;
4391 // Reposition cursor
4394 mwindow->session->drag_edit = edit_result;
4395 mwindow->session->drag_handle = handle_result;
4396 mwindow->session->drag_button = get_buttonpress() - 1;
4397 mwindow->session->drag_position = position;
4398 mwindow->session->current_operation = DRAG_EDITHANDLE1;
4399 mwindow->session->drag_origin_x = get_cursor_x();
4400 mwindow->session->drag_origin_y = get_cursor_y();
4401 mwindow->session->drag_start = position;
4403 int rerender = start_selection(position);
4406 gui->unlock_window();
4407 mwindow->cwindow->update(1, 0, 0);
4408 gui->lock_window("TrackCanvas::do_edit_handles");
4410 gui->timebar->update_highlights();
4411 gui->zoombar->update();
4412 gui->cursor->hide();
4413 gui->cursor->draw();
4423 int TrackCanvas::do_plugin_handles(int cursor_x,
4429 Plugin *plugin_result = 0;
4430 int handle_result = 0;
4433 if(!mwindow->edl->session->show_assets) return 0;
4435 for(Track *track = mwindow->edl->tracks->first;
4437 track = track->next)
4439 for(int i = 0; i < track->plugin_set.total && !result; i++)
4441 PluginSet *plugin_set = track->plugin_set.values[i];
4442 for(Plugin *plugin = (Plugin*)plugin_set->first;
4444 plugin = (Plugin*)plugin->next)
4446 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
4447 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
4449 if(cursor_x >= plugin_x && cursor_x <= plugin_x + plugin_w &&
4450 cursor_y >= plugin_y && cursor_y < plugin_y + plugin_h)
4452 if(cursor_x < plugin_x + HANDLE_W)
4454 plugin_result = plugin;
4459 if(cursor_x >= plugin_x + plugin_w - HANDLE_W)
4461 plugin_result = plugin;
4468 if(result && shift_down())
4469 mwindow->session->trim_edits = plugin_set;
4477 if(handle_result == 0)
4479 position = plugin_result->track->from_units(plugin_result->startproject);
4480 new_cursor = LEFT_CURSOR;
4483 if(handle_result == 1)
4485 position = plugin_result->track->from_units(plugin_result->startproject + plugin_result->length);
4486 new_cursor = RIGHT_CURSOR;
4491 mwindow->session->drag_plugin = plugin_result;
4492 mwindow->session->drag_handle = handle_result;
4493 mwindow->session->drag_button = get_buttonpress() - 1;
4494 mwindow->session->drag_position = position;
4495 mwindow->session->current_operation = DRAG_PLUGINHANDLE1;
4496 mwindow->session->drag_origin_x = get_cursor_x();
4497 mwindow->session->drag_origin_y = get_cursor_y();
4498 mwindow->session->drag_start = position;
4500 int rerender = start_selection(position);
4503 gui->unlock_window();
4504 mwindow->cwindow->update(1, 0, 0);
4505 gui->lock_window("TrackCanvas::do_plugin_handles");
4507 gui->timebar->update_highlights();
4508 gui->zoombar->update();
4509 gui->cursor->hide();
4510 gui->cursor->draw();
4521 int TrackCanvas::do_tracks(int cursor_x,
4528 if(!mwindow->edl->session->show_assets) return 0;
4531 for(Track *track = mwindow->edl->tracks->first;
4533 track = track->next)
4535 int64_t track_x, track_y, track_w, track_h;
4536 track_dimensions(track, track_x, track_y, track_w, track_h);
4539 get_buttonpress() == 3 &&
4540 cursor_y >= track_y &&
4541 cursor_y < track_y + track_h)
4543 gui->edit_menu->update(track, 0);
4544 gui->edit_menu->activate_menu();
4551 int TrackCanvas::do_edits(int cursor_x,
4561 int over_edit_handle = 0;
4563 if(!mwindow->edl->session->show_assets) return 0;
4565 for(Track *track = mwindow->edl->tracks->first;
4567 track = track->next)
4569 for(Edit *edit = track->edits->first;
4573 int64_t edit_x, edit_y, edit_w, edit_h;
4574 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
4576 // Cursor inside a track
4577 // Cursor inside an edit
4578 if(cursor_x >= edit_x && cursor_x < edit_x + edit_w &&
4579 cursor_y >= edit_y && cursor_y < edit_y + edit_h)
4581 // Select duration of edit
4584 if(get_double_click() && !drag_start)
4586 mwindow->edl->local_session->set_selectionstart(edit->track->from_units(edit->startproject));
4587 mwindow->edl->local_session->set_selectionend(edit->track->from_units(edit->startproject) +
4588 edit->track->from_units(edit->length));
4589 if(mwindow->edl->session->cursor_on_frames)
4591 mwindow->edl->local_session->set_selectionstart(
4592 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionstart(1), 0));
4593 mwindow->edl->local_session->set_selectionend(
4594 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionend(1), 1));
4602 if(drag_start && track->record)
4604 if(mwindow->edl->session->editing_mode == EDITING_ARROW)
4606 // Need to create drag window
4607 mwindow->session->current_operation = DRAG_EDIT;
4608 mwindow->session->drag_edit = edit;
4609 //printf("TrackCanvas::do_edits 2\n");
4611 // Drag only one edit
4614 mwindow->session->drag_edits->remove_all();
4615 mwindow->session->drag_edits->append(edit);
4618 // Construct list of all affected edits
4620 mwindow->edl->tracks->get_affected_edits(
4621 mwindow->session->drag_edits,
4622 edit->track->from_units(edit->startproject),
4625 mwindow->session->drag_origin_x = cursor_x;
4626 mwindow->session->drag_origin_y = cursor_y;
4627 // Where the drag started, so we know relative position inside the edit later
4628 mwindow->session->drag_position = (double)cursor_x *
4629 mwindow->edl->local_session->zoom_sample /
4630 mwindow->edl->session->sample_rate +
4631 (double)mwindow->edl->local_session->view_start *
4632 mwindow->edl->local_session->zoom_sample /
4633 mwindow->edl->session->sample_rate;
4635 drag_popup = new BC_DragWindow(gui,
4636 mwindow->theme->get_image("clip_icon"),
4637 get_abs_cursor_x(0) - mwindow->theme->get_image("clip_icon")->get_w() / 2,
4638 get_abs_cursor_y(0) - mwindow->theme->get_image("clip_icon")->get_h() / 2);
4650 int TrackCanvas::test_resources(int cursor_x, int cursor_y)
4655 int TrackCanvas::do_plugins(int cursor_x,
4669 if(!mwindow->edl->session->show_assets) return 0;
4672 for(track = mwindow->edl->tracks->first;
4674 track = track->next)
4676 if(!track->expand_view) continue;
4679 for(int i = 0; i < track->plugin_set.total && !done; i++)
4681 // first check if plugins are visible at all
4682 if (!track->expand_view)
4684 PluginSet *plugin_set = track->plugin_set.values[i];
4685 for(plugin = (Plugin*)plugin_set->first;
4687 plugin = (Plugin*)plugin->next)
4689 plugin_dimensions(plugin, x, y, w, h);
4690 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
4691 MWindowGUI::visible(y, y + h, 0, get_h()))
4693 if(cursor_x >= x && cursor_x < x + w &&
4694 cursor_y >= y && cursor_y < y + h)
4706 // Start plugin popup
4709 if(get_buttonpress() == 3)
4711 gui->plugin_menu->update(plugin);
4712 gui->plugin_menu->activate_menu();
4716 // Select range of plugin on doubleclick over plugin
4717 if (get_double_click() && !drag_start)
4719 mwindow->edl->local_session->set_selectionstart(plugin->track->from_units(plugin->startproject));
4720 mwindow->edl->local_session->set_selectionend(plugin->track->from_units(plugin->startproject) +
4721 plugin->track->from_units(plugin->length));
4722 if(mwindow->edl->session->cursor_on_frames)
4724 mwindow->edl->local_session->set_selectionstart(
4725 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionstart(1), 0));
4726 mwindow->edl->local_session->set_selectionend(
4727 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionend(1), 1));
4736 if(drag_start && plugin->track->record)
4738 if(mwindow->edl->session->editing_mode == EDITING_ARROW)
4740 if(plugin->track->data_type == TRACK_AUDIO)
4741 mwindow->session->current_operation = DRAG_AEFFECT_COPY;
4743 if(plugin->track->data_type == TRACK_VIDEO)
4744 mwindow->session->current_operation = DRAG_VEFFECT_COPY;
4746 mwindow->session->drag_plugin = plugin;
4753 switch(plugin->plugin_type)
4755 case PLUGIN_STANDALONE:
4757 PluginServer *server = mwindow->scan_plugindb(
4759 plugin->track->data_type);
4762 VFrame *frame = server->picon;
4763 //printf("TrackCanvas::test_plugins 7\n");
4764 drag_popup = new BC_DragWindow(gui,
4766 get_abs_cursor_x(0) - frame->get_w() / 2,
4767 get_abs_cursor_y(0) - frame->get_h() / 2);
4772 case PLUGIN_SHAREDPLUGIN:
4773 case PLUGIN_SHAREDMODULE:
4774 drag_popup = new BC_DragWindow(gui,
4775 mwindow->theme->get_image("clip_icon"),
4776 get_abs_cursor_x(0) - mwindow->theme->get_image("clip_icon")->get_w() / 2,
4777 get_abs_cursor_y(0) - mwindow->theme->get_image("clip_icon")->get_h() / 2);
4790 int TrackCanvas::do_transitions(int cursor_x,
4796 Transition *transition = 0;
4802 if(!mwindow->edl->session->show_assets ||
4803 !mwindow->edl->session->auto_conf->transitions) return 0;
4807 for(Track *track = mwindow->edl->tracks->first;
4809 track = track->next)
4811 for(Edit *edit = track->edits->first;
4815 if(edit->transition)
4817 edit_dimensions(edit, x, y, w, h);
4818 get_transition_coords(x, y, w, h);
4820 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
4821 MWindowGUI::visible(y, y + h, 0, get_h()))
4823 if(cursor_x >= x && cursor_x < x + w &&
4824 cursor_y >= y && cursor_y < y + h)
4826 transition = edit->transition;
4840 new_cursor = UPRIGHT_ARROW_CURSOR;
4843 if(get_buttonpress() == 3)
4845 gui->transition_menu->update(transition);
4846 gui->transition_menu->activate_menu();
4853 int TrackCanvas::button_press_event()
4856 int cursor_x, cursor_y;
4857 int new_cursor, update_cursor;
4859 cursor_x = get_cursor_x();
4860 cursor_y = get_cursor_y();
4861 mwindow->session->trim_edits = 0;
4863 if(is_event_win() && cursor_inside())
4865 double position = (double)cursor_x *
4866 mwindow->edl->local_session->zoom_sample /
4867 mwindow->edl->session->sample_rate +
4868 (double)mwindow->edl->local_session->view_start *
4869 mwindow->edl->local_session->zoom_sample /
4870 mwindow->edl->session->sample_rate;
4878 if(get_buttonpress() == 1)
4880 gui->unlock_window();
4881 gui->mbuttons->transport->handle_transport(STOP, 1);
4882 gui->lock_window("TrackCanvas::button_press_event");
4885 int update_overlay = 0, update_cursor = 0, rerender = 0;
4887 if(get_buttonpress() == 4)
4890 mwindow->expand_sample();
4892 mwindow->move_up(get_h() / 10);
4896 if(get_buttonpress() == 5)
4899 mwindow->zoom_in_sample();
4901 mwindow->move_down(get_h() / 10);
4905 switch(mwindow->edl->session->editing_mode)
4907 // Test handles and resource boundaries and highlight a track
4912 if(mwindow->edl->session->auto_conf->transitions &&
4913 do_transitions(cursor_x,
4922 if(do_keyframes(cursor_x,
4933 // Test edit boundaries
4934 if(do_edit_handles(cursor_x,
4943 // Test plugin boundaries
4944 if(do_plugin_handles(cursor_x,
4953 if(do_edits(cursor_x, cursor_y, 1, 0, update_cursor, rerender, new_cursor, update_cursor))
4958 if(do_plugins(cursor_x, cursor_y, 0, 1, update_cursor, rerender))
4963 if(test_resources(cursor_x, cursor_y))
4968 if(do_tracks(cursor_x, cursor_y, 1))
4975 // Test handles only and select a region
4978 //printf("TrackCanvas::button_press_event %d\n", position);
4980 if(mwindow->edl->session->auto_conf->transitions &&
4981 do_transitions(cursor_x,
4990 if(do_keyframes(cursor_x,
5002 // Test edit boundaries
5003 if(do_edit_handles(cursor_x,
5012 // Test plugin boundaries
5013 if(do_plugin_handles(cursor_x,
5022 if(do_edits(cursor_x,
5034 if(do_plugins(cursor_x,
5044 if(do_tracks(cursor_x, cursor_y, 1))
5048 // Highlight selection
5051 rerender = start_selection(position);
5052 mwindow->session->current_operation = SELECT_REGION;
5063 gui->unlock_window();
5064 mwindow->cwindow->update(1, 0, 0, 0, 1);
5065 gui->lock_window("TrackCanvas::button_press_event 2");
5067 mwindow->update_plugin_guis();
5068 gui->patchbay->update();
5079 gui->timebar->update_highlights();
5080 gui->cursor->hide();
5081 gui->cursor->show();
5082 gui->zoombar->update();
5093 int TrackCanvas::start_selection(double position)
5096 position = mwindow->edl->align_to_frame(position, 0);
5101 double midpoint = (mwindow->edl->local_session->get_selectionstart(1) +
5102 mwindow->edl->local_session->get_selectionend(1)) / 2;
5104 if(position < midpoint)
5106 mwindow->edl->local_session->set_selectionstart(position);
5107 selection_midpoint1 = mwindow->edl->local_session->get_selectionend(1);
5113 mwindow->edl->local_session->set_selectionend(position);
5114 selection_midpoint1 = mwindow->edl->local_session->get_selectionstart(1);
5115 // Don't que the CWindow for the end
5119 // Start a new selection
5121 //printf("TrackCanvas::start_selection %f\n", position);
5122 mwindow->edl->local_session->set_selectionstart(position);
5123 mwindow->edl->local_session->set_selectionend(position);
5124 selection_midpoint1 = position;
5132 void TrackCanvas::end_edithandle_selection()
5134 mwindow->modify_edithandles();
5137 void TrackCanvas::end_pluginhandle_selection()
5139 mwindow->modify_pluginhandles();
5143 double TrackCanvas::time_visible()
5145 return (double)get_w() *
5146 mwindow->edl->local_session->zoom_sample /
5147 mwindow->edl->session->sample_rate;
5190 void TrackCanvas::draw_automation()
5195 int TrackCanvas::set_index_file(int flash, Asset *asset)
5201 int TrackCanvas::button_release()
5207 int TrackCanvas::auto_reposition(int &cursor_x, int &cursor_y, int64_t cursor_position)
5213 int TrackCanvas::draw_floating_handle(int flash)
5218 int TrackCanvas::draw_loop_point(int64_t position, int flash)
5223 int TrackCanvas::draw_playback_cursor(int pixel, int flash)
5229 int TrackCanvas::update_handle_selection(int64_t cursor_position)
5234 int TrackCanvas::end_translation()