3 #include "automation.h"
11 #include "cwindowgui.h"
12 #include "edithandles.h"
13 #include "editpopup.h"
16 #include "edlsession.h"
17 #include "floatauto.h"
18 #include "floatautos.h"
21 #include "keyframepopup.h"
22 #include "keyframes.h"
24 #include "localsession.h"
25 #include "mainclock.h"
26 #include "maincursor.h"
28 #include "maskautos.h"
32 #include "mwindowgui.h"
36 #include "resourcethread.h"
37 #include "playbackengine.h"
38 #include "playtransport.h"
40 #include "pluginpopup.h"
41 #include "pluginset.h"
42 #include "pluginserver.h"
43 #include "plugintoggles.h"
44 #include "preferences.h"
45 #include "resourcepixmap.h"
46 #include "mainsession.h"
47 #include "transitionhandles.h"
48 #include "transitionpopup.h"
49 #include "transportque.h"
53 #include "trackcanvas.h"
55 #include "transition.h"
57 #include "apatchgui.inc"
58 #include "vpatchgui.inc"
62 TrackCanvas::TrackCanvas(MWindow *mwindow, MWindowGUI *gui)
63 : BC_SubWindow(mwindow->theme->mcanvas_x,
64 mwindow->theme->mcanvas_y,
68 this->mwindow = mwindow;
71 selection_midpoint1 = selection_midpoint2 = 0;
76 translate_selected = 0;
83 resource_timer = new Timer;
84 hourglass_enabled = 0;
85 resource_thread = new ResourceThread(mwindow);
88 TrackCanvas::~TrackCanvas()
90 for(int i = 0; i < resource_pixmaps.total; i++)
91 delete resource_pixmaps.values[i];
92 // delete transition_handles;
94 delete keyframe_pixmap;
95 delete camerakeyframe_pixmap;
96 delete modekeyframe_pixmap;
97 delete pankeyframe_pixmap;
98 delete projectorkeyframe_pixmap;
99 delete maskkeyframe_pixmap;
100 delete background_pixmap;
101 if(temp_picon) delete temp_picon;
102 delete resource_timer;
105 int TrackCanvas::create_objects()
107 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
108 // transition_handles = new TransitionHandles(mwindow, this);
109 edit_handles = new EditHandles(mwindow, this);
110 keyframe_pixmap = new BC_Pixmap(this, mwindow->theme->keyframe_data, PIXMAP_ALPHA);
111 camerakeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->camerakeyframe_data, PIXMAP_ALPHA);
112 modekeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->modekeyframe_data, PIXMAP_ALPHA);
113 pankeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->pankeyframe_data, PIXMAP_ALPHA);
114 projectorkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->projectorkeyframe_data, PIXMAP_ALPHA);
115 maskkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->maskkeyframe_data, PIXMAP_ALPHA);
116 resource_thread->create_objects();
123 void TrackCanvas::resize_event()
125 //printf("TrackCanvas::resize_event 1\n");
128 //printf("TrackCanvas::resize_event 2\n");
131 int TrackCanvas::keypress_event()
139 int TrackCanvas::drag_motion()
141 int cursor_x = get_relative_cursor_x();
142 int cursor_y = get_relative_cursor_y();
143 Track *over_track = 0;
145 PluginSet *over_pluginset = 0;
146 Plugin *over_plugin = 0;
152 drag_popup->cursor_motion_event();
156 // there's no point in drawing highlights has until drag operation has been set
157 if (!mwindow->session->current_operation)
160 if(get_cursor_over_window() &&
163 cursor_x < get_w() &&
166 // Find the edit and track the cursor is over
167 for(Track *track = mwindow->edl->tracks->first; track; track = track->next)
169 int64_t track_x, track_y, track_w, track_h;
170 track_dimensions(track, track_x, track_y, track_w, track_h);
172 if(cursor_y >= track_y &&
173 cursor_y < track_y + track_h)
176 for(Edit *edit = track->edits->first; edit; edit = edit->next)
178 if (mwindow->session->current_operation != DRAG_ATRANSITION &&
179 mwindow->session->current_operation != DRAG_VTRANSITION &&
180 edit == track->edits->last)
182 int64_t edit_x, edit_y, edit_w, edit_h;
183 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
185 if(cursor_x >= edit_x &&
186 cursor_y >= edit_y &&
187 cursor_x < edit_x + edit_w &&
188 cursor_y < edit_y + edit_h)
195 for(int i = 0; i < track->plugin_set.total; i++)
197 PluginSet *pluginset = track->plugin_set.values[i];
201 for(Plugin *plugin = (Plugin*)pluginset->first;
202 plugin != pluginset->last;
203 plugin = (Plugin*)plugin->next)
205 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
206 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
208 if(cursor_y >= plugin_y &&
209 cursor_y < plugin_y + plugin_h)
211 over_pluginset = plugin->plugin_set;
213 if(cursor_x >= plugin_x &&
214 cursor_x < plugin_x + plugin_w)
216 over_plugin = plugin;
227 if (!over_track) // check for pastes from patchbay
228 over_track = mwindow->gui->patchbay->is_over_track();
230 if(mwindow->session->track_highlighted != over_track)
232 mwindow->session->track_highlighted = over_track;
236 if(mwindow->session->edit_highlighted != over_edit)
238 mwindow->session->edit_highlighted = over_edit;
242 if(mwindow->session->pluginset_highlighted != over_pluginset)
244 mwindow->session->pluginset_highlighted = over_pluginset;
248 if(mwindow->session->plugin_highlighted != over_plugin)
250 mwindow->session->plugin_highlighted = over_plugin;
254 if (mwindow->session->current_operation == DRAG_ASSET ||
255 mwindow->session->current_operation == DRAG_EDIT)
262 lock_window("TrackCanvas::drag_motion");
271 int TrackCanvas::drag_start_event()
276 int new_cursor, update_cursor;
278 if(mwindow->session->current_operation != NO_OPERATION) return 0;
282 if(do_plugins(get_drag_x(),
292 if(do_edits(get_drag_x(),
308 int TrackCanvas::drag_motion_event()
310 return drag_motion();
313 int TrackCanvas::cursor_leave_event()
315 // Because drag motion calls get_cursor_over_window we can be sure that
316 // all highlights get deleted now.
317 // This ended up blocking keyboard input from the drag operations.
319 // return drag_motion();
323 int TrackCanvas::drag_stop_event()
325 int result = drag_stop();
336 int TrackCanvas::drag_stop()
338 // In most cases the editing routine redraws and not the drag_stop
339 int result = 0, redraw = 0;
341 int insertion = 0; // used in drag and drop mode
342 switch(mwindow->session->current_operation)
344 case DRAG_VTRANSITION:
345 case DRAG_ATRANSITION:
346 if(mwindow->session->edit_highlighted)
348 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
349 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
350 (mwindow->session->current_operation == DRAG_VTRANSITION &&
351 mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
353 mwindow->session->current_operation = NO_OPERATION;
354 mwindow->paste_transition();
364 // Behavior for dragged plugins is limited by the fact that a shared plugin
365 // can only refer to a standalone plugin that exists in the same position in
366 // time. Dragging a plugin from one point in time to another can't produce
367 // a shared plugin to the original plugin. In this case we relocate the
368 // plugin instead of sharing it.
369 case DRAG_AEFFECT_COPY:
370 case DRAG_VEFFECT_COPY:
371 if(mwindow->session->track_highlighted &&
372 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY &&
373 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
374 (mwindow->session->current_operation == DRAG_VEFFECT_COPY &&
375 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
377 mwindow->session->current_operation = NO_OPERATION;
379 // Insert shared plugin in source
380 if(mwindow->session->track_highlighted != mwindow->session->drag_plugin->track &&
381 !mwindow->session->plugin_highlighted &&
382 !mwindow->session->pluginset_highlighted)
384 // Move plugin if different startproject
385 mwindow->move_effect(mwindow->session->drag_plugin,
387 mwindow->session->track_highlighted,
392 // Move source to different location
393 if(mwindow->session->pluginset_highlighted)
395 //printf("TrackCanvas::drag_stop 6\n");
396 if(mwindow->session->plugin_highlighted)
398 mwindow->move_effect(mwindow->session->drag_plugin,
399 mwindow->session->plugin_highlighted->plugin_set,
401 mwindow->session->plugin_highlighted->startproject);
405 mwindow->move_effect(mwindow->session->drag_plugin,
406 mwindow->session->pluginset_highlighted,
408 mwindow->session->pluginset_highlighted->last->startproject);
413 // Move to a new plugin set between two edits
414 if(mwindow->session->edit_highlighted)
416 mwindow->move_effect(mwindow->session->drag_plugin,
418 mwindow->session->track_highlighted,
419 mwindow->session->edit_highlighted->startproject);
423 // Move to a new plugin set
424 if(mwindow->session->track_highlighted)
426 mwindow->move_effect(mwindow->session->drag_plugin,
428 mwindow->session->track_highlighted,
437 if(mwindow->session->track_highlighted &&
438 ((mwindow->session->current_operation == DRAG_AEFFECT &&
439 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
440 (mwindow->session->current_operation == DRAG_VEFFECT &&
441 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
443 // Drop all the effects
444 PluginSet *plugin_set = mwindow->session->pluginset_highlighted;
445 Track *track = mwindow->session->track_highlighted;
447 double length = track->get_length();
449 if(mwindow->session->plugin_highlighted)
451 start = track->from_units(mwindow->session->plugin_highlighted->startproject);
452 length = track->from_units(mwindow->session->plugin_highlighted->length);
453 if(length <= 0) length = track->get_length();
456 if(mwindow->session->pluginset_highlighted)
458 start = track->from_units(plugin_set->last->startproject);
459 length = track->get_length() - start;
460 if(length <= 0) length = track->get_length();
463 if(mwindow->edl->local_session->get_selectionend() >
464 mwindow->edl->local_session->get_selectionstart())
466 start = mwindow->edl->local_session->get_selectionstart();
467 length = mwindow->edl->local_session->get_selectionend() -
468 mwindow->edl->local_session->get_selectionstart();
470 // Move to a point between two edits
472 if(mwindow->session->edit_highlighted)
474 start = mwindow->session->track_highlighted->from_units(
475 mwindow->session->edit_highlighted->startproject);
476 length = mwindow->session->track_highlighted->from_units(
477 mwindow->session->edit_highlighted->length);
480 mwindow->insert_effects_canvas(start, length);
483 if (mwindow->session->track_highlighted)
484 result = 1; // we have to cleanup
488 if(mwindow->session->track_highlighted)
490 float asset_length_float;
491 int64_t asset_length_units;
492 int64_t position = 0;
494 if(mwindow->session->current_operation == DRAG_ASSET &&
495 mwindow->session->drag_assets->total)
497 Asset *asset = mwindow->session->drag_assets->values[0];
498 // we use video if we are over video and audio if we are over audio
499 if (asset->video_data && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
501 // Images have length -1
502 double video_length = asset->video_length;
503 if (video_length < 0)
505 if(mwindow->edl->session->si_useduration)
506 video_length = mwindow->edl->session->si_duration;
508 video_length = 1.0 / mwindow->edl->session->frame_rate ;
510 asset_length_float = video_length / asset->frame_rate;
512 else if (asset->audio_data && mwindow->session->track_highlighted->data_type == TRACK_AUDIO)
513 asset_length_float = asset->audio_length / asset->sample_rate;
517 break; // Do not do anything
520 if(mwindow->session->current_operation == DRAG_ASSET &&
521 mwindow->session->drag_clips->total)
523 EDL *clip = mwindow->session->drag_clips->values[0];
524 asset_length_float = clip->tracks->total_length();
527 printf("DRAG_ASSET error: Asset dropped, but both drag_clips and drag_assets total is zero\n");
530 asset_length_units = mwindow->session->track_highlighted->to_units(asset_length_float, 1);
531 position = get_drop_position (&insertion, NULL, asset_length_units);
535 break; // Do not do anything
538 double position_f = mwindow->session->track_highlighted->from_units(position);
539 Track *track = mwindow->session->track_highlighted;
543 // // FIXME, we should create an mwindow/EDL method that overwrites, without clearing the keyframes and autos
544 // // Unfortunately, this is _a lot_ of work to do right
545 // printf("Problematic insertion\n");
546 // mwindow->edl->tracks->clear(position_f,
547 // position_f + asset_length_float, 0);
549 mwindow->paste_assets(position_f, track, !insertion);
550 result = 1; // need to be one no matter what, since we have track highlited so we have to cleanup....
555 mwindow->session->current_operation = NO_OPERATION;
556 if(mwindow->session->track_highlighted)
558 if(mwindow->session->track_highlighted->data_type == mwindow->session->drag_edit->track->data_type)
560 int64_t position = 0;
562 position = get_drop_position (&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length);
567 break; // Do not do anything
570 double 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 mode, int hide_cursor)
765 // Swap pixmap layers
766 if(get_w() != background_pixmap->get_w() ||
767 get_h() != background_pixmap->get_h())
769 delete background_pixmap;
770 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
773 // Cursor disappears after resize when this is called.
774 // Cursor doesn't redraw after editing when this isn't called.
775 if(gui->cursor && hide_cursor) gui->cursor->hide();
776 draw_top_background(get_parent(), 0, 0, get_w(), get_h(), background_pixmap);
777 draw_resources(mode);
781 void TrackCanvas::update_cursor()
783 switch(mwindow->edl->session->editing_mode)
785 case EDITING_ARROW: set_cursor(ARROW_CURSOR); break;
786 case EDITING_IBEAM: set_cursor(IBEAM_CURSOR); break;
791 void TrackCanvas::test_timer()
793 if(resource_timer->get_difference() > 1000 &&
797 hourglass_enabled = 1;
802 void TrackCanvas::draw_indexes(Asset *asset)
804 // Don't redraw raw samples
805 if(asset->index_zoom > mwindow->edl->local_session->zoom_sample)
808 draw_resources(0, 1, asset);
816 void TrackCanvas::draw_resources(int mode,
820 if(!mwindow->edl->session->show_assets) return;
822 if(mode != 3 && !indexes_only)
823 resource_thread->stop_draw(!indexes_only);
825 resource_timer->update();
827 // Age resource pixmaps for deletion
829 for(int i = 0; i < resource_pixmaps.total; i++)
830 resource_pixmaps.values[i]->visible--;
833 resource_pixmaps.remove_all_objects();
837 for(Track *current = mwindow->edl->tracks->first;
841 for(Edit *edit = current->edits->first; edit; edit = edit->next)
843 if(!edit->asset) continue;
846 if(edit->track->data_type != TRACK_AUDIO) continue;
847 if(!edit->asset->test_path(index_asset->path)) continue;
850 int64_t edit_x, edit_y, edit_w, edit_h;
851 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
854 if(MWindowGUI::visible(edit_x, edit_x + edit_w, 0, get_w()) &&
855 MWindowGUI::visible(edit_y, edit_y + edit_h, 0, get_h()))
857 int64_t pixmap_x, pixmap_w, pixmap_h;
859 // Search for existing pixmap containing edit
860 for(int i = 0; i < resource_pixmaps.total; i++)
862 ResourcePixmap* pixmap = resource_pixmaps.values[i];
863 // Same pointer can be different edit if editing took place
864 if(pixmap->edit_id == edit->id)
871 // Get new size, offset of pixmap needed
872 get_pixmap_size(edit,
880 if(pixmap_w && pixmap_h)
882 // Create pixmap if it doesn't exist
883 ResourcePixmap* pixmap = create_pixmap(edit,
888 // Resize it if it's bigger
889 if(pixmap_w > pixmap->pixmap_w ||
890 pixmap_h > pixmap->pixmap_h)
891 pixmap->resize(pixmap_w, pixmap_h);
892 pixmap->draw_data(edit,
900 // Resize it if it's smaller
901 if(pixmap_w < pixmap->pixmap_w ||
902 pixmap_h < pixmap->pixmap_h)
903 pixmap->resize(pixmap_w, pixmap_h);
905 // Copy pixmap to background canvas
906 background_pixmap->draw_pixmap(pixmap,
916 // Delete unused pixmaps
918 for(int i = resource_pixmaps.total - 1; i >= 0; i--)
919 if(resource_pixmaps.values[i]->visible < -5)
921 delete resource_pixmaps.values[i];
922 resource_pixmaps.remove(resource_pixmaps.values[i]);
925 if(hourglass_enabled)
928 hourglass_enabled = 0;
931 if(mode != 3 && !indexes_only)
932 resource_thread->start_draw();
935 ResourcePixmap* TrackCanvas::create_pixmap(Edit *edit,
941 ResourcePixmap *result = 0;
943 for(int i = 0; i < resource_pixmaps.total; i++)
945 //printf("TrackCanvas::create_pixmap 1 %d %d\n", edit->id, resource_pixmaps.values[i]->edit->id);
946 if(resource_pixmaps.values[i]->edit_id == edit->id)
948 result = resource_pixmaps.values[i];
955 //printf("TrackCanvas::create_pixmap 2\n");
956 result = new ResourcePixmap(mwindow,
961 resource_pixmaps.append(result);
964 // result->resize(pixmap_w, pixmap_h);
968 void TrackCanvas::get_pixmap_size(Edit *edit,
976 // Align x on frame boundaries
979 // switch(edit->edits->track->data_type)
991 if(pixmap_x + pixmap_w > get_w())
993 pixmap_w = get_w() - pixmap_x;
1000 // int64_t picon_w = (int64_t)(edit->picon_w() + 0.5);
1001 // int64_t frame_w = (int64_t)(edit->frame_w() + 0.5);
1002 // int64_t pixel_increment = MAX(picon_w, frame_w);
1003 // int64_t pixmap_x1 = edit_x;
1004 // int64_t pixmap_x2 = edit_x + edit_w;
1006 // if(pixmap_x1 < 0)
1008 // pixmap_x1 = (int64_t)((double)-edit_x / pixel_increment) *
1009 // pixel_increment +
1013 // if(pixmap_x2 > get_w())
1015 // pixmap_x2 = (int64_t)((double)(get_w() - edit_x) / pixel_increment + 1) *
1016 // pixel_increment +
1019 // pixmap_x = pixmap_x1;
1020 // pixmap_w = pixmap_x2 - pixmap_x1;
1025 pixmap_h = mwindow->edl->local_session->zoom_track;
1026 if(mwindow->edl->session->show_titles) pixmap_h += mwindow->theme->get_image("title_bg_data")->get_h();
1027 //printf("get_pixmap_size %d %d %d %d\n", edit_x, edit_w, pixmap_x, pixmap_w);
1030 void TrackCanvas::edit_dimensions(Edit *edit,
1036 // w = Units::round(edit->track->from_units(edit->length) *
1037 // mwindow->edl->session->sample_rate /
1038 // mwindow->edl->local_session->zoom_sample);
1042 x = Units::round(edit->track->from_units(edit->startproject) *
1043 mwindow->edl->session->sample_rate /
1044 mwindow->edl->local_session->zoom_sample -
1045 mwindow->edl->local_session->view_start);
1047 // Method for calculating w so when edits are together we never get off by one error due to rounding
1048 int64_t x_next = Units::round(edit->track->from_units(edit->startproject + edit->length) *
1049 mwindow->edl->session->sample_rate /
1050 mwindow->edl->local_session->zoom_sample -
1051 mwindow->edl->local_session->view_start);
1054 y = edit->edits->track->y_pixel;
1056 if(mwindow->edl->session->show_titles)
1057 h += mwindow->theme->get_image("title_bg_data")->get_h();
1060 void TrackCanvas::track_dimensions(Track *track, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1065 h = track->vertical_span(mwindow->theme);
1069 void TrackCanvas::draw_paste_destination()
1071 int current_atrack = 0;
1072 int current_vtrack = 0;
1073 int current_aedit = 0;
1074 int current_vedit = 0;
1081 if((mwindow->session->current_operation == DRAG_ASSET &&
1082 (mwindow->session->drag_assets->total ||
1083 mwindow->session->drag_clips->total)) ||
1084 (mwindow->session->current_operation == DRAG_EDIT &&
1085 mwindow->session->drag_edits->total))
1092 if(mwindow->session->current_operation == DRAG_ASSET &&
1093 mwindow->session->drag_assets->total)
1094 asset = mwindow->session->drag_assets->values[0];
1096 if(mwindow->session->current_operation == DRAG_ASSET &&
1097 mwindow->session->drag_clips->total)
1098 clip = mwindow->session->drag_clips->values[0];
1100 // Get destination track
1101 for(Track *dest = mwindow->session->track_highlighted;
1107 // Get source width in pixels
1110 // Use start of highlighted edit
1111 if(mwindow->session->edit_highlighted)
1112 position = mwindow->session->track_highlighted->from_units(
1113 mwindow->session->edit_highlighted->startproject);
1115 // Use end of highlighted track, disregarding effects
1116 position = mwindow->session->track_highlighted->from_units(
1117 mwindow->session->track_highlighted->edits->last->startproject);
1120 if(dest->data_type == TRACK_AUDIO)
1122 if(asset && current_atrack < asset->channels)
1124 w = Units::to_int64((double)asset->audio_length /
1125 asset->sample_rate *
1126 mwindow->edl->session->sample_rate /
1127 mwindow->edl->local_session->zoom_sample);
1129 // FIXME: more obvious, get_drop_position should be called only ONCE - for highlighted track
1130 int64_t asset_length;
1131 // we use video if we are over video and audio if we are over audio
1132 if (asset->video_data && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
1134 // Images have length -1
1135 double video_length = asset->video_length;
1136 if (video_length < 0)
1138 if(mwindow->edl->session->si_useduration)
1139 video_length = mwindow->edl->session->si_duration;
1141 video_length = 1.0 / mwindow->edl->session->frame_rate ;
1143 asset_length = mwindow->session->track_highlighted->to_units(video_length / asset->frame_rate, 1);
1146 asset_length = mwindow->session->track_highlighted->to_units(asset->audio_length / asset->sample_rate, 1);
1148 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1158 if(clip && current_atrack < clip->tracks->total_audio_tracks())
1160 w = Units::to_int64((double)clip->tracks->total_length() *
1161 mwindow->edl->session->sample_rate /
1162 mwindow->edl->local_session->zoom_sample);
1163 //printf("draw_paste_destination %d\n", x);
1164 int64_t asset_length = mwindow->session->track_highlighted->to_units((double)clip->tracks->total_length(), 1);
1166 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1176 if(mwindow->session->current_operation == DRAG_EDIT &&
1177 current_aedit < mwindow->session->drag_edits->total)
1180 while(current_aedit < mwindow->session->drag_edits->total &&
1181 mwindow->session->drag_edits->values[current_aedit]->track->data_type != TRACK_AUDIO)
1184 if(current_aedit < mwindow->session->drag_edits->total)
1186 edit = mwindow->session->drag_edits->values[current_aedit];
1187 w = Units::to_int64(edit->length / mwindow->edl->local_session->zoom_sample);
1189 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length));
1201 if(dest->data_type == TRACK_VIDEO)
1203 //printf("draw_paste_destination 1\n");
1204 if(asset && current_vtrack < asset->layers)
1206 // Images have length -1
1207 double video_length = asset->video_length;
1208 if (video_length < 0)
1210 if(mwindow->edl->session->si_useduration)
1211 video_length = mwindow->edl->session->si_duration;
1213 video_length = 1.0 / mwindow->edl->session->frame_rate ;
1215 w = Units::to_int64((double)video_length /
1217 mwindow->edl->session->sample_rate /
1218 mwindow->edl->local_session->zoom_sample);
1219 int64_t asset_length = mwindow->session->track_highlighted->to_units((double)video_length /
1220 asset->frame_rate, 1);
1222 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1232 if(clip && current_vtrack < clip->tracks->total_video_tracks())
1234 w = Units::to_int64(clip->tracks->total_length() *
1235 mwindow->edl->session->sample_rate /
1236 mwindow->edl->local_session->zoom_sample);
1237 int64_t asset_length = mwindow->session->track_highlighted->to_units((double)clip->tracks->total_length(), 1);
1239 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, NULL, asset_length));
1249 if(mwindow->session->current_operation == DRAG_EDIT &&
1250 current_vedit < mwindow->session->drag_edits->total)
1253 while(current_vedit < mwindow->session->drag_edits->total &&
1254 mwindow->session->drag_edits->values[current_vedit]->track->data_type != TRACK_VIDEO)
1257 if(current_vedit < mwindow->session->drag_edits->total)
1259 edit = mwindow->session->drag_edits->values[current_vedit];
1260 w = Units::to_int64(edit->track->from_units(edit->length) *
1261 mwindow->edl->session->sample_rate /
1262 mwindow->edl->local_session->zoom_sample);
1264 position = mwindow->session->track_highlighted->from_units(get_drop_position(&insertion, mwindow->session->drag_edit, mwindow->session->drag_edit->length));
1278 // Get the x coordinate
1279 x = Units::to_int64(position *
1280 mwindow->edl->session->sample_rate /
1281 mwindow->edl->local_session->zoom_sample) -
1282 mwindow->edl->local_session->view_start;
1283 int y = dest->y_pixel;
1284 int h = dest->vertical_span(mwindow->theme);
1287 //printf("TrackCanvas::draw_paste_destination 2 %d %d %d %d\n", x, y, w, h);
1289 draw_highlight_insertion(x, y, w, h);
1291 draw_highlight_rectangle(x, y, w, h);
1298 void TrackCanvas::plugin_dimensions(Plugin *plugin, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1300 x = Units::round(plugin->track->from_units(plugin->startproject) *
1301 mwindow->edl->session->sample_rate /
1302 mwindow->edl->local_session->zoom_sample -
1303 mwindow->edl->local_session->view_start);
1304 w = Units::round(plugin->track->from_units(plugin->length) *
1305 mwindow->edl->session->sample_rate /
1306 mwindow->edl->local_session->zoom_sample);
1307 y = plugin->track->y_pixel +
1308 mwindow->edl->local_session->zoom_track +
1309 plugin->plugin_set->get_number() *
1310 mwindow->theme->get_image("plugin_bg_data")->get_h();
1311 if(mwindow->edl->session->show_titles)
1312 y += mwindow->theme->get_image("title_bg_data")->get_h();
1313 h = mwindow->theme->get_image("plugin_bg_data")->get_h();
1316 int TrackCanvas::resource_h()
1318 return mwindow->edl->local_session->zoom_track;
1321 void TrackCanvas::draw_highlight_rectangle(int x, int y, int w, int h)
1324 // if we have to draw a highlighted rectangle completely on the left or completely on the right of the viewport,
1325 // just draw arrows, so user has indication that something is there
1326 // FIXME: get better colors
1330 draw_triangle_left(0, y + h /6, h * 2/3, h * 2/3, BLACK, GREEN, YELLOW, RED, BLUE);
1335 draw_triangle_right(get_w() - h * 2/3, y + h /6, h * 2/3, h * 2/3, BLACK, GREEN, YELLOW, RED, BLUE);
1339 // Fix bug in heroines & cvs version as of 22.8.2005:
1340 // If we grab when zoomed in and zoom out while dragging, when edit gets really narrow strange things start happening
1341 if (w >= 0 && w < 3) {x -= w /2; w = 3;};
1352 w = MIN(w, get_w() + 20);
1353 h = MIN(h, get_h() + 20);
1356 draw_rectangle(x, y, w, h);
1357 draw_rectangle(x + 1, y + 1, w - 2, h - 2);
1359 //printf("TrackCanvas::draw_highlight_rectangle %d %d %d %d\n", x, y, w, h);
1362 void TrackCanvas::draw_highlight_insertion(int x, int y, int w, int h)
1365 // if we have to draw a highlighted rectangle completely on the left or completely on the right of the viewport,
1366 // just draw arrows, so user has indication that something is there
1367 // FIXME: get better colors
1376 /* these don't look so good
1378 draw_line(x, y, x, y+h);
1379 draw_line(x - h2 * 2, y + h1*2, x - h2, y+h1*2);
1380 draw_line(x - h2 * 2, y + h1*2+1, x - h2, y+h1*2+1);
1381 draw_line(x - h2 * 2, y + h1*6, x - h2, y+h1*6);
1382 draw_line(x - h2 * 2, y + h1*6+1, x - h2, y+h1*6+1);
1384 draw_triangle_right(x - h2, y + h1, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1385 draw_triangle_right(x - h2, y + h1*5, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1387 /* draw_line(x + h2 * 2, y + h1*2, x + h2, y+h1*2);
1388 draw_line(x + h2 * 2, y + h1*2+1, x + h2, y+h1*2+1);
1389 draw_line(x + h2 * 2, y + h1*6, x + h2, y+h1*6);
1390 draw_line(x - h2 * 2, y + h1*6+1, x + h2, y+h1*6+1);
1392 draw_triangle_left(x, y + h1, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1393 draw_triangle_left(x, y + h1*5, h2, h2, BLACK, GREEN, YELLOW, RED, BLUE);
1395 // draw the box centred around x
1397 // Fix bug in heroines & cvs version as of 22.8.2005:
1398 // If we grab when zoomed in and zoom out while dragging, when edit gets really narrow strange things start happening
1399 if (w >= 0 && w < 3) {x -= w /2; w = 3;};
1410 w = MIN(w, get_w() + 20);
1411 h = MIN(h, get_h() + 20);
1414 draw_rectangle(x, y, w, h);
1415 draw_rectangle(x + 1, y + 1, w - 2, h - 2);
1417 //printf("TrackCanvas::draw_highlight_insertion %d %d %d %d\n", x, y, w, h);
1420 void TrackCanvas::draw_playback_cursor()
1422 // Called before playback_cursor exists
1423 // if(mwindow->playback_cursor && mwindow->playback_cursor->visible)
1425 // mwindow->playback_cursor->visible = 0;
1426 // mwindow->playback_cursor->draw();
1430 void TrackCanvas::get_handle_coords(Edit *edit, int64_t &x, int64_t &y, int64_t &w, int64_t &h, int side)
1432 int handle_w = mwindow->theme->edithandlein_data[0]->get_w();
1433 int handle_h = mwindow->theme->edithandlein_data[0]->get_h();
1435 edit_dimensions(edit, x, y, w, h);
1437 if(mwindow->edl->session->show_titles)
1439 y += mwindow->theme->get_image("title_bg_data")->get_h();
1446 if(side == EDIT_OUT)
1455 void TrackCanvas::get_transition_coords(int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1457 //printf("TrackCanvas::get_transition_coords 1\n");
1458 // int transition_w = mwindow->theme->transitionhandle_data[0]->get_w();
1459 // int transition_h = mwindow->theme->transitionhandle_data[0]->get_h();
1460 int transition_w = 30;
1461 int transition_h = 30;
1462 //printf("TrackCanvas::get_transition_coords 1\n");
1464 if(mwindow->edl->session->show_titles)
1465 y += mwindow->theme->get_image("title_bg_data")->get_h();
1466 //printf("TrackCanvas::get_transition_coords 2\n");
1468 y += (h - mwindow->theme->get_image("title_bg_data")->get_h()) / 2 - transition_h / 2;
1469 x -= transition_w / 2;
1475 void TrackCanvas::draw_highlighting()
1483 switch(mwindow->session->current_operation)
1485 case DRAG_ATRANSITION:
1486 case DRAG_VTRANSITION:
1487 //printf("TrackCanvas::draw_highlighting 1 %p %p\n",
1488 // mwindow->session->track_highlighted, mwindow->session->edit_highlighted);
1489 if(mwindow->session->edit_highlighted)
1491 //printf("TrackCanvas::draw_highlighting 2\n");
1492 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
1493 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1494 (mwindow->session->current_operation == DRAG_VTRANSITION &&
1495 mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
1497 //printf("TrackCanvas::draw_highlighting 2\n");
1498 edit_dimensions(mwindow->session->edit_highlighted, x, y, w, h);
1499 //printf("TrackCanvas::draw_highlighting 2\n");
1501 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1502 MWindowGUI::visible(y, y + h, 0, get_h()))
1505 get_transition_coords(x, y, w, h);
1507 //printf("TrackCanvas::draw_highlighting 3\n");
1514 // Dragging a new effect from the Resource window
1517 if(mwindow->session->track_highlighted &&
1518 ((mwindow->session->current_operation == DRAG_AEFFECT && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1519 (mwindow->session->current_operation == DRAG_VEFFECT && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
1521 // Put it before another plugin
1522 if(mwindow->session->plugin_highlighted)
1524 plugin_dimensions(mwindow->session->plugin_highlighted,
1529 //printf("TrackCanvas::draw_highlighting 1 %d %d\n", x, w);
1532 // Put it after a plugin set
1533 if(mwindow->session->pluginset_highlighted &&
1534 mwindow->session->pluginset_highlighted->last)
1536 plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last,
1541 //printf("TrackCanvas::draw_highlighting 1 %d %d\n", x, w);
1542 int64_t track_x, track_y, track_w, track_h;
1543 track_dimensions(mwindow->session->track_highlighted,
1551 mwindow->session->track_highlighted->get_length() *
1552 mwindow->edl->session->sample_rate /
1553 mwindow->edl->local_session->zoom_sample -
1554 mwindow->edl->local_session->view_start) -
1556 //printf("TrackCanvas::draw_highlighting 2 %d\n", w);
1557 if(w <= 0) w = track_w;
1561 track_dimensions(mwindow->session->track_highlighted,
1567 //printf("TrackCanvas::draw_highlighting 1 %d %d %d %d\n", x, y, w, h);
1568 // Put it in a new plugin set determined by the selected range
1569 if(mwindow->edl->local_session->get_selectionend() >
1570 mwindow->edl->local_session->get_selectionstart())
1572 x = Units::to_int64(mwindow->edl->local_session->get_selectionstart() *
1573 mwindow->edl->session->sample_rate /
1574 mwindow->edl->local_session->zoom_sample -
1575 mwindow->edl->local_session->view_start);
1576 w = Units::to_int64((mwindow->edl->local_session->get_selectionend() -
1577 mwindow->edl->local_session->get_selectionstart()) *
1578 mwindow->edl->session->sample_rate /
1579 mwindow->edl->local_session->zoom_sample);
1581 // Put it in a new plugin set determined by an edit boundary
1583 if(mwindow->session->edit_highlighted)
1585 int64_t temp_y, temp_h;
1586 edit_dimensions(mwindow->session->edit_highlighted,
1592 // Put it at the beginning of the track in a new plugin set
1595 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1596 MWindowGUI::visible(y, y + h, 0, get_h()))
1598 //printf("TrackCanvas::draw_highlighting 1\n");
1605 if(mwindow->session->track_highlighted)
1607 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1609 if(MWindowGUI::visible(y, y + h, 0, get_h()))
1611 draw_paste_destination();
1616 // Dragging an effect from the timeline
1617 case DRAG_AEFFECT_COPY:
1618 case DRAG_VEFFECT_COPY:
1619 if((mwindow->session->plugin_highlighted || mwindow->session->track_highlighted) &&
1620 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1621 (mwindow->session->current_operation == DRAG_VEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
1623 // Put it before another plugin
1624 if(mwindow->session->plugin_highlighted)
1625 plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
1627 // Put it after a plugin set
1628 if(mwindow->session->pluginset_highlighted &&
1629 mwindow->session->pluginset_highlighted->last)
1631 plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last, x, y, w, h);
1635 if(mwindow->session->track_highlighted)
1637 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1639 // Put it in a new plugin set determined by an edit boundary
1640 if(mwindow->session->edit_highlighted)
1642 int64_t temp_y, temp_h;
1643 edit_dimensions(mwindow->session->edit_highlighted,
1649 // Put it in a new plugin set at the start of the track
1652 // Calculate length of plugin based on data type of track and units
1653 if(mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
1655 w = (int64_t)((double)mwindow->session->drag_plugin->length /
1656 mwindow->edl->session->frame_rate *
1657 mwindow->edl->session->sample_rate /
1658 mwindow->edl->local_session->zoom_sample);
1662 w = (int64_t)mwindow->session->drag_plugin->length /
1663 mwindow->edl->local_session->zoom_sample;
1666 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1667 MWindowGUI::visible(y, y + h, 0, get_h()))
1674 case DRAG_PLUGINKEY:
1675 if(mwindow->session->plugin_highlighted &&
1676 mwindow->session->current_operation == DRAG_PLUGINKEY)
1678 // Just highlight the plugin
1679 plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
1681 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1682 MWindowGUI::visible(y, y + h, 0, get_h()))
1690 if(mwindow->session->track_highlighted)
1692 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1694 if(MWindowGUI::visible(y, y + h, 0, get_h()))
1696 draw_paste_destination();
1705 draw_highlight_rectangle(x, y, w, h);
1709 void TrackCanvas::draw_plugins()
1711 char string[BCTEXTLEN];
1712 int current_toggle = 0;
1714 if(!mwindow->edl->session->show_assets) goto done;
1716 for(int i = 0; i < plugin_on_toggles.total; i++)
1717 plugin_on_toggles.values[i]->in_use = 0;
1718 for(int i = 0; i < plugin_show_toggles.total; i++)
1719 plugin_show_toggles.values[i]->in_use = 0;
1722 for(Track *track = mwindow->edl->tracks->first;
1724 track = track->next)
1726 if(track->expand_view)
1728 for(int i = 0; i < track->plugin_set.total; i++)
1730 PluginSet *pluginset = track->plugin_set.values[i];
1732 for(Plugin *plugin = (Plugin*)pluginset->first; plugin; plugin = (Plugin*)plugin->next)
1734 int64_t total_x, y, total_w, h;
1735 plugin_dimensions(plugin, total_x, y, total_w, h);
1737 if(MWindowGUI::visible(total_x, total_x + total_w, 0, get_w()) &&
1738 MWindowGUI::visible(y, y + h, 0, get_h()) &&
1739 plugin->plugin_type != PLUGIN_NONE)
1741 int x = total_x, w = total_w, left_margin = 5;
1742 int right_margin = 5;
1748 if(w + x > get_w()) w -= (w + x) - get_w();
1755 mwindow->theme->get_image("plugin_bg_data"),
1757 set_color(get_resources()->default_text_color);
1758 set_font(MEDIUMFONT_3D);
1759 plugin->calculate_title(string, 0);
1761 // Truncate string to int64_test visible in background
1762 int len = strlen(string), j;
1763 for(j = len; j >= 0; j--)
1765 if(left_margin + get_text_width(MEDIUMFONT_3D, string) > w)
1773 // Justify the text on the left boundary of the edit if it is visible.
1774 // Otherwise justify it on the left side of the screen.
1775 int text_x = total_x + left_margin;
1776 text_x = MAX(left_margin, text_x);
1778 y + get_text_ascent(MEDIUMFONT_3D) + 2,
1784 // Update plugin toggles
1785 int toggle_x = total_x + total_w;
1786 toggle_x = MIN(get_w() - right_margin, toggle_x);
1787 toggle_x -= PluginOn::calculate_w(mwindow) + 10;
1789 if(current_toggle >= plugin_on_toggles.total)
1791 PluginOn *plugin_on = new PluginOn(mwindow, toggle_x, toggle_y, plugin);
1792 add_subwindow(plugin_on);
1793 plugin_on_toggles.append(plugin_on);
1797 plugin_on_toggles.values[current_toggle]->update(toggle_x, toggle_y, plugin);
1800 toggle_x -= PluginShow::calculate_w(mwindow) + 10;
1801 if(current_toggle >= plugin_show_toggles.total)
1803 PluginShow *plugin_off = new PluginShow(mwindow, toggle_x, toggle_y, plugin);
1804 add_subwindow(plugin_off);
1805 plugin_show_toggles.append(plugin_off);
1809 plugin_show_toggles.values[current_toggle]->update(toggle_x, toggle_y, plugin);
1820 int i = current_toggle;
1821 while(i < plugin_on_toggles.total &&
1822 i < plugin_show_toggles.total)
1824 plugin_on_toggles.remove_object_number(current_toggle);
1825 plugin_show_toggles.remove_object_number(current_toggle);
1829 void TrackCanvas::refresh_plugintoggles()
1831 for(int i = 0; i < plugin_on_toggles.total; i++)
1833 PluginOn *on = plugin_on_toggles.values[i];
1834 on->reposition_window(on->get_x(), on->get_y());
1836 for(int i = 0; i < plugin_show_toggles.total; i++)
1838 PluginShow *show = plugin_show_toggles.values[i];
1839 show->reposition_window(show->get_x(), show->get_y());
1843 void TrackCanvas::draw_inout_points()
1848 void TrackCanvas::draw_drag_handle()
1850 if(mwindow->session->current_operation == DRAG_EDITHANDLE2 ||
1851 mwindow->session->current_operation == DRAG_PLUGINHANDLE2)
1853 //printf("TrackCanvas::draw_drag_handle 1 %ld %ld\n", mwindow->session->drag_sample, mwindow->edl->local_session->view_start);
1854 int64_t pixel1 = Units::round(mwindow->session->drag_position *
1855 mwindow->edl->session->sample_rate /
1856 mwindow->edl->local_session->zoom_sample -
1857 mwindow->edl->local_session->view_start);
1858 //printf("TrackCanvas::draw_drag_handle 2 %d\n", pixel1);
1861 //printf("TrackCanvas::draw_drag_handle 3\n");
1862 draw_line(pixel1, 0, pixel1, get_h());
1864 //printf("TrackCanvas::draw_drag_handle 4\n");
1869 void TrackCanvas::draw_transitions()
1873 if(!mwindow->edl->session->show_assets) return;
1875 for(Track *track = mwindow->edl->tracks->first;
1877 track = track->next)
1879 for(Edit *edit = track->edits->first;
1883 if(edit->transition)
1885 int64_t strip_w, strip_x, strip_y;
1886 edit_dimensions(edit, x, y, w, h);
1889 if(mwindow->edl->session->show_titles)
1890 strip_y += mwindow->theme->get_image("title_bg_data")->get_h();
1892 get_transition_coords(x, y, w, h);
1893 strip_w = Units::round(edit->track->from_units(edit->transition->length) *
1894 mwindow->edl->session->sample_rate /
1895 mwindow->edl->local_session->zoom_sample);
1897 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1898 MWindowGUI::visible(y, y + h, 0, get_h()))
1900 PluginServer *server = mwindow->scan_plugindb(edit->transition->title,
1902 draw_vframe(server->picon,
1909 server->picon->get_w(),
1910 server->picon->get_h());
1912 if(MWindowGUI::visible(strip_x, strip_x + strip_w, 0, get_w()) &&
1913 MWindowGUI::visible(strip_y, strip_y + h, 0, get_h()))
1915 int x = strip_x, w = strip_w, left_margin = 5;
1921 if(w + x > get_w()) w -= (w + x) - get_w();
1929 mwindow->theme->get_image("plugin_bg_data"),
1938 void TrackCanvas::draw_loop_points()
1940 //printf("TrackCanvas::draw_loop_points 1\n");
1941 if(mwindow->edl->local_session->loop_playback)
1943 //printf("TrackCanvas::draw_loop_points 2\n");
1944 int64_t x = Units::round(mwindow->edl->local_session->loop_start *
1945 mwindow->edl->session->sample_rate /
1946 mwindow->edl->local_session->zoom_sample -
1947 mwindow->edl->local_session->view_start);
1948 //printf("TrackCanvas::draw_loop_points 3\n");
1950 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1953 draw_line(x, 0, x, get_h());
1955 //printf("TrackCanvas::draw_loop_points 4\n");
1957 x = Units::round(mwindow->edl->local_session->loop_end *
1958 mwindow->edl->session->sample_rate /
1959 mwindow->edl->local_session->zoom_sample -
1960 mwindow->edl->local_session->view_start);
1961 //printf("TrackCanvas::draw_loop_points 5\n");
1963 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1966 draw_line(x, 0, x, get_h());
1968 //printf("TrackCanvas::draw_loop_points 6\n");
1970 //printf("TrackCanvas::draw_loop_points 7\n");
1973 void TrackCanvas::draw_brender_start()
1975 if(mwindow->preferences->use_brender)
1977 int64_t x = Units::round(mwindow->edl->session->brender_start *
1978 mwindow->edl->session->sample_rate /
1979 mwindow->edl->local_session->zoom_sample -
1980 mwindow->edl->local_session->view_start);
1982 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1985 draw_line(x, 0, x, get_h());
1990 static int auto_colors[] =
2006 // The operations which correspond to each automation type
2007 static int auto_operations[] =
2023 // The buttonpress operations, so nothing changes unless the mouse moves
2024 // a certain amount. This allows the keyframe to be used to position the
2025 // insertion point without moving itself.
2026 static int pre_auto_operations[] =
2043 int TrackCanvas::do_keyframes(int cursor_x,
2051 // Note: button 3 (right mouse button) is not eaten to allow
2052 // track context menu to appear
2053 int current_tool = 0;
2055 EDLSession *session = mwindow->edl->session;
2059 BC_Pixmap *auto_pixmaps[] =
2070 modekeyframe_pixmap,
2071 maskkeyframe_pixmap,
2077 for(Track *track = mwindow->edl->tracks->first;
2079 track = track->next)
2081 Auto *auto_keyframe;
2082 Automation *automation = track->automation;
2085 // Handle float autos
2086 for(int i = 0; i < AUTOMATION_TOTAL && !result; i++)
2088 // Event not trapped and automation visible
2089 Autos *autos = automation->autos[i];
2090 if(!result && session->auto_conf->autos[i] && autos)
2094 case AUTOMATION_MODE:
2095 case AUTOMATION_PAN:
2096 case AUTOMATION_MASK:
2097 result = do_autos(track,
2098 automation->autos[i],
2108 switch(autos->get_type())
2110 case AUTOMATION_TYPE_FLOAT:
2112 Automation *dummy = new Automation(0,track);
2113 int autogrouptype = dummy->autogrouptype(i,track);
2114 result = do_float_autos(track,
2126 case AUTOMATION_TYPE_INT:
2127 result = do_toggle_autos(track,
2144 if(mwindow->session->current_operation == auto_operations[i])
2148 if (buttonpress != 3)
2150 if(i == AUTOMATION_FADE)
2151 synchronize_autos(0,
2153 (FloatAuto*)mwindow->session->drag_auto,
2155 mwindow->session->current_operation = pre_auto_operations[i];
2156 update_drag_caption();
2160 gui->keyframe_menu->update(automation, autos, auto_keyframe);
2161 gui->keyframe_menu->activate_menu();
2162 rerender = 1; // the position changes
2173 session->auto_conf->plugins &&
2174 mwindow->edl->session->show_assets)
2178 result = do_plugin_autos(track,
2185 if(result && mwindow->session->current_operation == DRAG_PLUGINKEY)
2189 if(result && (buttonpress == 1))
2191 mwindow->session->current_operation = DRAG_PLUGINKEY_PRE;
2192 update_drag_caption();
2195 if (result && (buttonpress == 3))
2197 gui->keyframe_menu->update(plugin, keyframe);
2198 gui->keyframe_menu->activate_menu();
2199 rerender = 1; // the position changes
2204 // Final pass to trap event
2205 for(int i = 0; i < AUTOMATION_TOTAL; i++)
2207 if(mwindow->session->current_operation == pre_auto_operations[i] ||
2208 mwindow->session->current_operation == auto_operations[i])
2212 if(mwindow->session->current_operation == DRAG_PLUGINKEY ||
2213 mwindow->session->current_operation == DRAG_PLUGINKEY_PRE)
2221 new_cursor = UPRIGHT_ARROW_CURSOR;
2227 void TrackCanvas::draw_auto(Auto *current,
2235 char string[BCTEXTLEN];
2237 x1 = x - HANDLE_W / 2;
2238 x2 = x + HANDLE_W / 2;
2239 y1 = center_pixel + y - HANDLE_W / 2;
2240 y2 = center_pixel + y + HANDLE_W / 2;
2242 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2243 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2246 draw_box(x1 + 1, y1 + 1, x2 - x1, y2 - y1);
2248 draw_box(x1, y1, x2 - x1, y2 - y1);
2251 void TrackCanvas::draw_floatauto(Auto *current,
2263 int in_x1, in_y1, in_x2, in_y2;
2264 int out_x1, out_y1, out_x2, out_y2;
2265 char string[BCTEXTLEN];
2268 x1 = x - HANDLE_W / 2;
2269 x2 = x + HANDLE_W / 2;
2270 y1 = center_pixel + y - HANDLE_W / 2;
2271 y2 = center_pixel + y + HANDLE_W / 2;
2273 CLAMP(y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2274 CLAMP(y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2279 draw_box(x1 + 1, y1 + 1, x2 - x1, y2 - y1);
2281 draw_box(x1, y1, x2 - x1, y2 - y1);
2285 in_x1 = in_x - HANDLE_W / 2;
2286 in_x2 = in_x + HANDLE_W / 2;
2287 in_y1 = center_pixel + in_y - HANDLE_W / 2;
2288 in_y2 = center_pixel + in_y + HANDLE_W / 2;
2290 CLAMP(in_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2291 CLAMP(in_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2292 CLAMP(in_y, -zoom_track / 2, zoom_track / 2);
2297 draw_line(x + 1, center_pixel + y + 1, in_x + 1, center_pixel + in_y + 1);
2298 draw_box(in_x1 + 1, in_y1 + 1, in_x2 - in_x1, in_y2 - in_y1);
2300 draw_line(x, center_pixel + y, in_x, center_pixel + in_y);
2301 draw_box(in_x1, in_y1, in_x2 - in_x1, in_y2 - in_y1);
2306 out_x1 = out_x - HANDLE_W / 2;
2307 out_x2 = out_x + HANDLE_W / 2;
2308 out_y1 = center_pixel + out_y - HANDLE_W / 2;
2309 out_y2 = center_pixel + out_y + HANDLE_W / 2;
2311 CLAMP(out_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2312 CLAMP(out_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2313 CLAMP(out_y, -zoom_track / 2, zoom_track / 2);
2318 draw_line(x + 1, center_pixel + y + 1, out_x + 1, center_pixel + out_y + 1);
2319 draw_box(out_x1 + 1, out_y1 + 1, out_x2 - out_x1, out_y2 - out_y1);
2321 draw_line(x, center_pixel + y, out_x, center_pixel + out_y);
2322 draw_box(out_x1, out_y1, out_x2 - out_x1, out_y2 - out_y1);
2326 int TrackCanvas::test_auto(Auto *current,
2336 char string[BCTEXTLEN];
2339 x1 = x - HANDLE_W / 2;
2340 x2 = x + HANDLE_W / 2;
2341 y1 = center_pixel + y - HANDLE_W / 2;
2342 y2 = center_pixel + y + HANDLE_W / 2;
2344 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2345 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2347 if(cursor_x >= x1 && cursor_x < x2 && cursor_y >= y1 && cursor_y < y2)
2349 if(buttonpress && buttonpress != 3)
2351 mwindow->session->drag_auto = current;
2352 mwindow->session->drag_start_percentage = current->value_to_percentage();
2353 mwindow->session->drag_start_position = current->position;
2354 mwindow->session->drag_origin_x = cursor_x;
2355 mwindow->session->drag_origin_y = cursor_y;
2363 int TrackCanvas::test_floatauto(Auto *current,
2377 int in_x1, in_y1, in_x2, in_y2;
2378 int out_x1, out_y1, out_x2, out_y2;
2379 char string[BCTEXTLEN];
2382 x1 = x - HANDLE_W / 2;
2383 x2 = x + HANDLE_W / 2;
2384 y1 = center_pixel + y - HANDLE_W / 2;
2385 y2 = center_pixel + y + HANDLE_W / 2;
2387 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2388 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2390 in_x1 = in_x - HANDLE_W / 2;
2391 in_x2 = in_x + HANDLE_W / 2;
2392 in_y1 = center_pixel + in_y - HANDLE_W / 2;
2393 in_y2 = center_pixel + in_y + HANDLE_W / 2;
2395 if(in_y1 < center_pixel + -zoom_track / 2) in_y1 = center_pixel + -zoom_track / 2;
2396 if(in_y2 > center_pixel + zoom_track / 2) in_y2 = center_pixel + zoom_track / 2;
2398 out_x1 = out_x - HANDLE_W / 2;
2399 out_x2 = out_x + HANDLE_W / 2;
2400 out_y1 = center_pixel + out_y - HANDLE_W / 2;
2401 out_y2 = center_pixel + out_y + HANDLE_W / 2;
2403 if(out_y1 < center_pixel + -zoom_track / 2) out_y1 = center_pixel + -zoom_track / 2;
2404 if(out_y2 > center_pixel + zoom_track / 2) out_y2 = center_pixel + zoom_track / 2;
2408 //printf("TrackCanvas::test_floatauto %d %d %d %d %d %d\n", cursor_x, cursor_y, x1, x2, y1, y2);
2416 if(buttonpress && (buttonpress != 3))
2418 mwindow->session->drag_auto = current;
2419 mwindow->session->drag_start_percentage = current->value_to_percentage();
2420 mwindow->session->drag_start_position = current->position;
2421 mwindow->session->drag_origin_x = cursor_x;
2422 mwindow->session->drag_origin_y = cursor_y;
2423 mwindow->session->drag_handle = 0;
2430 cursor_x >= in_x1 &&
2432 cursor_y >= in_y1 &&
2434 current->position > 0)
2436 if(buttonpress && (buttonpress != 3))
2438 mwindow->session->drag_auto = current;
2439 mwindow->session->drag_start_percentage =
2440 current->invalue_to_percentage();
2441 mwindow->session->drag_start_position =
2442 ((FloatAuto*)current)->control_in_position;
2443 mwindow->session->drag_origin_x = cursor_x;
2444 mwindow->session->drag_origin_y = cursor_y;
2445 mwindow->session->drag_handle = 1;
2452 cursor_x >= out_x1 &&
2453 cursor_x < out_x2 &&
2454 cursor_y >= out_y1 &&
2457 if(buttonpress && (buttonpress != 3))
2459 mwindow->session->drag_auto = current;
2460 mwindow->session->drag_start_percentage =
2461 current->outvalue_to_percentage();
2462 mwindow->session->drag_start_position =
2463 ((FloatAuto*)current)->control_out_position;
2464 mwindow->session->drag_origin_x = cursor_x;
2465 mwindow->session->drag_origin_y = cursor_y;
2466 mwindow->session->drag_handle = 2;
2472 // 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",
2473 // mwindow->session->drag_handle,
2482 void TrackCanvas::draw_floatline(int center_pixel,
2483 FloatAuto *previous,
2496 // Solve bezier equation for either every pixel or a certain large number of
2501 // Not using slope intercept
2508 // Call by reference fails for some reason here
2509 FloatAuto *previous1 = previous, *next1 = next;
2510 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
2511 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
2512 float automation_range = automation_max - automation_min;
2514 for(int x = x1; x < x2; x++)
2516 int64_t position = (int64_t)(unit_start + x * zoom_units);
2517 float value = autos->get_value(position, PLAY_FORWARD, previous1, next1);
2518 AUTOMATIONCLAMPS(value, autogrouptype);
2520 int y = center_pixel +
2521 (int)(((value - automation_min) / automation_range - 0.5) * -yscale);
2524 y >= center_pixel - yscale / 2 &&
2525 y < center_pixel + yscale / 2 - 1)
2528 draw_line(x - 1, prev_y + 1, x, y + 1);
2530 draw_line(x - 1, prev_y, x, y);
2538 void TrackCanvas::synchronize_autos(float change,
2543 // fill mwindow->session->drag_auto_gang
2544 if (fill_gangs == 1 && skip->gang)
2546 for(Track *current = mwindow->edl->tracks->first;
2550 if(current->data_type == skip->data_type &&
2555 FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
2556 double position = skip->from_units(fauto->position);
2557 FloatAuto *previous = 0, *next = 0;
2559 float init_value = fade_autos->get_value(fauto->position, PLAY_FORWARD, previous, next);
2560 FloatAuto *keyframe;
2561 keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position);
2565 // create keyframe at exactly this point in time
2566 keyframe = (FloatAuto*)fade_autos->insert_auto(fauto->position);
2567 keyframe->value = init_value;
2571 // keyframe exists, just change it
2572 keyframe->value += change;
2575 keyframe->position = fauto->position;
2576 keyframe->control_out_position = fauto->control_out_position;
2577 keyframe->control_in_position = fauto->control_in_position;
2578 keyframe->control_out_value = fauto->control_out_value;
2579 keyframe->control_in_value = fauto->control_in_value;
2581 mwindow->session->drag_auto_gang->append((Auto *)keyframe);
2586 if (fill_gangs == 0)
2589 for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
2591 FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
2593 keyframe->value += change;
2594 keyframe->position = fauto->position;
2595 CLAMP(keyframe->value,
2596 mwindow->edl->local_session->automation_mins[keyframe->autos->autogrouptype],
2597 mwindow->edl->local_session->automation_maxs[keyframe->autos->autogrouptype]);
2598 keyframe->control_out_position = fauto->control_out_position;
2599 keyframe->control_in_position = fauto->control_in_position;
2600 keyframe->control_out_value = fauto->control_out_value;
2601 keyframe->control_in_value = fauto->control_in_value;
2607 if (fill_gangs == -1)
2609 for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
2611 FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
2612 keyframe->autos->remove_nonsequential(
2615 mwindow->session->drag_auto_gang->remove_all();
2620 int TrackCanvas::test_floatline(int center_pixel,
2635 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
2636 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
2637 float automation_range = automation_max - automation_min;
2638 int64_t position = (int64_t)(unit_start + cursor_x * zoom_units);
2639 // Call by reference fails for some reason here
2640 FloatAuto *previous = 0, *next = 0;
2641 float value = autos->get_value(position, PLAY_FORWARD, previous, next);
2642 AUTOMATIONCLAMPS(value,autogrouptype);
2643 int y = center_pixel +
2644 (int)(((value - automation_min) / automation_range - 0.5) * -yscale);
2646 if(cursor_x >= x1 &&
2648 cursor_y >= y - HANDLE_W / 2 &&
2649 cursor_y < y + HANDLE_W / 2 &&
2660 current = mwindow->session->drag_auto = autos->insert_auto(position);
2661 ((FloatAuto*)current)->value = value;
2662 mwindow->session->drag_start_percentage = current->value_to_percentage();
2663 mwindow->session->drag_start_position = current->position;
2664 mwindow->session->drag_origin_x = cursor_x;
2665 mwindow->session->drag_origin_y = cursor_y;
2666 mwindow->session->drag_handle = 0;
2675 void TrackCanvas::draw_toggleline(int center_pixel,
2683 draw_line(x1, center_pixel + y1 + 1, x2, center_pixel + y1 + 1);
2685 draw_line(x1, center_pixel + y1, x2, center_pixel + y1);
2690 draw_line(x2 + 1, center_pixel + y1, x2 + 1, center_pixel + y2);
2692 draw_line(x2, center_pixel + y1, x2, center_pixel + y2);
2696 int TrackCanvas::test_toggleline(Autos *autos,
2707 if(cursor_x >= x1 && cursor_x < x2)
2709 int miny = center_pixel + y1 - HANDLE_W / 2;
2710 int maxy = center_pixel + y1 + HANDLE_W / 2;
2711 if(cursor_y >= miny && cursor_y < maxy)
2720 double position = (double)(cursor_x +
2721 mwindow->edl->local_session->view_start) *
2722 mwindow->edl->local_session->zoom_sample /
2723 mwindow->edl->session->sample_rate;
2724 int64_t unit_position = autos->track->to_units(position, 0);
2725 int new_value = (int)((IntAutos*)autos)->get_automation_constant(unit_position, unit_position);
2727 current = mwindow->session->drag_auto = autos->insert_auto(unit_position);
2728 ((IntAuto*)current)->value = new_value;
2729 mwindow->session->drag_start_percentage = current->value_to_percentage();
2730 mwindow->session->drag_start_position = current->position;
2731 mwindow->session->drag_origin_x = cursor_x;
2732 mwindow->session->drag_origin_y = cursor_y;
2740 void TrackCanvas::calculate_viewport(Track *track,
2741 double &view_start, // Seconds
2743 double &view_end, // Seconds
2747 double &zoom_sample,
2750 view_start = (double)mwindow->edl->local_session->view_start *
2751 mwindow->edl->local_session->zoom_sample /
2752 mwindow->edl->session->sample_rate;
2753 unit_start = track->to_doubleunits(view_start);
2754 view_end = (double)(mwindow->edl->local_session->view_start +
2756 mwindow->edl->local_session->zoom_sample /
2757 mwindow->edl->session->sample_rate;
2758 unit_end = track->to_doubleunits(view_end);
2759 yscale = mwindow->edl->local_session->zoom_track;
2760 center_pixel = (int)(track->y_pixel + yscale / 2) +
2761 (mwindow->edl->session->show_titles ?
2762 mwindow->theme->get_image("title_bg_data")->get_h() :
2764 zoom_sample = mwindow->edl->local_session->zoom_sample;
2766 zoom_units = track->to_doubleunits(zoom_sample / mwindow->edl->session->sample_rate);
2769 float TrackCanvas::percentage_to_value(float percentage,
2777 if(percentage > 0.5)
2784 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
2785 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
2786 float automation_range = automation_max - automation_min;
2788 result = percentage * automation_range + automation_min;
2791 FloatAuto *ptr = (FloatAuto*)reference;
2792 result -= ptr->value;
2799 void TrackCanvas::calculate_auto_position(double *x,
2811 float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
2812 float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
2813 float automation_range = automation_max - automation_min;
2814 FloatAuto *ptr = (FloatAuto*)current;
2815 *x = (double)(ptr->position - unit_start) / zoom_units;
2816 *y = ((ptr->value - automation_min) /
2817 automation_range - 0.5) *
2821 *in_x = (double)(ptr->position +
2822 ptr->control_in_position -
2828 *in_y = (((ptr->value + ptr->control_in_value) -
2830 automation_range - 0.5) *
2835 *out_x = (double)(ptr->position +
2836 ptr->control_out_position -
2842 *out_y = (((ptr->value + ptr->control_out_value) -
2844 automation_range - 0.5) *
2853 int TrackCanvas::do_float_autos(Track *track,
2860 Auto* &auto_instance,
2873 double ax, ay, ax2, ay2;
2874 double in_x2, in_y2, out_x2, out_y2;
2881 calculate_viewport(track,
2893 // Get first auto before start
2896 for(current = autos->last;
2897 current && current->position >= unit_start;
2903 calculate_auto_position(&ax,
2918 current = autos->first ? autos->first : autos->default_auto;
2921 calculate_auto_position(&ax,
2952 calculate_auto_position(&ax2,
2971 slope = (ay2 - ay) / (ax2 - ax);
2977 ay2 = ay + slope * (get_w() - ax);
2982 ay = ay + slope * (0 - ax);
3000 if(current && !result)
3002 if(current != autos->default_auto)
3007 result = test_floatauto(current,
3020 auto_instance = current;
3024 draw_floatauto(current,
3041 // Draw joining line
3046 if(track->record && buttonpress != 3)
3048 result = test_floatline(center_pixel,
3054 // Exclude auto coverage from the end of the line. The auto overlaps
3055 (int)ax2 - HANDLE_W / 2,
3064 draw_floatline(center_pixel,
3065 (FloatAuto*)previous,
3066 (FloatAuto*)current,
3095 current->position <= unit_end &&
3098 //printf("TrackCanvas::do_float_autos 100\n");
3107 if(ax < get_w() && !result)
3113 if(track->record && buttonpress != 3)
3115 result = test_floatline(center_pixel,
3129 draw_floatline(center_pixel,
3130 (FloatAuto*)previous,
3131 (FloatAuto*)current,
3155 int TrackCanvas::do_toggle_autos(Track *track,
3162 Auto * &auto_instance)
3173 double ax, ay, ax2, ay2;
3177 calculate_viewport(track,
3188 double high = -yscale * 0.8 / 2;
3189 double low = yscale * 0.8 / 2;
3191 // Get first auto before start
3193 for(current = autos->last; current && current->position >= unit_start; current = PREVIOUS)
3199 ay = ((IntAuto*)current)->value > 0 ? high : low;
3204 current = autos->first ? autos->first : autos->default_auto;
3208 ay = ((IntAuto*)current)->value > 0 ? high : low;
3221 ax2 = (double)(current->position - unit_start) / zoom_units;
3222 ay2 = ((IntAuto*)current)->value > 0 ? high : low;
3230 if(ax2 > get_w()) ax2 = get_w();
3232 if(current && !result)
3234 if(current != autos->default_auto)
3240 result = test_auto(current,
3249 auto_instance = current;
3268 if(track->record && buttonpress != 3)
3270 result = test_toggleline(autos,
3283 draw_toggleline(center_pixel,
3292 }while(current && current->position <= unit_end && !result);
3294 if(ax < get_w() && !result)
3300 if(track->record && buttonpress != 3)
3302 result = test_toggleline(autos,
3314 draw_toggleline(center_pixel,
3324 int TrackCanvas::do_autos(Track *track,
3331 Auto * &auto_instance)
3344 calculate_viewport(track,
3357 for(current = autos->first; current && !result; current = NEXT)
3359 if(current->position >= unit_start && current->position < unit_end)
3362 x = (int64_t)((double)(current->position - unit_start) /
3363 zoom_units - (pixmap->get_w() / 2 + 0.5));
3364 y = center_pixel - pixmap->get_h() / 2;
3368 if(cursor_x >= x && cursor_y >= y &&
3369 cursor_x < x + pixmap->get_w() &&
3370 cursor_y < y + pixmap->get_h())
3373 auto_instance = current;
3375 if(buttonpress && (buttonpress != 3))
3377 mwindow->session->drag_auto = current;
3378 mwindow->session->drag_start_position = current->position;
3379 mwindow->session->drag_origin_x = cursor_x;
3380 mwindow->session->drag_origin_y = cursor_y;
3382 double position = autos->track->from_units(current->position);
3383 double center = (mwindow->edl->local_session->get_selectionstart(1) +
3384 mwindow->edl->local_session->get_selectionend(1)) /
3389 mwindow->edl->local_session->set_selectionstart(position);
3390 mwindow->edl->local_session->set_selectionend(position);
3393 if(position < center)
3395 mwindow->edl->local_session->set_selectionstart(position);
3398 mwindow->edl->local_session->set_selectionend(position);
3403 draw_pixmap(pixmap, x, y);
3409 // so this means it is always >0 when keyframe is found
3410 int TrackCanvas::do_plugin_autos(Track *track,
3415 Plugin* &keyframe_plugin,
3416 KeyFrame* &keyframe_instance)
3429 if(!track->expand_view) return 0;
3431 calculate_viewport(track,
3443 for(int i = 0; i < track->plugin_set.total && !result; i++)
3445 PluginSet *plugin_set = track->plugin_set.values[i];
3446 int center_pixel = (int)(track->y_pixel +
3447 mwindow->edl->local_session->zoom_track +
3448 (i + 0.5) * mwindow->theme->get_image("plugin_bg_data")->get_h() +
3449 (mwindow->edl->session->show_titles ? mwindow->theme->get_image("title_bg_data")->get_h() : 0));
3451 for(Plugin *plugin = (Plugin*)plugin_set->first;
3453 plugin = (Plugin*)plugin->next)
3455 for(KeyFrame *keyframe = (KeyFrame*)plugin->keyframes->first;
3456 keyframe && !result;
3457 keyframe = (KeyFrame*)keyframe->next)
3459 //printf("TrackCanvas::draw_plugin_autos 3 %d\n", keyframe->position);
3460 if(keyframe->position >= unit_start && keyframe->position < unit_end)
3462 int64_t x = (int64_t)((keyframe->position - unit_start) / zoom_units);
3463 int y = center_pixel - keyframe_pixmap->get_h() / 2;
3465 //printf("TrackCanvas::draw_plugin_autos 4 %d %d\n", x, center_pixel);
3468 if(cursor_x >= x && cursor_y >= y &&
3469 cursor_x < x + keyframe_pixmap->get_w() &&
3470 cursor_y < y + keyframe_pixmap->get_h())
3473 keyframe_plugin = plugin;
3474 keyframe_instance = keyframe;
3478 mwindow->session->drag_auto = keyframe;
3479 mwindow->session->drag_start_position = keyframe->position;
3480 mwindow->session->drag_origin_x = cursor_x;
3481 mwindow->session->drag_origin_y = cursor_y;
3483 double position = track->from_units(keyframe->position);
3484 double center = (mwindow->edl->local_session->get_selectionstart(1) +
3485 mwindow->edl->local_session->get_selectionend(1)) /
3490 mwindow->edl->local_session->set_selectionstart(position);
3491 mwindow->edl->local_session->set_selectionend(position);
3494 if(position < center)
3496 mwindow->edl->local_session->set_selectionstart(position);
3499 mwindow->edl->local_session->set_selectionend(position);
3504 draw_pixmap(keyframe_pixmap,
3511 //printf("TrackCanvas::draw_plugin_autos 5\n");
3515 void TrackCanvas::draw_overlays()
3517 int new_cursor, update_cursor, rerender;
3519 // Move background pixmap to foreground pixmap
3520 draw_pixmap(background_pixmap,
3529 draw_inout_points();
3532 if(mwindow->edl->session->auto_conf->transitions) draw_transitions();
3539 draw_brender_start();
3541 // Highlighted areas
3542 draw_highlighting();
3554 if(gui->cursor) gui->cursor->restore(1);
3560 draw_playback_cursor();
3564 int TrackCanvas::activate()
3568 get_top_level()->deactivate();
3570 set_active_subwindow(this);
3571 gui->cursor->activate();
3576 int TrackCanvas::deactivate()
3581 gui->cursor->deactivate();
3587 void TrackCanvas::update_drag_handle()
3589 double new_position;
3592 (double)(get_cursor_x() + mwindow->edl->local_session->view_start) *
3593 mwindow->edl->local_session->zoom_sample /
3594 mwindow->edl->session->sample_rate;
3596 mwindow->edl->align_to_frame(new_position, 0);
3599 if(new_position != mwindow->session->drag_position)
3601 mwindow->session->drag_position = new_position;
3602 gui->mainclock->update(new_position);
3603 // Que the CWindow. Doesn't do anything if selectionstart and selection end
3605 // mwindow->cwindow->update(1, 0, 0);
3609 int TrackCanvas::update_drag_edit()
3618 #define UPDATE_DRAG_HEAD(do_clamp) \
3620 int x = cursor_x - mwindow->session->drag_origin_x; \
3621 int y = cursor_y - mwindow->session->drag_origin_y; \
3623 if(!current->autos->track->record) return 0; \
3624 double view_start; \
3625 double unit_start; \
3630 double zoom_sample; \
3631 double zoom_units; \
3633 calculate_viewport(current->autos->track, \
3643 float percentage = (float)(mwindow->session->drag_origin_y - cursor_y) / \
3645 mwindow->session->drag_start_percentage; \
3646 if(do_clamp) CLAMP(percentage, 0, 1); \
3648 int64_t position = Units::to_int64(zoom_units * \
3649 (cursor_x - mwindow->session->drag_origin_x) + \
3650 mwindow->session->drag_start_position); \
3652 if((do_clamp) && position < 0) position = 0;
3662 int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y)
3664 FloatAuto *current = (FloatAuto*)mwindow->session->drag_auto;
3666 UPDATE_DRAG_HEAD(mwindow->session->drag_handle == 0);
3671 switch(mwindow->session->drag_handle)
3675 // Snap to nearby values
3676 old_value = current->value;
3684 if(current->previous)
3686 int autogrouptype = current->previous->autos->autogrouptype;
3687 value = percentage_to_value(percentage, 0, 0, autogrouptype);
3688 value1 = ((FloatAuto*)current->previous)->value;
3689 distance1 = fabs(value - value1);
3690 current->value = value1;
3695 int autogrouptype = current->next->autos->autogrouptype;
3696 value = percentage_to_value(percentage, 0, 0, autogrouptype);
3697 value2 = ((FloatAuto*)current->next)->value;
3698 distance2 = fabs(value - value2);
3699 if(!current->previous || distance2 < distance1)
3701 current->value = value2;
3705 if(!current->previous && !current->next)
3707 current->value = ((FloatAutos*)current->autos)->default_;
3709 value = current->value;
3713 int autogrouptype = current->autos->autogrouptype;
3714 value = percentage_to_value(percentage, 0, 0, autogrouptype);
3717 if(value != old_value || position != current->position)
3720 float change = value - old_value;
3721 current->value = value;
3722 current->position = position;
3723 synchronize_autos(change, current->autos->track, current, 0);
3725 char string[BCTEXTLEN], string2[BCTEXTLEN];
3726 Units::totext(string2,
3727 current->autos->track->from_units(current->position),
3728 mwindow->edl->session->time_format,
3729 mwindow->edl->session->sample_rate,
3730 mwindow->edl->session->frame_rate,
3731 mwindow->edl->session->frames_per_foot);
3732 sprintf(string, "%s, %.2f", string2, current->value);
3733 gui->show_message(string);
3740 int autogrouptype = current->autos->autogrouptype;
3741 value = percentage_to_value(percentage, 0, current, autogrouptype);
3742 position = MIN(0, position);
3743 if(value != current->control_in_value ||
3744 position != current->control_in_position)
3747 current->control_in_value = value;
3748 current->control_in_position = position;
3749 synchronize_autos(0, current->autos->track, current, 0);
3751 char string[BCTEXTLEN], string2[BCTEXTLEN];
3752 Units::totext(string2,
3753 current->autos->track->from_units(current->control_in_position),
3754 mwindow->edl->session->time_format,
3755 mwindow->edl->session->sample_rate,
3756 mwindow->edl->session->frame_rate,
3757 mwindow->edl->session->frames_per_foot);
3758 sprintf(string, "%s, %.2f", string2, current->control_in_value);
3759 gui->show_message(string);
3767 int autogrouptype = current->autos->autogrouptype;
3768 value = percentage_to_value(percentage, 0, current, autogrouptype);
3769 position = MAX(0, position);
3770 if(value != current->control_out_value ||
3771 position != current->control_out_position)
3774 current->control_out_value = value;
3775 current->control_out_position = position;
3776 synchronize_autos(0, current->autos->track, current, 0);
3778 char string[BCTEXTLEN], string2[BCTEXTLEN];
3779 Units::totext(string2,
3780 current->autos->track->from_units(
3781 ((FloatAuto*)current)->control_out_position),
3782 mwindow->edl->session->time_format,
3783 mwindow->edl->session->sample_rate,
3784 mwindow->edl->session->frame_rate,
3785 mwindow->edl->session->frames_per_foot);
3786 sprintf(string, "%s, %.2f",
3788 ((FloatAuto*)current)->control_out_value);
3789 gui->show_message(string);
3798 int TrackCanvas::update_drag_toggleauto(int cursor_x, int cursor_y)
3800 IntAuto *current = (IntAuto*)mwindow->session->drag_auto;
3802 UPDATE_DRAG_HEAD(1);
3803 int value = (int)percentage_to_value(percentage, 1, 0, AUTOGROUPTYPE_INT255);
3805 if(value != current->value || position != current->position)
3808 current->value = value;
3809 current->position = position;
3811 char string[BCTEXTLEN], string2[BCTEXTLEN];
3812 Units::totext(string2,
3813 current->autos->track->from_units(current->position),
3814 mwindow->edl->session->time_format,
3815 mwindow->edl->session->sample_rate,
3816 mwindow->edl->session->frame_rate,
3817 mwindow->edl->session->frames_per_foot);
3818 sprintf(string, "%s, %d", string2, current->value);
3819 gui->show_message(string);
3825 // Autos which can't change value through dragging.
3827 int TrackCanvas::update_drag_auto(int cursor_x, int cursor_y)
3829 Auto *current = (Auto*)mwindow->session->drag_auto;
3832 if(position != current->position)
3835 current->position = position;
3837 char string[BCTEXTLEN];
3838 Units::totext(string,
3839 current->autos->track->from_units(current->position),
3840 mwindow->edl->session->time_format,
3841 mwindow->edl->session->sample_rate,
3842 mwindow->edl->session->frame_rate,
3843 mwindow->edl->session->frames_per_foot);
3844 gui->show_message(string);
3846 double position_f = current->autos->track->from_units(current->position);
3847 double center_f = (mwindow->edl->local_session->get_selectionstart(1) +
3848 mwindow->edl->local_session->get_selectionend(1)) /
3852 mwindow->edl->local_session->set_selectionstart(position_f);
3853 mwindow->edl->local_session->set_selectionend(position_f);
3856 if(position_f < center_f)
3858 mwindow->edl->local_session->set_selectionstart(position_f);
3861 mwindow->edl->local_session->set_selectionend(position_f);
3868 int TrackCanvas::update_drag_pluginauto(int cursor_x, int cursor_y)
3870 KeyFrame *current = (KeyFrame*)mwindow->session->drag_auto;
3873 if(position != current->position)
3875 // printf("uida: autos: %p, track: %p ta: %p\n", current->autos, current->autos->track, current->autos->track->automation);
3876 Track *track = current->autos->track;
3877 PluginAutos *pluginautos = (PluginAutos *)current->autos;
3878 PluginSet *pluginset;
3880 // figure out the correct pluginset & correct plugin
3882 for(int i = 0; i < track->plugin_set.total; i++)
3884 pluginset = track->plugin_set.values[i];
3885 for(plugin = (Plugin *)pluginset->first; plugin; plugin = (Plugin *)plugin->next)
3887 KeyFrames *keyframes = plugin->keyframes;
3888 for(KeyFrame *currentkeyframe = (KeyFrame *)keyframes->first; currentkeyframe; currentkeyframe = (KeyFrame *) currentkeyframe->next)
3890 if (currentkeyframe == current)
3902 mwindow->session->plugin_highlighted = plugin;
3903 mwindow->session->track_highlighted = track;
3905 current->position = position;
3907 char string[BCTEXTLEN];
3908 Units::totext(string,
3909 current->autos->track->from_units(current->position),
3910 mwindow->edl->session->time_format,
3911 mwindow->edl->session->sample_rate,
3912 mwindow->edl->session->frame_rate,
3913 mwindow->edl->session->frames_per_foot);
3914 gui->show_message(string);
3916 double position_f = current->autos->track->from_units(current->position);
3917 double center_f = (mwindow->edl->local_session->get_selectionstart(1) +
3918 mwindow->edl->local_session->get_selectionend(1)) /
3922 mwindow->edl->local_session->set_selectionstart(position_f);
3923 mwindow->edl->local_session->set_selectionend(position_f);
3926 if(position_f < center_f)
3928 mwindow->edl->local_session->set_selectionstart(position_f);
3931 mwindow->edl->local_session->set_selectionend(position_f);
3938 void TrackCanvas::update_drag_caption()
3940 switch(mwindow->session->current_operation)
3950 int TrackCanvas::cursor_motion_event()
3952 int result, cursor_x, cursor_y;
3953 int update_clock = 0;
3954 int update_zoom = 0;
3955 int update_scroll = 0;
3956 int update_overlay = 0;
3957 int update_cursor = 0;
3960 double position = 0;
3961 //printf("TrackCanvas::cursor_motion_event 1\n");
3965 switch(mwindow->edl->session->editing_mode)
3967 case EDITING_ARROW: new_cursor = ARROW_CURSOR; break;
3968 case EDITING_IBEAM: new_cursor = IBEAM_CURSOR; break;
3971 switch(mwindow->session->current_operation)
3973 case DRAG_EDITHANDLE1:
3974 // Outside threshold. Upgrade status
3975 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3977 mwindow->session->current_operation = DRAG_EDITHANDLE2;
3982 case DRAG_EDITHANDLE2:
3983 update_drag_handle();
3987 case DRAG_PLUGINHANDLE1:
3988 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3990 mwindow->session->current_operation = DRAG_PLUGINHANDLE2;
3995 case DRAG_PLUGINHANDLE2:
3996 update_drag_handle();
4000 // Rubber band curves
4007 case DRAG_PROJECTOR_X:
4008 case DRAG_PROJECTOR_Y:
4009 case DRAG_PROJECTOR_Z:
4010 rerender = update_overlay = update_drag_floatauto(get_cursor_x(), get_cursor_y());
4014 rerender = update_overlay = update_drag_toggleauto(get_cursor_x(), get_cursor_y());
4018 rerender = update_overlay = update_drag_toggleauto(get_cursor_x(), get_cursor_y());
4021 // Keyframe icons are sticky
4025 case DRAG_PLUGINKEY_PRE:
4026 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
4028 mwindow->session->current_operation++;
4036 rerender = update_overlay =
4037 update_drag_pluginauto(get_cursor_x(), get_cursor_y());
4040 case DRAG_PLUGINKEY:
4041 rerender = update_overlay =
4042 update_drag_pluginauto(get_cursor_x(), get_cursor_y());
4047 cursor_x = get_cursor_x();
4048 cursor_y = get_cursor_y();
4049 position = (double)(cursor_x + mwindow->edl->local_session->view_start) *
4050 mwindow->edl->local_session->zoom_sample /
4051 mwindow->edl->session->sample_rate;
4053 position = mwindow->edl->align_to_frame(position, 0);
4054 position = MAX(position, 0);
4056 if(position < selection_midpoint1)
4058 mwindow->edl->local_session->set_selectionend(selection_midpoint1);
4059 mwindow->edl->local_session->set_selectionstart(position);
4061 gui->unlock_window();
4062 mwindow->cwindow->update(1, 0, 0, 0, 1);
4063 gui->lock_window("TrackCanvas::cursor_motion_event 1");
4064 // Update the faders
4065 mwindow->update_plugin_guis();
4066 gui->patchbay->update();
4070 mwindow->edl->local_session->set_selectionstart(selection_midpoint1);
4071 mwindow->edl->local_session->set_selectionend(position);
4072 // Don't que the CWindow
4075 gui->cursor->hide(0);
4076 gui->cursor->draw(1);
4086 if(is_event_win() && cursor_inside())
4089 cursor_x = get_cursor_x();
4090 position = (double)cursor_x *
4091 (double)mwindow->edl->local_session->zoom_sample /
4092 (double)mwindow->edl->session->sample_rate +
4093 (double)mwindow->edl->local_session->view_start *
4094 (double)mwindow->edl->local_session->zoom_sample /
4095 (double)mwindow->edl->session->sample_rate;
4096 position = mwindow->edl->align_to_frame(position, 0);
4100 if(do_transitions(get_cursor_x(),
4110 if(do_keyframes(get_cursor_x(),
4122 if(do_edit_handles(get_cursor_x(),
4131 // Plugin boundaries
4132 if(do_plugin_handles(get_cursor_x(),
4141 if(do_edits(get_cursor_x(),
4156 //printf("TrackCanvas::cursor_motion_event 1\n");
4157 if(update_cursor && new_cursor != get_cursor())
4159 set_cursor(new_cursor);
4162 //printf("TrackCanvas::cursor_motion_event 1 %d\n", rerender);
4165 mwindow->restart_brender();
4166 mwindow->sync_parameters(CHANGE_PARAMS);
4167 mwindow->update_plugin_guis();
4168 gui->unlock_window();
4169 mwindow->cwindow->update(1, 0, 0, 0, 1);
4170 gui->lock_window("TrackCanvas::cursor_motion_event 2");
4172 gui->patchbay->update();
4178 if(!mwindow->cwindow->playback_engine->is_playing_back)
4179 gui->mainclock->update(position);
4184 gui->zoombar->update();
4190 (cursor_x >= get_w() || cursor_x < 0 || cursor_y >= get_h() || cursor_y < 0))
4194 (cursor_x < get_w() && cursor_x >= 0 && cursor_y < get_h() && cursor_y >= 0))
4205 //printf("TrackCanvas::cursor_motion_event 100\n");
4209 void TrackCanvas::start_dragscroll()
4214 set_repeat(BC_WindowBase::get_resources()->scroll_repeat);
4215 //printf("TrackCanvas::start_dragscroll 1\n");
4219 void TrackCanvas::stop_dragscroll()
4224 unset_repeat(BC_WindowBase::get_resources()->scroll_repeat);
4225 //printf("TrackCanvas::stop_dragscroll 1\n");
4229 int TrackCanvas::repeat_event(int64_t duration)
4231 if(!drag_scroll) return 0;
4232 if(duration != BC_WindowBase::get_resources()->scroll_repeat) return 0;
4234 int sample_movement = 0;
4235 int track_movement = 0;
4236 int64_t x_distance = 0;
4237 int64_t y_distance = 0;
4238 double position = 0;
4241 switch(mwindow->session->current_operation)
4244 //printf("TrackCanvas::repeat_event 1 %d\n", mwindow->edl->local_session->view_start);
4245 if(get_cursor_x() > get_w())
4247 x_distance = get_cursor_x() - get_w();
4248 sample_movement = 1;
4251 if(get_cursor_x() < 0)
4253 x_distance = get_cursor_x();
4254 sample_movement = 1;
4257 if(get_cursor_y() > get_h())
4259 y_distance = get_cursor_y() - get_h();
4263 if(get_cursor_y() < 0)
4265 y_distance = get_cursor_y();
4275 position = (double)(get_cursor_x() +
4276 mwindow->edl->local_session->view_start +
4278 mwindow->edl->local_session->zoom_sample /
4279 mwindow->edl->session->sample_rate;
4280 position = mwindow->edl->align_to_frame(position, 0);
4281 position = MAX(position, 0);
4283 //printf("TrackCanvas::repeat_event 1 %f\n", position);
4284 switch(mwindow->session->current_operation)
4287 if(position < selection_midpoint1)
4289 mwindow->edl->local_session->set_selectionend(selection_midpoint1);
4290 mwindow->edl->local_session->set_selectionstart(position);
4292 gui->unlock_window();
4293 mwindow->cwindow->update(1, 0, 0);
4294 gui->lock_window("TrackCanvas::repeat_event");
4295 // Update the faders
4296 mwindow->update_plugin_guis();
4297 gui->patchbay->update();
4301 mwindow->edl->local_session->set_selectionstart(selection_midpoint1);
4302 mwindow->edl->local_session->set_selectionend(position);
4303 // Don't que the CWindow
4308 mwindow->samplemovement(mwindow->edl->local_session->view_start +
4314 mwindow->trackmovement(mwindow->edl->local_session->track_start +
4321 int TrackCanvas::button_release_event()
4323 int redraw = 0, update_overlay = 0, result = 0;
4325 switch(mwindow->session->current_operation)
4327 case DRAG_EDITHANDLE2:
4328 mwindow->session->current_operation = NO_OPERATION;
4332 end_edithandle_selection();
4335 case DRAG_EDITHANDLE1:
4336 mwindow->session->current_operation = NO_OPERATION;
4341 case DRAG_PLUGINHANDLE2:
4342 mwindow->session->current_operation = NO_OPERATION;
4346 end_pluginhandle_selection();
4349 case DRAG_PLUGINHANDLE1:
4350 mwindow->session->current_operation = NO_OPERATION;
4356 // delete the drag_auto_gang first and remove out of order keys
4357 synchronize_autos(0, 0, 0, -1);
4368 case DRAG_PROJECTOR_X:
4369 case DRAG_PROJECTOR_Y:
4370 case DRAG_PROJECTOR_Z:
4371 case DRAG_PLUGINKEY:
4372 mwindow->session->current_operation = NO_OPERATION;
4373 mwindow->session->drag_handle = 0;
4374 // Remove any out-of-order keyframe
4375 if(mwindow->session->drag_auto)
4377 mwindow->session->drag_auto->autos->remove_nonsequential(
4378 mwindow->session->drag_auto);
4379 // mwindow->session->drag_auto->autos->optimize();
4382 mwindow->undo->update_undo(_("keyframe"), LOAD_AUTOMATION);
4387 case DRAG_AEFFECT_COPY:
4388 case DRAG_VEFFECT_COPY:
4389 // Trap in drag stop
4395 if(mwindow->session->current_operation)
4397 if(mwindow->session->current_operation == SELECT_REGION)
4399 mwindow->undo->update_undo(_("select"), LOAD_SESSION, 0, 0);
4402 mwindow->session->current_operation = NO_OPERATION;
4404 // Traps button release events
4410 cursor_motion_event();
4424 int TrackCanvas::do_edit_handles(int cursor_x,
4430 Edit *edit_result = 0;
4431 int handle_result = 0;
4434 if(!mwindow->edl->session->show_assets) return 0;
4436 for(Track *track = mwindow->edl->tracks->first;
4438 track = track->next)
4440 for(Edit *edit = track->edits->first;
4444 int64_t edit_x, edit_y, edit_w, edit_h;
4445 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
4447 if(cursor_x >= edit_x && cursor_x <= edit_x + edit_w &&
4448 cursor_y >= edit_y && cursor_y < edit_y + edit_h)
4450 if(cursor_x < edit_x + HANDLE_W)
4457 if(cursor_x >= edit_x + edit_w - HANDLE_W)
4475 if(handle_result == 0)
4477 position = edit_result->track->from_units(edit_result->startproject);
4478 new_cursor = LEFT_CURSOR;
4481 if(handle_result == 1)
4483 position = edit_result->track->from_units(edit_result->startproject + edit_result->length);
4484 new_cursor = RIGHT_CURSOR;
4487 // Reposition cursor
4490 mwindow->session->drag_edit = edit_result;
4491 mwindow->session->drag_handle = handle_result;
4492 mwindow->session->drag_button = get_buttonpress() - 1;
4493 mwindow->session->drag_position = position;
4494 mwindow->session->current_operation = DRAG_EDITHANDLE1;
4495 mwindow->session->drag_origin_x = get_cursor_x();
4496 mwindow->session->drag_origin_y = get_cursor_y();
4497 mwindow->session->drag_start = position;
4499 int rerender = start_selection(position);
4502 gui->unlock_window();
4503 mwindow->cwindow->update(1, 0, 0);
4504 gui->lock_window("TrackCanvas::do_edit_handles");
4506 gui->timebar->update_highlights();
4507 gui->zoombar->update();
4508 gui->cursor->hide(0);
4509 gui->cursor->draw(1);
4519 int TrackCanvas::do_plugin_handles(int cursor_x,
4525 Plugin *plugin_result = 0;
4526 int handle_result = 0;
4529 if(!mwindow->edl->session->show_assets) return 0;
4531 for(Track *track = mwindow->edl->tracks->first;
4533 track = track->next)
4535 for(int i = 0; i < track->plugin_set.total && !result; i++)
4537 PluginSet *plugin_set = track->plugin_set.values[i];
4538 for(Plugin *plugin = (Plugin*)plugin_set->first;
4540 plugin = (Plugin*)plugin->next)
4542 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
4543 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
4545 if(cursor_x >= plugin_x && cursor_x <= plugin_x + plugin_w &&
4546 cursor_y >= plugin_y && cursor_y < plugin_y + plugin_h)
4548 if(cursor_x < plugin_x + HANDLE_W)
4550 plugin_result = plugin;
4555 if(cursor_x >= plugin_x + plugin_w - HANDLE_W)
4557 plugin_result = plugin;
4564 if(result && shift_down())
4565 mwindow->session->trim_edits = plugin_set;
4573 if(handle_result == 0)
4575 position = plugin_result->track->from_units(plugin_result->startproject);
4576 new_cursor = LEFT_CURSOR;
4579 if(handle_result == 1)
4581 position = plugin_result->track->from_units(plugin_result->startproject + plugin_result->length);
4582 new_cursor = RIGHT_CURSOR;
4587 mwindow->session->drag_plugin = plugin_result;
4588 mwindow->session->drag_handle = handle_result;
4589 mwindow->session->drag_button = get_buttonpress() - 1;
4590 mwindow->session->drag_position = position;
4591 mwindow->session->current_operation = DRAG_PLUGINHANDLE1;
4592 mwindow->session->drag_origin_x = get_cursor_x();
4593 mwindow->session->drag_origin_y = get_cursor_y();
4594 mwindow->session->drag_start = position;
4596 int rerender = start_selection(position);
4599 gui->unlock_window();
4600 mwindow->cwindow->update(1, 0, 0);
4601 gui->lock_window("TrackCanvas::do_plugin_handles");
4603 gui->timebar->update_highlights();
4604 gui->zoombar->update();
4605 gui->cursor->hide(0);
4606 gui->cursor->draw(1);
4617 int TrackCanvas::do_tracks(int cursor_x,
4624 if(!mwindow->edl->session->show_assets) return 0;
4627 for(Track *track = mwindow->edl->tracks->first;
4629 track = track->next)
4631 int64_t track_x, track_y, track_w, track_h;
4632 track_dimensions(track, track_x, track_y, track_w, track_h);
4635 get_buttonpress() == 3 &&
4636 cursor_y >= track_y &&
4637 cursor_y < track_y + track_h)
4639 gui->edit_menu->update(track, 0);
4640 gui->edit_menu->activate_menu();
4647 int TrackCanvas::do_edits(int cursor_x,
4657 int over_edit_handle = 0;
4659 if(!mwindow->edl->session->show_assets) return 0;
4661 for(Track *track = mwindow->edl->tracks->first;
4663 track = track->next)
4665 for(Edit *edit = track->edits->first;
4666 edit != track->edits->last && !result;
4669 int64_t edit_x, edit_y, edit_w, edit_h;
4670 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
4672 // Cursor inside a track
4673 // Cursor inside an edit
4674 if(cursor_x >= edit_x && cursor_x < edit_x + edit_w &&
4675 cursor_y >= edit_y && cursor_y < edit_y + edit_h)
4677 // Select duration of edit
4680 if(get_double_click() && !drag_start)
4682 mwindow->edl->local_session->set_selectionstart(edit->track->from_units(edit->startproject));
4683 mwindow->edl->local_session->set_selectionend(edit->track->from_units(edit->startproject) +
4684 edit->track->from_units(edit->length));
4685 if(mwindow->edl->session->cursor_on_frames)
4687 mwindow->edl->local_session->set_selectionstart(
4688 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionstart(1), 0));
4689 mwindow->edl->local_session->set_selectionend(
4690 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionend(1), 1));
4698 if(drag_start && track->record)
4700 if(mwindow->edl->session->editing_mode == EDITING_ARROW)
4702 // Need to create drag window
4703 mwindow->session->current_operation = DRAG_EDIT;
4704 mwindow->session->drag_edit = edit;
4705 //printf("TrackCanvas::do_edits 2\n");
4707 // Drag only one edit
4710 mwindow->session->drag_edits->remove_all();
4711 mwindow->session->drag_edits->append(edit);
4714 // Construct list of all affected edits
4716 mwindow->edl->tracks->get_affected_edits(
4717 mwindow->session->drag_edits,
4718 edit->track->from_units(edit->startproject),
4721 mwindow->session->drag_origin_x = cursor_x;
4722 mwindow->session->drag_origin_y = cursor_y;
4723 // Where the drag started, so we know relative position inside the edit later
4724 mwindow->session->drag_position = (double)cursor_x *
4725 mwindow->edl->local_session->zoom_sample /
4726 mwindow->edl->session->sample_rate +
4727 (double)mwindow->edl->local_session->view_start *
4728 mwindow->edl->local_session->zoom_sample /
4729 mwindow->edl->session->sample_rate;
4731 drag_popup = new BC_DragWindow(gui,
4732 mwindow->theme->get_image("clip_icon"),
4733 get_abs_cursor_x(0) - mwindow->theme->get_image("clip_icon")->get_w() / 2,
4734 get_abs_cursor_y(0) - mwindow->theme->get_image("clip_icon")->get_h() / 2);
4746 int TrackCanvas::test_resources(int cursor_x, int cursor_y)
4751 int TrackCanvas::do_plugins(int cursor_x,
4765 if(!mwindow->edl->session->show_assets) return 0;
4768 for(track = mwindow->edl->tracks->first;
4770 track = track->next)
4772 if(!track->expand_view) continue;
4775 for(int i = 0; i < track->plugin_set.total && !done; i++)
4777 // first check if plugins are visible at all
4778 if (!track->expand_view)
4780 PluginSet *plugin_set = track->plugin_set.values[i];
4781 for(plugin = (Plugin*)plugin_set->first;
4783 plugin = (Plugin*)plugin->next)
4785 plugin_dimensions(plugin, x, y, w, h);
4786 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
4787 MWindowGUI::visible(y, y + h, 0, get_h()))
4789 if(cursor_x >= x && cursor_x < x + w &&
4790 cursor_y >= y && cursor_y < y + h)
4802 // Start plugin popup
4805 if(get_buttonpress() == 3)
4807 gui->plugin_menu->update(plugin);
4808 gui->plugin_menu->activate_menu();
4812 // Select range of plugin on doubleclick over plugin
4813 if (get_double_click() && !drag_start)
4815 mwindow->edl->local_session->set_selectionstart(plugin->track->from_units(plugin->startproject));
4816 mwindow->edl->local_session->set_selectionend(plugin->track->from_units(plugin->startproject) +
4817 plugin->track->from_units(plugin->length));
4818 if(mwindow->edl->session->cursor_on_frames)
4820 mwindow->edl->local_session->set_selectionstart(
4821 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionstart(1), 0));
4822 mwindow->edl->local_session->set_selectionend(
4823 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionend(1), 1));
4832 if(drag_start && plugin->track->record)
4834 if(mwindow->edl->session->editing_mode == EDITING_ARROW)
4836 if(plugin->track->data_type == TRACK_AUDIO)
4837 mwindow->session->current_operation = DRAG_AEFFECT_COPY;
4839 if(plugin->track->data_type == TRACK_VIDEO)
4840 mwindow->session->current_operation = DRAG_VEFFECT_COPY;
4842 mwindow->session->drag_plugin = plugin;
4849 switch(plugin->plugin_type)
4851 case PLUGIN_STANDALONE:
4853 PluginServer *server = mwindow->scan_plugindb(
4855 plugin->track->data_type);
4858 VFrame *frame = server->picon;
4860 drag_popup = new BC_DragWindow(gui,
4862 get_abs_cursor_x(0) - frame->get_w() / 2,
4863 get_abs_cursor_y(0) - frame->get_h() / 2);
4868 case PLUGIN_SHAREDPLUGIN:
4869 case PLUGIN_SHAREDMODULE:
4870 drag_popup = new BC_DragWindow(gui,
4871 mwindow->theme->get_image("clip_icon"),
4872 get_abs_cursor_x(0) - mwindow->theme->get_image("clip_icon")->get_w() / 2,
4873 get_abs_cursor_y(0) - mwindow->theme->get_image("clip_icon")->get_h() / 2);
4886 int TrackCanvas::do_transitions(int cursor_x,
4892 Transition *transition = 0;
4898 if(!mwindow->edl->session->show_assets ||
4899 !mwindow->edl->session->auto_conf->transitions) return 0;
4903 for(Track *track = mwindow->edl->tracks->first;
4905 track = track->next)
4907 for(Edit *edit = track->edits->first;
4911 if(edit->transition)
4913 edit_dimensions(edit, x, y, w, h);
4914 get_transition_coords(x, y, w, h);
4916 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
4917 MWindowGUI::visible(y, y + h, 0, get_h()))
4919 if(cursor_x >= x && cursor_x < x + w &&
4920 cursor_y >= y && cursor_y < y + h)
4922 transition = edit->transition;
4936 new_cursor = UPRIGHT_ARROW_CURSOR;
4939 if(get_buttonpress() == 3)
4941 gui->transition_menu->update(transition);
4942 gui->transition_menu->activate_menu();
4949 int TrackCanvas::button_press_event()
4952 int cursor_x, cursor_y;
4953 int new_cursor, update_cursor;
4955 cursor_x = get_cursor_x();
4956 cursor_y = get_cursor_y();
4957 mwindow->session->trim_edits = 0;
4959 if(is_event_win() && cursor_inside())
4961 double position = (double)cursor_x *
4962 mwindow->edl->local_session->zoom_sample /
4963 mwindow->edl->session->sample_rate +
4964 (double)mwindow->edl->local_session->view_start *
4965 mwindow->edl->local_session->zoom_sample /
4966 mwindow->edl->session->sample_rate;
4974 if(get_buttonpress() == 1)
4976 gui->unlock_window();
4977 gui->mbuttons->transport->handle_transport(STOP, 1, 0, 0);
4978 gui->lock_window("TrackCanvas::button_press_event");
4981 int update_overlay = 0, update_cursor = 0, rerender = 0;
4983 if(get_buttonpress() == 4)
4986 mwindow->expand_sample();
4988 mwindow->move_up(get_h() / 10);
4992 if(get_buttonpress() == 5)
4995 mwindow->zoom_in_sample();
4997 mwindow->move_down(get_h() / 10);
5001 switch(mwindow->edl->session->editing_mode)
5003 // Test handles and resource boundaries and highlight a track
5008 if(mwindow->edl->session->auto_conf->transitions &&
5009 do_transitions(cursor_x,
5018 if(do_keyframes(cursor_x,
5029 // Test edit boundaries
5030 if(do_edit_handles(cursor_x,
5039 // Test plugin boundaries
5040 if(do_plugin_handles(cursor_x,
5049 if(do_edits(cursor_x, cursor_y, 1, 0, update_cursor, rerender, new_cursor, update_cursor))
5054 if(do_plugins(cursor_x, cursor_y, 0, 1, update_cursor, rerender))
5059 if(test_resources(cursor_x, cursor_y))
5064 if(do_tracks(cursor_x, cursor_y, 1))
5071 // Test handles only and select a region
5074 //printf("TrackCanvas::button_press_event %d\n", position);
5076 if(mwindow->edl->session->auto_conf->transitions &&
5077 do_transitions(cursor_x,
5086 if(do_keyframes(cursor_x,
5098 // Test edit boundaries
5099 if(do_edit_handles(cursor_x,
5108 // Test plugin boundaries
5109 if(do_plugin_handles(cursor_x,
5118 if(do_edits(cursor_x,
5130 if(do_plugins(cursor_x,
5140 if(do_tracks(cursor_x, cursor_y, 1))
5144 // Highlight selection
5148 rerender = start_selection(position);
5150 mwindow->session->current_operation = SELECT_REGION;
5162 gui->unlock_window();
5163 mwindow->cwindow->update(1, 0, 0, 0, 1);
5165 gui->lock_window("TrackCanvas::button_press_event 2");
5167 mwindow->update_plugin_guis();
5168 gui->patchbay->update();
5181 gui->timebar->update_highlights();
5182 gui->cursor->hide();
5183 gui->cursor->show();
5184 gui->zoombar->update();
5196 int TrackCanvas::start_selection(double position)
5199 position = mwindow->edl->align_to_frame(position, 0);
5205 double midpoint = (mwindow->edl->local_session->get_selectionstart(1) +
5206 mwindow->edl->local_session->get_selectionend(1)) / 2;
5208 if(position < midpoint)
5210 mwindow->edl->local_session->set_selectionstart(position);
5211 selection_midpoint1 = mwindow->edl->local_session->get_selectionend(1);
5217 mwindow->edl->local_session->set_selectionend(position);
5218 selection_midpoint1 = mwindow->edl->local_session->get_selectionstart(1);
5219 // Don't que the CWindow for the end
5223 // Start a new selection
5225 //printf("TrackCanvas::start_selection %f\n", position);
5226 mwindow->edl->local_session->set_selectionstart(position);
5227 mwindow->edl->local_session->set_selectionend(position);
5228 selection_midpoint1 = position;
5236 void TrackCanvas::end_edithandle_selection()
5238 mwindow->modify_edithandles();
5241 void TrackCanvas::end_pluginhandle_selection()
5243 mwindow->modify_pluginhandles();
5247 double TrackCanvas::time_visible()
5249 return (double)get_w() *
5250 mwindow->edl->local_session->zoom_sample /
5251 mwindow->edl->session->sample_rate;
5294 void TrackCanvas::draw_automation()
5299 int TrackCanvas::set_index_file(int flash, Asset *asset)
5305 int TrackCanvas::button_release()
5311 int TrackCanvas::auto_reposition(int &cursor_x, int &cursor_y, int64_t cursor_position)
5317 int TrackCanvas::draw_floating_handle(int flash)
5322 int TrackCanvas::draw_loop_point(int64_t position, int flash)
5327 int TrackCanvas::draw_playback_cursor(int pixel, int flash)
5333 int TrackCanvas::update_handle_selection(int64_t cursor_position)
5338 int TrackCanvas::end_translation()