4 * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "apatchgui.inc"
25 #include "automation.h"
26 #include "bcsignals.h"
30 #include "cplayback.h"
32 #include "cwindowgui.h"
34 #include "edithandles.h"
35 #include "editpopup.h"
38 #include "edlsession.h"
39 #include "floatauto.h"
40 #include "floatautos.h"
42 #include "indexstate.h"
46 #include "keyframepopup.h"
47 #include "keyframes.h"
49 #include "localsession.h"
50 #include "mainclock.h"
51 #include "maincursor.h"
52 #include "mainsession.h"
54 #include "maskautos.h"
57 #include "mwindowgui.h"
61 #include "playbackengine.h"
62 #include "playtransport.h"
64 #include "pluginpopup.h"
65 #include "pluginserver.h"
66 #include "pluginset.h"
67 #include "plugintoggles.h"
68 #include "preferences.h"
69 #include "resourcepixmap.h"
70 #include "resourcethread.h"
73 #include "trackcanvas.h"
76 #include "transition.h"
77 #include "transitionhandles.h"
78 #include "transitionpopup.h"
79 #include "transportque.h"
81 #include "vpatchgui.inc"
86 //#define PIXMAP_AGE -5
87 #define PIXMAP_AGE -32
89 TrackCanvas::TrackCanvas(MWindow *mwindow,
100 this->mwindow = mwindow;
101 this->gui = mwindow->gui;
104 selection_midpoint = 0;
108 resource_timer = new Timer;
109 hourglass_enabled = 0;
110 timebar_position = -1;
113 TrackCanvas::~TrackCanvas()
115 // delete transition_handles;
117 delete keyframe_pixmap;
118 delete camerakeyframe_pixmap;
119 delete modekeyframe_pixmap;
120 delete pankeyframe_pixmap;
121 delete projectorkeyframe_pixmap;
122 delete maskkeyframe_pixmap;
123 delete background_pixmap;
124 if(temp_picon) delete temp_picon;
125 delete resource_timer;
128 void TrackCanvas::create_objects()
130 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
131 // transition_handles = new TransitionHandles(mwindow, this);
132 edit_handles = new EditHandles(mwindow, this);
133 keyframe_pixmap = new BC_Pixmap(this, mwindow->theme->keyframe_data, PIXMAP_ALPHA);
134 camerakeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->camerakeyframe_data, PIXMAP_ALPHA);
135 modekeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->modekeyframe_data, PIXMAP_ALPHA);
136 pankeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->pankeyframe_data, PIXMAP_ALPHA);
137 projectorkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->projectorkeyframe_data, PIXMAP_ALPHA);
138 maskkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->maskkeyframe_data, PIXMAP_ALPHA);
144 void TrackCanvas::resize_event()
146 //printf("TrackCanvas::resize_event 1\n");
149 //printf("TrackCanvas::resize_event 2\n");
152 int TrackCanvas::keypress_event()
161 int TrackCanvas::drag_stop_event()
163 return gui->drag_stop();
167 int TrackCanvas::drag_motion_event()
169 return gui->drag_motion();
172 int TrackCanvas::drag_motion(Track **over_track,
174 PluginSet **over_pluginset,
175 Plugin **over_plugin)
177 int cursor_x = get_relative_cursor_x();
178 int cursor_y = get_relative_cursor_y();
181 if(get_cursor_over_window() &&
184 cursor_x < get_w() &&
187 //printf("TrackCanvas::drag_motion %d %d\n", __LINE__, pane->number);
188 // Find the edit and track the cursor is over
189 for(Track *track = mwindow->edl->tracks->first; track; track = track->next)
191 int64_t track_x, track_y, track_w, track_h;
192 track_dimensions(track, track_x, track_y, track_w, track_h);
194 if(cursor_y >= track_y &&
195 cursor_y < track_y + track_h)
198 for(Edit *edit = track->edits->first; edit; edit = edit->next)
200 int64_t edit_x, edit_y, edit_w, edit_h;
201 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
203 if(cursor_x >= edit_x &&
204 cursor_y >= edit_y &&
205 cursor_x < edit_x + edit_w &&
206 cursor_y < edit_y + edit_h)
213 for(int i = 0; i < track->plugin_set.total; i++)
215 PluginSet *pluginset = track->plugin_set.values[i];
219 for(Plugin *plugin = (Plugin*)pluginset->first;
221 plugin = (Plugin*)plugin->next)
223 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
224 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
226 if(cursor_y >= plugin_y &&
227 cursor_y < plugin_y + plugin_h)
229 *over_pluginset = plugin->plugin_set;
231 if(cursor_x >= plugin_x &&
232 cursor_x < plugin_x + plugin_w)
234 *over_plugin = plugin;
248 int TrackCanvas::drag_stop(int *redraw)
251 int cursor_x = get_relative_cursor_x();
252 int cursor_y = get_relative_cursor_y();
255 if(get_cursor_over_window() &&
258 cursor_x < get_w() &&
261 switch(mwindow->session->current_operation)
263 case DRAG_VTRANSITION:
264 case DRAG_ATRANSITION:
265 if(mwindow->session->edit_highlighted)
267 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
268 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
269 (mwindow->session->current_operation == DRAG_VTRANSITION &&
270 mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
272 mwindow->session->current_operation = NO_OPERATION;
273 mwindow->paste_transition();
283 // Behavior for dragged plugins is limited by the fact that a shared plugin
284 // can only refer to a standalone plugin that exists in the same position in
285 // time. Dragging a plugin from one point in time to another can't produce
286 // a shared plugin to the original plugin. In this case we relocate the
287 // plugin instead of sharing it.
288 case DRAG_AEFFECT_COPY:
289 case DRAG_VEFFECT_COPY:
290 if(mwindow->session->track_highlighted &&
291 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY &&
292 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
293 (mwindow->session->current_operation == DRAG_VEFFECT_COPY &&
294 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
296 mwindow->session->current_operation = NO_OPERATION;
298 // Insert shared plugin in source
299 if(mwindow->session->track_highlighted != mwindow->session->drag_plugin->track &&
300 !mwindow->session->plugin_highlighted &&
301 !mwindow->session->pluginset_highlighted)
303 // Move plugin if different startproject
305 mwindow->move_effect(mwindow->session->drag_plugin,
307 mwindow->session->track_highlighted,
312 // Move source to different location
313 if(mwindow->session->pluginset_highlighted)
315 if(mwindow->session->plugin_highlighted)
317 if(mwindow->session->plugin_highlighted !=
318 mwindow->session->drag_plugin)
320 mwindow->move_effect(mwindow->session->drag_plugin,
321 mwindow->session->plugin_highlighted->plugin_set,
323 mwindow->session->plugin_highlighted->startproject);
328 mwindow->move_effect(mwindow->session->drag_plugin,
329 mwindow->session->pluginset_highlighted,
331 mwindow->session->pluginset_highlighted->length());
336 // Move to a new plugin set between two edits
337 if(mwindow->session->edit_highlighted)
339 mwindow->move_effect(mwindow->session->drag_plugin,
341 mwindow->session->track_highlighted,
342 mwindow->session->edit_highlighted->startproject);
346 // Move to a new plugin set
347 if(mwindow->session->track_highlighted)
349 mwindow->move_effect(mwindow->session->drag_plugin,
351 mwindow->session->track_highlighted,
360 if(mwindow->session->track_highlighted &&
361 ((mwindow->session->current_operation == DRAG_AEFFECT &&
362 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
363 (mwindow->session->current_operation == DRAG_VEFFECT &&
364 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
366 // Drop all the effects
367 PluginSet *plugin_set = mwindow->session->pluginset_highlighted;
368 Track *track = mwindow->session->track_highlighted;
370 double length = track->get_length();
372 if(mwindow->session->plugin_highlighted)
374 start = track->from_units(mwindow->session->plugin_highlighted->startproject);
375 length = track->from_units(mwindow->session->plugin_highlighted->length);
376 if(length <= 0) length = track->get_length();
379 if(mwindow->session->pluginset_highlighted)
381 start = track->from_units(plugin_set->length());
382 length = track->get_length() - start;
383 if(length <= 0) length = track->get_length();
386 if(mwindow->edl->local_session->get_selectionend() >
387 mwindow->edl->local_session->get_selectionstart())
389 start = mwindow->edl->local_session->get_selectionstart();
390 length = mwindow->edl->local_session->get_selectionend() -
391 mwindow->edl->local_session->get_selectionstart();
393 // Move to a point between two edits
395 // if(mwindow->session->edit_highlighted)
397 // start = mwindow->session->track_highlighted->from_units(
398 // mwindow->session->edit_highlighted->startproject);
399 // length = mwindow->session->track_highlighted->from_units(
400 // mwindow->session->edit_highlighted->length);
403 mwindow->insert_effects_canvas(start, length);
406 if (mwindow->session->track_highlighted)
407 result = 1; // we have to cleanup
411 if(mwindow->session->track_highlighted)
413 int64_t position = mwindow->session->edit_highlighted ?
414 mwindow->session->edit_highlighted->startproject :
415 mwindow->session->track_highlighted->edits->length();
416 double position_f = mwindow->session->track_highlighted->from_units(position);
417 Track *track = mwindow->session->track_highlighted;
418 mwindow->paste_assets(position_f, track);
419 result = 1; // need to be one no matter what, since we have track highlited so we have to cleanup....
424 mwindow->session->current_operation = NO_OPERATION;
425 if(mwindow->session->track_highlighted)
427 if(mwindow->session->track_highlighted->data_type == mwindow->session->drag_edit->track->data_type)
430 double position_f = 0;
431 if(mwindow->session->free_drag)
433 position_f = (double)(cursor_x +
434 mwindow->edl->local_session->view_start[pane->number]) *
435 mwindow->edl->local_session->zoom_sample /
436 mwindow->edl->session->sample_rate;
440 position = mwindow->session->edit_highlighted ?
441 mwindow->session->edit_highlighted->startproject :
442 mwindow->session->track_highlighted->edits->length();
443 position_f = mwindow->session->track_highlighted->from_units(position);
445 Track *track = mwindow->session->track_highlighted;
446 mwindow->move_edits(mwindow->session->drag_edits,
461 int TrackCanvas::drag_start_event()
466 int new_cursor, update_cursor;
468 if(mwindow->session->current_operation != NO_OPERATION) return 0;
473 if(do_plugins(get_drag_x(),
483 if(do_edits(get_drag_x(),
496 if(result) mwindow->session->free_drag = ctrl_down();
501 int TrackCanvas::cursor_leave_event()
503 // Because drag motion calls get_cursor_over_window we can be sure that
504 // all highlights get deleted now.
505 // This ended up blocking keyboard input from the drag operations.
506 if(timebar_position >= 0)
508 timebar_position = -1;
509 if(pane->timebar) pane->timebar->update(1);
513 // return drag_motion();
519 void TrackCanvas::draw(int mode, int hide_cursor)
524 // Swap pixmap layers
525 if(get_w() != background_pixmap->get_w() ||
526 get_h() != background_pixmap->get_h())
528 delete background_pixmap;
529 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
532 // Cursor disappears after resize when this is called.
533 // Cursor doesn't redraw after editing when this isn't called.
534 if(pane->cursor && hide_cursor) pane->cursor->hide();
535 draw_top_background(get_parent(), 0, 0, get_w(), get_h(), background_pixmap);
537 if(debug) PRINT_TRACE
538 draw_resources(mode);
540 if(debug) PRINT_TRACE
542 if(debug) PRINT_TRACE
545 void TrackCanvas::update_cursor(int flush)
547 switch(mwindow->edl->session->editing_mode)
549 case EDITING_ARROW: set_cursor(ARROW_CURSOR, 0, flush); break;
550 case EDITING_IBEAM: set_cursor(IBEAM_CURSOR, 0, flush); break;
555 void TrackCanvas::test_timer()
557 if(resource_timer->get_difference() > 1000 &&
561 hourglass_enabled = 1;
566 void TrackCanvas::draw_indexes(Indexable *indexable)
568 // Don't redraw raw samples
569 IndexState *index_state = 0;
570 index_state = indexable->index_state;
573 if(index_state->index_zoom > mwindow->edl->local_session->zoom_sample)
577 draw_resources(0, 1, indexable);
583 void TrackCanvas::draw_resources(int mode,
585 Indexable *indexable)
589 if(debug) PRINT_TRACE
591 if(!mwindow->edl->session->show_assets) return;
594 // can't stop thread here, because this is called for every pane
595 // if(mode != IGNORE_THREAD && !indexes_only)
596 // gui->resource_thread->stop_draw(!indexes_only);
598 if(mode != IGNORE_THREAD &&
600 !gui->resource_thread->interrupted)
602 printf("TrackCanvas::draw_resources %d: called without stopping ResourceThread\n",
605 BC_Signals::dump_stack();
608 if(debug) PRINT_TRACE
610 resource_timer->update();
612 // Age resource pixmaps for deletion
614 for(int i = 0; i < gui->resource_pixmaps.total; i++)
615 gui->resource_pixmaps.values[i]->visible--;
617 if(mode == FORCE_REDRAW)
618 gui->resource_pixmaps.remove_all_objects();
620 if(debug) PRINT_TRACE
623 for(Track *current = mwindow->edl->tracks->first;
627 if(debug) PRINT_TRACE
628 for(Edit *edit = current->edits->first; edit; edit = edit->next)
630 if(debug) PRINT_TRACE
631 if( current->data_type != TRACK_SUBTITLE )
632 if(!edit->asset && !edit->nested_edl) continue;
635 if(edit->track->data_type != TRACK_AUDIO) continue;
637 if(edit->nested_edl &&
638 strcmp(indexable->path, edit->nested_edl->path)) continue;
641 strcmp(indexable->path, edit->asset->path)) continue;
644 if(debug) PRINT_TRACE
646 int64_t edit_x, edit_y, edit_w, edit_h;
647 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
650 if(MWindowGUI::visible(edit_x, edit_x + edit_w, 0, get_w()) &&
651 MWindowGUI::visible(edit_y, edit_y + edit_h, 0, get_h()))
653 int64_t pixmap_x, pixmap_w, pixmap_h;
654 if(debug) PRINT_TRACE
656 // Search for existing pixmap containing edit
657 for(int i = 0; i < gui->resource_pixmaps.total; i++)
659 ResourcePixmap* pixmap = gui->resource_pixmaps.values[i];
660 // Same pointer can be different edit if editing took place
661 if(pixmap->edit_id == edit->id &&
662 pixmap->pane_number == pane->number)
668 if(debug) PRINT_TRACE
670 // Get new size, offset of pixmap needed
671 get_pixmap_size(edit,
677 if(debug) PRINT_TRACE
680 if(pixmap_w && pixmap_h)
682 // Create pixmap if it doesn't exist
683 ResourcePixmap* pixmap = create_pixmap(edit,
688 // Resize it if it's bigger
689 if(pixmap_w > pixmap->pixmap_w ||
690 pixmap_h > pixmap->pixmap_h)
691 pixmap->resize(pixmap_w, pixmap_h);
692 pixmap->draw_data(this,
701 // Resize it if it's smaller
702 if(pixmap_w < pixmap->pixmap_w ||
703 pixmap_h < pixmap->pixmap_h)
704 pixmap->resize(pixmap_w, pixmap_h);
706 // Copy pixmap to background canvas
707 background_pixmap->draw_pixmap(pixmap,
709 current->y_pixel - mwindow->edl->local_session->track_start[pane->number],
713 if(debug) PRINT_TRACE
720 // Delete unused pixmaps
721 if(debug) PRINT_TRACE
723 for(int i = gui->resource_pixmaps.total - 1; i >= 0; i--)
724 if(gui->resource_pixmaps.values[i]->visible < PIXMAP_AGE)
726 //printf("TrackCanvas::draw_resources %d\n", __LINE__);
727 delete gui->resource_pixmaps.values[i];
728 gui->resource_pixmaps.remove(gui->resource_pixmaps.values[i]);
730 if(debug) PRINT_TRACE
732 if(hourglass_enabled)
735 hourglass_enabled = 0;
737 if(debug) PRINT_TRACE
739 // can't stop thread here, because this is called for every pane
740 // if(mode != IGNORE_THREAD && !indexes_only)
741 // gui->resource_thread->start_draw();
742 if(debug) PRINT_TRACE
747 ResourcePixmap* TrackCanvas::create_pixmap(Edit *edit,
753 ResourcePixmap *result = 0;
755 for(int i = 0; i < gui->resource_pixmaps.total; i++)
757 //printf("TrackCanvas::create_pixmap 1 %d %d\n", edit->id, resource_pixmaps.values[i]->edit->id);
758 if(gui->resource_pixmaps.values[i]->edit_id == edit->id &&
759 gui->resource_pixmaps.values[i]->pane_number == pane->number)
761 result = gui->resource_pixmaps.values[i];
769 result = new ResourcePixmap(mwindow,
776 gui->resource_pixmaps.append(result);
779 // result->resize(pixmap_w, pixmap_h);
783 void TrackCanvas::get_pixmap_size(Edit *edit,
791 // Align x on frame boundaries
794 // switch(edit->edits->track->data_type)
806 if(pixmap_x + pixmap_w > get_w())
808 pixmap_w = get_w() - pixmap_x;
815 // int64_t picon_w = (int64_t)(edit->picon_w() + 0.5);
816 // int64_t frame_w = (int64_t)(edit->frame_w() + 0.5);
817 // int64_t pixel_increment = MAX(picon_w, frame_w);
818 // int64_t pixmap_x1 = edit_x;
819 // int64_t pixmap_x2 = edit_x + edit_w;
823 // pixmap_x1 = (int64_t)((double)-edit_x / pixel_increment) *
828 // if(pixmap_x2 > get_w())
830 // pixmap_x2 = (int64_t)((double)(get_w() - edit_x) / pixel_increment + 1) *
834 // pixmap_x = pixmap_x1;
835 // pixmap_w = pixmap_x2 - pixmap_x1;
840 pixmap_h = mwindow->edl->local_session->zoom_track;
841 if(mwindow->edl->session->show_titles) pixmap_h += mwindow->theme->get_image("title_bg_data")->get_h();
842 //printf("get_pixmap_size %d %d %d %d\n", edit_x, edit_w, pixmap_x, pixmap_w);
845 void TrackCanvas::edit_dimensions(Edit *edit,
851 // w = Units::round(edit->track->from_units(edit->length) *
852 // mwindow->edl->session->sample_rate /
853 // mwindow->edl->local_session->zoom_sample);
857 x = Units::round(edit->track->from_units(edit->startproject) *
858 mwindow->edl->session->sample_rate /
859 mwindow->edl->local_session->zoom_sample -
860 mwindow->edl->local_session->view_start[pane->number]);
862 // Method for calculating w so when edits are together we never get off by one error due to rounding
863 int64_t x_next = Units::round(edit->track->from_units(edit->startproject + edit->length) *
864 mwindow->edl->session->sample_rate /
865 mwindow->edl->local_session->zoom_sample -
866 mwindow->edl->local_session->view_start[pane->number]);
869 y = edit->edits->track->y_pixel - mwindow->edl->local_session->track_start[pane->number];
871 if(mwindow->edl->session->show_titles)
872 h += mwindow->theme->get_image("title_bg_data")->get_h();
875 void TrackCanvas::track_dimensions(Track *track, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
879 y = track->y_pixel - mwindow->edl->local_session->track_start[pane->number];
880 h = track->vertical_span(mwindow->theme);
884 void TrackCanvas::draw_paste_destination()
886 int cursor_x = get_relative_cursor_x();
887 //int cursor_y = get_relative_cursor_y();
888 int current_atrack = 0;
889 int current_vtrack = 0;
890 int current_aedit = 0;
891 int current_vedit = 0;
896 //if(pane->number == BOTTOM_RIGHT_PANE)
897 //printf("TrackCanvas::draw_paste_destination %d %p\n", __LINE__, mwindow->session->track_highlighted);
899 if((mwindow->session->current_operation == DRAG_ASSET &&
900 (mwindow->session->drag_assets->total ||
901 mwindow->session->drag_clips->total)) ||
902 (mwindow->session->current_operation == DRAG_EDIT &&
903 mwindow->session->drag_edits->total))
906 Indexable *indexable = 0;
910 if(mwindow->session->current_operation == DRAG_ASSET &&
911 mwindow->session->drag_assets->size())
912 indexable = mwindow->session->drag_assets->get(0);
914 if(mwindow->session->current_operation == DRAG_ASSET &&
915 mwindow->session->drag_clips->size())
916 clip = mwindow->session->drag_clips->get(0);
918 // Get destination track
919 for(Track *dest = mwindow->session->track_highlighted;
925 // Get source width in pixels
928 // Use current cursor position
929 if(mwindow->session->free_drag)
931 position = (double)(cursor_x +
932 mwindow->edl->local_session->view_start[pane->number]) *
933 mwindow->edl->local_session->zoom_sample /
934 mwindow->edl->session->sample_rate;
937 // Use start of highlighted edit
938 if(mwindow->session->edit_highlighted)
940 position = mwindow->session->track_highlighted->from_units(
941 mwindow->session->edit_highlighted->startproject);
944 // Use end of highlighted track, disregarding effects
946 position = mwindow->session->track_highlighted->from_units(
947 mwindow->session->track_highlighted->edits->length());
950 // Get the x coordinate
951 x = Units::to_int64(position *
952 mwindow->edl->session->sample_rate /
953 mwindow->edl->local_session->zoom_sample) -
954 mwindow->edl->local_session->view_start[pane->number];
956 if(dest->data_type == TRACK_AUDIO)
958 if(indexable && current_atrack < indexable->get_audio_channels())
960 //printf("TrackCanvas::draw_paste_destination %d %d\n", __LINE__, current_atrack);
961 w = Units::to_int64((double)indexable->get_audio_samples() /
962 indexable->get_sample_rate() *
963 mwindow->edl->session->sample_rate /
964 mwindow->edl->local_session->zoom_sample);
969 if(clip && current_atrack < clip->tracks->total_audio_tracks())
971 w = Units::to_int64((double)clip->tracks->total_length() *
972 mwindow->edl->session->sample_rate /
973 mwindow->edl->local_session->zoom_sample);
974 //printf("draw_paste_destination %d\n", x);
979 if(mwindow->session->current_operation == DRAG_EDIT &&
980 current_aedit < mwindow->session->drag_edits->total)
983 while(current_aedit < mwindow->session->drag_edits->total &&
984 mwindow->session->drag_edits->values[current_aedit]->track->data_type != TRACK_AUDIO)
987 if(current_aedit < mwindow->session->drag_edits->total)
989 edit = mwindow->session->drag_edits->values[current_aedit];
990 w = Units::to_int64(edit->length / mwindow->edl->local_session->zoom_sample);
998 if(dest->data_type == TRACK_VIDEO)
1000 //printf("draw_paste_destination 1\n");
1001 if(indexable && current_vtrack < indexable->get_video_layers())
1003 w = Units::to_int64((double)indexable->get_video_frames() /
1004 indexable->get_frame_rate() *
1005 mwindow->edl->session->sample_rate /
1006 mwindow->edl->local_session->zoom_sample);
1011 if(clip && current_vtrack < clip->tracks->total_video_tracks())
1013 w = Units::to_int64(clip->tracks->total_length() *
1014 mwindow->edl->session->sample_rate /
1015 mwindow->edl->local_session->zoom_sample);
1020 if(mwindow->session->current_operation == DRAG_EDIT &&
1021 current_vedit < mwindow->session->drag_edits->total)
1024 while(current_vedit < mwindow->session->drag_edits->total &&
1025 mwindow->session->drag_edits->values[current_vedit]->track->data_type != TRACK_VIDEO)
1028 if(current_vedit < mwindow->session->drag_edits->total)
1030 edit = mwindow->session->drag_edits->values[current_vedit];
1031 w = Units::to_int64(edit->track->from_units(edit->length) *
1032 mwindow->edl->session->sample_rate /
1033 mwindow->edl->local_session->zoom_sample);
1043 int y = dest->y_pixel - mwindow->edl->local_session->track_start[pane->number];
1044 int h = dest->vertical_span(mwindow->theme);
1047 //printf("TrackCanvas::draw_paste_destination 2 %d %d %d %d\n", x, y, w, h);
1048 if(x < -BC_INFINITY)
1050 w -= -BC_INFINITY - x;
1051 x += -BC_INFINITY - x;
1054 // if(pane->number == TOP_RIGHT_PANE)
1055 // printf("TrackCanvas::draw_paste_destination %d %d %d %d %d\n",
1061 draw_highlight_rectangle(x, y, w, h);
1068 void TrackCanvas::plugin_dimensions(Plugin *plugin, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1070 x = Units::round(plugin->track->from_units(plugin->startproject) *
1071 mwindow->edl->session->sample_rate /
1072 mwindow->edl->local_session->zoom_sample -
1073 mwindow->edl->local_session->view_start[pane->number]);
1074 w = Units::round(plugin->track->from_units(plugin->length) *
1075 mwindow->edl->session->sample_rate /
1076 mwindow->edl->local_session->zoom_sample);
1077 y = plugin->track->y_pixel -
1078 mwindow->edl->local_session->track_start[pane->number] +
1079 mwindow->edl->local_session->zoom_track +
1080 plugin->plugin_set->get_number() *
1081 mwindow->theme->get_image("plugin_bg_data")->get_h();
1082 if(mwindow->edl->session->show_titles)
1083 y += mwindow->theme->get_image("title_bg_data")->get_h();
1084 h = mwindow->theme->get_image("plugin_bg_data")->get_h();
1087 int TrackCanvas::resource_h()
1089 return mwindow->edl->local_session->zoom_track;
1092 void TrackCanvas::draw_highlight_rectangle(int x, int y, int w, int h)
1106 w = MIN(w, get_w() + 20);
1107 h = MIN(h, get_h() + 20);
1112 draw_rectangle(x, y, w, h);
1113 draw_rectangle(x + 1, y + 1, w - 2, h - 2);
1114 draw_rectangle(x + 2, y + 2, w - 4, h - 4);
1117 //if(pane->number == TOP_RIGHT_PANE)
1118 //printf("TrackCanvas::draw_highlight_rectangle %d %d %d %d %d\n", __LINE__, x, y, w, h);
1121 void TrackCanvas::draw_playback_cursor()
1123 // Called before playback_cursor exists
1124 // if(mwindow->playback_cursor && mwindow->playback_cursor->visible)
1126 // mwindow->playback_cursor->visible = 0;
1127 // mwindow->playback_cursor->draw();
1131 void TrackCanvas::get_handle_coords(Edit *edit, int64_t &x, int64_t &y, int64_t &w, int64_t &h, int side)
1133 int handle_w = mwindow->theme->edithandlein_data[0]->get_w();
1134 int handle_h = mwindow->theme->edithandlein_data[0]->get_h();
1136 edit_dimensions(edit, x, y, w, h);
1138 if(mwindow->edl->session->show_titles)
1140 y += mwindow->theme->get_image("title_bg_data")->get_h();
1147 if(side == EDIT_OUT)
1156 void TrackCanvas::get_transition_coords(int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1158 //printf("TrackCanvas::get_transition_coords 1\n");
1159 // int transition_w = mwindow->theme->transitionhandle_data[0]->get_w();
1160 // int transition_h = mwindow->theme->transitionhandle_data[0]->get_h();
1161 int transition_w = 30;
1162 int transition_h = 30;
1163 //printf("TrackCanvas::get_transition_coords 1\n");
1165 if(mwindow->edl->session->show_titles)
1166 y += mwindow->theme->get_image("title_bg_data")->get_h();
1167 //printf("TrackCanvas::get_transition_coords 2\n");
1169 y += (h - mwindow->theme->get_image("title_bg_data")->get_h()) / 2 - transition_h / 2;
1170 x -= transition_w / 2;
1176 void TrackCanvas::draw_highlighting()
1184 switch(mwindow->session->current_operation)
1186 case DRAG_ATRANSITION:
1187 case DRAG_VTRANSITION:
1188 //printf("TrackCanvas::draw_highlighting 1 %p %p\n",
1189 // mwindow->session->track_highlighted, mwindow->session->edit_highlighted);
1190 if(mwindow->session->edit_highlighted)
1192 //printf("TrackCanvas::draw_highlighting 2\n");
1193 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
1194 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1195 (mwindow->session->current_operation == DRAG_VTRANSITION &&
1196 mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
1198 //printf("TrackCanvas::draw_highlighting 2\n");
1199 edit_dimensions(mwindow->session->edit_highlighted, x, y, w, h);
1200 //printf("TrackCanvas::draw_highlighting 2\n");
1202 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1203 MWindowGUI::visible(y, y + h, 0, get_h()))
1206 get_transition_coords(x, y, w, h);
1208 //printf("TrackCanvas::draw_highlighting 3\n");
1215 // Dragging a new effect from the Resource window
1218 if(mwindow->session->track_highlighted &&
1219 ((mwindow->session->current_operation == DRAG_AEFFECT && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1220 (mwindow->session->current_operation == DRAG_VEFFECT && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
1222 // Put it before another plugin
1223 if(mwindow->session->plugin_highlighted)
1225 plugin_dimensions(mwindow->session->plugin_highlighted,
1230 //printf("TrackCanvas::draw_highlighting 1 %d %d\n", x, w);
1233 // Put it after a plugin set
1234 if(mwindow->session->pluginset_highlighted &&
1235 mwindow->session->pluginset_highlighted->last)
1237 plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last,
1242 //printf("TrackCanvas::draw_highlighting 1 %d %d\n", x, w);
1243 int64_t track_x, track_y, track_w, track_h;
1244 track_dimensions(mwindow->session->track_highlighted,
1252 mwindow->session->track_highlighted->get_length() *
1253 mwindow->edl->session->sample_rate /
1254 mwindow->edl->local_session->zoom_sample -
1255 mwindow->edl->local_session->view_start[pane->number]) -
1257 //printf("TrackCanvas::draw_highlighting 2 %d\n", w);
1258 if(w <= 0) w = track_w;
1262 track_dimensions(mwindow->session->track_highlighted,
1268 //printf("TrackCanvas::draw_highlighting 1 %d %d %d %d\n", x, y, w, h);
1269 // Put it in a new plugin set determined by the selected range
1270 if(mwindow->edl->local_session->get_selectionend() >
1271 mwindow->edl->local_session->get_selectionstart())
1273 x = Units::to_int64(mwindow->edl->local_session->get_selectionstart() *
1274 mwindow->edl->session->sample_rate /
1275 mwindow->edl->local_session->zoom_sample -
1276 mwindow->edl->local_session->view_start[pane->number]);
1277 w = Units::to_int64((mwindow->edl->local_session->get_selectionend() -
1278 mwindow->edl->local_session->get_selectionstart()) *
1279 mwindow->edl->session->sample_rate /
1280 mwindow->edl->local_session->zoom_sample);
1282 // Put it in a new plugin set determined by an edit boundary
1284 // if(mwindow->session->edit_highlighted)
1286 // int64_t temp_y, temp_h;
1287 // edit_dimensions(mwindow->session->edit_highlighted,
1293 // Put it at the beginning of the track in a new plugin set
1296 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1297 MWindowGUI::visible(y, y + h, 0, get_h()))
1299 //printf("TrackCanvas::draw_highlighting 1\n");
1306 if(mwindow->session->track_highlighted)
1308 // track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1310 // if(MWindowGUI::visible(y, y + h, 0, get_h()))
1312 draw_paste_destination();
1318 if(mwindow->session->track_highlighted)
1320 // track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1322 // if(MWindowGUI::visible(y, y + h, 0, get_h()))
1324 draw_paste_destination();
1329 // Dragging an effect from the timeline
1330 case DRAG_AEFFECT_COPY:
1331 case DRAG_VEFFECT_COPY:
1332 if((mwindow->session->plugin_highlighted || mwindow->session->track_highlighted) &&
1333 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1334 (mwindow->session->current_operation == DRAG_VEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
1336 // Put it before another plugin
1337 if(mwindow->session->plugin_highlighted)
1338 plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
1340 // Put it after a plugin set
1341 if(mwindow->session->pluginset_highlighted &&
1342 mwindow->session->pluginset_highlighted->last)
1344 plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last, x, y, w, h);
1348 if(mwindow->session->track_highlighted)
1350 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1352 // Put it in a new plugin set determined by an edit boundary
1353 if(mwindow->session->edit_highlighted)
1355 int64_t temp_y, temp_h;
1356 edit_dimensions(mwindow->session->edit_highlighted,
1362 // Put it in a new plugin set at the start of the track
1365 // Calculate length of plugin based on data type of track and units
1366 if(mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
1368 w = (int64_t)((double)mwindow->session->drag_plugin->length /
1369 mwindow->edl->session->frame_rate *
1370 mwindow->edl->session->sample_rate /
1371 mwindow->edl->local_session->zoom_sample);
1375 w = (int64_t)mwindow->session->drag_plugin->length /
1376 mwindow->edl->local_session->zoom_sample;
1379 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1380 MWindowGUI::visible(y, y + h, 0, get_h()))
1387 case DRAG_PLUGINKEY:
1388 if(mwindow->session->plugin_highlighted &&
1389 mwindow->session->current_operation == DRAG_PLUGINKEY)
1391 // Just highlight the plugin
1392 plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
1394 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1395 MWindowGUI::visible(y, y + h, 0, get_h()))
1407 draw_highlight_rectangle(x, y, w, h);
1411 void TrackCanvas::draw_plugins()
1413 char string[BCTEXTLEN];
1415 int current_show = 0;
1418 // if(!mwindow->edl->session->show_assets) goto done;
1420 for(int i = 0; i < plugin_on_toggles.total; i++)
1421 plugin_on_toggles.values[i]->in_use = 0;
1422 for(int i = 0; i < plugin_show_toggles.total; i++)
1423 plugin_show_toggles.values[i]->in_use = 0;
1426 for(Track *track = mwindow->edl->tracks->first;
1428 track = track->next)
1430 if(track->expand_view)
1432 for(int i = 0; i < track->plugin_set.total; i++)
1434 PluginSet *pluginset = track->plugin_set.values[i];
1436 for(Plugin *plugin = (Plugin*)pluginset->first; plugin; plugin = (Plugin*)plugin->next)
1438 int64_t total_x, y, total_w, h;
1439 plugin_dimensions(plugin, total_x, y, total_w, h);
1441 if(MWindowGUI::visible(total_x, total_x + total_w, 0, get_w()) &&
1442 MWindowGUI::visible(y, y + h, 0, get_h()) &&
1443 plugin->plugin_type != PLUGIN_NONE)
1445 int x = total_x, w = total_w, left_margin = 5;
1446 int right_margin = 5;
1452 if(w + x > get_w()) w -= (w + x) - get_w();
1459 mwindow->theme->get_image("plugin_bg_data"),
1461 set_color(mwindow->theme->title_color);
1462 set_font(mwindow->theme->title_font);
1463 plugin->calculate_title(string, 0);
1465 // Truncate string to int64_test visible in background
1466 int len = strlen(string), j;
1467 for(j = len; j >= 0; j--)
1469 if(left_margin + get_text_width(mwindow->theme->title_font, string) > w)
1477 // Justify the text on the left boundary of the edit if it is visible.
1478 // Otherwise justify it on the left side of the screen.
1479 int64_t text_x = total_x + left_margin;
1480 int64_t text_w = get_text_width(mwindow->theme->title_font, string, strlen(string));
1481 text_x = MAX(left_margin, text_x);
1483 y + get_text_ascent(mwindow->theme->title_font) + 2,
1487 int64_t min_x = total_x + text_w;
1490 // Update plugin toggles
1491 int toggle_x = total_x + total_w;
1493 toggle_x = MIN(get_w() - right_margin, toggle_x);
1496 toggle_x -= PluginOn::calculate_w(mwindow) + 10;
1497 if(toggle_x > min_x)
1499 if(current_on >= plugin_on_toggles.total)
1501 PluginOn *plugin_on = new PluginOn(mwindow, toggle_x, toggle_y, plugin);
1502 add_subwindow(plugin_on);
1503 plugin_on_toggles.append(plugin_on);
1507 plugin_on_toggles.values[current_on]->update(toggle_x, toggle_y, plugin);
1512 // Toggles for standalone plugins only
1513 if(plugin->plugin_type == PLUGIN_STANDALONE)
1516 toggle_x -= PluginShow::calculate_w(mwindow) + 10;
1517 if(toggle_x > min_x)
1519 if(current_show >= plugin_show_toggles.total)
1521 PluginShow *plugin_show = new PluginShow(mwindow, toggle_x, toggle_y, plugin);
1522 add_subwindow(plugin_show);
1523 plugin_show_toggles.append(plugin_show);
1527 plugin_show_toggles.values[current_show]->update(toggle_x, toggle_y, plugin);
1541 // Remove unused toggles
1543 while(current_show < plugin_show_toggles.total)
1545 plugin_show_toggles.remove_object_number(current_show);
1548 while(current_on < plugin_on_toggles.total)
1550 plugin_on_toggles.remove_object_number(current_on);
1555 void TrackCanvas::refresh_plugintoggles()
1557 for(int i = 0; i < plugin_on_toggles.total; i++)
1559 PluginOn *on = plugin_on_toggles.values[i];
1560 on->reposition_window(on->get_x(), on->get_y());
1562 for(int i = 0; i < plugin_show_toggles.total; i++)
1564 PluginShow *show = plugin_show_toggles.values[i];
1565 show->reposition_window(show->get_x(), show->get_y());
1569 void TrackCanvas::draw_inout_points()
1574 void TrackCanvas::draw_drag_handle()
1576 if(mwindow->session->current_operation == DRAG_EDITHANDLE2 ||
1577 mwindow->session->current_operation == DRAG_PLUGINHANDLE2)
1579 //printf("TrackCanvas::draw_drag_handle 1 %ld %ld\n", mwindow->session->drag_sample, mwindow->edl->local_session->view_start);
1580 int64_t pixel1 = Units::round(mwindow->session->drag_position *
1581 mwindow->edl->session->sample_rate /
1582 mwindow->edl->local_session->zoom_sample -
1583 mwindow->edl->local_session->view_start[pane->number]);
1584 //printf("TrackCanvas::draw_drag_handle 2 %d %jd\n", pane->number, pixel1);
1587 //printf("TrackCanvas::draw_drag_handle 3\n");
1588 draw_line(pixel1, 0, pixel1, get_h());
1590 //printf("TrackCanvas::draw_drag_handle 4\n");
1595 void TrackCanvas::draw_transitions()
1599 // if(!mwindow->edl->session->show_assets) return;
1601 for(Track *track = mwindow->edl->tracks->first; track; track = track->next) {
1602 for(Edit *edit = track->edits->first; edit; edit = edit->next) {
1603 if(!edit->transition) continue;
1604 edit_dimensions(edit, x, y, w, h);
1605 get_transition_coords(x, y, w, h);
1606 if( !MWindowGUI::visible(x, x + w, 0, get_w()) ) continue;
1607 if( !MWindowGUI::visible(y, y + h, 0, get_h()) ) continue;
1608 PluginServer *server = mwindow->scan_plugindb(edit->transition->title,
1610 if( !server ) continue;
1611 VFrame *picon = server->get_picon();
1612 if( !picon ) continue;
1613 draw_vframe(picon, x, y, w, h, 0, 0, picon->get_w(), picon->get_h());
1618 void TrackCanvas::draw_loop_points()
1620 //printf("TrackCanvas::draw_loop_points 1\n");
1621 if(mwindow->edl->local_session->loop_playback)
1623 //printf("TrackCanvas::draw_loop_points 2\n");
1624 int64_t x = Units::round(mwindow->edl->local_session->loop_start *
1625 mwindow->edl->session->sample_rate /
1626 mwindow->edl->local_session->zoom_sample -
1627 mwindow->edl->local_session->view_start[pane->number]);
1628 //printf("TrackCanvas::draw_loop_points 3\n");
1630 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1633 draw_line(x, 0, x, get_h());
1635 //printf("TrackCanvas::draw_loop_points 4\n");
1637 x = Units::round(mwindow->edl->local_session->loop_end *
1638 mwindow->edl->session->sample_rate /
1639 mwindow->edl->local_session->zoom_sample -
1640 mwindow->edl->local_session->view_start[pane->number]);
1641 //printf("TrackCanvas::draw_loop_points 5\n");
1643 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1646 draw_line(x, 0, x, get_h());
1648 //printf("TrackCanvas::draw_loop_points 6\n");
1650 //printf("TrackCanvas::draw_loop_points 7\n");
1653 void TrackCanvas::draw_brender_start()
1655 if(mwindow->preferences->use_brender)
1657 int64_t x = Units::round(mwindow->edl->session->brender_start *
1658 mwindow->edl->session->sample_rate /
1659 mwindow->edl->local_session->zoom_sample -
1660 mwindow->edl->local_session->view_start[pane->number]);
1662 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1665 draw_line(x, 0, x, get_h());
1670 static int auto_colors[AUTOMATION_TOTAL] =
1686 // The operations which correspond to each automation type
1687 static int auto_operations[AUTOMATION_TOTAL] =
1703 // The buttonpress operations, so nothing changes unless the mouse moves
1704 // a certain amount. This allows the keyframe to be used to position the
1705 // insertion point without moving itself.
1706 static int pre_auto_operations[AUTOMATION_TOTAL] =
1723 int TrackCanvas::do_keyframes(int cursor_x,
1731 // Note: button 3 (right mouse button) is not eaten to allow
1732 // track context menu to appear
1734 EDLSession *session = mwindow->edl->session;
1738 BC_Pixmap *auto_pixmaps[AUTOMATION_TOTAL] =
1740 0, 0, 0, 0, 0, 0, 0, 0,
1742 modekeyframe_pixmap,
1743 maskkeyframe_pixmap,
1748 for(Track *track = mwindow->edl->tracks->first;
1750 track = track->next)
1752 Auto *auto_keyframe;
1753 Automation *automation = track->automation;
1756 // Handle keyframes in reverse drawing order if a button press
1758 int end = AUTOMATION_TOTAL;
1762 start = AUTOMATION_TOTAL - 1;
1766 for(int i = start; i != end && !result; i += step)
1768 // Event not trapped and automation visible
1769 Autos *autos = automation->autos[i];
1770 if(!result && session->auto_conf->autos[i] && autos)
1774 case AUTOMATION_MODE:
1775 case AUTOMATION_PAN:
1776 case AUTOMATION_MASK:
1777 result = do_autos(track,
1778 automation->autos[i],
1789 switch(autos->get_type())
1791 case Autos::AUTOMATION_TYPE_FLOAT:
1794 result = do_float_autos(track,
1805 result = do_float_autos(track,
1817 case Autos::AUTOMATION_TYPE_INT:
1820 result = do_int_autos(track,
1830 result = do_int_autos(track,
1849 if(mwindow->session->current_operation == auto_operations[i])
1852 // printf("TrackCanvas::do_keyframes %d %d %d\n",
1854 // mwindow->session->current_operation,
1855 // auto_operations[i]);
1858 if (buttonpress != 3)
1860 if(i == AUTOMATION_FADE)
1861 synchronize_autos(0,
1863 (FloatAuto*)mwindow->session->drag_auto,
1865 mwindow->session->current_operation = pre_auto_operations[i];
1866 update_drag_caption();
1870 gui->keyframe_menu->update(automation,
1873 gui->keyframe_menu->activate_menu();
1874 rerender = 1; // the position changes
1885 session->auto_conf->plugins /* &&
1886 mwindow->edl->session->show_assets */)
1890 result = do_plugin_autos(track,
1897 if(result && mwindow->session->current_operation == DRAG_PLUGINKEY)
1901 if(result && (buttonpress == 1))
1903 mwindow->session->current_operation = DRAG_PLUGINKEY_PRE;
1904 update_drag_caption();
1907 if (result && (buttonpress == 3))
1909 gui->keyframe_menu->update(plugin, keyframe);
1910 gui->keyframe_menu->activate_menu();
1911 rerender = 1; // the position changes
1916 // Final pass to trap event
1917 for(int i = 0; i < AUTOMATION_TOTAL; i++)
1919 if(mwindow->session->current_operation == pre_auto_operations[i] ||
1920 mwindow->session->current_operation == auto_operations[i])
1927 if(mwindow->session->current_operation == DRAG_PLUGINKEY ||
1928 mwindow->session->current_operation == DRAG_PLUGINKEY_PRE)
1936 new_cursor = UPRIGHT_ARROW_CURSOR;
1943 void TrackCanvas::draw_auto(Auto *current,
1951 x1 = x - HANDLE_W / 2;
1952 x2 = x + HANDLE_W / 2;
1953 y1 = center_pixel + y - HANDLE_W / 2;
1954 y2 = center_pixel + y + HANDLE_W / 2;
1956 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
1957 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
1959 draw_box(x1, y1, x2 - x1, y2 - y1);
1969 // This draws lines for bezier in & out controls
1970 void TrackCanvas::draw_cropped_line(int x1,
1979 // Don't care about x since it is clipped by the window.
1980 // Put y coords in ascending order
1993 double slope = (double)(x2 - x1) / (y2 - y1);
1994 //printf("TrackCanvas::draw_cropped_line %d %d %d %d %d\n", __LINE__, x1, y1, x2, y2);
1997 x1 = (int)(x1 + (min_y - y1) * slope);
2003 x1 = (int)(x1 + (max_y - 1 - y1) * slope);
2009 x2 = (int)(x2 + (max_y - 1 - y2) * slope);
2015 x2 = (int)(x2 + (min_y - y2) * slope);
2020 //printf("TrackCanvas::draw_cropped_line %d %d %d %d %d\n", __LINE__, x1, y1, x2, y2);
2025 draw_line(x1, y1, x2, y2);
2031 void TrackCanvas::draw_floatauto(Auto *current,
2044 //int out_x1, out_x2;
2048 x1 = x - HANDLE_W / 2;
2049 x2 = x + HANDLE_W / 2;
2050 y1 = center_pixel + y - HANDLE_W / 2;
2051 y2 = center_pixel + y + HANDLE_W / 2;
2053 CLAMP(y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2054 CLAMP(y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2058 if(((FloatAuto*)current)->mode == Auto::LINEAR)
2060 draw_box(x1, y1, x2 - x1, y2 - y1);
2064 ArrayList<int> polygon_x;
2065 ArrayList<int> polygon_y;
2066 polygon_x.append((x1 + x2) / 2 + 1);
2067 polygon_y.append(y1 + 1);
2068 polygon_x.append(x2 + 1);
2069 polygon_y.append((y1 + y2) / 2 + 1);
2070 polygon_x.append((x1 + x2) / 2 + 1);
2071 polygon_y.append(y2 + 1);
2072 polygon_x.append(x1 + 1);
2073 polygon_y.append((y1 + y2) / 2 + 1);
2074 fill_polygon(&polygon_x, &polygon_y);
2079 if(current->mode == Auto::BEZIER)
2081 //in_x1 = in_x - HANDLE_W / 2;
2082 //in_x2 = in_x + HANDLE_W / 2;
2083 in_y1 = center_pixel + in_y - HANDLE_W / 2;
2084 in_y2 = center_pixel + in_y + HANDLE_W / 2;
2087 draw_cropped_line(x,
2090 center_pixel + in_y,
2091 center_pixel + -zoom_track / 2,
2092 center_pixel + zoom_track / 2);
2094 CLAMP(in_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2095 CLAMP(in_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2096 CLAMP(in_y, -zoom_track / 2, zoom_track / 2);
2099 // if(in_y2 > in_y1)
2101 // set_color(BLACK);
2102 // draw_box(in_x1 + 1, in_y1 + 1, in_x2 - in_x1, in_y2 - in_y1);
2103 // set_color(color);
2104 // draw_box(in_x1, in_y1, in_x2 - in_x1, in_y2 - in_y1);
2109 //out_x1 = out_x - HANDLE_W / 2;
2110 //out_x2 = out_x + HANDLE_W / 2;
2111 out_y1 = center_pixel + out_y - HANDLE_W / 2;
2112 out_y2 = center_pixel + out_y + HANDLE_W / 2;
2115 draw_cropped_line(x,
2118 center_pixel + out_y,
2119 center_pixel + -zoom_track / 2,
2120 center_pixel + zoom_track / 2);
2122 CLAMP(out_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2123 CLAMP(out_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
2124 CLAMP(out_y, -zoom_track / 2, zoom_track / 2);
2126 // if(out_y2 > out_y1)
2128 // set_color(BLACK);
2129 // draw_box(out_x1 + 1, out_y1 + 1, out_x2 - out_x1, out_y2 - out_y1);
2130 // set_color(color);
2131 // draw_box(out_x1, out_y1, out_x2 - out_x1, out_y2 - out_y1);
2136 int TrackCanvas::test_auto(Auto *current,
2148 x1 = x - HANDLE_W / 2;
2149 x2 = x + HANDLE_W / 2;
2150 y1 = center_pixel + y - HANDLE_W / 2;
2151 y2 = center_pixel + y + HANDLE_W / 2;
2153 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2154 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2156 if(cursor_x >= x1 && cursor_x < x2 && cursor_y >= y1 && cursor_y < y2)
2158 if(buttonpress && buttonpress != 3)
2160 mwindow->session->drag_auto = current;
2161 mwindow->session->drag_start_percentage = current->value_to_percentage();
2162 mwindow->session->drag_start_position = current->position;
2163 mwindow->session->drag_origin_x = cursor_x;
2164 mwindow->session->drag_origin_y = cursor_y;
2169 if(buttonpress && buttonpress != 3 && result)
2171 //printf("TrackCanvas::test_auto %d\n", __LINE__);
2172 mwindow->undo->update_undo_before();
2178 int TrackCanvas::test_floatauto(Auto *current,
2192 int in_x1, in_y1, in_x2, in_y2;
2193 int out_x1, out_y1, out_x2, out_y2;
2196 x1 = x - HANDLE_W / 2;
2197 x2 = x + HANDLE_W / 2;
2198 y1 = center_pixel + y - HANDLE_W / 2;
2199 y2 = center_pixel + y + HANDLE_W / 2;
2201 if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
2202 if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
2207 // Compute in handle extents from x position
2210 in_y1 = center_pixel +
2219 in_y1 = in_y - HANDLE_W / 2;
2221 in_y2 = in_y1 + HANDLE_W;
2223 if(in_y1 < center_pixel + -zoom_track / 2) in_y1 = center_pixel + -zoom_track / 2;
2224 if(in_y2 > center_pixel + zoom_track / 2) in_y2 = center_pixel + zoom_track / 2;
2230 out_y1 = center_pixel +
2238 out_y1 = out_y - HANDLE_W / 2;
2240 out_y2 = out_y1 + HANDLE_W;
2242 if(out_y1 < center_pixel + -zoom_track / 2) out_y1 = center_pixel + -zoom_track / 2;
2243 if(out_y2 > center_pixel + zoom_track / 2) out_y2 = center_pixel + zoom_track / 2;
2247 //printf("TrackCanvas::test_floatauto %d cursor_x=%d cursor_y=%d in_x1=%d in_x2=%d in_y=%d in_y1=%d in_y2=%d position=" _LD "\n",
2248 //__LINE__, cursor_x, cursor_y, in_x1, in_x2, in_y, in_y1, in_y2, current->position);
2250 //printf("TrackCanvas::test_floatauto %d cursor_x=%d cursor_y=%d out_x1=%d out_x2=%d out_y=%d out_y1=%d out_y2=%d\n",
2251 //__LINE__, cursor_x, cursor_y, out_x1, out_x2, out_y, out_y1, out_y2);
2253 //printf("TrackCanvas::test_floatauto %d %d %d %d %d %d\n", cursor_x, cursor_y, x1, x2, y1, y2);
2261 if(buttonpress && (buttonpress != 3))
2263 mwindow->session->drag_auto = current;
2264 mwindow->session->drag_start_percentage = current->value_to_percentage();
2265 mwindow->session->drag_start_position = current->position;
2266 mwindow->session->drag_origin_x = cursor_x;
2267 mwindow->session->drag_origin_y = cursor_y;
2268 mwindow->session->drag_handle = 0;
2273 // Test in control line
2275 cursor_x >= in_x1 &&
2277 cursor_y >= in_y1 &&
2279 current->position > 0 &&
2280 current->mode == Auto::BEZIER)
2282 if(buttonpress && (buttonpress != 3))
2284 mwindow->session->drag_auto = current;
2285 mwindow->session->drag_start_percentage =
2286 current->invalue_to_percentage();
2287 // mwindow->session->drag_start_position =
2288 // ((FloatAuto*)current)->control_in_position;
2289 mwindow->session->drag_origin_x = cursor_x;
2290 mwindow->session->drag_origin_y = cursor_y;
2291 mwindow->session->drag_handle = 1;
2298 cursor_x >= out_x1 &&
2299 cursor_x < out_x2 &&
2300 cursor_y >= out_y1 &&
2301 cursor_y < out_y2 &&
2302 current->mode == Auto::BEZIER)
2304 if(buttonpress && (buttonpress != 3))
2306 mwindow->session->drag_auto = current;
2307 mwindow->session->drag_start_percentage =
2308 current->outvalue_to_percentage();
2309 // mwindow->session->drag_start_position =
2310 // ((FloatAuto*)current)->control_out_position;
2311 mwindow->session->drag_origin_x = cursor_x;
2312 mwindow->session->drag_origin_y = cursor_y;
2313 mwindow->session->drag_handle = 2;
2319 // 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",
2320 // mwindow->session->drag_handle,
2325 if(buttonpress && (buttonpress != 3) && result)
2327 mwindow->undo->update_undo_before();
2334 // Get the float value & y for position x on the canvas
2335 #define X_TO_FLOATLINE(x) \
2336 int64_t position1 = (int64_t)(unit_start + x * zoom_units); \
2337 int64_t position2 = (int64_t)(unit_start + x * zoom_units) + 1; \
2338 /* Call by reference fails for some reason here */ \
2339 float value1 = autos->get_value(position1, PLAY_FORWARD, previous1, next1); \
2340 float value2 = autos->get_value(position2, PLAY_FORWARD, previous1, next1); \
2341 double position = unit_start + x * zoom_units; \
2343 if(position2 > position1) \
2346 (value2 - value1) * \
2347 (position - position1) / \
2348 (position2 - position1); \
2354 int y = center_pixel + \
2355 (int)(((value - automation_min) / automation_range - 0.5) * -yscale);
2358 void TrackCanvas::draw_floatline(int center_pixel,
2359 FloatAuto *previous,
2370 // Solve bezier equation for either every pixel or a certain large number of
2373 // Not using slope intercept
2378 // Call by reference fails for some reason here
2379 FloatAuto *previous1 = previous, *next1 = next;
2380 float automation_min = mwindow->edl->local_session->automation_min;
2381 float automation_max = mwindow->edl->local_session->automation_max;
2382 float automation_range = automation_max - automation_min;
2384 for(int x = x1; x < x2; x++)
2386 // Interpolate value between frames
2390 y >= center_pixel - yscale / 2 &&
2391 y < center_pixel + yscale / 2 - 1)
2393 // printf("TrackCanvas::draw_floatline y=%d min=%d max=%d\n",
2395 // (int)(center_pixel - yscale / 2),
2396 // (int)(center_pixel + yscale / 2 - 1));
2398 draw_line(x - 1, prev_y, x, y);
2408 int TrackCanvas::test_floatline(int center_pixel,
2422 float automation_min = mwindow->edl->local_session->automation_min;
2423 float automation_max = mwindow->edl->local_session->automation_max;
2424 float automation_range = automation_max - automation_min;
2425 FloatAuto *previous1 = 0, *next1 = 0;
2426 X_TO_FLOATLINE(cursor_x);
2428 if(cursor_x >= x1 &&
2430 cursor_y >= y - HANDLE_W / 2 &&
2431 cursor_y < y + HANDLE_W / 2 &&
2437 if(buttonpress == 3)
2445 mwindow->undo->update_undo_before();
2446 current = mwindow->session->drag_auto = autos->insert_auto(position1);
2447 ((FloatAuto*)current)->value = value;
2448 mwindow->session->drag_start_percentage = current->value_to_percentage();
2449 mwindow->session->drag_start_position = current->position;
2450 mwindow->session->drag_origin_x = cursor_x;
2451 mwindow->session->drag_origin_y = cursor_y;
2452 mwindow->session->drag_handle = 0;
2461 void TrackCanvas::synchronize_autos(float change,
2466 // fill mwindow->session->drag_auto_gang
2467 if (fill_gangs == 1 && skip->gang)
2469 for(Track *current = mwindow->edl->tracks->first;
2473 if(current->data_type == skip->data_type &&
2478 FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
2479 double position = skip->from_units(fauto->position);
2480 FloatAuto *previous = 0, *next = 0;
2482 float init_value = fade_autos->get_value(fauto->position, PLAY_FORWARD, previous, next);
2483 FloatAuto *keyframe;
2484 keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position);
2488 // create keyframe at exactly this point in time
2489 keyframe = (FloatAuto*)fade_autos->insert_auto(fauto->position);
2490 keyframe->value = init_value;
2494 // keyframe exists, just change it
2495 keyframe->value += change;
2498 keyframe->position = fauto->position;
2499 // keyframe->control_out_position = fauto->control_out_position;
2500 // keyframe->control_in_position = fauto->control_in_position;
2501 keyframe->control_out_value = fauto->control_out_value;
2502 keyframe->control_in_value = fauto->control_in_value;
2504 mwindow->session->drag_auto_gang->append((Auto *)keyframe);
2509 if (fill_gangs == 0)
2512 for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
2514 FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
2516 keyframe->value += change;
2517 keyframe->position = fauto->position;
2518 if(skip->data_type == TRACK_AUDIO)
2519 CLAMP(keyframe->value, INFINITYGAIN, MAX_AUDIO_FADE);
2521 CLAMP(keyframe->value, 0, MAX_VIDEO_FADE);
2522 // keyframe->control_out_position = fauto->control_out_position;
2523 // keyframe->control_in_position = fauto->control_in_position;
2524 keyframe->control_out_value = fauto->control_out_value;
2525 keyframe->control_in_value = fauto->control_in_value;
2531 if (fill_gangs == -1)
2533 for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
2535 FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
2536 keyframe->autos->remove_nonsequential(
2539 mwindow->session->drag_auto_gang->remove_all();
2544 void TrackCanvas::draw_toggleline(int center_pixel,
2550 draw_line(x1, center_pixel + y1, x2, center_pixel + y1);
2554 draw_line(x2, center_pixel + y1, x2, center_pixel + y2);
2558 int TrackCanvas::test_toggleline(Autos *autos,
2569 if(cursor_x >= x1 && cursor_x < x2)
2571 int miny = center_pixel + y1 - HANDLE_W / 2;
2572 int maxy = center_pixel + y1 + HANDLE_W / 2;
2573 if(cursor_y >= miny && cursor_y < maxy)
2578 if(buttonpress == 3)
2586 double position = (double)(cursor_x +
2587 mwindow->edl->local_session->view_start[pane->number]) *
2588 mwindow->edl->local_session->zoom_sample /
2589 mwindow->edl->session->sample_rate;
2590 int64_t unit_position = autos->track->to_units(position, 0);
2591 int new_value = (int)((IntAutos*)autos)->get_automation_constant(unit_position, unit_position);
2593 mwindow->undo->update_undo_before();
2595 current = mwindow->session->drag_auto = autos->insert_auto(unit_position);
2596 ((IntAuto*)current)->value = new_value;
2597 mwindow->session->drag_start_percentage = current->value_to_percentage();
2598 mwindow->session->drag_start_position = current->position;
2599 mwindow->session->drag_origin_x = cursor_x;
2600 mwindow->session->drag_origin_y = cursor_y;
2608 void TrackCanvas::calculate_viewport(Track *track,
2609 double &view_start, // Seconds
2611 double &view_end, // Seconds
2615 double &zoom_sample,
2618 view_start = (double)mwindow->edl->local_session->view_start[pane->number] *
2619 mwindow->edl->local_session->zoom_sample /
2620 mwindow->edl->session->sample_rate;
2621 unit_start = track->to_doubleunits(view_start);
2622 view_end = (double)(mwindow->edl->local_session->view_start[pane->number] +
2624 mwindow->edl->local_session->zoom_sample /
2625 mwindow->edl->session->sample_rate;
2626 unit_end = track->to_doubleunits(view_end);
2627 yscale = mwindow->edl->local_session->zoom_track;
2628 //printf("TrackCanvas::calculate_viewport yscale=%.0f\n", yscale);
2629 center_pixel = (int)(track->y_pixel -
2630 mwindow->edl->local_session->track_start[pane->number] +
2632 (mwindow->edl->session->show_titles ?
2633 mwindow->theme->get_image("title_bg_data")->get_h() :
2635 zoom_sample = mwindow->edl->local_session->zoom_sample;
2637 zoom_units = track->to_doubleunits(zoom_sample / mwindow->edl->session->sample_rate);
2640 float TrackCanvas::percentage_to_value(float percentage,
2647 if(percentage > 0.5)
2654 float automation_min = mwindow->edl->local_session->automation_min;
2655 float automation_max = mwindow->edl->local_session->automation_max;
2656 float automation_range = automation_max - automation_min;
2658 result = percentage * automation_range + automation_min;
2661 FloatAuto *ptr = (FloatAuto*)reference;
2662 result -= ptr->value;
2664 //printf("TrackCanvas::percentage_to_value %d %f\n", __LINE__, result);
2670 void TrackCanvas::calculate_auto_position(double *x,
2681 float automation_min = mwindow->edl->local_session->automation_min;
2682 float automation_max = mwindow->edl->local_session->automation_max;
2683 float automation_range = automation_max - automation_min;
2684 FloatAuto *ptr = (FloatAuto*)current;
2685 *x = (double)(ptr->position - unit_start) / zoom_units;
2686 *y = ((ptr->value - automation_min) /
2687 automation_range - 0.5) *
2692 // if(!EQUIV(ptr->control_in_value, 0.0))
2693 *in_x = *x - mwindow->theme->control_pixels;
2697 // *in_x = (double)(ptr->position +
2698 // ptr->control_in_position -
2705 *in_y = (((ptr->value + ptr->control_in_value) -
2707 automation_range - 0.5) *
2713 // if(!EQUIV(ptr->control_out_value, 0.0))
2714 *out_x = *x + mwindow->theme->control_pixels;
2718 // *out_x = (double)(ptr->position +
2719 // ptr->control_out_position -
2726 *out_y = (((ptr->value + ptr->control_out_value) -
2728 automation_range - 0.5) *
2737 int TrackCanvas::do_float_autos(Track *track,
2746 Auto* &auto_instance)
2758 double ax, ay, ax2, ay2;
2759 double in_x2, in_y2, out_x2, out_y2;
2766 if(draw) set_color(color);
2768 calculate_viewport(track,
2780 // Get first auto before start
2783 for(current = autos->last;
2784 current && current->position >= unit_start;
2790 calculate_auto_position(&ax,
2804 current = autos->first ? autos->first : autos->default_auto;
2807 calculate_auto_position(&ax,
2837 calculate_auto_position(&ax2,
2855 slope = (ay2 - ay) / (ax2 - ax);
2861 ay2 = ay + slope * (get_w() - ax);
2866 ay = ay + slope * (0 - ax);
2884 if(current && !result)
2886 if(current != autos->default_auto)
2891 result = test_floatauto(current,
2904 auto_instance = current;
2908 draw_floatauto(current,
2909 (int)ax2 + x_offset,
2911 (int)in_x2 + x_offset,
2913 (int)out_x2 + x_offset,
2915 (int)center_pixel + y_offset,
2924 // Draw joining line
2929 if(track->record /* && buttonpress != 3 */)
2931 result = test_floatline(center_pixel,
2937 // Exclude auto coverage from the end of the line. The auto overlaps
2938 (int)ax2 - HANDLE_W / 2,
2946 draw_floatline(center_pixel + y_offset,
2947 (FloatAuto*)previous,
2948 (FloatAuto*)current,
2975 current->position <= unit_end &&
2986 if(ax < get_w() && !result)
2992 if(track->record /* && buttonpress != 3 */)
2994 result = test_floatline(center_pixel,
3007 draw_floatline(center_pixel + y_offset,
3008 (FloatAuto*)previous,
3009 (FloatAuto*)current,
3031 int TrackCanvas::do_int_autos(Track *track,
3040 Auto * &auto_instance)
3051 double ax, ay, ax2, ay2;
3055 if(draw) set_color(color);
3057 calculate_viewport(track,
3068 double high = -yscale * 0.8 / 2;
3069 double low = yscale * 0.8 / 2;
3071 // Get first auto before start
3073 for(current = autos->last; current && current->position >= unit_start; current = PREVIOUS)
3079 ay = ((IntAuto*)current)->value > 0 ? high : low;
3084 current = autos->first ? autos->first : autos->default_auto;
3088 ay = ((IntAuto*)current)->value > 0 ? high : low;
3101 ax2 = (double)(current->position - unit_start) / zoom_units;
3102 ay2 = ((IntAuto*)current)->value > 0 ? high : low;
3110 if(ax2 > get_w()) ax2 = get_w();
3112 if(current && !result)
3114 if(current != autos->default_auto)
3120 result = test_auto(current,
3129 auto_instance = current;
3134 (int)ax2 + x_offset,
3135 (int)ay2 + y_offset,
3147 if(track->record /* && buttonpress != 3 */)
3149 result = test_toggleline(autos,
3162 draw_toggleline(center_pixel + y_offset,
3170 }while(current && current->position <= unit_end && !result);
3172 if(ax < get_w() && !result)
3178 if(track->record /* && buttonpress != 3 */)
3180 result = test_toggleline(autos,
3192 draw_toggleline(center_pixel + y_offset,
3201 int TrackCanvas::do_autos(Track *track,
3208 Auto * &auto_instance,
3222 calculate_viewport(track,
3235 for(current = autos->first; current && !result; current = NEXT)
3237 if(current->position >= unit_start && current->position < unit_end)
3240 x = (int64_t)((double)(current->position - unit_start) /
3241 zoom_units - (pixmap->get_w() / 2 + 0.5));
3242 y = center_pixel - pixmap->get_h() / 2;
3246 if(cursor_x >= x && cursor_y >= y &&
3247 cursor_x < x + pixmap->get_w() &&
3248 cursor_y < y + pixmap->get_h())
3251 auto_instance = current;
3253 if(buttonpress && (buttonpress != 3))
3255 mwindow->session->drag_auto = current;
3256 mwindow->session->drag_start_position = current->position;
3257 mwindow->session->drag_origin_x = cursor_x;
3258 mwindow->session->drag_origin_y = cursor_y;
3260 double position = autos->track->from_units(current->position);
3261 double center = (mwindow->edl->local_session->get_selectionstart(1) +
3262 mwindow->edl->local_session->get_selectionend(1)) /
3267 mwindow->edl->local_session->set_selectionstart(position);
3268 mwindow->edl->local_session->set_selectionend(position);
3271 if(position < center)
3273 mwindow->edl->local_session->set_selectionstart(position);
3276 mwindow->edl->local_session->set_selectionend(position);
3283 draw_pixmap(pixmap, x, y);
3291 // so this means it is always >0 when keyframe is found
3292 int TrackCanvas::do_plugin_autos(Track *track,
3297 Plugin* &keyframe_plugin,
3298 KeyFrame* &keyframe_instance)
3311 if(!track->expand_view) return 0;
3313 calculate_viewport(track,
3325 for(int i = 0; i < track->plugin_set.total && !result; i++)
3327 PluginSet *plugin_set = track->plugin_set.values[i];
3328 int center_pixel = (int)(track->y_pixel -
3329 mwindow->edl->local_session->track_start[pane->number] +
3330 mwindow->edl->local_session->zoom_track +
3331 (i + 0.5) * mwindow->theme->get_image("plugin_bg_data")->get_h() +
3332 (mwindow->edl->session->show_titles ? mwindow->theme->get_image("title_bg_data")->get_h() : 0));
3334 for(Plugin *plugin = (Plugin*)plugin_set->first;
3336 plugin = (Plugin*)plugin->next)
3338 for(KeyFrame *keyframe = (KeyFrame*)plugin->keyframes->first;
3339 keyframe && !result;
3340 keyframe = (KeyFrame*)keyframe->next)
3342 //printf("TrackCanvas::draw_plugin_autos 3 %d\n", keyframe->position);
3343 if(keyframe->position >= unit_start && keyframe->position < unit_end)
3345 int64_t x = (int64_t)((keyframe->position - unit_start) / zoom_units);
3346 int y = center_pixel - keyframe_pixmap->get_h() / 2;
3348 //printf("TrackCanvas::draw_plugin_autos 4 %d %d\n", x, center_pixel);
3351 if(cursor_x >= x && cursor_y >= y &&
3352 cursor_x < x + keyframe_pixmap->get_w() &&
3353 cursor_y < y + keyframe_pixmap->get_h())
3356 keyframe_plugin = plugin;
3357 keyframe_instance = keyframe;
3361 mwindow->session->drag_auto = keyframe;
3362 mwindow->session->drag_start_position = keyframe->position;
3363 mwindow->session->drag_origin_x = cursor_x;
3364 mwindow->session->drag_origin_y = cursor_y;
3366 double position = track->from_units(keyframe->position);
3367 double center = (mwindow->edl->local_session->get_selectionstart(1) +
3368 mwindow->edl->local_session->get_selectionend(1)) /
3373 mwindow->edl->local_session->set_selectionstart(position);
3374 mwindow->edl->local_session->set_selectionend(position);
3377 if(position < center)
3379 mwindow->edl->local_session->set_selectionstart(position);
3382 mwindow->edl->local_session->set_selectionend(position);
3387 draw_pixmap(keyframe_pixmap,
3397 // if(buttonpress && buttonpress != 3 && result)
3399 // mwindow->undo->update_undo_before();
3405 void TrackCanvas::draw_overlays()
3407 int new_cursor, update_cursor, rerender;
3409 // Move background pixmap to foreground pixmap
3410 draw_pixmap(background_pixmap,
3419 draw_inout_points();
3422 if(mwindow->edl->session->auto_conf->transitions) draw_transitions();
3429 draw_brender_start();
3431 // Highlighted areas
3432 draw_highlighting();
3444 if(pane->cursor) pane->cursor->restore(1);
3450 draw_playback_cursor();
3455 int TrackCanvas::activate()
3459 //printf("TrackCanvas::activate %d %d\n", __LINE__, pane->number);
3460 //BC_Signals::dump_stack();
3461 get_top_level()->deactivate();
3463 set_active_subwindow(this);
3464 pane->cursor->activate();
3465 gui->focused_pane = pane->number;
3470 int TrackCanvas::deactivate()
3475 pane->cursor->deactivate();
3481 void TrackCanvas::update_drag_handle()
3483 double new_position;
3486 (double)(get_cursor_x() +
3487 mwindow->edl->local_session->view_start[pane->number]) *
3488 mwindow->edl->local_session->zoom_sample /
3489 mwindow->edl->session->sample_rate;
3491 mwindow->edl->align_to_frame(new_position, 0);
3494 if(new_position != mwindow->session->drag_position)
3496 mwindow->session->drag_position = new_position;
3497 gui->mainclock->update(new_position);
3500 timebar_position = new_position;
3501 gui->update_timebar(0);
3502 // Que the CWindow. Doesn't do anything if selectionstart and selection end
3504 // mwindow->cwindow->update(1, 0, 0);
3508 int TrackCanvas::update_drag_edit()
3517 int TrackCanvas::get_drag_values(float *percentage,
3524 //int x = cursor_x - mwindow->session->drag_origin_x;
3525 //int y = cursor_y - mwindow->session->drag_origin_y;
3529 if(!current->autos->track->record) return 1;
3539 calculate_viewport(current->autos->track,
3549 *percentage = (float)(mwindow->session->drag_origin_y - cursor_y) /
3551 mwindow->session->drag_start_percentage;
3552 if(do_clamp) CLAMP(*percentage, 0, 1);
3554 *position = Units::to_int64(zoom_units *
3555 (cursor_x - mwindow->session->drag_origin_x) +
3556 mwindow->session->drag_start_position + 0.5);
3558 if((do_clamp) && *position < 0) *position = 0;
3571 int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y)
3573 FloatAuto *current = (FloatAuto*)mwindow->session->drag_auto;
3580 if(get_drag_values(&percentage,
3582 mwindow->session->drag_handle == 0,
3587 //printf("TrackCanvas::update_drag_floatauto %d %f\n", __LINE__, percentage);
3590 switch(mwindow->session->drag_handle)
3594 // Snap to nearby values
3595 old_value = current->value;
3600 double distance1 = percentage_to_value(0., 0, 0);
3601 double distance2 = percentage_to_value(1., 0, 0);
3602 value = percentage_to_value(percentage, 0, 0);
3604 if(current->previous)
3606 value1 = ((FloatAuto*)current->previous)->value;
3607 distance1 = fabs(value - value1);
3608 current->value = value1;
3613 value2 = ((FloatAuto*)current->next)->value;
3614 distance2 = fabs(value - value2);
3615 if(!current->previous || distance2 < distance1)
3617 current->value = value2;
3621 if(!current->previous && !current->next)
3623 current->value = ((FloatAutos*)current->autos)->default_;
3625 value = current->value;
3628 value = percentage_to_value(percentage, 0, 0);
3630 if(value != old_value || position != current->position)
3633 float change = value - old_value;
3634 current->value = value;
3635 current->position = position;
3636 synchronize_autos(change, current->autos->track, current, 0);
3638 char string[BCTEXTLEN], string2[BCTEXTLEN];
3639 Units::totext(string2,
3640 current->autos->track->from_units(current->position),
3641 mwindow->edl->session->time_format,
3642 mwindow->edl->session->sample_rate,
3643 mwindow->edl->session->frame_rate,
3644 mwindow->edl->session->frames_per_foot);
3645 sprintf(string, "%s, %.2f", string2, current->value);
3646 gui->show_message(string);
3652 value = percentage_to_value(percentage, 0, current);
3653 position = MIN(0, position);
3654 if(value != current->control_in_value)
3657 current->control_in_value = value;
3658 synchronize_autos(0, current->autos->track, current, 0);
3660 char string[BCTEXTLEN];
3661 sprintf(string, "%.2f", current->control_in_value);
3662 gui->show_message(string);
3668 value = percentage_to_value(percentage, 0, current);
3669 position = MAX(0, position);
3670 if(value != current->control_out_value)
3673 current->control_out_value = value;
3674 synchronize_autos(0, current->autos->track, current, 0);
3676 char string[BCTEXTLEN];
3677 sprintf(string, "%.2f",
3678 ((FloatAuto*)current)->control_out_value);
3679 gui->show_message(string);
3687 int TrackCanvas::update_drag_toggleauto(int cursor_x, int cursor_y)
3689 IntAuto *current = (IntAuto*)mwindow->session->drag_auto;
3694 if(get_drag_values(&percentage,
3702 int value = (int)percentage_to_value(percentage, 1, 0);
3704 if(value != current->value || position != current->position)
3707 current->value = value;
3708 current->position = position;
3710 char string[BCTEXTLEN], string2[BCTEXTLEN];
3711 Units::totext(string2,
3712 current->autos->track->from_units(current->position),
3713 mwindow->edl->session->time_format,
3714 mwindow->edl->session->sample_rate,
3715 mwindow->edl->session->frame_rate,
3716 mwindow->edl->session->frames_per_foot);
3717 sprintf(string, "%s, %d", string2, current->value);
3718 gui->show_message(string);
3724 // Autos which can't change value through dragging.
3726 int TrackCanvas::update_drag_auto(int cursor_x, int cursor_y)
3728 Auto *current = (Auto*)mwindow->session->drag_auto;
3733 if(get_drag_values(&percentage,
3741 if(position != current->position)
3744 current->position = position;
3746 char string[BCTEXTLEN];
3747 Units::totext(string,
3748 current->autos->track->from_units(current->position),
3749 mwindow->edl->session->time_format,
3750 mwindow->edl->session->sample_rate,
3751 mwindow->edl->session->frame_rate,
3752 mwindow->edl->session->frames_per_foot);
3753 gui->show_message(string);
3755 double position_f = current->autos->track->from_units(current->position);
3756 double center_f = (mwindow->edl->local_session->get_selectionstart(1) +
3757 mwindow->edl->local_session->get_selectionend(1)) /
3761 mwindow->edl->local_session->set_selectionstart(position_f);
3762 mwindow->edl->local_session->set_selectionend(position_f);
3765 if(position_f < center_f)
3767 mwindow->edl->local_session->set_selectionstart(position_f);
3770 mwindow->edl->local_session->set_selectionend(position_f);
3777 int TrackCanvas::update_drag_pluginauto(int cursor_x, int cursor_y)
3779 KeyFrame *current = (KeyFrame*)mwindow->session->drag_auto;
3784 if(get_drag_values(&percentage, &position, 1,
3785 cursor_x, cursor_y, current)) return 0;
3787 if(position != current->position)
3789 // printf("uida: autos: %p, track: %p ta: %p\n", current->autos, current->autos->track, current->autos->track->automation);
3790 Track *track = current->autos->track;
3791 //PluginAutos *pluginautos = (PluginAutos *)current->autos;
3793 // figure out the correct pluginset & correct plugin
3795 for(int i = 0; i < track->plugin_set.total; i++)
3797 PluginSet *pluginset = track->plugin_set.values[i];
3798 for(plugin = (Plugin *)pluginset->first; plugin; plugin = (Plugin *)plugin->next)
3800 KeyFrames *keyframes = plugin->keyframes;
3801 for(KeyFrame *currentkeyframe = (KeyFrame *)keyframes->first; currentkeyframe; currentkeyframe = (KeyFrame *) currentkeyframe->next)
3803 if (currentkeyframe == current)
3815 mwindow->session->plugin_highlighted = plugin;
3816 mwindow->session->track_highlighted = track;
3818 current->position = position;
3820 char string[BCTEXTLEN];
3821 Units::totext(string,
3822 current->autos->track->from_units(current->position),
3823 mwindow->edl->session->time_format,
3824 mwindow->edl->session->sample_rate,
3825 mwindow->edl->session->frame_rate,
3826 mwindow->edl->session->frames_per_foot);
3827 gui->show_message(string);
3829 double position_f = current->autos->track->from_units(current->position);
3830 double center_f = (mwindow->edl->local_session->get_selectionstart(1) +
3831 mwindow->edl->local_session->get_selectionend(1)) /
3835 mwindow->edl->local_session->set_selectionstart(position_f);
3836 mwindow->edl->local_session->set_selectionend(position_f);
3839 if(position_f < center_f)
3841 mwindow->edl->local_session->set_selectionstart(position_f);
3844 mwindow->edl->local_session->set_selectionend(position_f);
3851 void TrackCanvas::update_drag_caption()
3853 switch(mwindow->session->current_operation)
3862 int TrackCanvas::cursor_motion_event()
3867 int update_clock = 0;
3868 int update_zoom = 0;
3869 int update_scroll = 0;
3870 int update_overlay = 0;
3871 int update_cursor = 0;
3874 double position = 0.;
3875 //printf("TrackCanvas::cursor_motion_event %d\n", __LINE__);
3878 switch(mwindow->edl->session->editing_mode)
3880 case EDITING_ARROW: new_cursor = ARROW_CURSOR; break;
3881 case EDITING_IBEAM: new_cursor = IBEAM_CURSOR; break;
3884 switch(mwindow->session->current_operation)
3886 case DRAG_EDITHANDLE1:
3887 // Outside threshold. Upgrade status
3890 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3892 mwindow->session->current_operation = DRAG_EDITHANDLE2;
3898 case DRAG_EDITHANDLE2:
3901 update_drag_handle();
3906 case DRAG_PLUGINHANDLE1:
3909 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3911 mwindow->session->current_operation = DRAG_PLUGINHANDLE2;
3917 case DRAG_PLUGINHANDLE2:
3920 update_drag_handle();
3925 // Rubber band curves
3933 case DRAG_PROJECTOR_X:
3934 case DRAG_PROJECTOR_Y:
3935 case DRAG_PROJECTOR_Z:
3936 if(active) rerender =
3938 update_drag_floatauto(get_cursor_x(), get_cursor_y());
3942 if(active) rerender =
3944 update_drag_toggleauto(get_cursor_x(), get_cursor_y());
3948 if(active) rerender =
3950 update_drag_toggleauto(get_cursor_x(), get_cursor_y());
3953 // Keyframe icons are sticky
3957 case DRAG_PLUGINKEY_PRE:
3960 if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3962 mwindow->session->current_operation++;
3965 mwindow->undo->update_undo_before();
3973 if(active) rerender =
3975 update_drag_auto(get_cursor_x(), get_cursor_y());
3978 case DRAG_PLUGINKEY:
3979 if(active) rerender =
3981 update_drag_pluginauto(get_cursor_x(), get_cursor_y());
3987 cursor_x = get_cursor_x();
3988 cursor_y = get_cursor_y();
3989 position = (double)(cursor_x + mwindow->edl->local_session->view_start[pane->number]) *
3990 mwindow->edl->local_session->zoom_sample /
3991 mwindow->edl->session->sample_rate;
3993 position = mwindow->edl->align_to_frame(position, 0);
3994 position = MAX(position, 0);
3996 if(position < selection_midpoint)
3998 mwindow->edl->local_session->set_selectionend(selection_midpoint);
3999 mwindow->edl->local_session->set_selectionstart(position);
4001 gui->unlock_window();
4002 mwindow->cwindow->update(1, 0, 0, 0, 1);
4003 gui->lock_window("TrackCanvas::cursor_motion_event 1");
4004 // Update the faders
4005 mwindow->update_plugin_guis();
4006 gui->update_patchbay();
4010 mwindow->edl->local_session->set_selectionstart(selection_midpoint);
4011 mwindow->edl->local_session->set_selectionend(position);
4012 // Don't que the CWindow
4015 timebar_position = mwindow->edl->local_session->get_selectionend(1);
4017 gui->hide_cursor(0);
4018 gui->draw_cursor(1);
4019 gui->update_timebar(0);
4020 gui->flash_canvas(1);
4029 if(is_event_win() && cursor_inside())
4032 cursor_x = get_cursor_x();
4033 position = (double)cursor_x *
4034 (double)mwindow->edl->local_session->zoom_sample /
4035 (double)mwindow->edl->session->sample_rate +
4036 (double)mwindow->edl->local_session->view_start[pane->number] *
4037 (double)mwindow->edl->local_session->zoom_sample /
4038 (double)mwindow->edl->session->sample_rate;
4039 position = mwindow->edl->align_to_frame(position, 0);
4043 for(int i = 0; i < TOTAL_PANES; i++)
4044 if(gui->pane[i]) gui->pane[i]->canvas->timebar_position = position;
4046 //printf("TrackCanvas::cursor_motion_event %d %d %p %p\n", __LINE__, pane->number, pane, pane->timebar);
4047 gui->update_timebar(0);
4050 if(do_transitions(get_cursor_x(),
4060 if(do_keyframes(get_cursor_x(),
4072 if(do_edit_handles(get_cursor_x(),
4081 // Plugin boundaries
4082 if(do_plugin_handles(get_cursor_x(),
4091 if(do_edits(get_cursor_x(),
4106 //printf("TrackCanvas::cursor_motion_event 1\n");
4107 if(update_cursor && new_cursor != get_cursor())
4109 set_cursor(new_cursor, 0, 1);
4112 //printf("TrackCanvas::cursor_motion_event 1 %d\n", rerender);
4115 mwindow->restart_brender();
4116 mwindow->sync_parameters(CHANGE_PARAMS);
4117 mwindow->update_plugin_guis();
4118 gui->unlock_window();
4119 mwindow->cwindow->update(1, 0, 0, 0, 1);
4120 gui->lock_window("TrackCanvas::cursor_motion_event 2");
4122 gui->update_patchbay();
4128 if(!mwindow->cwindow->playback_engine->is_playing_back)
4129 gui->mainclock->update(position);
4134 gui->zoombar->update();
4140 (cursor_x >= get_w() || cursor_x < 0 || cursor_y >= get_h() || cursor_y < 0))
4144 (cursor_x < get_w() && cursor_x >= 0 && cursor_y < get_h() && cursor_y >= 0))
4150 gui->draw_overlays(1);
4154 //printf("TrackCanvas::cursor_motion_event %d\n", __LINE__);
4158 void TrackCanvas::start_dragscroll()
4163 set_repeat(BC_WindowBase::get_resources()->scroll_repeat);
4164 //printf("TrackCanvas::start_dragscroll 1\n");
4168 void TrackCanvas::stop_dragscroll()
4173 unset_repeat(BC_WindowBase::get_resources()->scroll_repeat);
4174 //printf("TrackCanvas::stop_dragscroll 1\n");
4178 int TrackCanvas::repeat_event(int64_t duration)
4180 if(!drag_scroll) return 0;
4181 if(duration != BC_WindowBase::get_resources()->scroll_repeat) return 0;
4183 int sample_movement = 0;
4184 int track_movement = 0;
4185 int64_t x_distance = 0;
4186 int64_t y_distance = 0;
4187 double position = 0;
4190 switch(mwindow->session->current_operation)
4193 //printf("TrackCanvas::repeat_event 1 %d\n", mwindow->edl->local_session->view_start);
4194 if(get_cursor_x() > get_w())
4196 x_distance = get_cursor_x() - get_w();
4197 sample_movement = 1;
4200 if(get_cursor_x() < 0)
4202 x_distance = get_cursor_x();
4203 sample_movement = 1;
4206 if(get_cursor_y() > get_h())
4208 y_distance = get_cursor_y() - get_h();
4212 if(get_cursor_y() < 0)
4214 y_distance = get_cursor_y();
4224 position = (double)(get_cursor_x() +
4225 mwindow->edl->local_session->view_start[pane->number] +
4227 mwindow->edl->local_session->zoom_sample /
4228 mwindow->edl->session->sample_rate;
4229 position = mwindow->edl->align_to_frame(position, 0);
4230 position = MAX(position, 0);
4232 //printf("TrackCanvas::repeat_event 1 %f\n", position);
4233 switch(mwindow->session->current_operation)
4236 if(position < selection_midpoint)
4238 mwindow->edl->local_session->set_selectionend(selection_midpoint);
4239 mwindow->edl->local_session->set_selectionstart(position);
4241 gui->unlock_window();
4242 mwindow->cwindow->update(1, 0, 0);
4243 gui->lock_window("TrackCanvas::repeat_event");
4244 // Update the faders
4245 mwindow->update_plugin_guis();
4246 gui->update_patchbay();
4250 mwindow->edl->local_session->set_selectionstart(selection_midpoint);
4251 mwindow->edl->local_session->set_selectionend(position);
4252 // Don't que the CWindow
4257 mwindow->samplemovement(
4258 mwindow->edl->local_session->view_start[pane->number] + x_distance,
4265 mwindow->trackmovement(y_distance, pane->number);
4271 int TrackCanvas::button_release_event()
4273 int redraw = 0, update_overlay = 0, result = 0;
4275 // printf("TrackCanvas::button_release_event %d\n",
4276 // mwindow->session->current_operation);
4279 switch(mwindow->session->current_operation)
4281 case DRAG_EDITHANDLE2:
4282 mwindow->session->current_operation = NO_OPERATION;
4286 end_edithandle_selection();
4289 case DRAG_EDITHANDLE1:
4290 mwindow->session->current_operation = NO_OPERATION;
4295 case DRAG_PLUGINHANDLE2:
4296 mwindow->session->current_operation = NO_OPERATION;
4300 end_pluginhandle_selection();
4303 case DRAG_PLUGINHANDLE1:
4304 mwindow->session->current_operation = NO_OPERATION;
4311 // delete the drag_auto_gang first and remove out of order keys
4312 synchronize_autos(0, 0, 0, -1);
4323 case DRAG_PROJECTOR_X:
4324 case DRAG_PROJECTOR_Y:
4325 case DRAG_PROJECTOR_Z:
4326 case DRAG_PLUGINKEY:
4327 mwindow->session->current_operation = NO_OPERATION;
4328 mwindow->session->drag_handle = 0;
4329 // Remove any out-of-order keyframe
4330 if(mwindow->session->drag_auto)
4332 mwindow->session->drag_auto->autos->remove_nonsequential(
4333 mwindow->session->drag_auto);
4334 // mwindow->session->drag_auto->autos->optimize();
4339 mwindow->undo->update_undo_after(_("keyframe"), LOAD_AUTOMATION);
4344 case DRAG_AEFFECT_COPY:
4345 case DRAG_VEFFECT_COPY:
4346 // Trap in drag stop
4352 if(mwindow->session->current_operation)
4354 // if(mwindow->session->current_operation == SELECT_REGION)
4356 // mwindow->undo->update_undo_after(_("select"), LOAD_SESSION, 0, 0);
4359 mwindow->session->current_operation = NO_OPERATION;
4361 // Traps button release events
4369 cursor_motion_event();
4373 gui->draw_overlays(1);
4377 gui->draw_canvas(NORMAL_DRAW, 0);
4382 int TrackCanvas::do_edit_handles(int cursor_x,
4388 Edit *edit_result = 0;
4389 int handle_result = 0;
4392 if(!mwindow->edl->session->show_assets) return 0;
4394 for(Track *track = mwindow->edl->tracks->first;
4396 track = track->next)
4398 for(Edit *edit = track->edits->first;
4402 int64_t edit_x, edit_y, edit_w, edit_h;
4403 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
4405 if(cursor_x >= edit_x && cursor_x <= edit_x + edit_w &&
4406 cursor_y >= edit_y && cursor_y < edit_y + edit_h)
4408 if(cursor_x < edit_x + HANDLE_W)
4415 if(cursor_x >= edit_x + edit_w - HANDLE_W)
4432 double position = 0;
4433 if(handle_result == 0)
4435 position = edit_result->track->from_units(edit_result->startproject);
4436 new_cursor = LEFT_CURSOR;
4439 if(handle_result == 1)
4441 position = edit_result->track->from_units(edit_result->startproject + edit_result->length);
4442 new_cursor = RIGHT_CURSOR;
4445 // Reposition cursor
4448 mwindow->session->drag_edit = edit_result;
4449 mwindow->session->drag_handle = handle_result;
4450 mwindow->session->drag_button = get_buttonpress() - 1;
4451 mwindow->session->drag_position = position;
4452 mwindow->session->current_operation = DRAG_EDITHANDLE1;
4453 mwindow->session->drag_origin_x = get_cursor_x();
4454 mwindow->session->drag_origin_y = get_cursor_y();
4455 mwindow->session->drag_start = position;
4457 int rerender = start_selection(position);
4460 gui->unlock_window();
4461 mwindow->cwindow->update(1, 0, 0);
4462 gui->lock_window("TrackCanvas::do_edit_handles");
4464 gui->update_timebar(0);
4465 gui->zoombar->update();
4466 gui->hide_cursor(0);
4467 gui->draw_cursor(1);
4476 int TrackCanvas::do_plugin_handles(int cursor_x,
4482 Plugin *plugin_result = 0;
4483 int handle_result = 0;
4486 // if(!mwindow->edl->session->show_assets) return 0;
4488 for(Track *track = mwindow->edl->tracks->first;
4490 track = track->next)
4492 for(int i = 0; i < track->plugin_set.total && !result; i++)
4494 PluginSet *plugin_set = track->plugin_set.values[i];
4495 for(Plugin *plugin = (Plugin*)plugin_set->first;
4497 plugin = (Plugin*)plugin->next)
4499 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
4500 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
4502 if(cursor_x >= plugin_x && cursor_x <= plugin_x + plugin_w &&
4503 cursor_y >= plugin_y && cursor_y < plugin_y + plugin_h)
4505 if(cursor_x < plugin_x + HANDLE_W)
4507 plugin_result = plugin;
4512 if(cursor_x >= plugin_x + plugin_w - HANDLE_W)
4514 plugin_result = plugin;
4521 if(result && shift_down())
4522 mwindow->session->trim_edits = plugin_set;
4529 double position = 0;
4530 if(handle_result == 0)
4532 position = plugin_result->track->from_units(plugin_result->startproject);
4533 new_cursor = LEFT_CURSOR;
4536 if(handle_result == 1)
4538 position = plugin_result->track->from_units(plugin_result->startproject + plugin_result->length);
4539 new_cursor = RIGHT_CURSOR;
4544 mwindow->session->drag_plugin = plugin_result;
4545 mwindow->session->drag_handle = handle_result;
4546 mwindow->session->drag_button = get_buttonpress() - 1;
4547 mwindow->session->drag_position = position;
4548 mwindow->session->current_operation = DRAG_PLUGINHANDLE1;
4549 mwindow->session->drag_origin_x = get_cursor_x();
4550 mwindow->session->drag_origin_y = get_cursor_y();
4551 mwindow->session->drag_start = position;
4553 int rerender = start_selection(position);
4556 gui->unlock_window();
4557 mwindow->cwindow->update(1, 0, 0);
4558 gui->lock_window("TrackCanvas::do_plugin_handles");
4560 gui->update_timebar(0);
4561 gui->zoombar->update();
4562 gui->hide_cursor(0);
4563 gui->draw_cursor(1);
4564 gui->draw_overlays(0);
4565 gui->flash_canvas(1);
4573 int TrackCanvas::do_tracks(int cursor_x,
4580 // if(!mwindow->edl->session->show_assets) return 0;
4583 for(Track *track = mwindow->edl->tracks->first;
4585 track = track->next)
4587 int64_t track_x, track_y, track_w, track_h;
4588 track_dimensions(track, track_x, track_y, track_w, track_h);
4591 get_buttonpress() == 3 &&
4592 cursor_y >= track_y &&
4593 cursor_y < track_y + track_h)
4595 gui->edit_menu->update(track, 0);
4596 gui->edit_menu->activate_menu();
4604 int TrackCanvas::do_edits(int cursor_x,
4615 if(!mwindow->edl->session->show_assets) return 0;
4617 for(Track *track = mwindow->edl->tracks->first;
4619 track = track->next)
4621 for(Edit *edit = track->edits->first;
4625 int64_t edit_x, edit_y, edit_w, edit_h;
4626 edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
4628 // Cursor inside a track
4629 // Cursor inside an edit
4630 if(cursor_x >= edit_x && cursor_x < edit_x + edit_w &&
4631 cursor_y >= edit_y && cursor_y < edit_y + edit_h)
4633 // Select duration of edit
4636 if(get_double_click() && !drag_start)
4638 mwindow->edl->local_session->set_selectionstart(edit->track->from_units(edit->startproject));
4639 mwindow->edl->local_session->set_selectionend(edit->track->from_units(edit->startproject) +
4640 edit->track->from_units(edit->length));
4641 if(mwindow->edl->session->cursor_on_frames)
4643 mwindow->edl->local_session->set_selectionstart(
4644 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionstart(1), 0));
4645 mwindow->edl->local_session->set_selectionend(
4646 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionend(1), 1));
4655 if(drag_start && track->record)
4657 if(mwindow->edl->session->editing_mode == EDITING_ARROW)
4659 // Need to create drag window
4660 mwindow->session->current_operation = DRAG_EDIT;
4661 mwindow->session->drag_edit = edit;
4662 //printf("TrackCanvas::do_edits 2\n");
4664 // Drag only one edit if ctrl is initially down
4667 mwindow->session->drag_edits->remove_all();
4668 mwindow->session->drag_edits->append(edit);
4671 // Construct list of all affected edits
4673 mwindow->edl->tracks->get_affected_edits(
4674 mwindow->session->drag_edits,
4675 edit->track->from_units(edit->startproject),
4678 mwindow->session->drag_origin_x = cursor_x;
4679 mwindow->session->drag_origin_y = cursor_y;
4681 gui->drag_popup = new BC_DragWindow(gui,
4682 mwindow->theme->get_image("clip_icon") /*,
4683 get_abs_cursor_x(0) - mwindow->theme->get_image("clip_icon")->get_w() / 2,
4684 get_abs_cursor_y(0) - mwindow->theme->get_image("clip_icon")->get_h() / 2 */);
4696 int TrackCanvas::test_resources(int cursor_x, int cursor_y)
4701 int TrackCanvas::do_plugins(int cursor_x,
4715 // if(!mwindow->edl->session->show_assets) return 0;
4718 for(track = mwindow->edl->tracks->first;
4720 track = track->next)
4722 if(!track->expand_view) continue;
4725 for(int i = 0; i < track->plugin_set.total && !done; i++)
4727 PluginSet *plugin_set = track->plugin_set.values[i];
4728 for(plugin = (Plugin*)plugin_set->first;
4730 plugin = (Plugin*)plugin->next)
4732 plugin_dimensions(plugin, x, y, w, h);
4733 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
4734 MWindowGUI::visible(y, y + h, 0, get_h()))
4736 if(cursor_x >= x && cursor_x < x + w &&
4737 cursor_y >= y && cursor_y < y + h)
4749 // Start plugin popup
4752 if(get_buttonpress() == 3)
4754 gui->plugin_menu->update(plugin);
4755 gui->plugin_menu->activate_menu();
4759 // Select range of plugin on doubleclick over plugin
4760 if (get_double_click() && !drag_start)
4762 mwindow->edl->local_session->set_selectionstart(plugin->track->from_units(plugin->startproject));
4763 mwindow->edl->local_session->set_selectionend(plugin->track->from_units(plugin->startproject) +
4764 plugin->track->from_units(plugin->length));
4765 if(mwindow->edl->session->cursor_on_frames)
4767 mwindow->edl->local_session->set_selectionstart(
4768 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionstart(1), 0));
4769 mwindow->edl->local_session->set_selectionend(
4770 mwindow->edl->align_to_frame(mwindow->edl->local_session->get_selectionend(1), 1));
4779 if(drag_start && plugin->track->record)
4781 if(mwindow->edl->session->editing_mode == EDITING_ARROW)
4783 if(plugin->track->data_type == TRACK_AUDIO)
4784 mwindow->session->current_operation = DRAG_AEFFECT_COPY;
4786 if(plugin->track->data_type == TRACK_VIDEO)
4787 mwindow->session->current_operation = DRAG_VEFFECT_COPY;
4789 mwindow->session->drag_plugin = plugin;
4796 switch(plugin->plugin_type)
4798 case PLUGIN_STANDALONE:
4800 PluginServer *server = mwindow->scan_plugindb(
4802 plugin->track->data_type);
4803 VFrame *frame = server->picon;
4807 if(plugin->track->data_type == TRACK_AUDIO)
4809 frame = mwindow->theme->get_image("aeffect_icon");
4813 frame = mwindow->theme->get_image("veffect_icon");
4817 gui->drag_popup = new BC_DragWindow(gui,
4819 get_abs_cursor_x(0) - frame->get_w() / 2,
4820 get_abs_cursor_y(0) - frame->get_h() / 2 */);
4824 case PLUGIN_SHAREDPLUGIN:
4825 case PLUGIN_SHAREDMODULE:
4826 gui->drag_popup = new BC_DragWindow(gui,
4827 mwindow->theme->get_image("clip_icon") /*,
4828 get_abs_cursor_x(0) - mwindow->theme->get_image("clip_icon")->get_w() / 2,
4829 get_abs_cursor_y(0) - mwindow->theme->get_image("clip_icon")->get_h() / 2 */);
4842 int TrackCanvas::do_transitions(int cursor_x,
4848 Transition *transition = 0;
4854 if(/* !mwindow->edl->session->show_assets || */
4855 !mwindow->edl->session->auto_conf->transitions) return 0;
4859 for(Track *track = mwindow->edl->tracks->first;
4861 track = track->next)
4863 for(Edit *edit = track->edits->first;
4867 if(edit->transition)
4869 edit_dimensions(edit, x, y, w, h);
4870 get_transition_coords(x, y, w, h);
4872 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
4873 MWindowGUI::visible(y, y + h, 0, get_h()))
4875 if(cursor_x >= x && cursor_x < x + w &&
4876 cursor_y >= y && cursor_y < y + h)
4878 transition = edit->transition;
4892 new_cursor = UPRIGHT_ARROW_CURSOR;
4895 if(get_buttonpress() == 3)
4897 gui->transition_menu->update(transition);
4898 gui->transition_menu->activate_menu();
4905 int TrackCanvas::button_press_event()
4908 int cursor_x, cursor_y;
4911 cursor_x = get_cursor_x();
4912 cursor_y = get_cursor_y();
4913 mwindow->session->trim_edits = 0;
4915 if(is_event_win() && cursor_inside())
4922 if(get_buttonpress() == LEFT_BUTTON)
4924 gui->unlock_window();
4925 gui->mbuttons->transport->handle_transport(STOP, 1, 0, 0);
4926 gui->lock_window("TrackCanvas::button_press_event");
4929 int update_overlay = 0, update_cursor = 0, rerender = 0;
4931 if(get_buttonpress() == WHEEL_UP)
4934 mwindow->expand_sample();
4936 mwindow->move_up(get_h() / 10);
4940 if(get_buttonpress() == WHEEL_DOWN)
4943 mwindow->zoom_in_sample();
4945 mwindow->move_down(get_h() / 10);
4949 switch(mwindow->edl->session->editing_mode)
4951 // Test handles and resource boundaries and highlight a track
4954 if(mwindow->edl->session->auto_conf->transitions &&
4955 do_transitions(cursor_x, cursor_y,
4956 1, new_cursor, update_cursor))
4961 if(do_keyframes(cursor_x, cursor_y,
4962 0, get_buttonpress(), new_cursor,
4963 update_cursor, rerender))
4968 // Test edit boundaries
4969 if(do_edit_handles(cursor_x, cursor_y,
4970 1, new_cursor, update_cursor))
4975 // Test plugin boundaries
4976 if(do_plugin_handles(cursor_x, cursor_y,
4977 1, new_cursor, update_cursor))
4982 if(do_edits(cursor_x, cursor_y, 1, 0,
4983 update_cursor, rerender, new_cursor, update_cursor))
4988 if(do_plugins(cursor_x, cursor_y, 0, 1,
4989 update_cursor, rerender))
4994 if(test_resources(cursor_x, cursor_y))
4999 if(do_tracks(cursor_x, cursor_y, 1))
5006 // Test handles only and select a region
5009 double position = (double)cursor_x *
5010 mwindow->edl->local_session->zoom_sample /
5011 mwindow->edl->session->sample_rate +
5012 (double)mwindow->edl->local_session->view_start[pane->number] *
5013 mwindow->edl->local_session->zoom_sample /
5014 mwindow->edl->session->sample_rate;
5015 //printf("TrackCanvas::button_press_event %d\n", position);
5017 if(mwindow->edl->session->auto_conf->transitions &&
5018 do_transitions(cursor_x, cursor_y,
5019 1, new_cursor, update_cursor))
5024 if(do_keyframes(cursor_x, cursor_y,
5025 0, get_buttonpress(), new_cursor,
5026 update_cursor, rerender))
5032 // Test edit boundaries
5033 if(do_edit_handles(cursor_x, cursor_y,
5034 1, new_cursor, update_cursor))
5039 // Test plugin boundaries
5040 if(do_plugin_handles(cursor_x, cursor_y,
5041 1, new_cursor, update_cursor))
5046 if(do_edits(cursor_x, cursor_y,
5047 1, 0, update_cursor,
5048 rerender, new_cursor, update_cursor))
5053 if(do_plugins(cursor_x, cursor_y,
5054 0, 1, update_cursor, rerender))
5059 if(do_tracks(cursor_x, cursor_y, 1))
5063 // Highlight selection
5066 rerender = start_selection(position);
5067 mwindow->session->current_operation = SELECT_REGION;
5078 gui->unlock_window();
5079 mwindow->cwindow->update(1, 0, 0, 0, 1);
5081 gui->lock_window("TrackCanvas::button_press_event 2");
5083 mwindow->update_plugin_guis();
5084 gui->update_patchbay();
5089 gui->draw_overlays(1);
5092 if(update_cursor > 0)
5094 gui->update_timebar(0);
5095 gui->hide_cursor(0);
5096 gui->show_cursor(1);
5097 gui->zoombar->update();
5098 gui->flash_canvas(1);
5101 else if(update_cursor < 0)
5102 gui->swindow->update_selection();
5110 int TrackCanvas::start_selection(double position)
5113 position = mwindow->edl->align_to_frame(position, 0);
5119 double midpoint = (mwindow->edl->local_session->get_selectionstart(1) +
5120 mwindow->edl->local_session->get_selectionend(1)) / 2;
5122 if(position < midpoint)
5124 mwindow->edl->local_session->set_selectionstart(position);
5125 selection_midpoint = mwindow->edl->local_session->get_selectionend(1);
5131 mwindow->edl->local_session->set_selectionend(position);
5132 selection_midpoint = mwindow->edl->local_session->get_selectionstart(1);
5133 // Don't que the CWindow for the end
5137 // Start a new selection
5139 //printf("TrackCanvas::start_selection %f\n", position);
5140 mwindow->edl->local_session->set_selectionstart(position);
5141 mwindow->edl->local_session->set_selectionend(position);
5142 selection_midpoint = position;
5150 void TrackCanvas::end_edithandle_selection()
5152 mwindow->modify_edithandles();
5155 void TrackCanvas::end_pluginhandle_selection()
5157 mwindow->modify_pluginhandles();
5161 double TrackCanvas::time_visible()
5163 return (double)get_w() *
5164 mwindow->edl->local_session->zoom_sample /
5165 mwindow->edl->session->sample_rate;
5168 // Patchbay* TrackCanvas::get_patchbay()
5170 // if(pane->patchbay) return pane->patchbay;
5171 // if(gui->total_panes() == 2 &&
5172 // gui->pane[TOP_LEFT_PANE] &&
5173 // gui->pane[TOP_RIGHT_PANE])
5174 // return gui->pane[TOP_LEFT_PANE]->patchbay;
5175 // if(gui->total_panes() == 4)
5177 // if(pane->number == TOP_RIGHT_PANE)
5178 // return gui->pane[TOP_LEFT_PANE]->patchbay;
5180 // return gui->pane[BOTTOM_LEFT_PANE]->patchbay;