r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / trackcanvas.C
blob9edf1f8daba9b6fc9a67618c2838db29a5974a9a
1 #include "assets.h"
2 #include "autoconf.h"
3 #include "automation.h"
4 #include "bcsignals.h"
5 #include "bezierauto.h"
6 #include "bezierautos.h"
7 #include "clip.h"
8 #include "colors.h"
9 #include "cplayback.h"
10 #include "cursors.h"
11 #include "cwindow.h"
12 #include "cwindowgui.h"
13 #include "edithandles.h"
14 #include "editpopup.h"
15 #include "edits.h"
16 #include "edl.h"
17 #include "edlsession.h"
18 #include "floatauto.h"
19 #include "floatautos.h"
20 #include "intauto.h"
21 #include "keyframe.h"
22 #include "keyframes.h"
23 #include "keys.h"
24 #include "localsession.h"
25 #include "mainclock.h"
26 #include "mainundo.h"
27 #include "maskautos.h"
28 #include "mbuttons.h"
29 #include "mtimebar.h"
30 #include "mwindow.h"
31 #include "mwindowgui.h"
32 #include "patchbay.h"
33 #include "tracking.h"
34 #include "panautos.h"
35 #include "playbackengine.h"
36 #include "playtransport.h"
37 #include "plugin.h"
38 #include "pluginpopup.h"
39 #include "pluginset.h"
40 #include "pluginserver.h"
41 #include "preferences.h"
42 #include "resourcepixmap.h"
43 #include "mainsession.h"
44 #include "transitionhandles.h"
45 #include "transitionpopup.h"
46 #include "transportque.h"
47 #include "zoombar.h"
48 #include "theme.h"
49 #include "intautos.h"
50 #include "trackcanvas.h"
51 #include "tracks.h"
52 #include "transition.h"
53 #include "vframe.h"
55 #include <string.h>
57 TrackCanvas::TrackCanvas(MWindow *mwindow, MWindowGUI *gui)
58  : BC_SubWindow(mwindow->theme->mcanvas_x,
59         mwindow->theme->mcanvas_y,
60         gui->view_w,
61         gui->view_h)
63         this->mwindow = mwindow;
64         this->gui = gui;
65         current_end = 0;
66         selection_midpoint1 = selection_midpoint2 = 0;
67         selection_type = 0;
68         region_selected = 0;
69         handle_selected = 0;
70         auto_selected = 0;
71         translate_selected = 0;
72         which_handle = 0;
73         handle_pixel = 0;
74         drag_scroll = 0;
75         drag_pixmap = 0;
76         drag_popup = 0;
77         active = 0;
80 TrackCanvas::~TrackCanvas()
82         for(int i = 0; i < resource_pixmaps.total; i++)
83                 delete resource_pixmaps.values[i];
84 //      delete transition_handles;
85         delete edit_handles;
86         delete keyframe_pixmap;
87         delete camerakeyframe_pixmap;
88         delete modekeyframe_pixmap;
89         delete pankeyframe_pixmap;
90         delete projectorkeyframe_pixmap;
91         delete maskkeyframe_pixmap;
92         delete background_pixmap;
95 int TrackCanvas::create_objects()
97         background_pixmap = new BC_Pixmap(this, get_w(), get_h());
98 //      transition_handles = new TransitionHandles(mwindow, this);
99         edit_handles = new EditHandles(mwindow, this);
100         keyframe_pixmap = new BC_Pixmap(this, mwindow->theme->keyframe_data, PIXMAP_ALPHA);
101         camerakeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->camerakeyframe_data, PIXMAP_ALPHA);
102         modekeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->modekeyframe_data, PIXMAP_ALPHA);
103         pankeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->pankeyframe_data, PIXMAP_ALPHA);
104         projectorkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->projectorkeyframe_data, PIXMAP_ALPHA);
105         maskkeyframe_pixmap = new BC_Pixmap(this, mwindow->theme->maskkeyframe_data, PIXMAP_ALPHA);
106         draw();
107         update_cursor();
108         flash();
109         return 0;
112 void TrackCanvas::resize_event()
114 //printf("TrackCanvas::resize_event 1\n");
115         draw(0, 0);
116         flash();
117 //printf("TrackCanvas::resize_event 2\n");
120 int TrackCanvas::keypress_event()
122         int result = 0;
124         switch(get_keypress())
125         {
126                 case LEFT:
127                         if(!ctrl_down()) 
128                         { 
129                                 mwindow->move_left(); 
130                                 result = 1; 
131                         }
132                         break;
133                 case RIGHT:
134                         if(!ctrl_down()) 
135                         { 
136                                 mwindow->move_right(); 
137                                 result = 1; 
138                         }
139                         break;
141                 case UP:
142                         if(!ctrl_down())
143                         {
144                                 mwindow->expand_sample();
145                                 result = 1;
146                         }
147                         else
148                         {
149                                 mwindow->expand_y();
150                                 result = 1;
151                         }
152                         break;
154                 case DOWN:
155                         if(!ctrl_down())
156                         {
157                                 mwindow->zoom_in_sample();
158                                 result = 1;
159                         }
160                         else
161                         {
162                                 mwindow->zoom_in_y();
163                                 result = 1;
164                         }
165                         break;
167                 case PGUP:
168                         if(!ctrl_down())
169                         {
170                                 mwindow->move_up();
171                                 result = 1;
172                         }
173                         else
174                         {
175                                 mwindow->expand_t();
176                                 result = 1;
177                         }
178                         break;
180                 case PGDN:
181                         if(!ctrl_down())
182                         {
183                                 mwindow->move_down();
184                                 result = 1;
185                         }
186                         else
187                         {
188                                 mwindow->zoom_in_t();
189                                 result = 1;
190                         }
191                         break;
192         }
194         return result;
197 int TrackCanvas::drag_motion()
200         int cursor_x = get_relative_cursor_x();
201         int cursor_y = get_relative_cursor_y();
202         Track *over_track = 0;
203         Edit *over_edit = 0;
204         PluginSet *over_pluginset = 0;
205         Plugin *over_plugin = 0;
206         int redraw = 0;
209         if(drag_popup)
210         {
211                 drag_popup->cursor_motion_event();
212         }
217         if(get_cursor_over_window() &&
218                 cursor_x >= 0 && 
219                 cursor_y >= 0 && 
220                 cursor_x < get_w() && 
221                 cursor_y < get_h())
222         {
223 // Find the edit and track the cursor is over
224                 for(Track *track = mwindow->edl->tracks->first; track; track = track->next)
225                 {
226                         int64_t track_x, track_y, track_w, track_h;
227                         track_dimensions(track, track_x, track_y, track_w, track_h);
229                         if(cursor_y >= track_y && 
230                                 cursor_y < track_y + track_h)
231                         {
232                                 over_track = track;
233                                 for(Edit *edit = track->edits->first; edit; edit = edit->next)
234                                 {
235                                         int64_t edit_x, edit_y, edit_w, edit_h;
236                                         edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
238                                         if(cursor_x >= edit_x && 
239                                                 cursor_y >= edit_y && 
240                                                 cursor_x < edit_x + edit_w && 
241                                                 cursor_y < edit_y + edit_h)
242                                         {
243                                                 over_edit = edit;
244                                                 break;
245                                         }
246                                 }
248                                 for(int i = 0; i < track->plugin_set.total; i++)
249                                 {
250                                         PluginSet *pluginset = track->plugin_set.values[i];
251                                         
254                                         for(Plugin *plugin = (Plugin*)pluginset->first;
255                                                 plugin;
256                                                 plugin = (Plugin*)plugin->next)
257                                         {
258                                                 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
259                                                 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
260                                                 
261                                                 if(cursor_y >= plugin_y &&
262                                                         cursor_y < plugin_y + plugin_h)
263                                                 {
264                                                         over_pluginset = plugin->plugin_set;
265                                                 
266                                                         if(cursor_x >= plugin_x &&
267                                                                 cursor_x < plugin_x + plugin_w)
268                                                         {
269                                                                 over_plugin = plugin;
270                                                                 break;
271                                                         }
272                                                 }
273                                         }
274                                 }
275                                 break;
276                         }
277                 }
278         }
280         if(mwindow->session->track_highlighted != over_track) 
281         {
282                 mwindow->session->track_highlighted = over_track;
283                 redraw = 1;
284         }
286         if(mwindow->session->edit_highlighted != over_edit)
287         {
288                 mwindow->session->edit_highlighted = over_edit;
289                 redraw = 1;
290         }
292         if(mwindow->session->pluginset_highlighted != over_pluginset)
293         {
294                 mwindow->session->pluginset_highlighted = over_pluginset;
295                 redraw = 1;
296         }
298         if(mwindow->session->plugin_highlighted != over_plugin)
299         {
300                 mwindow->session->plugin_highlighted = over_plugin;
301                 redraw = 1;
302         }
304 //printf("TrackCanvas::drag_motion 2 %p\n", mwindow->session->track_highlighted);
305         if(redraw)
306         {
307                 lock_window();
308                 draw_overlays();
309                 flash();
310                 unlock_window();
311         }
313         return 0;
316 int TrackCanvas::drag_start_event()
318         int result = 0;
319         int redraw = 0;
320         int rerender = 0;
321         int new_cursor, update_cursor;
323         if(mwindow->session->current_operation != NO_OPERATION) return 0;
325         if(is_event_win())
326         {
327                 if(test_plugins(get_drag_x(), 
328                         get_drag_y(), 
329                         1,
330                         0))
331                 {
332                         result = 1;
333                 }
334                 else
335                 if(test_edits(get_drag_x(),
336                         get_drag_y(),
337                         0,
338                         1,
339                         redraw,
340                         rerender,
341                         new_cursor,
342                         update_cursor))
343                 {
344                         result = 1;
345                 }
346         }
348         return result;
351 int TrackCanvas::drag_motion_event()
353         return drag_motion();
356 int TrackCanvas::drag_stop_event()
358         int result = drag_stop();
360         if(drag_popup)
361         {
362 //printf("TrackCanvas::drag_stop_event 1 %p\n", drag_popup);
363                 delete drag_popup;
364                 delete drag_pixmap;
365                 drag_popup = 0;
366                 drag_pixmap = 0;
367         }
368         return result;
372 int TrackCanvas::drag_stop()
374 // In most cases the editing routine redraws and not the drag_stop
375         int result = 0, redraw = 0;
377         switch(mwindow->session->current_operation)
378         {
379                 case DRAG_VTRANSITION:
380                 case DRAG_ATRANSITION:
381                         if(mwindow->session->edit_highlighted)
382                         {
383                                 if((mwindow->session->current_operation == DRAG_ATRANSITION &&
384                                         mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
385                                         (mwindow->session->current_operation == DRAG_VTRANSITION &&
386                                         mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
387                                 {
388                                         mwindow->session->current_operation = NO_OPERATION;
389                                         mwindow->paste_transition();
390                                         result = 1;
391                                 }
392                         }
393                         redraw = 1;
394                         break;
399 // Behavior for dragged plugins is limited by the fact that a shared plugin
400 // can only refer to a standalone plugin that exists in the same position in
401 // time.  Dragging a plugin from one point in time to another can't produce
402 // a shared plugin to the original plugin.  In this case we relocate the
403 // plugin instead of sharing it.
404                 case DRAG_AEFFECT_COPY:
405                 case DRAG_VEFFECT_COPY:
406                         if(mwindow->session->track_highlighted &&
407                                 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY &&
408                                         mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
409                                         (mwindow->session->current_operation == DRAG_VEFFECT_COPY &&
410                                         mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
411                         {
412                                 mwindow->session->current_operation = NO_OPERATION;
414 // Insert shared plugin in source
415                                 if(mwindow->session->track_highlighted != mwindow->session->drag_plugin->track &&
416                                         !mwindow->session->plugin_highlighted &&
417                                         !mwindow->session->pluginset_highlighted)
418                                 {
419 // Move plugin if different startproject
420                                         mwindow->move_effect(mwindow->session->drag_plugin,
421                                                 0,
422                                                 mwindow->session->track_highlighted,
423                                                 0);
424                                         result = 1;
425                                 }
426                                 else
427 // Move source to different location
428                                 if(mwindow->session->pluginset_highlighted)
429                                 {
430 //printf("TrackCanvas::drag_stop 6\n");
431                                         if(mwindow->session->plugin_highlighted)
432                                         {
433                                                 mwindow->move_effect(mwindow->session->drag_plugin,
434                                                         mwindow->session->plugin_highlighted->plugin_set,
435                                                         0,
436                                                         mwindow->session->plugin_highlighted->startproject);
437                                                 result = 1;
438                                         }
439                                         else
440                                         {
441                                                 mwindow->move_effect(mwindow->session->drag_plugin,
442                                                         mwindow->session->pluginset_highlighted,
443                                                         0,
444                                                         mwindow->session->pluginset_highlighted->length());
445                                                 result = 1;
446                                         }
447                                 }
448                                 else
449 // Move to a new plugin set between two edits
450                                 if(mwindow->session->edit_highlighted)
451                                 {
452                                         mwindow->move_effect(mwindow->session->drag_plugin,
453                                                 0,
454                                                 mwindow->session->track_highlighted,
455                                                 mwindow->session->edit_highlighted->startproject);
456                                         result = 1;
457                                 }
458                                 else
459 // Move to a new plugin set
460                                 if(mwindow->session->track_highlighted)
461                                 {
462                                         mwindow->move_effect(mwindow->session->drag_plugin,
463                                                 0,
464                                                 mwindow->session->track_highlighted,
465                                                 0);
466                                         result = 1;
467                                 }
468                         }
469                         break;
471                 case DRAG_AEFFECT:
472                 case DRAG_VEFFECT:
473                         if(mwindow->session->track_highlighted && 
474                                 ((mwindow->session->current_operation == DRAG_AEFFECT &&
475                                 mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
476                                 (mwindow->session->current_operation == DRAG_VEFFECT &&
477                                 mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
478                         {
479 // Drop all the effects
480                                 PluginSet *plugin_set = mwindow->session->pluginset_highlighted;
481                                 Track *track = mwindow->session->track_highlighted;
482                                 double start = 0;
483                                 double length = track->get_length();
485                                 if(mwindow->session->plugin_highlighted)
486                                 {
487                                         start = track->from_units(mwindow->session->plugin_highlighted->startproject);
488                                         length = track->from_units(mwindow->session->plugin_highlighted->length);
489                                         if(length <= 0) length = track->get_length();
490                                 }
491                                 else
492                                 if(mwindow->session->pluginset_highlighted)
493                                 {
494                                         start = track->from_units(plugin_set->length());
495                                         length = track->get_length() - start;
496                                         if(length <= 0) length = track->get_length();
497                                 }
498                                 else
499                                 if(mwindow->edl->local_session->get_selectionend() > 
500                                         mwindow->edl->local_session->get_selectionstart())
501                                 {
502                                         start = mwindow->edl->local_session->get_selectionstart();
503                                         length = mwindow->edl->local_session->get_selectionend() - 
504                                                 mwindow->edl->local_session->get_selectionstart();
505                                 }
506 // Move to a point between two edits
507 //                              else
508 //                              if(mwindow->session->edit_highlighted)
509 //                              {
510 //                                      start = mwindow->session->track_highlighted->from_units(
511 //                                              mwindow->session->edit_highlighted->startproject);
512 //                                      length = mwindow->session->track_highlighted->from_units(
513 //                                              mwindow->session->edit_highlighted->length);
514 //                              }
516                                 mwindow->insert_effects_canvas(start, length);
517                                 result = 1;
518                                 redraw = 1;
519                         }
520                         break;
522                 case DRAG_ASSET:
523                         if(mwindow->session->track_highlighted)
524                         {
525                                 int64_t position = mwindow->session->edit_highlighted ?
526                                         mwindow->session->edit_highlighted->startproject :
527                                         mwindow->session->track_highlighted->edits->length();
528                                 double position_f = mwindow->session->track_highlighted->from_units(position);
529                                 Track *track = mwindow->session->track_highlighted;
530                                 mwindow->session->track_highlighted = 0;
531                                 result = mwindow->paste_assets(position_f, track);
532                         }
533                         break;
535                 case DRAG_EDIT:
536                         mwindow->session->current_operation = NO_OPERATION;
537                         if(mwindow->session->track_highlighted)
538                         {
539                                 if(mwindow->session->track_highlighted->data_type == mwindow->session->drag_edit->track->data_type)
540                                 {
541                                         int64_t position = mwindow->session->edit_highlighted ?
542                                                 mwindow->session->edit_highlighted->startproject :
543                                                 mwindow->session->track_highlighted->edits->length();
544                                         double position_f = mwindow->session->track_highlighted->from_units(position);
545                                         Track *track = mwindow->session->track_highlighted;
546                                         mwindow->session->track_highlighted = 0;
547                                         mwindow->move_edits(mwindow->session->drag_edits,
548                                                 track,
549                                                 position_f);
550                                 }
552                                 result = 1;
553                         }
554                         break;
555         }
557         if(result)
558         {
559                 mwindow->session->track_highlighted = 0;
560                 mwindow->session->edit_highlighted = 0;
561                 mwindow->session->plugin_highlighted = 0;
562                 mwindow->session->current_operation = NO_OPERATION;
563         }
566 //printf("TrackCanvas::drag_stop %d %d\n", redraw, mwindow->session->current_operation);
567         if(redraw)
568         {
569                 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
570                 gui->get_scrollbars();
571                 draw();
572                 gui->patchbay->update();
573                 gui->cursor->update();
574                 flash();
575                 flush();
576         }
578         return result;
582 void TrackCanvas::draw(int force, int hide_cursor)
584 // Swap pixmap layers
585 TRON("TrackCanvas::draw")
586         if(get_w() != background_pixmap->get_w() ||
587                 get_h() != background_pixmap->get_h())
588         {
589                 delete background_pixmap;
590                 background_pixmap = new BC_Pixmap(this, get_w(), get_h());
591         }
593 //printf("TrackCanvas::draw 2\n");
594 // Cursor disappears after resize when this is called.
595 // Cursor doesn't redraw after editing when this isn't called.
596         if(gui->cursor && hide_cursor) gui->cursor->hide();
597 //printf("TrackCanvas::draw 3\n");
598         draw_top_background(get_parent(), 0, 0, get_w(), get_h(), background_pixmap);
599 //printf("TrackCanvas::draw 4\n");
600         draw_resources(force);
601 //printf("TrackCanvas::draw 5\n");
602         draw_overlays();
603 TROFF("TrackCanvas::draw")
606 void TrackCanvas::update_cursor()
608         switch(mwindow->edl->session->editing_mode)
609         {
610                 case EDITING_ARROW: set_cursor(ARROW_CURSOR); break;
611                 case EDITING_IBEAM: set_cursor(IBEAM_CURSOR); break;
612         }
616 void TrackCanvas::draw_indexes(Asset *asset)
618 // Don't redraw raw samples
619         if(asset->index_zoom > mwindow->edl->local_session->zoom_sample)
620                 return;
622         draw_resources(0, 1, asset);
624         draw_overlays();
625         draw_automation();
626         flash();
627         flush();
630 void TrackCanvas::draw_resources(int force, 
631         int indexes_only, 
632         Asset *index_asset)
634 // Age resource pixmaps for deletion
635         if(!indexes_only)
636                 for(int i = 0; i < resource_pixmaps.total; i++)
637                         resource_pixmaps.values[i]->visible--;
639         if(force)
640                 resource_pixmaps.remove_all_objects();
642 //printf("TrackCanvas::draw_resources 1 %d %d\n", force, indexes_only);
644 // Search every edit
645         for(Track *current = mwindow->edl->tracks->first;
646                 current;
647                 current = NEXT)
648         {
649 //printf("TrackCanvas::draw_resources 2\n");
650                 for(Edit *edit = current->edits->first; edit; edit = edit->next)
651                 {
652 //printf("TrackCanvas::draw_resources 3\n");
653                         if(!edit->asset) continue;
654 //printf("TrackCanvas::draw_resources 4\n");
655                         if(indexes_only)
656                         {
657                                 if(edit->track->data_type != TRACK_AUDIO) continue;
658                                 if(!edit->asset->test_path(index_asset->path)) continue;
659                         }
661                         int64_t edit_x, edit_y, edit_w, edit_h;
662                         edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
663 //printf("TrackCanvas::draw_resources 10\n");
665 // Edit is visible
666                         if(MWindowGUI::visible(edit_x, edit_x + edit_w, 0, get_w()) &&
667                                 MWindowGUI::visible(edit_y, edit_y + edit_h, 0, get_h()))
668                         {
669                                 int64_t pixmap_x, pixmap_w, pixmap_h;
671 //printf("TrackCanvas::draw_resources 20\n");
672 // Search for existing pixmap containing edit
673                                 for(int i = 0; i < resource_pixmaps.total; i++)
674                                 {
675                                         ResourcePixmap* pixmap = resource_pixmaps.values[i];
676 //printf("TrackCanvas::draw_resources 30\n");
677 // Same pointer can be different edit if editing took place
678                                         if(pixmap->edit_id == edit->id)
679                                         {
680 //printf("TrackCanvas::draw_resources 40\n");
681                                                 pixmap->visible = 1;
682                                                 break;
683                                         }
684 //printf("TrackCanvas::draw_resources 50\n");
685                                 }
687 // Get new size, offset of pixmap needed
688                                 get_pixmap_size(edit, 
689                                         edit_x, 
690                                         edit_w, 
691                                         pixmap_x, 
692                                         pixmap_w, 
693                                         pixmap_h);
694 //printf("TrackCanvas::draw_resources 60\n");
696 // Draw new data
697                                 if(pixmap_w && pixmap_h)
698                                 {
699 // Create pixmap if it doesn't exist
700                                         ResourcePixmap* pixmap = create_pixmap(edit, 
701                                                 edit_x, 
702                                                 pixmap_x, 
703                                                 pixmap_w, 
704                                                 pixmap_h);
705 //printf("TrackCanvas::draw_resources 70\n");
706 // Resize it if it's bigger
707                                         if(pixmap_w > pixmap->pixmap_w ||
708                                                 pixmap_h > pixmap->pixmap_h)
709                                                 pixmap->resize(pixmap_w, pixmap_h);
710 //printf("TrackCanvas::draw_resources 80\n");
711                                         pixmap->draw_data(edit,
712                                                 edit_x, 
713                                                 edit_w, 
714                                                 pixmap_x, 
715                                                 pixmap_w, 
716                                                 pixmap_h, 
717                                                 force,
718                                                 indexes_only);
719 //printf("TrackCanvas::draw_resources 90\n");
720 // Resize it if it's smaller
721                                         if(pixmap_w < pixmap->pixmap_w ||
722                                                 pixmap_h < pixmap->pixmap_h)
723                                                 pixmap->resize(pixmap_w, pixmap_h);
724 //printf("TrackCanvas::draw_resources 100\n");
725 // Copy pixmap to background canvas
726                                         background_pixmap->draw_pixmap(pixmap, 
727                                                 pixmap->pixmap_x, 
728                                                 current->y_pixel,
729                                                 pixmap->pixmap_w,
730                                                 edit_h);
731 //printf("TrackCanvas::draw_resources 110\n");
732                                 }
733                         }
734                 }
735         }
736 //printf("TrackCanvas::draw_resources 200\n");
738 // Delete unused pixmaps
739         if(!indexes_only)
740                 for(int i = resource_pixmaps.total - 1; i >= 0; i--)
741                         if(resource_pixmaps.values[i]->visible < -5)
742                         {
743                                 delete resource_pixmaps.values[i];
744                                 resource_pixmaps.remove(resource_pixmaps.values[i]);
745                         }
748 ResourcePixmap* TrackCanvas::create_pixmap(Edit *edit, 
749         int64_t edit_x, 
750         int64_t pixmap_x, 
751         int64_t pixmap_w, 
752         int64_t pixmap_h)
754         ResourcePixmap *result = 0;
756         for(int i = 0; i < resource_pixmaps.total; i++)
757         {
758 //printf("TrackCanvas::create_pixmap 1 %d %d\n", edit->id, resource_pixmaps.values[i]->edit->id);
759                 if(resource_pixmaps.values[i]->edit_id == edit->id) 
760                 {
761                         result = resource_pixmaps.values[i];
762                         break;
763                 }
764         }
766         if(!result)
767         {
768 //printf("TrackCanvas::create_pixmap 2\n");
769                 result = new ResourcePixmap(mwindow, 
770                         this, 
771                         edit, 
772                         pixmap_w, 
773                         pixmap_h);
774                 resource_pixmaps.append(result);
775         }
777 //      result->resize(pixmap_w, pixmap_h);
778         return result;
781 void TrackCanvas::get_pixmap_size(Edit *edit, 
782         int64_t edit_x, 
783         int64_t edit_w, 
784         int64_t &pixmap_x, 
785         int64_t &pixmap_w,
786         int64_t &pixmap_h)
789 // Align x on frame boundaries
792 //      switch(edit->edits->track->data_type)
793 //      {
794 //              case TRACK_AUDIO:
796                         pixmap_x = edit_x;
797                         pixmap_w = edit_w;
798                         if(pixmap_x < 0)
799                         {
800                                 pixmap_w -= -edit_x;
801                                 pixmap_x = 0;
802                         }
804                         if(pixmap_x + pixmap_w > get_w())
805                         {
806                                 pixmap_w = get_w() - pixmap_x;
807                         }
809 //                      break;
810 // 
811 //              case TRACK_VIDEO:
812 //              {
813 //                      int64_t picon_w = (int64_t)(edit->picon_w() + 0.5);
814 //                      int64_t frame_w = (int64_t)(edit->frame_w() + 0.5);
815 //                      int64_t pixel_increment = MAX(picon_w, frame_w);
816 //                      int64_t pixmap_x1 = edit_x;
817 //                      int64_t pixmap_x2 = edit_x + edit_w;
818 // 
819 //                      if(pixmap_x1 < 0)
820 //                      {
821 //                              pixmap_x1 = (int64_t)((double)-edit_x / pixel_increment) * 
822 //                                      pixel_increment + 
823 //                                      edit_x;
824 //                      }
825 // 
826 //                      if(pixmap_x2 > get_w())
827 //                      {
828 //                              pixmap_x2 = (int64_t)((double)(get_w() - edit_x) / pixel_increment + 1) * 
829 //                                      pixel_increment + 
830 //                                      edit_x;
831 //                      }
832 //                      pixmap_x = pixmap_x1;
833 //                      pixmap_w = pixmap_x2 - pixmap_x1;
834 //                      break;
835 //              }
836 //      }
838         pixmap_h = mwindow->edl->local_session->zoom_track;
839         if(mwindow->edl->session->show_titles) pixmap_h += mwindow->theme->title_bg_data->get_h();
840 //printf("get_pixmap_size %d %d %d %d\n", edit_x, edit_w, pixmap_x, pixmap_w);
843 void TrackCanvas::edit_dimensions(Edit *edit, 
844         int64_t &x, 
845         int64_t &y, 
846         int64_t &w, 
847         int64_t &h)
849 //printf("TrackCanvas::edit_dimensions 1 %p\n", edit->track);
850         w = Units::round(edit->track->from_units(edit->length) * 
851                 mwindow->edl->session->sample_rate / 
852                 mwindow->edl->local_session->zoom_sample);
853 //printf("TrackCanvas::edit_dimensions 1\n");
855         h = resource_h();
857 //printf("TrackCanvas::edit_dimensions 1\n");
858         x = Units::round(edit->track->from_units(edit->startproject) * 
859                         mwindow->edl->session->sample_rate /
860                         mwindow->edl->local_session->zoom_sample - 
861                         mwindow->edl->local_session->view_start);
863 //printf("TrackCanvas::edit_dimensions 1\n");
864         y = edit->edits->track->y_pixel;
865 //printf("TrackCanvas::edit_dimensions 1\n");
867         if(mwindow->edl->session->show_titles) 
868                 h += mwindow->theme->title_bg_data->get_h();
869 //printf("TrackCanvas::edit_dimensions 2\n");
872 void TrackCanvas::track_dimensions(Track *track, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
874         x = 0;
875         w = get_w();
876         y = track->y_pixel;
877         h = track->vertical_span(mwindow->theme);
881 void TrackCanvas::draw_paste_destination()
883         int cursor_x = get_cursor_x();
884         int cursor_y = get_cursor_y();
885         int current_atrack = 0;
886         int current_vtrack = 0;
887         int current_aedit = 0;
888         int current_vedit = 0;
889         int64_t w = 0;
890         int64_t x;
891         double position;
893 //printf("TrackCanvas::draw_paste_destination 1\n");
894         if((mwindow->session->current_operation == DRAG_ASSET &&
895                         (mwindow->session->drag_assets->total ||
896                         mwindow->session->drag_clips->total)) ||
897                 (mwindow->session->current_operation == DRAG_EDIT &&
898                         mwindow->session->drag_edits->total))
899         {
900 //printf("TrackCanvas::draw_paste_destination 1\n");
901                 Asset *asset = 0;
902                 EDL *clip = 0;
903                 int draw_box = 0;
905                 if(mwindow->session->current_operation == DRAG_ASSET &&
906                         mwindow->session->drag_assets->total)
907                         asset = mwindow->session->drag_assets->values[0];
909                 if(mwindow->session->current_operation == DRAG_ASSET &&
910                         mwindow->session->drag_clips->total)
911                         clip = mwindow->session->drag_clips->values[0];
913 // Get destination track
914                 for(Track *dest = mwindow->session->track_highlighted; 
915                         dest; 
916                         dest = dest->next)
917                 {
918                         if(dest->record)
919                         {
920 // Get source width in pixels
921                                 w = 0;
924 // Use start of highlighted edit
925                                 if(mwindow->session->edit_highlighted)
926                                         position = mwindow->session->track_highlighted->from_units(
927                                                 mwindow->session->edit_highlighted->startproject);
928                                 else
929 // Use end of highlighted track, disregarding effects
930                                         position = mwindow->session->track_highlighted->from_units(
931                                                 mwindow->session->track_highlighted->edits->length());
933 // Get the x coordinate
934                                 x = Units::to_int64(position * 
935                                         mwindow->edl->session->sample_rate /
936                                         mwindow->edl->local_session->zoom_sample) - 
937                                         mwindow->edl->local_session->view_start;
939                                 if(dest->data_type == TRACK_AUDIO)
940                                 {
941                                         if(asset && current_atrack < asset->channels)
942                                         {
943                                                 w = Units::to_int64((double)asset->audio_length /
944                                                         asset->sample_rate *
945                                                         mwindow->edl->session->sample_rate / 
946                                                         mwindow->edl->local_session->zoom_sample);
947                                                 current_atrack++;
948                                                 draw_box = 1;
949                                         }
950                                         else
951                                         if(clip && current_atrack < clip->tracks->total_audio_tracks())
952                                         {
953                                                 w = Units::to_int64((double)clip->tracks->total_length() *
954                                                         mwindow->edl->session->sample_rate / 
955                                                         mwindow->edl->local_session->zoom_sample);
956 //printf("draw_paste_destination %d\n", x);
957                                                 current_atrack++;
958                                                 draw_box = 1;
959                                         }
960                                         else
961                                         if(mwindow->session->current_operation == DRAG_EDIT &&
962                                                 current_aedit < mwindow->session->drag_edits->total)
963                                         {
964                                                 Edit *edit;
965                                                 while(current_aedit < mwindow->session->drag_edits->total &&
966                                                         mwindow->session->drag_edits->values[current_aedit]->track->data_type != TRACK_AUDIO)
967                                                         current_aedit++;
969                                                 if(current_aedit < mwindow->session->drag_edits->total)
970                                                 {
971                                                         edit = mwindow->session->drag_edits->values[current_aedit];
972                                                         w = Units::to_int64(edit->length / mwindow->edl->local_session->zoom_sample);
974                                                         current_aedit++;
975                                                         draw_box = 1;
976                                                 }
977                                         }
978                                 }
979                                 else
980                                 if(dest->data_type == TRACK_VIDEO)
981                                 {
982 //printf("draw_paste_destination 1\n");
983                                         if(asset && current_vtrack < asset->layers)
984                                         {
985                                                 w = Units::to_int64((double)asset->video_length / 
986                                                         asset->frame_rate *
987                                                         mwindow->edl->session->sample_rate /
988                                                         mwindow->edl->local_session->zoom_sample);
989                                                 current_vtrack++;
990                                                 draw_box = 1;
991                                         }
992                                         else
993                                         if(clip && current_vtrack < clip->tracks->total_video_tracks())
994                                         {
995                                                 w = Units::to_int64(clip->tracks->total_length() *
996                                                         mwindow->edl->session->sample_rate / 
997                                                         mwindow->edl->local_session->zoom_sample);
998                                                 current_vtrack++;
999                                                 draw_box = 1;
1000                                         }
1001                                         else
1002                                         if(mwindow->session->current_operation == DRAG_EDIT &&
1003                                                 current_vedit < mwindow->session->drag_edits->total)
1004                                         {
1005 //printf("draw_paste_destination 2\n");
1006                                                 Edit *edit;
1007                                                 while(current_vedit < mwindow->session->drag_edits->total &&
1008                                                         mwindow->session->drag_edits->values[current_vedit]->track->data_type != TRACK_VIDEO)
1009                                                         current_vedit++;
1011                                                 if(current_vedit < mwindow->session->drag_edits->total)
1012                                                 {
1013 //printf("draw_paste_destination 3\n");
1014                                                         edit = mwindow->session->drag_edits->values[current_vedit];
1015                                                         w = Units::to_int64(edit->track->from_units(edit->length) *
1016                                                                 mwindow->edl->session->sample_rate / 
1017                                                                 mwindow->edl->local_session->zoom_sample);
1019                                                         current_vedit++;
1020                                                         draw_box = 1;
1021                                                 }
1022                                         }
1023                                 }
1025                                 if(w)
1026                                 {
1027                                         int y = dest->y_pixel;
1028                                         int h = dest->vertical_span(mwindow->theme);
1031 //printf("TrackCanvas::draw_paste_destination 2 %d %d %d %d\n", x, y, w, h);
1032                                         if(x < -BC_INFINITY)
1033                                         {
1034                                                 w -= -BC_INFINITY - x;
1035                                                 x += -BC_INFINITY - x;
1036                                         }
1037                                         w = MIN(65535, w);
1038                                         draw_highlight_rectangle(x, y, w, h);
1039                                 }
1040                         }
1041                 }
1042         }
1045 void TrackCanvas::plugin_dimensions(Plugin *plugin, int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1047         x = Units::round(plugin->track->from_units(plugin->startproject) *
1048                 mwindow->edl->session->sample_rate / 
1049                 mwindow->edl->local_session->zoom_sample - 
1050                 mwindow->edl->local_session->view_start);
1051         w = Units::round(plugin->track->from_units(plugin->length) *
1052                 mwindow->edl->session->sample_rate / 
1053                 mwindow->edl->local_session->zoom_sample);
1054         y = plugin->track->y_pixel + 
1055                         mwindow->edl->local_session->zoom_track +
1056                         plugin->plugin_set->get_number() * 
1057                         mwindow->theme->plugin_bg_data->get_h();
1058         if(mwindow->edl->session->show_titles)
1059                 y += mwindow->theme->title_bg_data->get_h();
1060         h = mwindow->theme->plugin_bg_data->get_h();
1063 int TrackCanvas::resource_h()
1065         return mwindow->edl->local_session->zoom_track;
1068 void TrackCanvas::draw_highlight_rectangle(int x, int y, int w, int h)
1070         if(x < -10)
1071         {
1072                 w += x - -10;
1073                 x = -10;
1074         }
1075         if(y < -10)
1076         {
1077                 h += y - -10;
1078                 y = -10;
1079         }
1080         w = MIN(w, get_w() + 20);
1081         h = MIN(h, get_h() + 20);
1082         set_color(WHITE);
1083         set_inverse();
1084         draw_rectangle(x, y, w, h);
1085         draw_rectangle(x + 1, y + 1, w - 2, h - 2);
1086         set_opaque();
1087 //printf("TrackCanvas::draw_highlight_rectangle %d %d %d %d\n", x, y, w, h);
1090 void TrackCanvas::draw_playback_cursor()
1092 // Called before playback_cursor exists
1093 //      if(mwindow->playback_cursor && mwindow->playback_cursor->visible)
1094 //      {
1095 //              mwindow->playback_cursor->visible = 0;
1096 //              mwindow->playback_cursor->draw();
1097 //      }
1100 void TrackCanvas::get_handle_coords(Edit *edit, int64_t &x, int64_t &y, int64_t &w, int64_t &h, int side)
1102         int handle_w = mwindow->theme->edithandlein_data[0]->get_w();
1103         int handle_h = mwindow->theme->edithandlein_data[0]->get_h();
1105         edit_dimensions(edit, x, y, w, h);
1107         if(mwindow->edl->session->show_titles)
1108         {
1109                 y += mwindow->theme->title_bg_data->get_h();
1110         }
1111         else
1112         {
1113                 y = 0;
1114         }
1116         if(side == EDIT_OUT)
1117         {
1118                 x += w - handle_w;
1119         }
1121         h = handle_h;
1122         w = handle_w;
1125 void TrackCanvas::get_transition_coords(int64_t &x, int64_t &y, int64_t &w, int64_t &h)
1127 //printf("TrackCanvas::get_transition_coords 1\n");
1128 //      int transition_w = mwindow->theme->transitionhandle_data[0]->get_w();
1129 //      int transition_h = mwindow->theme->transitionhandle_data[0]->get_h();
1130         int transition_w = 30;
1131         int transition_h = 30;
1132 //printf("TrackCanvas::get_transition_coords 1\n");
1134         if(mwindow->edl->session->show_titles)
1135                 y += mwindow->theme->title_bg_data->get_h();
1136 //printf("TrackCanvas::get_transition_coords 2\n");
1138         y += (h - mwindow->theme->title_bg_data->get_h()) / 2 - transition_h / 2;
1139         x -= transition_w / 2;
1141         h = transition_h;
1142         w = transition_w;
1145 void TrackCanvas::draw_highlighting()
1147         int64_t x, y, w, h;
1148         int draw_box = 0;
1149 //printf("TrackCanvas::draw_highlighting 1 %p %d\n", mwindow->session->track_highlighted, mwindow->session->current_operation);
1153         switch(mwindow->session->current_operation)
1154         {
1155                 case DRAG_ATRANSITION:
1156                 case DRAG_VTRANSITION:
1157 //printf("TrackCanvas::draw_highlighting 1 %p %p\n", 
1158 //      mwindow->session->track_highlighted, mwindow->session->edit_highlighted);
1159                         if(mwindow->session->edit_highlighted)
1160                         {
1161 //printf("TrackCanvas::draw_highlighting 2\n");
1162                                 if((mwindow->session->current_operation == DRAG_ATRANSITION && 
1163                                         mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1164                                         (mwindow->session->current_operation == DRAG_VTRANSITION && 
1165                                         mwindow->session->track_highlighted->data_type == TRACK_VIDEO))
1166                                 {
1167 //printf("TrackCanvas::draw_highlighting 2\n");
1168                                         edit_dimensions(mwindow->session->edit_highlighted, x, y, w, h);
1169 //printf("TrackCanvas::draw_highlighting 2\n");
1171                                         if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1172                                                 MWindowGUI::visible(y, y + h, 0, get_h()))
1173                                         {
1174                                                 draw_box = 1;
1175                                                 get_transition_coords(x, y, w, h);
1176                                         }
1177 //printf("TrackCanvas::draw_highlighting 3\n");
1178                                 }
1179                         }
1180                         break;
1184 // Dragging a new effect from the Resource window
1185                 case DRAG_AEFFECT:
1186                 case DRAG_VEFFECT:
1187                         if(mwindow->session->track_highlighted &&
1188                                 ((mwindow->session->current_operation == DRAG_AEFFECT && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1189                                         (mwindow->session->current_operation == DRAG_VEFFECT && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
1190                         {
1191 // Put it before another plugin
1192                                 if(mwindow->session->plugin_highlighted)
1193                                 {
1194                                         plugin_dimensions(mwindow->session->plugin_highlighted, 
1195                                                 x, 
1196                                                 y, 
1197                                                 w, 
1198                                                 h);
1199 //printf("TrackCanvas::draw_highlighting 1 %d %d\n", x, w);
1200                                 }
1201                                 else
1202 // Put it after a plugin set
1203                                 if(mwindow->session->pluginset_highlighted &&
1204                                         mwindow->session->pluginset_highlighted->last)
1205                                 {
1206                                         plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last, 
1207                                                 x, 
1208                                                 y, 
1209                                                 w, 
1210                                                 h);
1211 //printf("TrackCanvas::draw_highlighting 1 %d %d\n", x, w);
1212                                         int64_t track_x, track_y, track_w, track_h;
1213                                         track_dimensions(mwindow->session->track_highlighted, 
1214                                                 track_x, 
1215                                                 track_y, 
1216                                                 track_w, 
1217                                                 track_h);
1219                                         x += w;
1220                                         w = Units::round(
1221                                                         mwindow->session->track_highlighted->get_length() *
1222                                                         mwindow->edl->session->sample_rate / 
1223                                                         mwindow->edl->local_session->zoom_sample - 
1224                                                         mwindow->edl->local_session->view_start) -
1225                                                 x;
1226 //printf("TrackCanvas::draw_highlighting 2 %d\n", w);
1227                                         if(w <= 0) w = track_w;
1228                                 }
1229                                 else
1230                                 {
1231                                         track_dimensions(mwindow->session->track_highlighted, 
1232                                                 x, 
1233                                                 y, 
1234                                                 w, 
1235                                                 h);
1237 //printf("TrackCanvas::draw_highlighting 1 %d %d %d %d\n", x, y, w, h);
1238 // Put it in a new plugin set determined by the selected range
1239                                         if(mwindow->edl->local_session->get_selectionend() > 
1240                                                 mwindow->edl->local_session->get_selectionstart())
1241                                         {
1242                                                 x = Units::to_int64(mwindow->edl->local_session->get_selectionstart() *
1243                                                         mwindow->edl->session->sample_rate / 
1244                                                         mwindow->edl->local_session->zoom_sample -
1245                                                         mwindow->edl->local_session->view_start);
1246                                                 w = Units::to_int64((mwindow->edl->local_session->get_selectionend() - 
1247                                                         mwindow->edl->local_session->get_selectionstart()) *
1248                                                         mwindow->edl->session->sample_rate / 
1249                                                         mwindow->edl->local_session->zoom_sample);
1250                                         }
1251 // Put it in a new plugin set determined by an edit boundary
1252 //                                      else
1253 //                                      if(mwindow->session->edit_highlighted)
1254 //                                      {
1255 //                                              int64_t temp_y, temp_h;
1256 //                                              edit_dimensions(mwindow->session->edit_highlighted, 
1257 //                                                      x, 
1258 //                                                      temp_y, 
1259 //                                                      w, 
1260 //                                                      temp_h);
1261 //                                      }
1262 // Put it at the beginning of the track in a new plugin set
1263                                 }
1265                                 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1266                                         MWindowGUI::visible(y, y + h, 0, get_h()))
1267                                 {
1268 //printf("TrackCanvas::draw_highlighting 1\n");
1269                                         draw_box = 1;
1270                                 }
1271                         }
1272                         break;
1273                 
1274                 case DRAG_ASSET:
1275                         if(mwindow->session->track_highlighted)
1276                         {
1277                                 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1279                                 if(MWindowGUI::visible(y, y + h, 0, get_h()))
1280                                 {
1281                                         draw_paste_destination();
1282                                 }
1283                         }
1284                         break;
1286 // Dragging an effect from the timeline
1287                 case DRAG_AEFFECT_COPY:
1288                 case DRAG_VEFFECT_COPY:
1289                         if((mwindow->session->plugin_highlighted || mwindow->session->track_highlighted) &&
1290                                 ((mwindow->session->current_operation == DRAG_AEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_AUDIO) ||
1291                                 (mwindow->session->current_operation == DRAG_VEFFECT_COPY && mwindow->session->track_highlighted->data_type == TRACK_VIDEO)))
1292                         {
1293 // Put it before another plugin
1294                                 if(mwindow->session->plugin_highlighted)
1295                                         plugin_dimensions(mwindow->session->plugin_highlighted, x, y, w, h);
1296                                 else
1297 // Put it after a plugin set
1298                                 if(mwindow->session->pluginset_highlighted &&
1299                                         mwindow->session->pluginset_highlighted->last)
1300                                 {
1301                                         plugin_dimensions((Plugin*)mwindow->session->pluginset_highlighted->last, x, y, w, h);
1302                                         x += w;
1303                                 }
1304                                 else
1305                                 if(mwindow->session->track_highlighted)
1306                                 {
1307                                         track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1309 // Put it in a new plugin set determined by an edit boundary
1310                                         if(mwindow->session->edit_highlighted)
1311                                         {
1312                                                 int64_t temp_y, temp_h;
1313                                                 edit_dimensions(mwindow->session->edit_highlighted, 
1314                                                         x, 
1315                                                         temp_y, 
1316                                                         w, 
1317                                                         temp_h);
1318                                         }
1319 // Put it in a new plugin set at the start of the track
1320                                 }
1322 // Calculate length of plugin based on data type of track and units
1323                                 if(mwindow->session->track_highlighted->data_type == TRACK_VIDEO)
1324                                 {
1325                                         w = (int64_t)((double)mwindow->session->drag_plugin->length / 
1326                                                 mwindow->edl->session->frame_rate *
1327                                                 mwindow->edl->session->sample_rate /
1328                                                 mwindow->edl->local_session->zoom_sample);
1329                                 }
1330                                 else
1331                                 {
1332                                         w = (int64_t)mwindow->session->drag_plugin->length /
1333                                                 mwindow->edl->local_session->zoom_sample;
1334                                 }
1336                                 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1337                                         MWindowGUI::visible(y, y + h, 0, get_h()))
1338                                 {
1339                                         draw_box = 1;
1340                                 }
1342                         }
1343                         break;
1345                 case DRAG_EDIT:
1346 //printf("TrackCanvas::draw_highlighting 1\n");
1347                         if(mwindow->session->track_highlighted)
1348                         {
1349                                 track_dimensions(mwindow->session->track_highlighted, x, y, w, h);
1351                                 if(MWindowGUI::visible(y, y + h, 0, get_h()))
1352                                 {
1353                                         draw_paste_destination();
1354                                 }
1355                         }
1358                         break;
1359         }
1362         if(draw_box)
1363         {
1364                 draw_highlight_rectangle(x, y, w, h);
1365         }
1368 void TrackCanvas::draw_plugins()
1370         char string[BCTEXTLEN];
1372         for(Track *track = mwindow->edl->tracks->first;
1373                 track;
1374                 track = track->next)
1375         {
1376                 if(track->expand_view)
1377                 {
1378                         for(int i = 0; i < track->plugin_set.total; i++)
1379                         {
1380                                 PluginSet *pluginset = track->plugin_set.values[i];
1382                                 for(Plugin *plugin = (Plugin*)pluginset->first; plugin; plugin = (Plugin*)plugin->next)
1383                                 {
1384                                         int64_t total_x, y, total_w, h;
1385                                         plugin_dimensions(plugin, total_x, y, total_w, h);
1386                                         
1387                                         if(MWindowGUI::visible(total_x, total_x + total_w, 0, get_w()) &&
1388                                                 MWindowGUI::visible(y, y + h, 0, get_h()) &&
1389                                                 plugin->plugin_type != PLUGIN_NONE)
1390                                         {
1391                                                 int x = total_x, w = total_w, left_margin = 5;
1392                                                 if(x < 0)
1393                                                 {
1394                                                         w -= -x;
1395                                                         x = 0;
1396                                                 }
1397                                                 if(w + x > get_w()) w -= (w + x) - get_w();
1399                                                 draw_3segmenth(x, 
1400                                                         y, 
1401                                                         w, 
1402                                                         total_x,
1403                                                         total_w,
1404                                                         mwindow->theme->plugin_bg_data,
1405                                                         0);
1406                                                 set_color(WHITE);
1407                                                 set_font(MEDIUMFONT_3D);
1408                                                 plugin->calculate_title(string);
1410 // Truncate string to int64_test visible in background
1411                                                 int len = strlen(string), j;
1412                                                 for(j = len; j >= 0; j--)
1413                                                 {
1414                                                         if(left_margin + get_text_width(MEDIUMFONT_3D, string) > w)
1415                                                         {
1416                                                                 string[j] = 0;
1417                                                         }
1418                                                         else
1419                                                                 break;
1420                                                 }
1422 // Justify the text on the left boundary of the edit if it is visible.
1423 // Otherwise justify it on the left side of the screen.
1424                                                 int text_x = total_x + left_margin;
1425                                                 text_x = MAX(left_margin, text_x);
1426                                                 draw_text(text_x, 
1427                                                         y + get_text_ascent(MEDIUMFONT_3D) + 2, 
1428                                                         string,
1429                                                         strlen(string),
1430                                                         0);
1431                                         }
1432                                 }
1433                         }
1434                 }
1435         }
1439 void TrackCanvas::draw_inout_points()
1444 void TrackCanvas::draw_drag_handle()
1446         if(mwindow->session->current_operation == DRAG_EDITHANDLE2 ||
1447                 mwindow->session->current_operation == DRAG_PLUGINHANDLE2)
1448         {
1449 //printf("TrackCanvas::draw_drag_handle 1 %ld %ld\n", mwindow->session->drag_sample, mwindow->edl->local_session->view_start);
1450                 int64_t pixel1 = Units::round(mwindow->session->drag_position * 
1451                         mwindow->edl->session->sample_rate /
1452                         mwindow->edl->local_session->zoom_sample - 
1453                         mwindow->edl->local_session->view_start);
1454 //printf("TrackCanvas::draw_drag_handle 2 %d\n", pixel1);
1455                 set_color(GREEN);
1456                 set_inverse();
1457 //printf("TrackCanvas::draw_drag_handle 3\n");
1458                 draw_line(pixel1, 0, pixel1, get_h());
1459                 set_opaque();
1460 //printf("TrackCanvas::draw_drag_handle 4\n");
1461         }
1465 void TrackCanvas::draw_transitions()
1467         int64_t x, y, w, h;
1469         for(Track *track = mwindow->edl->tracks->first;
1470                 track;
1471                 track = track->next)
1472         {
1473                 for(Edit *edit = track->edits->first;
1474                         edit;
1475                         edit = edit->next)
1476                 {
1477                         if(edit->transition)
1478                         {
1479                                 edit_dimensions(edit, x, y, w, h);
1480                                 get_transition_coords(x, y, w, h);
1482                                 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
1483                                         MWindowGUI::visible(y, y + h, 0, get_h()))
1484                                 {
1485                                         PluginServer *server = mwindow->scan_plugindb(edit->transition->title);
1486                                         draw_vframe(server->picon, 
1487                                                 x, 
1488                                                 y, 
1489                                                 w, 
1490                                                 h, 
1491                                                 0, 
1492                                                 0, 
1493                                                 server->picon->get_w(), 
1494                                                 server->picon->get_h());
1495                                 }
1496                         }
1497                 }
1498         }
1501 void TrackCanvas::draw_loop_points()
1503 //printf("TrackCanvas::draw_loop_points 1\n");
1504         if(mwindow->edl->local_session->loop_playback)
1505         {
1506 //printf("TrackCanvas::draw_loop_points 2\n");
1507                 int64_t x = Units::round(mwindow->edl->local_session->loop_start *
1508                         mwindow->edl->session->sample_rate /
1509                         mwindow->edl->local_session->zoom_sample - 
1510                         mwindow->edl->local_session->view_start);
1511 //printf("TrackCanvas::draw_loop_points 3\n");
1513                 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1514                 {
1515                         set_color(GREEN);
1516                         draw_line(x, 0, x, get_h());
1517                 }
1518 //printf("TrackCanvas::draw_loop_points 4\n");
1520                 x = Units::round(mwindow->edl->local_session->loop_end *
1521                         mwindow->edl->session->sample_rate /
1522                         mwindow->edl->local_session->zoom_sample - 
1523                         mwindow->edl->local_session->view_start);
1524 //printf("TrackCanvas::draw_loop_points 5\n");
1526                 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1527                 {
1528                         set_color(GREEN);
1529                         draw_line(x, 0, x, get_h());
1530                 }
1531 //printf("TrackCanvas::draw_loop_points 6\n");
1532         }
1533 //printf("TrackCanvas::draw_loop_points 7\n");
1536 void TrackCanvas::draw_brender_start()
1538         if(mwindow->preferences->use_brender)
1539         {
1540                 int64_t x = Units::round(mwindow->edl->session->brender_start *
1541                         mwindow->edl->session->sample_rate /
1542                         mwindow->edl->local_session->zoom_sample - 
1543                         mwindow->edl->local_session->view_start);
1545                 if(MWindowGUI::visible(x, x + 1, 0, get_w()))
1546                 {
1547                         set_color(RED);
1548                         draw_line(x, 0, x, get_h());
1549                 }
1550         }
1553 int TrackCanvas::do_keyframes(int cursor_x, 
1554         int cursor_y, 
1555         int draw, 
1556         int buttonpress, 
1557         int &new_cursor,
1558         int &update_cursor,
1559         int &rerender)
1561         int current_tool = 0;
1562         int result = 0;
1563         EDLSession *session = mwindow->edl->session;
1565         for(Track *track = mwindow->edl->tracks->first;
1566                 track && !result;
1567                 track = track->next)
1568         {
1569                 Automation *automation = track->automation;
1571 //printf("TrackCanvas::draw_keyframes 1\n");
1572                 if(!result && session->auto_conf->fade)
1573                 {
1574                         result = do_float_autos(track, 
1575                                 automation->fade_autos,
1576                                 cursor_x, 
1577                                 cursor_y, 
1578                                 draw, 
1579                                 buttonpress, 
1580                                 WHITE);
1581                         if(result && mwindow->session->current_operation == DRAG_FADE)
1582                         {
1583                                 rerender = 1;
1584                         }
1585                         if(result && buttonpress)
1586                         {
1587                                 mwindow->session->current_operation = DRAG_FADE;
1588                                 update_drag_caption();
1589                         }
1590                 }
1592 //printf("TrackCanvas::draw_keyframes 1 %d\n", result);
1594                 if(!result && session->auto_conf->czoom && automation->czoom_autos)
1595                 {
1596                         result = do_float_autos(track, 
1597                                 automation->czoom_autos,
1598                                 cursor_x, 
1599                                 cursor_y, 
1600                                 draw, 
1601                                 buttonpress,
1602                                 MEPURPLE);
1603                         if(result && mwindow->session->current_operation == DRAG_CZOOM)
1604                         {
1605                                 rerender = 1;
1606                         }
1607                         if(result && buttonpress)
1608                         {
1609                                 mwindow->session->current_operation = DRAG_CZOOM;
1610                                 update_drag_caption();
1611                         }
1612                 }
1614 //printf("TrackCanvas::draw_keyframes 2 %d\n", result);
1615                 if(!result && session->auto_conf->pzoom && automation->pzoom_autos)
1616                 {
1617                         result = do_float_autos(track, 
1618                                 automation->pzoom_autos,
1619                                 cursor_x, 
1620                                 cursor_y, 
1621                                 draw, 
1622                                 buttonpress,
1623                                 PINK);
1624                         if(result && mwindow->session->current_operation == DRAG_PZOOM)
1625                         {
1626                                 rerender = 1;
1627                         }
1628                         if(result && buttonpress)
1629                         {
1630                                 mwindow->session->current_operation = DRAG_PZOOM;
1631                                 update_drag_caption();
1632                         }
1633                 }
1635 //printf("TrackCanvas::draw_keyframes 1 %d\n", result);
1636                 if(!result && session->auto_conf->mute)
1637                 {
1638                         result = do_toggle_autos(track, 
1639                                 automation->mute_autos,
1640                                 cursor_x, 
1641                                 cursor_y, 
1642                                 draw, 
1643                                 buttonpress,
1644                                 BLUE);
1645                         if(result && mwindow->session->current_operation == DRAG_MUTE)
1646                         {
1647                                 rerender = 1;
1648                         }
1649                         if(result && buttonpress)
1650                         {
1651                                 mwindow->session->current_operation = DRAG_MUTE;
1652                                 update_drag_caption();
1653                         }
1654                 }
1656 //printf("TrackCanvas::draw_keyframes 1 %d\n", result);
1657                 if(!result && session->auto_conf->camera && automation->camera_autos)
1658                 {
1659                         result = do_autos(track, 
1660                                 automation->camera_autos,
1661                                 cursor_x, 
1662                                 cursor_y, 
1663                                 draw, 
1664                                 buttonpress,
1665                                 camerakeyframe_pixmap);
1666                         if(result && mwindow->session->current_operation == DRAG_CAMERA)
1667                         {
1668                                 rerender = 1;
1669                         }
1670                         if(result && buttonpress)
1671                         {
1672                                 mwindow->session->current_operation = DRAG_CAMERA_PRE;
1673                                 update_drag_caption();
1674                                 rerender = 1;
1675                         }
1676                 }
1678                 if(!result && session->auto_conf->mode && automation->mode_autos)
1679                 {
1680                         result = do_autos(track, 
1681                                 automation->mode_autos,
1682                                 cursor_x, 
1683                                 cursor_y, 
1684                                 draw, 
1685                                 buttonpress,
1686                                 modekeyframe_pixmap);
1687                         if(result && mwindow->session->current_operation == DRAG_MODE)
1688                         {
1689                                 rerender = 1;
1690                         }
1691                         if(result && buttonpress)
1692                         {
1693                                 mwindow->session->current_operation = DRAG_MODE_PRE;
1694                                 update_drag_caption();
1695                                 rerender = 1;
1696                         }
1697                 }
1699 //printf("TrackCanvas::draw_keyframes 1 %d\n", result);
1700                 if(!result && session->auto_conf->projector && automation->projector_autos)
1701                 {
1702                         result = do_autos(track, 
1703                                 automation->projector_autos,
1704                                 cursor_x, 
1705                                 cursor_y, 
1706                                 draw, 
1707                                 buttonpress,
1708                                 projectorkeyframe_pixmap);
1709                         if(result && mwindow->session->current_operation == DRAG_PROJECTOR)
1710                         {
1711                                 rerender = 1;
1712                         }
1713                         if(result && buttonpress)
1714                         {
1715                                 mwindow->session->current_operation = DRAG_PROJECTOR_PRE;
1716                                 update_drag_caption();
1717                                 rerender = 1;
1718                         }
1719                 }
1721                 if(!result && session->auto_conf->mask && automation->mask_autos)
1722                 {
1723                         result = do_autos(track, 
1724                                 automation->mask_autos,
1725                                 cursor_x, 
1726                                 cursor_y, 
1727                                 draw, 
1728                                 buttonpress,
1729                                 maskkeyframe_pixmap);
1730                         if(result && mwindow->session->current_operation == DRAG_MASK)
1731                         {
1732                                 rerender = 1;
1733                         }
1734                         if(result && buttonpress)
1735                         {
1736                                 mwindow->session->current_operation = DRAG_MASK_PRE;
1737                                 update_drag_caption();
1738                                 rerender = 1;
1739                         }
1740                 }
1742 //printf("TrackCanvas::draw_keyframes 1 %d\n", result);
1743                 if(!result && session->auto_conf->pan && automation->pan_autos)
1744                 {
1745                         result = do_autos(track, 
1746                                 automation->pan_autos,
1747                                 cursor_x, 
1748                                 cursor_y, 
1749                                 draw, 
1750                                 buttonpress,
1751                                 pankeyframe_pixmap);
1752                         if(result && mwindow->session->current_operation == DRAG_PAN)
1753                         {
1754                                 rerender = 1;
1755                         }
1756                         if(result && buttonpress)
1757                         {
1758                                 mwindow->session->current_operation = DRAG_PAN_PRE;
1759                                 update_drag_caption();
1760                                 rerender = 1;
1761                         }
1762                 }
1764 //printf("TrackCanvas::draw_keyframes 1 %d\n", result);
1765                 if(!result && session->auto_conf->plugins)
1766                 {
1767                         result = do_plugin_autos(track,
1768                                 cursor_x, 
1769                                 cursor_y, 
1770                                 draw, 
1771                                 buttonpress);
1772                         if(result && mwindow->session->current_operation == DRAG_PLUGINKEY)
1773                         {
1774                                 rerender = 1;
1775                         }
1776                         if(result && buttonpress)
1777                         {
1778                                 mwindow->session->current_operation = DRAG_PLUGINKEY_PRE;
1779                                 update_drag_caption();
1780                                 rerender = 1;
1781                         }
1782                 }
1783 //printf("TrackCanvas::draw_keyframes 1 %d\n", result);
1784         }
1786         if(mwindow->session->current_operation == DRAG_FADE ||
1787                 mwindow->session->current_operation == DRAG_CZOOM ||
1788                 mwindow->session->current_operation == DRAG_PZOOM ||
1789                 mwindow->session->current_operation == DRAG_PLAY ||
1790                 mwindow->session->current_operation == DRAG_MUTE ||
1791                 mwindow->session->current_operation == DRAG_CAMERA ||
1792                 mwindow->session->current_operation == DRAG_CAMERA_PRE ||
1793                 mwindow->session->current_operation == DRAG_MASK ||
1794                 mwindow->session->current_operation == DRAG_MASK_PRE ||
1795                 mwindow->session->current_operation == DRAG_MODE ||
1796                 mwindow->session->current_operation == DRAG_MODE_PRE ||
1797                 mwindow->session->current_operation == DRAG_PAN ||
1798                 mwindow->session->current_operation == DRAG_PAN_PRE ||
1799                 mwindow->session->current_operation == DRAG_PLUGINKEY ||
1800                 mwindow->session->current_operation == DRAG_PLUGINKEY_PRE ||
1801                 mwindow->session->current_operation == DRAG_PROJECTOR ||
1802                 mwindow->session->current_operation == DRAG_PROJECTOR_PRE)
1803         {
1804                 result = 1;
1805         }
1807 //printf("TrackCanvas::draw_keyframes 2 %d\n", result);
1808         update_cursor = 1;
1809         if(result)
1810         {
1811                 new_cursor = UPRIGHT_ARROW_CURSOR;
1812 //              rerender = 1;
1813         }
1815 //printf("TrackCanvas::do_keyframes 3 %d\n", result);
1816         return result;
1819 void TrackCanvas::draw_auto(Auto *current, 
1820         int x, 
1821         int y, 
1822         int center_pixel, 
1823         int zoom_track,
1824         int color)
1826         int x1, y1, x2, y2;
1827         char string[BCTEXTLEN];
1829         x1 = x - HANDLE_W / 2;
1830         x2 = x + HANDLE_W / 2;
1831         y1 = center_pixel + y - HANDLE_W / 2;
1832         y2 = center_pixel + y + HANDLE_W / 2;
1834         if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
1835         if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
1837         set_color(BLACK);
1838         draw_box(x1 + 1, y1 + 1, x2 - x1, y2 - y1);
1839         set_color(color);
1840         draw_box(x1, y1, x2 - x1, y2 - y1);
1843 void TrackCanvas::draw_floatauto(Auto *current, 
1844         int x, 
1845         int y, 
1846         int in_x, 
1847         int in_y, 
1848         int out_x, 
1849         int out_y, 
1850         int center_pixel, 
1851         int zoom_track,
1852         int color)
1854         int x1, y1, x2, y2;
1855         int in_x1, in_y1, in_x2, in_y2;
1856         int out_x1, out_y1, out_x2, out_y2;
1857         char string[BCTEXTLEN];
1859 // Center
1860         x1 = x - HANDLE_W / 2;
1861         x2 = x + HANDLE_W / 2;
1862         y1 = center_pixel + y - HANDLE_W / 2;
1863         y2 = center_pixel + y + HANDLE_W / 2;
1865         CLAMP(y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
1866         CLAMP(y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
1868         set_color(BLACK);
1869         draw_box(x1 + 1, y1 + 1, x2 - x1, y2 - y1);
1870         set_color(color);
1871         draw_box(x1, y1, x2 - x1, y2 - y1);
1873 // In handle
1874         in_x1 = in_x - HANDLE_W / 2;
1875         in_x2 = in_x + HANDLE_W / 2;
1876         in_y1 = center_pixel + in_y - HANDLE_W / 2;
1877         in_y2 = center_pixel + in_y + HANDLE_W / 2;
1879         CLAMP(in_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
1880         CLAMP(in_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
1881         CLAMP(in_y, -zoom_track / 2, zoom_track / 2);
1883         set_color(BLACK);
1884         draw_line(x + 1, center_pixel + y + 1, in_x + 1, center_pixel + in_y + 1);
1885         draw_box(in_x1 + 1, in_y1 + 1, in_x2 - in_x1, in_y2 - in_y1);
1886         set_color(color);
1887         draw_line(x, center_pixel + y, in_x, center_pixel + in_y);
1888         draw_box(in_x1, in_y1, in_x2 - in_x1, in_y2 - in_y1);
1892 // Out handle
1893         out_x1 = out_x - HANDLE_W / 2;
1894         out_x2 = out_x + HANDLE_W / 2;
1895         out_y1 = center_pixel + out_y - HANDLE_W / 2;
1896         out_y2 = center_pixel + out_y + HANDLE_W / 2;
1898         CLAMP(out_y1, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
1899         CLAMP(out_y2, center_pixel + -zoom_track / 2, center_pixel + zoom_track / 2);
1900         CLAMP(out_y, -zoom_track / 2, zoom_track / 2);
1903         set_color(BLACK);
1904         draw_line(x + 1, center_pixel + y + 1, out_x + 1, center_pixel + out_y + 1);
1905         draw_box(out_x1 + 1, out_y1 + 1, out_x2 - out_x1, out_y2 - out_y1);
1906         set_color(color);
1907         draw_line(x, center_pixel + y, out_x, center_pixel + out_y);
1908         draw_box(out_x1, out_y1, out_x2 - out_x1, out_y2 - out_y1);
1912 int TrackCanvas::test_auto(Auto *current, 
1913         int x, 
1914         int y, 
1915         int center_pixel, 
1916         int zoom_track, 
1917         int cursor_x, 
1918         int cursor_y, 
1919         int buttonpress)
1921         int x1, y1, x2, y2;
1922         char string[BCTEXTLEN];
1923         int result = 0;
1925         x1 = x - HANDLE_W / 2;
1926         x2 = x + HANDLE_W / 2;
1927         y1 = center_pixel + y - HANDLE_W / 2;
1928         y2 = center_pixel + y + HANDLE_W / 2;
1930         if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
1931         if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
1932 //printf("test_auto 1 %d %d %d %d %d %d\n", cursor_x, cursor_y, x1, x2, y1, y2);
1934         if(cursor_x >= x1 && cursor_x < x2 && cursor_y >= y1 && cursor_y < y2)
1935         {
1936 //printf("test_auto 2 %d\n", buttonpress);
1937                 if(buttonpress)
1938                 {
1939 //printf("test_auto 3\n");
1940                         mwindow->session->drag_auto = current;
1941                         mwindow->session->drag_start_percentage = current->value_to_percentage();
1942                         mwindow->session->drag_start_position = current->position;
1943                         mwindow->session->drag_origin_x = cursor_x;
1944                         mwindow->session->drag_origin_y = cursor_y;
1945                 }
1946                 result = 1;
1947         }
1949         return result;
1952 int TrackCanvas::test_floatauto(Auto *current, 
1953         int x, 
1954         int y, 
1955         int in_x,
1956         int in_y,
1957         int out_x,
1958         int out_y,
1959         int center_pixel, 
1960         int zoom_track, 
1961         int cursor_x, 
1962         int cursor_y, 
1963         int buttonpress)
1965         int x1, y1, x2, y2;
1966         int in_x1, in_y1, in_x2, in_y2;
1967         int out_x1, out_y1, out_x2, out_y2;
1968         char string[BCTEXTLEN];
1969         int result = 0;
1971         x1 = x - HANDLE_W / 2;
1972         x2 = x + HANDLE_W / 2;
1973         y1 = center_pixel + y - HANDLE_W / 2;
1974         y2 = center_pixel + y + HANDLE_W / 2;
1976         if(y1 < center_pixel + -zoom_track / 2) y1 = center_pixel + -zoom_track / 2;
1977         if(y2 > center_pixel + zoom_track / 2) y2 = center_pixel + zoom_track / 2;
1979         in_x1 = in_x - HANDLE_W / 2;
1980         in_x2 = in_x + HANDLE_W / 2;
1981         in_y1 = center_pixel + in_y - HANDLE_W / 2;
1982         in_y2 = center_pixel + in_y + HANDLE_W / 2;
1984         if(in_y1 < center_pixel + -zoom_track / 2) in_y1 = center_pixel + -zoom_track / 2;
1985         if(in_y2 > center_pixel + zoom_track / 2) in_y2 = center_pixel + zoom_track / 2;
1987         out_x1 = out_x - HANDLE_W / 2;
1988         out_x2 = out_x + HANDLE_W / 2;
1989         out_y1 = center_pixel + out_y - HANDLE_W / 2;
1990         out_y2 = center_pixel + out_y + HANDLE_W / 2;
1992         if(out_y1 < center_pixel + -zoom_track / 2) out_y1 = center_pixel + -zoom_track / 2;
1993         if(out_y2 > center_pixel + zoom_track / 2) out_y2 = center_pixel + zoom_track / 2;
1997 //printf("TrackCanvas::test_floatauto %d %d %d %d %d %d\n", cursor_x, cursor_y, x1, x2, y1, y2);
1998 // Test value
1999         if(!ctrl_down() &&
2000                 cursor_x >= x1 && 
2001                 cursor_x < x2 && 
2002                 cursor_y >= y1 && 
2003                 cursor_y < y2)
2004         {
2005                 if(buttonpress)
2006                 {
2007                         mwindow->session->drag_auto = current;
2008                         mwindow->session->drag_start_percentage = current->value_to_percentage();
2009                         mwindow->session->drag_start_position = current->position;
2010                         mwindow->session->drag_origin_x = cursor_x;
2011                         mwindow->session->drag_origin_y = cursor_y;
2012                         mwindow->session->drag_handle = 0;
2013                 }
2014                 result = 1;
2015         }
2016         else
2017 // Test in control
2018         if(ctrl_down() &&
2019                 cursor_x >= in_x1 && 
2020                 cursor_x < in_x2 && 
2021                 cursor_y >= in_y1 && 
2022                 cursor_y < in_y2 &&
2023                 current->position > 0)
2024         {
2025                 if(buttonpress)
2026                 {
2027                         mwindow->session->drag_auto = current;
2028                         mwindow->session->drag_start_percentage = 
2029                                 current->invalue_to_percentage();
2030                         mwindow->session->drag_start_position = 
2031                                 ((FloatAuto*)current)->control_in_position;
2032                         mwindow->session->drag_origin_x = cursor_x;
2033                         mwindow->session->drag_origin_y = cursor_y;
2034                         mwindow->session->drag_handle = 1;
2035                 }
2036                 result = 1;
2037         }
2038         else
2039 // Test out control
2040         if(ctrl_down() &&
2041                 cursor_x >= out_x1 && 
2042                 cursor_x < out_x2 && 
2043                 cursor_y >= out_y1 && 
2044                 cursor_y < out_y2)
2045         {
2046                 if(buttonpress)
2047                 {
2048                         mwindow->session->drag_auto = current;
2049                         mwindow->session->drag_start_percentage = 
2050                                 current->outvalue_to_percentage();
2051                         mwindow->session->drag_start_position = 
2052                                 ((FloatAuto*)current)->control_out_position;
2053                         mwindow->session->drag_origin_x = cursor_x;
2054                         mwindow->session->drag_origin_y = cursor_y;
2055                         mwindow->session->drag_handle = 2;
2056                 }
2057                 result = 1;
2058         }
2060 // if(buttonpress) 
2061 // 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", 
2062 // mwindow->session->drag_handle,
2063 // ctrl_down(),
2064 // cursor_x,
2065 // cursor_y,
2066 // x1, x2, y1, y2);
2068         return result;
2071 void TrackCanvas::draw_floatline(int center_pixel, 
2072         FloatAuto *previous,
2073         FloatAuto *next,
2074         FloatAutos *autos,
2075         int64_t unit_start,
2076         double zoom_units,
2077         double yscale,
2078         int x1,
2079         int y1,
2080         int x2,
2081         int y2,
2082         int color)
2084 // Solve bezier equation for either every pixel or a certain large number of
2085 // points.
2089 // Not using slope intercept
2090         x1 = MAX(0, x1);
2095         int prev_y;
2096 // Call by reference fails for some reason here
2097         FloatAuto *previous1 = previous, *next1 = next;
2098         for(int x = x1; x < x2; x++)
2099         {
2100                 int64_t position = (int64_t)(unit_start + x * zoom_units);
2101                 float value = autos->get_value(position, PLAY_FORWARD, previous1, next1);
2103                 int y = (int)(center_pixel + 
2104                         (autos->value_to_percentage(value) - 0.5) * -yscale);
2106                 if(x > x1)
2107                 {
2108                         set_color(BLACK);
2109                         draw_line(x - 1, prev_y + 1, x, y + 1);
2110                         set_color(color);
2111                         draw_line(x - 1, prev_y, x, y);
2112                 }
2113                 prev_y = y;
2114         }
2118 //      set_color(BLACK);
2119 //      draw_line(x1, center_pixel + y1 + 1, x2, center_pixel + y2 + 1);
2120 //      set_color(WHITE);
2121 //      draw_line(x1, center_pixel + y1, x2, center_pixel + y2);
2129 int TrackCanvas::test_floatline(int center_pixel, 
2130                 FloatAutos *autos,
2131                 int64_t unit_start,
2132                 double zoom_units,
2133                 double yscale,
2134                 int x1,
2135                 int x2,
2136                 int cursor_x, 
2137                 int cursor_y, 
2138                 int buttonpress)
2140         int result = 0;
2143         int64_t position = (int64_t)(unit_start + cursor_x * zoom_units);
2144 // Call by reference fails for some reason here
2145         FloatAuto *previous = 0, *next = 0;
2146         float value = autos->get_value(position, PLAY_FORWARD, previous, next);
2147         int y = (int)(center_pixel + 
2148                 (autos->value_to_percentage(value) - 0.5) * -yscale);
2150         if(cursor_x >= x1 && 
2151                 cursor_x < x2 &&
2152                 cursor_y >= y - HANDLE_W / 2 && 
2153                 cursor_y < y + HANDLE_W / 2 &&
2154                 !ctrl_down())
2155         {
2156                 result = 1;
2159                 if(buttonpress)
2160                 {
2161                         mwindow->undo->update_undo_before(_("keyframe"), LOAD_AUTOMATION);
2164                         Auto *current;
2165                         current = mwindow->session->drag_auto = autos->insert_auto(position);
2166                         ((FloatAuto*)current)->value = value;
2167                         mwindow->session->drag_start_percentage = current->value_to_percentage();
2168                         mwindow->session->drag_start_position = current->position;
2169                         mwindow->session->drag_origin_x = cursor_x;
2170                         mwindow->session->drag_origin_y = cursor_y;
2171                         mwindow->session->drag_handle = 0;
2173                 }
2174         }
2177         return result;
2180 void TrackCanvas::draw_toggleline(int center_pixel, 
2181         int x1,
2182         int y1,
2183         int x2,
2184         int y2,
2185         int color)
2187         set_color(BLACK);
2188         draw_line(x1, center_pixel + y1 + 1, x2, center_pixel + y1 + 1);
2189         set_color(color);
2190         draw_line(x1, center_pixel + y1, x2, center_pixel + y1);
2192         if(y2 != y1)
2193         {
2194                 set_color(BLACK);
2195                 draw_line(x2 + 1, center_pixel + y1, x2 + 1, center_pixel + y2);
2196                 set_color(color);
2197                 draw_line(x2, center_pixel + y1, x2, center_pixel + y2);
2198         }
2201 int TrackCanvas::test_toggleline(Autos *autos,
2202         int center_pixel, 
2203         int x1,
2204         int y1,
2205         int x2,
2206         int y2, 
2207         int cursor_x, 
2208         int cursor_y, 
2209         int buttonpress)
2211         int result = 0;
2212         if(cursor_x >= x1 && cursor_x < x2)
2213         {
2214                 int miny = center_pixel + y1 - HANDLE_W / 2;
2215                 int maxy = center_pixel + y1 + HANDLE_W / 2;
2216                 if(cursor_y >= miny && cursor_y < maxy) 
2217                 {
2218                         result = 1;
2220                         if(buttonpress)
2221                         {
2222                                 mwindow->undo->update_undo_before(_("keyframe"), LOAD_AUTOMATION);
2225                                 Auto *current;
2226                                 double position = (double)(cursor_x +
2227                                                 mwindow->edl->local_session->view_start) * 
2228                                         mwindow->edl->local_session->zoom_sample / 
2229                                         mwindow->edl->session->sample_rate;
2230                                 int64_t unit_position = autos->track->to_units(position, 0);
2231                                 int new_value = (int)((IntAutos*)autos)->get_automation_constant(unit_position, unit_position);
2233                                 current = mwindow->session->drag_auto = autos->insert_auto(unit_position);
2234                                 ((IntAuto*)current)->value = new_value;
2235                                 mwindow->session->drag_start_percentage = current->value_to_percentage();
2236                                 mwindow->session->drag_start_position = current->position;
2237                                 mwindow->session->drag_origin_x = cursor_x;
2238                                 mwindow->session->drag_origin_y = cursor_y;
2240                         }
2241                 }
2242         }
2243         return result;
2246 void TrackCanvas::calculate_viewport(Track *track, 
2247         double &view_start,   // Seconds
2248         int64_t &unit_start,
2249         double &view_end,     // Seconds
2250         int64_t &unit_end,
2251         double &yscale,
2252         int &center_pixel,
2253         double &zoom_sample,
2254         double &zoom_units)
2256         view_start = (double)mwindow->edl->local_session->view_start * 
2257                 mwindow->edl->local_session->zoom_sample /
2258                 mwindow->edl->session->sample_rate;
2259         unit_start = track->to_units(view_start, 0);
2260         view_end = (double)(mwindow->edl->local_session->view_start + 
2261                 get_w()) * 
2262                 mwindow->edl->local_session->zoom_sample / 
2263                 mwindow->edl->session->sample_rate;
2264         unit_end = (int64_t)(track->to_units(view_end, 1));
2265         yscale = mwindow->edl->local_session->zoom_track;
2266         center_pixel = (int)(track->y_pixel + yscale / 2) + 
2267                 (mwindow->edl->session->show_titles ? 
2268                         mwindow->theme->title_bg_data->get_h() : 
2269                         0);
2270         zoom_sample = mwindow->edl->local_session->zoom_sample;
2272         zoom_units = track->to_doubleunits(zoom_sample / mwindow->edl->session->sample_rate);
2275 int TrackCanvas::do_float_autos(Track *track, 
2276                 Autos *autos, 
2277                 int cursor_x, 
2278                 int cursor_y, 
2279                 int draw, 
2280                 int buttonpress,
2281                 int color)
2283         int result = 0;
2285         double view_start;
2286         int64_t unit_start;
2287         double view_end;
2288         int64_t unit_end;
2289         double yscale;
2290         int center_pixel;
2291         double zoom_sample;
2292         double zoom_units;
2293         double ax, ay, ax2, ay2;
2294         double in_x2, in_y2, out_x2, out_y2;
2295         int draw_auto;
2296         double slope;
2297         int skip = 0;
2299         calculate_viewport(track, 
2300                 view_start,
2301                 unit_start,
2302                 view_end,
2303                 unit_end,
2304                 yscale,
2305                 center_pixel,
2306                 zoom_sample,
2307                 zoom_units);
2311 // Get first auto before start
2312         Auto *current = 0;
2313         Auto *previous = 0;
2314         for(current = autos->last; 
2315                 current && current->position >= unit_start; 
2316                 current = PREVIOUS)
2317                 ;
2319         if(current)
2320         {
2321                 ax = (double)(current->position - unit_start) / zoom_units;
2322                 ay = (((FloatAuto*)current)->value_to_percentage() - 0.5) * -yscale;
2323                 current = NEXT;
2324         }
2325         else
2326         {
2327                 current = autos->first ? autos->first : autos->default_auto;
2328                 if(current)
2329                 {               
2330                         ax = 0;
2331                         ay = (((FloatAuto*)current)->value_to_percentage() - 0.5) * -yscale;
2332                 }
2333                 else
2334                 {
2335                         ax = 0;
2336                         ay = 0;
2337                 }
2338         }
2341 //printf("TrackCanvas::do_float_autos 1\n");
2345         do
2346         {
2347                 skip = 0;
2348                 draw_auto = 1;
2350                 if(current)
2351                 {
2352                         ax2 = (double)(current->position - unit_start) / zoom_units;
2353                         ay2 = (((FloatAuto*)current)->value_to_percentage() - 0.5) * -yscale;
2354                         in_x2 = (double)(current->position + 
2355                                 ((FloatAuto*)current)->control_in_position - 
2356                                 unit_start) / 
2357                                 zoom_units;
2358                         in_y2 = (((FloatAuto*)current)->invalue_to_percentage() - 0.5) * -yscale;
2359                         out_x2 = (double)(current->position + 
2360                                 ((FloatAuto*)current)->control_out_position - 
2361                                 unit_start) / 
2362                                 zoom_units;
2363                         out_y2 = (((FloatAuto*)current)->outvalue_to_percentage() - 0.5) * -yscale;
2364                 }
2365                 else
2366                 {
2367                         ax2 = get_w();
2368                         ay2 = ay;
2369                         skip = 1;
2370                 }
2372                 slope = (ay2 - ay) / (ax2 - ax);
2374                 if(ax2 > get_w())
2375                 {
2376                         draw_auto = 0;
2377                         ax2 = get_w();
2378                         ay2 = ay + slope * (get_w() - ax);
2379                 }
2380                 
2381                 if(ax < 0)
2382                 {
2383                         ay = ay + slope * (0 - ax);
2384                         ax = 0;
2385                 }
2400 // Draw handle
2401                 if(current && !result)
2402                 {
2403                         if(current != autos->default_auto)
2404                         {
2405                                 if(!draw)
2406                                 {
2407                                         if(track->record)
2408                                                 result = test_floatauto(current, 
2409                                                         (int)ax2, 
2410                                                         (int)ay2, 
2411                                                         (int)in_x2,
2412                                                         (int)in_y2,
2413                                                         (int)out_x2,
2414                                                         (int)out_y2,
2415                                                         (int)center_pixel, 
2416                                                         (int)yscale, 
2417                                                         cursor_x, 
2418                                                         cursor_y, 
2419                                                         buttonpress);
2420                                 }
2421                                 else
2422                                 if(draw_auto)
2423                                         draw_floatauto(current, 
2424                                                 (int)ax2, 
2425                                                 (int)ay2, 
2426                                                 (int)in_x2,
2427                                                 (int)in_y2,
2428                                                 (int)out_x2,
2429                                                 (int)out_y2,
2430                                                 (int)center_pixel, 
2431                                                 (int)yscale,
2432                                                 color);
2433                         }
2434                 }
2440 // Draw joining line
2441                 if(!draw)
2442                 {
2443                         if(!result)
2444                         {
2445                                 if(track->record)
2446                                 {
2447                                         result = test_floatline(center_pixel, 
2448                                                 (FloatAutos*)autos,
2449                                                 unit_start,
2450                                                 zoom_units,
2451                                                 yscale,
2452                                                 (int)ax,
2453 // Exclude auto coverage from the end of the line.  The auto overlaps
2454                                                 (int)ax2 - HANDLE_W / 2,
2455                                                 cursor_x, 
2456                                                 cursor_y, 
2457                                                 buttonpress);
2458                                 }
2459                         }
2460                 }
2461                 else
2462                         draw_floatline(center_pixel,
2463                                 (FloatAuto*)previous,
2464                                 (FloatAuto*)current,
2465                                 (FloatAutos*)autos,
2466                                 unit_start,
2467                                 zoom_units,
2468                                 yscale,
2469                                 (int)ax, 
2470                                 (int)ay, 
2471                                 (int)ax2, 
2472                                 (int)ay2,
2473                                 color);
2481                 if(current)
2482                 {
2483                         previous = current;
2484                         current = NEXT;
2485                 }
2489                 ax = ax2;
2490                 ay = ay2;
2491         }while(current && 
2492                 current->position <= unit_end && 
2493                 !result);
2495 //printf("TrackCanvas::do_float_autos 100\n");
2504         if(ax < get_w() && !result)
2505         {
2506                 ax2 = get_w();
2507                 ay2 = ay;
2508                 if(!draw)
2509                 {
2510                         if(track->record)
2511                         {
2512                                 result = test_floatline(center_pixel, 
2513                                         (FloatAutos*)autos,
2514                                         unit_start,
2515                                         zoom_units,
2516                                         yscale,
2517                                         (int)ax,
2518                                         (int)ax2,
2519                                         cursor_x, 
2520                                         cursor_y, 
2521                                         buttonpress);
2522                         }
2523                 }
2524                 else
2525                         draw_floatline(center_pixel, 
2526                                 (FloatAuto*)previous,
2527                                 (FloatAuto*)current,
2528                                 (FloatAutos*)autos,
2529                                 unit_start,
2530                                 zoom_units,
2531                                 yscale,
2532                                 (int)ax, 
2533                                 (int)ay, 
2534                                 (int)ax2, 
2535                                 (int)ay2,
2536                                 color);
2537         }
2546         return result;
2550 int TrackCanvas::do_toggle_autos(Track *track, 
2551                 Autos *autos, 
2552                 int cursor_x, 
2553                 int cursor_y, 
2554                 int draw, 
2555                 int buttonpress,
2556                 int color)
2558         int result = 0;
2559         double view_start;
2560         int64_t unit_start;
2561         double view_end;
2562         int64_t unit_end;
2563         double yscale;
2564         int center_pixel;
2565         double zoom_sample;
2566         double zoom_units;
2567         double ax, ay, ax2, ay2;
2569         calculate_viewport(track, 
2570                 view_start,
2571                 unit_start,
2572                 view_end,
2573                 unit_end,
2574                 yscale,
2575                 center_pixel,
2576                 zoom_sample,
2577                 zoom_units);
2580         double high = -yscale * 0.8 / 2;
2581         double low = yscale * 0.8 / 2;
2583 // Get first auto before start
2584         Auto *current;
2585         for(current = autos->last; current && current->position >= unit_start; current = PREVIOUS)
2586                 ;
2588         if(current)
2589         {
2590                 ax = 0;
2591                 ay = ((IntAuto*)current)->value > 0 ? high : low;
2592                 current = NEXT;
2593         }
2594         else
2595         {
2596                 current = autos->first ? autos->first : autos->default_auto;
2597                 if(current)
2598                 {
2599                         ax = 0;
2600                         ay = ((IntAuto*)current)->value > 0 ? high : low;
2601                 }
2602                 else
2603                 {
2604                         ax = 0;
2605                         ay = yscale;
2606                 }
2607         }
2609         do
2610         {
2611                 if(current)
2612                 {
2613                         ax2 = (double)(current->position - unit_start) / zoom_units;
2614                         ay2 = ((IntAuto*)current)->value > 0 ? high : low;
2615                 }
2616                 else
2617                 {
2618                         ax2 = get_w();
2619                         ay2 = ay;
2620                 }
2622                 if(ax2 > get_w()) ax2 = get_w();
2624             if(current && !result) 
2625                 {
2626                         if(current != autos->default_auto)
2627                         {
2628                                 if(!draw)
2629                                 {
2630                                         if(track->record)
2631                                         {
2632                                                 result = test_auto(current, 
2633                                                         (int)ax2, 
2634                                                         (int)ay2, 
2635                                                         (int)center_pixel, 
2636                                                         (int)yscale, 
2637                                                         cursor_x, 
2638                                                         cursor_y, 
2639                                                         buttonpress);
2640                                         }
2641                                 }
2642                                 else
2643                                         draw_auto(current, 
2644                                                 (int)ax2, 
2645                                                 (int)ay2, 
2646                                                 (int)center_pixel, 
2647                                                 (int)yscale,
2648                                                 color);
2649                         }
2651                         current = NEXT;
2652                 }
2654                 if(!draw)
2655                 {
2656                         if(!result)
2657                         {
2658                                 if(track->record)
2659                                 {
2660                                         result = test_toggleline(autos, 
2661                                                 center_pixel, 
2662                                                 (int)ax, 
2663                                                 (int)ay, 
2664                                                 (int)ax2, 
2665                                                 (int)ay2,
2666                                                 cursor_x, 
2667                                                 cursor_y, 
2668                                                 buttonpress);
2669                                 }
2670                         }
2671                 }
2672                 else
2673                         draw_toggleline(center_pixel, 
2674                                 (int)ax, 
2675                                 (int)ay, 
2676                                 (int)ax2, 
2677                                 (int)ay2,
2678                                 color);
2680                 ax = ax2;
2681                 ay = ay2;
2682         }while(current && current->position <= unit_end && !result);
2684         if(ax < get_w() && !result)
2685         {
2686                 ax2 = get_w();
2687                 ay2 = ay;
2688                 if(!draw)
2689                 {
2690                         if(track->record)
2691                         {
2692                                 result = test_toggleline(autos,
2693                                         center_pixel, 
2694                                         (int)ax, 
2695                                         (int)ay, 
2696                                         (int)ax2, 
2697                                         (int)ay2,
2698                                         cursor_x, 
2699                                         cursor_y, 
2700                                         buttonpress);
2701                         }
2702                 }
2703                 else
2704                         draw_toggleline(center_pixel, 
2705                                 (int)ax, 
2706                                 (int)ay, 
2707                                 (int)ax2, 
2708                                 (int)ay2,
2709                                 color);
2710         }
2711         return result;
2714 int TrackCanvas::do_autos(Track *track, 
2715                 Autos *autos, 
2716                 int cursor_x, 
2717                 int cursor_y, 
2718                 int draw, 
2719                 int buttonpress,
2720                 BC_Pixmap *pixmap)
2722         int result = 0;
2724         double view_start;
2725         int64_t unit_start;
2726         double view_end;
2727         int64_t unit_end;
2728         double yscale;
2729         int center_pixel;
2730         double zoom_sample;
2731         double zoom_units;
2733         calculate_viewport(track, 
2734                 view_start,
2735                 unit_start,
2736                 view_end,
2737                 unit_end,
2738                 yscale,
2739                 center_pixel,
2740                 zoom_sample,
2741                 zoom_units);
2743         Auto *current;
2745         for(current = autos->first; current && !result; current = NEXT)
2746         {
2747                 if(current->position >= unit_start && current->position < unit_end)
2748                 {
2749                         int64_t x, y;
2750                         x = (int64_t)((double)(current->position - unit_start) / 
2751                                 zoom_units - (pixmap->get_w() / 2 + 0.5));
2752                         y = center_pixel - pixmap->get_h() / 2;
2754                         if(!draw)
2755                         {
2756                                 if(cursor_x >= x && cursor_y >= y &&
2757                                         cursor_x < x + pixmap->get_w() &&
2758                                         cursor_y < y + pixmap->get_h())
2759                                 {
2760                                         result = 1;
2762                                         if(buttonpress)
2763                                         {
2764                                                 mwindow->session->drag_auto = current;
2765                                                 mwindow->session->drag_start_position = current->position;
2766                                                 mwindow->session->drag_origin_x = cursor_x;
2767                                                 mwindow->session->drag_origin_y = cursor_y;
2769                                                 double position = autos->track->from_units(current->position);
2770                                                 double center = (mwindow->edl->local_session->selectionstart +
2771                                                         mwindow->edl->local_session->selectionend) / 
2772                                                         2;
2774                                                 if(!shift_down())
2775                                                 {
2776                                                         mwindow->edl->local_session->selectionstart = position;
2777                                                         mwindow->edl->local_session->selectionend = position;
2778                                                 }
2779                                                 else
2780                                                 if(position < center)
2781                                                 {
2782                                                         mwindow->edl->local_session->selectionstart = position;
2783                                                 }
2784                                                 else
2785                                                         mwindow->edl->local_session->selectionend = position;
2786                                         }
2787                                 }
2788                         }
2789                         else
2790                                 draw_pixmap(pixmap, x, y);
2791                 }
2792         }
2793         return result;
2796 int TrackCanvas::do_plugin_autos(Track *track, 
2797                 int cursor_x, 
2798                 int cursor_y, 
2799                 int draw, 
2800                 int buttonpress)
2802         int result = 0;
2804         double view_start;
2805         int64_t unit_start;
2806         double view_end;
2807         int64_t unit_end;
2808         double yscale;
2809         int center_pixel;
2810         double zoom_sample;
2811         double zoom_units;
2813         calculate_viewport(track, 
2814                 view_start,
2815                 unit_start,
2816                 view_end,
2817                 unit_end,
2818                 yscale,
2819                 center_pixel,
2820                 zoom_sample,
2821                 zoom_units);
2823 //printf("TrackCanvas::draw_plugin_autos 1 %d\n", track->plugin_set.total);
2824         for(int i = 0; i < track->plugin_set.total && !result; i++)
2825         {
2826                 PluginSet *plugin_set = track->plugin_set.values[i];
2827                 int center_pixel = (int)(track->y_pixel + 
2828                         mwindow->edl->local_session->zoom_track +
2829                         (i + 0.5) * mwindow->theme->plugin_bg_data->get_h() + 
2830                         (mwindow->edl->session->show_titles ? mwindow->theme->title_bg_data->get_h() : 0));
2831                 
2832 //printf("TrackCanvas::draw_plugin_autos 2\n");
2833                 for(Plugin *plugin = (Plugin*)plugin_set->first; 
2834                         plugin && !result; 
2835                         plugin = (Plugin*)plugin->next)
2836                 {
2837                         for(KeyFrame *keyframe = (KeyFrame*)plugin->keyframes->first; 
2838                                 keyframe && !result; 
2839                                 keyframe = (KeyFrame*)keyframe->next)
2840                         {
2841 //printf("TrackCanvas::draw_plugin_autos 3 %d\n", keyframe->position);
2842                                 if(keyframe->position >= unit_start && keyframe->position < unit_end)
2843                                 {
2844                                         int64_t x = (int64_t)((keyframe->position - unit_start) / zoom_units);
2845                                         int y = center_pixel - keyframe_pixmap->get_h() / 2;
2847 //printf("TrackCanvas::draw_plugin_autos 4 %d %d\n", x, center_pixel);
2848                                         if(!draw)
2849                                         {
2850                                                 if(cursor_x >= x && cursor_y >= y &&
2851                                                         cursor_x < x + keyframe_pixmap->get_w() &&
2852                                                         cursor_y < y + keyframe_pixmap->get_h())
2853                                                 {
2854                                                         result = 1;
2856                                                         if(buttonpress)
2857                                                         {
2858                                                                 mwindow->session->drag_auto = keyframe;
2859                                                                 mwindow->session->drag_start_position = keyframe->position;
2860                                                                 mwindow->session->drag_origin_x = cursor_x;
2861                                                                 mwindow->session->drag_origin_y = cursor_y;
2863                                                                 double position = track->from_units(keyframe->position);
2864                                                                 double center = (mwindow->edl->local_session->selectionstart +
2865                                                                         mwindow->edl->local_session->selectionend) / 
2866                                                                         2;
2868                                                                 if(!shift_down())
2869                                                                 {
2870                                                                         mwindow->edl->local_session->selectionstart = position;
2871                                                                         mwindow->edl->local_session->selectionend = position;
2872                                                                 }
2873                                                                 else
2874                                                                 if(position < center)
2875                                                                 {
2876                                                                         mwindow->edl->local_session->selectionstart = position;
2877                                                                 }
2878                                                                 else
2879                                                                         mwindow->edl->local_session->selectionend = position;
2880                                                         }
2881                                                 }
2882                                         }
2883                                         else
2884                                                 draw_pixmap(keyframe_pixmap, 
2885                                                         x, 
2886                                                         y);
2887                                 }
2888                         }
2889                 }
2890         }
2891 //printf("TrackCanvas::draw_plugin_autos 5\n");
2892         return result;
2895 void TrackCanvas::draw_overlays()
2897         int new_cursor, update_cursor, rerender;
2898 TRON("TrackCanvas::draw_overlays")
2900 // Move background pixmap to foreground pixmap
2901         draw_pixmap(background_pixmap, 
2902                 0, 
2903                 0,
2904                 get_w(),
2905                 get_h(),
2906                 0,
2907                 0);
2908 TROFF("TrackCanvas::draw_overlays")
2910 //printf("TrackCanvas::draw_overlays 4\n");
2911 // In/Out points
2912         draw_inout_points();
2914 //printf("TrackCanvas::draw_overlays 5\n");
2915 // Transitions
2916         if(mwindow->edl->session->auto_conf->transitions) draw_transitions();
2918 //printf("TrackCanvas::draw_overlays 6\n");
2919 // Plugins
2920         draw_plugins();
2922 //printf("TrackCanvas::draw_overlays 2\n");
2923 // Loop points
2924         draw_loop_points();
2925         draw_brender_start();
2927 //printf("TrackCanvas::draw_overlays 7\n");
2928 // Highlighted areas
2929         draw_highlighting();
2931 //printf("TrackCanvas::draw_overlays 8\n");
2932 // Automation
2933         do_keyframes(0, 
2934                 0, 
2935                 1, 
2936                 0, 
2937                 new_cursor, 
2938                 update_cursor,
2939                 rerender);
2941 //printf("TrackCanvas::draw_overlays 9\n");
2942 // Selection cursor
2943         if(gui->cursor) gui->cursor->restore();
2945 //printf("TrackCanvas::draw_overlays 10\n");
2946 // Handle dragging
2947         draw_drag_handle();
2949 //printf("TrackCanvas::draw_overlays 11\n");
2950 // Playback cursor
2951         draw_playback_cursor();
2955 int TrackCanvas::activate()
2957         if(!active)
2958         {
2959                 get_top_level()->deactivate();
2960                 active = 1;
2961                 set_active_subwindow(this);
2962                 gui->cursor->activate();
2963         }
2964         return 0;
2967 int TrackCanvas::deactivate()
2969         if(active)
2970         {
2971                 active = 0;
2972                 gui->cursor->deactivate();
2973         }
2974         return 0;
2978 void TrackCanvas::update_drag_handle()
2980         double new_position;
2982         new_position = 
2983                 (double)(get_cursor_x() + mwindow->edl->local_session->view_start) *
2984                 mwindow->edl->local_session->zoom_sample /
2985                 mwindow->edl->session->sample_rate;
2986         new_position = 
2987                 mwindow->edl->align_to_frame(new_position, 0);
2990         if(new_position != mwindow->session->drag_position)
2991         {
2992                 mwindow->session->drag_position = new_position;
2993                 gui->mainclock->update(new_position);
2994 // Que the CWindow.  Doesn't do anything if selectionstart and selection end 
2995 // aren't changed.
2996 //              mwindow->cwindow->update(1, 0, 0);
2997         }
3000 int TrackCanvas::update_drag_edit()
3002         int result = 0;
3003         
3004         
3005         
3006         return result;
3009 #define UPDATE_DRAG_HEAD(do_clamp) \
3010         int result = 0; \
3011         int x = cursor_x - mwindow->session->drag_origin_x; \
3012         int y = cursor_y - mwindow->session->drag_origin_y; \
3014         if(!current->autos->track->record) return 0; \
3015         double view_start; \
3016         int64_t unit_start; \
3017         double view_end; \
3018         int64_t unit_end; \
3019         double yscale; \
3020         int center_pixel; \
3021         double zoom_sample; \
3022         double zoom_units; \
3024         mwindow->undo->update_undo_before(_("tweek"), LOAD_AUTOMATION); \
3025         calculate_viewport(current->autos->track,  \
3026                 view_start, \
3027                 unit_start, \
3028                 view_end, \
3029                 unit_end, \
3030                 yscale, \
3031                 center_pixel, \
3032                 zoom_sample, \
3033                 zoom_units); \
3035         float percentage = (float)(mwindow->session->drag_origin_y - cursor_y) / \
3036                 MAX(128, yscale) +  \
3037                 mwindow->session->drag_start_percentage; \
3038         if(do_clamp) CLAMP(percentage, 0, 1); \
3040         int64_t position = Units::to_int64(zoom_units * \
3041                 (cursor_x - mwindow->session->drag_origin_x) + \
3042                 mwindow->session->drag_start_position); \
3044         if((do_clamp) && position < 0) position = 0;
3054 int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y)
3056         FloatAuto *current = (FloatAuto*)mwindow->session->drag_auto;
3058         UPDATE_DRAG_HEAD(mwindow->session->drag_handle == 0);
3060         float value;
3061 //printf("TrackCanvas::update_drag_floatauto %ld %d\n", 
3062 //position, 
3063 //mwindow->session->drag_handle);
3065         switch(mwindow->session->drag_handle)
3066         {
3067 // Center
3068                 case 0:
3069 // Snap to nearby values
3070                         if(shift_down())
3071                         {
3072                                 if(current->previous)
3073                                         value = ((FloatAuto*)current->previous)->value;
3074                                 else
3075                                 if(current->next)
3076                                         value = ((FloatAuto*)current->next)->value;
3077                                 else
3078                                         value = ((FloatAutos*)current->autos)->default_;
3079                         }
3080                         else
3081                                 value = ((FloatAuto*)current)->percentage_to_value(percentage);
3083 //printf("TrackCanvas::update_drag_floatauto 1 %f\n", value);
3084                         if(value != current->value || position != current->position)
3085                         {
3086                                 result = 1;
3087                                 current->value = value;
3088                                 current->position = position;
3090                                 char string[BCTEXTLEN], string2[BCTEXTLEN];
3091                                 Units::totext(string2, 
3092                                         current->autos->track->from_units(current->position),
3093                                         mwindow->edl->session->time_format,
3094                                         mwindow->edl->session->sample_rate,
3095                                         mwindow->edl->session->frame_rate,
3096                                         mwindow->edl->session->frames_per_foot);
3097                                 sprintf(string, "%s, %.2f", string2, current->value);
3098                                 gui->show_message(string);
3099                         }
3100                         break;
3102 // In control
3103                 case 1:
3104                         value = ((FloatAuto*)current)->percentage_to_invalue(percentage);
3105                         position = MIN(0, position);
3106                         if(value != current->control_in_value || 
3107                                 position != current->control_in_position)
3108                         {
3109                                 result = 1;
3110                                 current->control_in_value = value;
3111                                 current->control_in_position = position;
3113                                 char string[BCTEXTLEN], string2[BCTEXTLEN];
3114                                 Units::totext(string2, 
3115                                         current->autos->track->from_units(current->control_in_position),
3116                                         mwindow->edl->session->time_format,
3117                                         mwindow->edl->session->sample_rate,
3118                                         mwindow->edl->session->frame_rate,
3119                                         mwindow->edl->session->frames_per_foot);
3120                                 sprintf(string, "%s, %.2f", string2, current->control_in_value);
3121                                 gui->show_message(string);
3122                         }
3123                         break;
3125 // Out control
3126                 case 2:
3127                         value = ((FloatAuto*)current)->percentage_to_outvalue(percentage);
3128                         position = MAX(0, position);
3129                         if(value != current->control_out_value || 
3130                                 position != current->control_out_position)
3131                         {
3132                                 result = 1;
3133                                 ((FloatAuto*)current)->control_out_value = value;
3134                                 ((FloatAuto*)current)->control_out_position = position;
3136                                 char string[BCTEXTLEN], string2[BCTEXTLEN];
3137                                 Units::totext(string2, 
3138                                         current->autos->track->from_units(
3139                                                 ((FloatAuto*)current)->control_out_position),
3140                                         mwindow->edl->session->time_format,
3141                                         mwindow->edl->session->sample_rate,
3142                                         mwindow->edl->session->frame_rate,
3143                                         mwindow->edl->session->frames_per_foot);
3144                                 sprintf(string, "%s, %.2f", 
3145                                         string2, 
3146                                         ((FloatAuto*)current)->control_out_value);
3147                                 gui->show_message(string);
3148                         }
3149                         break;
3150         }
3152         return result;
3155 int TrackCanvas::update_drag_toggleauto(int cursor_x, int cursor_y)
3157         IntAuto *current = (IntAuto*)mwindow->session->drag_auto;
3159         UPDATE_DRAG_HEAD(1);
3161         int value = ((IntAuto*)current)->percentage_to_value(percentage);
3163         if(value != current->value || position != current->position)
3164         {
3165                 result = 1;
3166                 current->value = value;
3167                 current->position = position;
3169                 char string[BCTEXTLEN], string2[BCTEXTLEN];
3170                 Units::totext(string2, 
3171                         current->autos->track->from_units(current->position),
3172                         mwindow->edl->session->time_format,
3173                         mwindow->edl->session->sample_rate,
3174                         mwindow->edl->session->frame_rate,
3175                         mwindow->edl->session->frames_per_foot);
3176                 sprintf(string, "%s, %d", string2, current->value);
3177                 gui->show_message(string);
3178         }
3180         return result;
3183 // Autos which can't change value through dragging.
3185 int TrackCanvas::update_drag_auto(int cursor_x, int cursor_y)
3187         Auto *current = (Auto*)mwindow->session->drag_auto;
3189         UPDATE_DRAG_HEAD(1)
3191         if(position != current->position)
3192         {
3193                 result = 1;
3194                 current->position = position;
3196                 char string[BCTEXTLEN];
3197                 Units::totext(string, 
3198                         current->autos->track->from_units(current->position),
3199                         mwindow->edl->session->time_format,
3200                         mwindow->edl->session->sample_rate,
3201                         mwindow->edl->session->frame_rate,
3202                         mwindow->edl->session->frames_per_foot);
3203                 gui->show_message(string);
3205                 double position_f = current->autos->track->from_units(current->position);
3206                 double center_f = (mwindow->edl->local_session->selectionstart +
3207                         mwindow->edl->local_session->selectionend) / 
3208                         2;
3209                 if(!shift_down())
3210                 {
3211                         mwindow->edl->local_session->selectionstart = position_f;
3212                         mwindow->edl->local_session->selectionend = position_f;
3213                 }
3214                 else
3215                 if(position_f < center_f)
3216                 {
3217                         mwindow->edl->local_session->selectionstart = position_f;
3218                 }
3219                 else
3220                         mwindow->edl->local_session->selectionend = position_f;
3221         }
3224         return result;
3227 void TrackCanvas::update_drag_caption()
3229         switch(mwindow->session->current_operation)
3230         {
3231                 case DRAG_FADE:
3232                         
3233                         break;
3234         }
3239 int TrackCanvas::cursor_motion_event()
3241         int result, cursor_x, cursor_y;
3242         int update_clock = 0;
3243         int update_zoom = 0;
3244         int update_scroll = 0;
3245         int update_overlay = 0;
3246         int update_cursor = 0;
3247         int new_cursor = 0;
3248         int rerender = 0;
3249         double position = 0;
3250 //printf("TrackCanvas::cursor_motion_event 1 %f\n", mwindow->edl->local_session->selectionstart);
3251         result = 0;
3253 // Default cursor
3254         switch(mwindow->edl->session->editing_mode)
3255         {
3256                 case EDITING_ARROW: new_cursor = ARROW_CURSOR; break;
3257                 case EDITING_IBEAM: new_cursor = IBEAM_CURSOR; break;
3258         }
3260         switch(mwindow->session->current_operation)
3261         {
3262                 case DRAG_EDITHANDLE1:
3263 // Outside threshold.  Upgrade status
3264 //printf("TrackCanvas::cursor_motion_event 1\n");
3265                         if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3266                         {
3267 //printf("TrackCanvas::cursor_motion_event 2\n");
3268                                 mwindow->session->current_operation = DRAG_EDITHANDLE2;
3269                                 update_overlay = 1;
3270                         }
3271                         break;
3273                 case DRAG_EDITHANDLE2:
3274                         update_drag_handle();
3275                         update_overlay = 1;
3276                         break;
3278                 case DRAG_PLUGINHANDLE1:
3279                         if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3280                         {
3281 //printf("TrackCanvas::cursor_motion_event 2\n");
3282                                 mwindow->session->current_operation = DRAG_PLUGINHANDLE2;
3283                                 update_overlay = 1;
3284                         }
3285                         break;
3287                 case DRAG_PLUGINHANDLE2:
3288                         update_drag_handle();
3289                         update_overlay = 1;
3290                         break;
3292 // Rubber band curves
3293                 case DRAG_FADE:
3294                         rerender = update_overlay = update_drag_floatauto(get_cursor_x(), get_cursor_y());
3295                         break;
3297                 case DRAG_CZOOM:
3298                         rerender = update_overlay = update_drag_floatauto(get_cursor_x(), get_cursor_y());
3299                         break;
3301                 case DRAG_PZOOM:
3302                         rerender = update_overlay = update_drag_floatauto(get_cursor_x(), get_cursor_y());
3303                         break;
3305                 case DRAG_PLAY:
3306                         rerender = update_overlay = update_drag_toggleauto(get_cursor_x(), get_cursor_y());
3307                         break;
3309                 case DRAG_MUTE:
3310                         rerender = update_overlay = update_drag_toggleauto(get_cursor_x(), get_cursor_y());
3311                         break;
3313 // Keyframe icons are sticky
3314                 case DRAG_PAN_PRE:
3315                 case DRAG_CAMERA_PRE:
3316                 case DRAG_MASK_PRE:
3317                 case DRAG_MODE_PRE:
3318                 case DRAG_PROJECTOR_PRE:
3319                 case DRAG_PLUGINKEY_PRE:
3320                         if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
3321                         {
3322 //printf("TrackCanvas::cursor_motion_event 2\n");
3323                                 mwindow->session->current_operation++;
3324                                 update_overlay = 1;
3325                         }
3326                         break;
3328                 case DRAG_PAN:
3329                 case DRAG_CAMERA:
3330                 case DRAG_MASK:
3331                 case DRAG_MODE:
3332                 case DRAG_PROJECTOR:
3333                 case DRAG_PLUGINKEY:
3334                         rerender = update_overlay = 
3335                                 update_drag_auto(get_cursor_x(), get_cursor_y());
3336                         break;
3338                 case SELECT_REGION:
3339                 {
3340                         cursor_x = get_cursor_x();
3341                         cursor_y = get_cursor_y();
3342                         position = (double)(cursor_x + mwindow->edl->local_session->view_start) * 
3343                                 mwindow->edl->local_session->zoom_sample /
3344                                 mwindow->edl->session->sample_rate;
3346                         position = mwindow->edl->align_to_frame(position, 0);
3347                         position = MAX(position, 0);
3349                         if(position < selection_midpoint1)
3350                         {
3351                                 mwindow->edl->local_session->selectionend = selection_midpoint1;
3352                                 mwindow->edl->local_session->selectionstart = position;
3353 // Que the CWindow
3354                                 mwindow->cwindow->update(1, 0, 0, 0, 1);
3355 // Update the faders
3356                                 mwindow->update_plugin_guis();
3357                                 gui->patchbay->update();
3358                         }
3359                         else
3360                         {
3361                                 mwindow->edl->local_session->selectionstart = selection_midpoint1;
3362                                 mwindow->edl->local_session->selectionend = position;
3363 // Don't que the CWindow
3364                         }
3365 //printf("TrackCanvas::cursor_motion_event 1 %f %f %f\n", position, mwindow->edl->local_session->selectionstart, mwindow->edl->local_session->selectionend);
3367                         gui->cursor->hide();
3368                         gui->cursor->draw();
3369                         flash();
3370                         result = 1;
3371                         update_clock = 1;
3372                         update_zoom = 1;
3373                         update_scroll = 1;
3374                         break;
3375                 }
3377                 default:
3378                         if(is_event_win() && cursor_inside())
3379                         {
3380 // Update clocks
3381                                 cursor_x = get_cursor_x();
3382                                 position = (double)cursor_x * 
3383                                         (double)mwindow->edl->local_session->zoom_sample / 
3384                                         (double)mwindow->edl->session->sample_rate + 
3385                                         (double)mwindow->edl->local_session->view_start * 
3386                                         (double)mwindow->edl->local_session->zoom_sample / 
3387                                         (double)mwindow->edl->session->sample_rate;
3388                                 position = mwindow->edl->align_to_frame(position, 0);
3389                                 update_clock = 1;
3391 // Update cursor
3392                                 if(mwindow->edl->session->auto_conf->transitions && 
3393                                         test_transitions(get_cursor_x(), 
3394                                                 get_cursor_y(), 
3395                                                 0, 
3396                                                 new_cursor, 
3397                                                 update_cursor))
3398                                 {
3399                                         break;
3400                                 }
3401                                 else
3402 // Update cursor
3403                                 if(do_keyframes(get_cursor_x(), 
3404                                         get_cursor_y(), 
3405                                         0, 
3406                                         0, 
3407                                         new_cursor,
3408                                         update_cursor,
3409                                         rerender))
3410                                 {
3411                                         break;
3412                                 }
3413                                 else
3414 // Edit boundaries
3415                                 if(test_edit_handles(get_cursor_x(), 
3416                                         get_cursor_y(), 
3417                                         0, 
3418                                         new_cursor,
3419                                         update_cursor))
3420                                 {
3421                                         break;
3422                                 }
3423                                 else
3424 // Plugin boundaries
3425                                 if(test_plugin_handles(get_cursor_x(), 
3426                                         get_cursor_y(), 
3427                                         0, 
3428                                         new_cursor,
3429                                         update_cursor))
3430                                 {
3431                                         break;
3432                                 }
3433                                 else
3434                                 if(test_edits(get_cursor_x(), 
3435                                         get_cursor_y(), 
3436                                         0, 
3437                                         0, 
3438                                         update_overlay, 
3439                                         rerender,
3440                                         new_cursor,
3441                                         update_cursor))
3442                                 {
3443                                         break;
3444                                 }
3445                         }
3446                         break;
3447         }
3449 //printf("TrackCanvas::cursor_motion_event 1\n");
3450         if(update_cursor && new_cursor != get_cursor())
3451         {
3452                 set_cursor(new_cursor);
3453         }
3455 //printf("TrackCanvas::cursor_motion_event 1 %d\n", rerender);
3456         if(rerender)
3457         {
3458                 mwindow->restart_brender();
3459                 mwindow->sync_parameters(CHANGE_PARAMS);
3460                 mwindow->update_plugin_guis();
3461                 mwindow->cwindow->update(1, 0, 0, 0, 1);
3462 // Update faders
3463                 gui->patchbay->update();
3464         }
3467         if(update_clock)
3468         {
3469                 if(!mwindow->cwindow->playback_engine->is_playing_back)
3470                         gui->mainclock->update(position);
3471         }
3473         if(update_zoom)
3474         {
3475                 gui->zoombar->update();
3476         }
3478         if(update_scroll)
3479         {
3480                 if(!drag_scroll && 
3481                         (cursor_x >= get_w() || cursor_x < 0 || cursor_y >= get_h() || cursor_y < 0))
3482                         start_dragscroll();
3483                 else
3484                 if(drag_scroll &&
3485                         (cursor_x < get_w() && cursor_x >= 0 && cursor_y < get_h() && cursor_y >= 0))
3486                         stop_dragscroll();
3487         }
3489         if(update_overlay)
3490         {
3491                 draw_overlays();
3492                 flash();
3493         }
3494 //printf("TrackCanvas::cursor_motion_event 100 %f\n", mwindow->edl->local_session->selectionstart);
3495         return result;
3498 void TrackCanvas::start_dragscroll()
3500         if(!drag_scroll)
3501         {
3502                 drag_scroll = 1;
3503                 set_repeat(BC_WindowBase::get_resources()->scroll_repeat);
3504 //printf("TrackCanvas::start_dragscroll 1\n");
3505         }
3508 void TrackCanvas::stop_dragscroll()
3510         if(drag_scroll)
3511         {
3512                 drag_scroll = 0;
3513                 unset_repeat(BC_WindowBase::get_resources()->scroll_repeat);
3514 //printf("TrackCanvas::stop_dragscroll 1\n");
3515         }
3518 int TrackCanvas::repeat_event(int64_t duration)
3520         if(!drag_scroll) return 0;
3521         if(duration != BC_WindowBase::get_resources()->scroll_repeat) return 0;
3523         int sample_movement = 0;
3524         int track_movement = 0;
3525         int64_t x_distance = 0;
3526         int64_t y_distance = 0;
3527         double position = 0;
3528         int result = 0;
3530         switch(mwindow->session->current_operation)
3531         {
3532                 case SELECT_REGION:
3533 //printf("TrackCanvas::repeat_event 1 %d\n", mwindow->edl->local_session->view_start);
3534                         if(get_cursor_x() > get_w())
3535                         {
3536                                 x_distance = get_cursor_x() - get_w();
3537                                 sample_movement = 1;
3538                         }
3539                         else
3540                         if(get_cursor_x() < 0)
3541                         {
3542                                 x_distance = get_cursor_x();
3543                                 sample_movement = 1;
3544                         }
3546                         if(get_cursor_y() > get_h())
3547                         {
3548                                 y_distance = get_cursor_y() - get_h();
3549                                 track_movement = 1;
3550                         }
3551                         else
3552                         if(get_cursor_y() < 0)
3553                         {
3554                                 y_distance = get_cursor_y();
3555                                 track_movement = 1;
3556                         }
3557                         result = 1;
3558                         break;
3559         }
3562         if(sample_movement)
3563         {
3564                 position = (double)(get_cursor_x() + 
3565                         mwindow->edl->local_session->view_start + 
3566                         x_distance) * 
3567                         mwindow->edl->local_session->zoom_sample /
3568                         mwindow->edl->session->sample_rate;
3569                 position = mwindow->edl->align_to_frame(position, 0);
3570                 position = MAX(position, 0);
3572 //printf("TrackCanvas::repeat_event 1 %f\n", position);
3573                 switch(mwindow->session->current_operation)
3574                 {
3575                         case SELECT_REGION:
3576                                 if(position < selection_midpoint1)
3577                                 {
3578                                         mwindow->edl->local_session->selectionend = selection_midpoint1;
3579                                         mwindow->edl->local_session->selectionstart = position;
3580 // Que the CWindow
3581                                         mwindow->cwindow->update(1, 0, 0);
3582 // Update the faders
3583                                         mwindow->update_plugin_guis();
3584                                         gui->patchbay->update();
3585                                 }
3586                                 else
3587                                 {
3588                                         mwindow->edl->local_session->selectionstart = selection_midpoint1;
3589                                         mwindow->edl->local_session->selectionend = position;
3590 // Don't que the CWindow
3591                                 }
3592                                 break;
3593                 }
3595                 mwindow->samplemovement(mwindow->edl->local_session->view_start + 
3596                         x_distance);
3597         }
3599         if(track_movement)
3600         {
3601                 mwindow->trackmovement(mwindow->edl->local_session->track_start + 
3602                         y_distance);
3603         }
3605         return result;
3608 int TrackCanvas::button_release_event()
3610         int redraw = 0, update_overlay = 0, result = 0;
3612         switch(mwindow->session->current_operation)
3613         {
3614                 case DRAG_EDITHANDLE2:
3615                         mwindow->session->current_operation = NO_OPERATION;
3616                         drag_scroll = 0;
3617                         result = 1;
3618                         
3619                         end_edithandle_selection();
3620                         break;
3622                 case DRAG_EDITHANDLE1:
3623                         mwindow->session->current_operation = NO_OPERATION;
3624                         drag_scroll = 0;
3625                         result = 1;
3626                         break;
3628                 case DRAG_PLUGINHANDLE2:
3629                         mwindow->session->current_operation = NO_OPERATION;
3630                         drag_scroll = 0;
3631                         result = 1;
3632                         
3633                         end_pluginhandle_selection();
3634                         break;
3636                 case DRAG_PLUGINHANDLE1:
3637                         mwindow->session->current_operation = NO_OPERATION;
3638                         drag_scroll = 0;
3639                         result = 1;
3640                         break;
3642                 case DRAG_FADE:
3643                 case DRAG_CZOOM:
3644                 case DRAG_PZOOM:
3645                 case DRAG_PLAY:
3646                 case DRAG_MUTE:
3647                 case DRAG_MASK:
3648                 case DRAG_MODE:
3649                 case DRAG_PAN:
3650                 case DRAG_CAMERA:
3651                 case DRAG_PROJECTOR:
3652                 case DRAG_PLUGINKEY:
3653                         mwindow->session->current_operation = NO_OPERATION;
3654                         mwindow->session->drag_handle = 0;
3655 // Remove any out-of-order keyframe
3656                         if(mwindow->session->drag_auto)
3657                         {
3658                                 mwindow->session->drag_auto->autos->remove_nonsequential(
3659                                         mwindow->session->drag_auto);
3660 //                              mwindow->session->drag_auto->autos->optimize();
3661                                 update_overlay = 1;
3662                         }
3663                         mwindow->undo->update_undo_after();
3664                         result = 1;
3665                         break;
3667                 case DRAG_EDIT:
3668                 case DRAG_AEFFECT_COPY:
3669                 case DRAG_VEFFECT_COPY:
3670 // Trap in drag stop
3672                         break;
3675                 default:
3676                         if(mwindow->session->current_operation)
3677                         {
3678                                 mwindow->session->current_operation = NO_OPERATION;
3679                                 drag_scroll = 0;
3680 // Traps button release events
3681 //                              result = 1;
3682                         }
3683                         break;
3684         }
3686         if(update_overlay)
3687         {
3688                 draw_overlays();
3689                 flash();
3690         }
3691         if(redraw)
3692         {
3693                 draw();
3694                 flash();
3695         }
3696         return result;
3699 int TrackCanvas::test_edit_handles(int cursor_x, 
3700         int cursor_y, 
3701         int button_press, 
3702         int &new_cursor,
3703         int &update_cursor)
3705         Edit *edit_result = 0;
3706         int handle_result = 0;
3707         int result = 0;
3709         for(Track *track = mwindow->edl->tracks->first;
3710                 track && !result;
3711                 track = track->next)
3712         {
3713                 for(Edit *edit = track->edits->first;
3714                         edit && !result;
3715                         edit = edit->next)
3716                 {
3717                         int64_t edit_x, edit_y, edit_w, edit_h;
3718                         edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
3720                         if(cursor_x >= edit_x && cursor_x < edit_x + edit_w &&
3721                                 cursor_y >= edit_y && cursor_y < edit_y + edit_h)
3722                         {
3723                                 if(cursor_x < edit_x + HANDLE_W)
3724                                 {
3725                                         edit_result = edit;
3726                                         handle_result = 0;
3727                                         result = 1;
3728                                 }
3729                                 else
3730                                 if(cursor_x >= edit_x + edit_w - HANDLE_W)
3731                                 {
3732                                         edit_result = edit;
3733                                         handle_result = 1;
3734                                         result = 1;
3735                                 }
3736                                 else
3737                                 {
3738                                         result = 0;
3739                                 }
3740                         }
3741                 }
3742         }
3744         update_cursor = 1;
3745         if(result)
3746         {
3747                 double position;
3748                 if(handle_result == 0)
3749                 {
3750                         position = edit_result->track->from_units(edit_result->startproject);
3751                         new_cursor = LEFT_CURSOR;
3752                 }
3753                 else
3754                 if(handle_result == 1)
3755                 {
3756                         position = edit_result->track->from_units(edit_result->startproject + edit_result->length);
3757                         new_cursor = RIGHT_CURSOR;
3758                 }
3760 // Reposition cursor
3761                 if(button_press)
3762                 {
3763                         mwindow->session->drag_edit = edit_result;
3764                         mwindow->session->drag_handle = handle_result;
3765                         mwindow->session->drag_button = get_buttonpress() - 1;
3766                         mwindow->session->drag_position = position;
3767                         mwindow->session->current_operation = DRAG_EDITHANDLE1;
3768                         mwindow->session->drag_origin_x = get_cursor_x();
3769                         mwindow->session->drag_origin_y = get_cursor_y();
3770                         mwindow->session->drag_start = position;
3772                         int rerender = start_selection(position);
3773                         if(rerender)
3774                                 mwindow->cwindow->update(1, 0, 0);
3775                         gui->timebar->update_highlights();
3776                         gui->zoombar->update();
3777                         gui->cursor->hide();
3778                         gui->cursor->draw();
3779                         draw_overlays();
3780                         flash();
3781                         flush();
3782                 }
3783         }
3785         return result;
3788 int TrackCanvas::test_plugin_handles(int cursor_x, 
3789         int cursor_y, 
3790         int button_press,
3791         int &new_cursor,
3792         int &update_cursor)
3794         Plugin *plugin_result = 0;
3795         int handle_result = 0;
3796         int result = 0;
3797         
3798         for(Track *track = mwindow->edl->tracks->first;
3799                 track && !result;
3800                 track = track->next)
3801         {
3802                 for(int i = 0; i < track->plugin_set.total && !result; i++)
3803                 {
3804                         PluginSet *plugin_set = track->plugin_set.values[i];
3805                         for(Plugin *plugin = (Plugin*)plugin_set->first; 
3806                                 plugin && !result; 
3807                                 plugin = (Plugin*)plugin->next)
3808                         {
3809                                 int64_t plugin_x, plugin_y, plugin_w, plugin_h;
3810                                 plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
3811                                 
3812                                 if(cursor_x >= plugin_x && cursor_x < plugin_x + plugin_w &&
3813                                         cursor_y >= plugin_y && cursor_y < plugin_y + plugin_h)
3814                                 {
3815                                         if(cursor_x < plugin_x + HANDLE_W)
3816                                         {
3817                                                 plugin_result = plugin;
3818                                                 handle_result = 0;
3819                                                 result = 1;
3820                                         }
3821                                         else
3822                                         if(cursor_x >= plugin_x + plugin_w - HANDLE_W)
3823                                         {
3824                                                 plugin_result = plugin;
3825                                                 handle_result = 1;
3826                                                 result = 1;
3827                                         }
3828                                 }
3829                         }
3830                 }
3831         }
3833 //printf("TrackCanvas::test_plugin_handles %d %d %d\n", button_press, handle_result, result);
3834         update_cursor = 1;
3835         if(result)
3836         {
3837                 double position;
3838                 if(handle_result == 0)
3839                 {
3840                         position = plugin_result->track->from_units(plugin_result->startproject);
3841                         new_cursor = LEFT_CURSOR;
3842                 }
3843                 else
3844                 if(handle_result == 1)
3845                 {
3846                         position = plugin_result->track->from_units(plugin_result->startproject + plugin_result->length);
3847                         new_cursor = RIGHT_CURSOR;
3848                 }
3849                 
3850                 if(button_press)
3851                 {
3852                         mwindow->session->drag_plugin = plugin_result;
3853                         mwindow->session->drag_handle = handle_result;
3854                         mwindow->session->drag_button = get_buttonpress() - 1;
3855                         mwindow->session->drag_position = position;
3856                         mwindow->session->current_operation = DRAG_PLUGINHANDLE1;
3857                         mwindow->session->drag_origin_x = get_cursor_x();
3858                         mwindow->session->drag_origin_y = get_cursor_y();
3859                         mwindow->session->drag_start = position;
3861                         int rerender = start_selection(position);
3862                         if(rerender) mwindow->cwindow->update(1, 0, 0);
3863                         gui->timebar->update_highlights();
3864                         gui->zoombar->update();
3865                         gui->cursor->hide();
3866                         gui->cursor->draw();
3867                         draw_overlays();
3868                         flash();
3869                         flush();
3870                 }
3871         }
3872         
3873         return result;
3877 int TrackCanvas::test_tracks(int cursor_x, 
3878                 int cursor_y,
3879                 int button_press)
3881         int result = 0;
3882         for(Track *track = mwindow->edl->tracks->first;
3883                 track && !result;
3884                 track = track->next)
3885         {
3886                 int64_t track_x, track_y, track_w, track_h;
3887                 track_dimensions(track, track_x, track_y, track_w, track_h);
3889                 if(button_press && 
3890                         get_buttonpress() == 3 &&
3891                         cursor_y >= track_y && 
3892                         cursor_y < track_y + track_h)
3893                 {
3894                         gui->edit_menu->update(track, 0);
3895                         gui->edit_menu->activate_menu();
3896                         result = 1;
3897                 }
3898         }
3899         return result;
3902 int TrackCanvas::test_edits(int cursor_x, 
3903         int cursor_y, 
3904         int button_press,
3905         int drag_start,
3906         int &redraw,
3907         int &rerender,
3908         int &new_cursor,
3909         int &update_cursor)
3911         int result = 0;
3912         int over_edit_handle = 0;
3914 //printf("TrackCanvas::test_edits 1\n");
3915         for(Track *track = mwindow->edl->tracks->first;
3916                 track && !result;
3917                 track = track->next)
3918         {
3919                 for(Edit *edit = track->edits->first;
3920                         edit && !result;
3921                         edit = edit->next)
3922                 {
3923                         int64_t edit_x, edit_y, edit_w, edit_h;
3924 //printf("TrackCanvas::test_edits 1\n");
3925                         edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
3927 // Cursor inside a track
3928 // Cursor inside an edit
3929                         if(cursor_x >= edit_x && cursor_x < edit_x + edit_w &&
3930                                 cursor_y >= edit_y && cursor_y < edit_y + edit_h)
3931                         {
3932 // Select duration of edit
3933 //printf("TrackCanvas::test_edits 2\n");
3934                                 if(button_press)
3935                                 {
3936                                         if(get_double_click() && !drag_start)
3937                                         {
3938 //printf("TrackCanvas::test_edits 3\n");
3939                                                 mwindow->edl->local_session->selectionstart = 
3940                                                         edit->track->from_units(edit->startproject);
3941                                                 mwindow->edl->local_session->selectionend = 
3942                                                         edit->track->from_units(edit->startproject) + 
3943                                                         edit->track->from_units(edit->length);
3944                                                 if(mwindow->edl->session->cursor_on_frames) 
3945                                                 {
3946                                                         mwindow->edl->local_session->selectionstart = 
3947                                                                 mwindow->edl->align_to_frame(mwindow->edl->local_session->selectionstart, 0);
3948                                                         mwindow->edl->local_session->selectionend = 
3949                                                                 mwindow->edl->align_to_frame(mwindow->edl->local_session->selectionend, 1);
3950                                                 }
3951                                                 redraw = 1;
3952                                                 rerender = 1;
3953                                                 result = 1;
3954                                         }
3955                                 }
3956                                 else
3957                                 if(drag_start)
3958                                 {
3959                                         if(mwindow->edl->session->editing_mode == EDITING_ARROW)
3960                                         {
3961 // Need to create drag window
3962                                                 mwindow->session->current_operation = DRAG_EDIT;
3963                                                 mwindow->session->drag_edit = edit;
3964 //printf("TrackCanvas::test_edits 2\n");
3966 // Drag only one edit
3967                                                 if(ctrl_down())
3968                                                 {
3969                                                         mwindow->session->drag_edits->remove_all();
3970                                                         mwindow->session->drag_edits->append(edit);
3971                                                 }
3972                                                 else
3973 // Construct list of all affected edits
3974                                                 {
3975                                                         mwindow->edl->tracks->get_affected_edits(
3976                                                                 mwindow->session->drag_edits, 
3977                                                                 edit->track->from_units(edit->startproject),
3978                                                                 edit->track);
3979                                                 }
3980                                                 mwindow->session->drag_origin_x = cursor_x;
3981                                                 mwindow->session->drag_origin_y = cursor_y;
3983                                                 drag_pixmap = new BC_Pixmap(gui,
3984                                                         mwindow->theme->clip_icon,
3985                                                         PIXMAP_ALPHA);
3986                                                 drag_popup = new BC_DragWindow(gui, 
3987                                                         drag_pixmap, 
3988                                                         get_abs_cursor_x() - drag_pixmap->get_w() / 2,
3989                                                         get_abs_cursor_y() - drag_pixmap->get_h() / 2);
3990 //printf("TrackCanvas::test_edits 3 %p\n", drag_popup);
3992                                                 result = 1;
3993                                         }
3994                                 }
3995                         }
3996                 }
3997         }
3998         return result;
4002 int TrackCanvas::test_resources(int cursor_x, int cursor_y)
4004         return 0;
4007 int TrackCanvas::test_plugins(int cursor_x, 
4008         int cursor_y, 
4009         int drag_start,
4010         int button_press)
4012         Plugin *plugin = 0;
4013         int result = 0;
4014         int done = 0;
4015         int64_t x, y, w, h;
4017 //printf("TrackCanvas::test_plugins 1\n");
4018         for(Track *track = mwindow->edl->tracks->first;
4019                 track && !done;
4020                 track = track->next)
4021         {
4022                 for(int i = 0; i < track->plugin_set.total && !done; i++)
4023                 {
4024                         PluginSet *plugin_set = track->plugin_set.values[i];
4025                         for(plugin = (Plugin*)plugin_set->first;
4026                                 plugin && !done;
4027                                 plugin = (Plugin*)plugin->next)
4028                         {
4029                                 plugin_dimensions(plugin, x, y, w, h);
4030                                 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
4031                                         MWindowGUI::visible(y, y + h, 0, get_h()))
4032                                 {
4033                                         if(cursor_x >= x && cursor_x < x + w &&
4034                                                 cursor_y >= y && cursor_y < y + h)
4035                                         {
4036                                                 done = 1;
4037                                                 break;
4038                                         }
4039                                 }
4040                         }
4041                 }
4042         }
4044 //printf("TrackCanvas::test_plugins 1\n");
4045         if(plugin)
4046         {
4047 // Start plugin popup
4048                 if(button_press)
4049                 {
4050 //printf("TrackCanvas::test_plugins 2\n");
4051                         if(get_buttonpress() == 3)
4052                         {
4053                                 gui->plugin_menu->update(plugin);
4054                                 gui->plugin_menu->activate_menu();
4055                                 result = 1;
4056                         }
4057 //printf("TrackCanvas::test_plugins 3\n");
4058                 }
4059                 else
4060 // Move plugin
4061                 if(drag_start)
4062                 {
4063 //printf("TrackCanvas::test_plugins 4\n");
4064                         if(mwindow->edl->session->editing_mode == EDITING_ARROW)
4065                         {
4066 //printf("TrackCanvas::test_plugins 5\n");
4067                                 if(plugin->track->data_type == TRACK_AUDIO)
4068                                         mwindow->session->current_operation = DRAG_AEFFECT_COPY;
4069                                 else
4070                                 if(plugin->track->data_type == TRACK_VIDEO)
4071                                         mwindow->session->current_operation = DRAG_VEFFECT_COPY;
4073                                 mwindow->session->drag_plugin = plugin;
4074 //printf("TrackCanvas::test_plugins 6\n");
4080 // Create picon
4081                                 switch(plugin->plugin_type)
4082                                 {
4083                                         case PLUGIN_STANDALONE:
4084                                         {
4085                                                 PluginServer *server = mwindow->scan_plugindb(plugin->title);
4086                                                 VFrame *frame = server->picon;
4087 //printf("TrackCanvas::test_plugins 7\n");
4088                                                 if(frame->get_color_model() == BC_RGB888)
4089                                                 {
4090                                                         drag_pixmap = new BC_Pixmap(gui, frame->get_w(), frame->get_h());
4091                                                         drag_pixmap->draw_vframe(frame,
4092                                                                 0,
4093                                                                 0,
4094                                                                 frame->get_w(),
4095                                                                 frame->get_h(),
4096                                                                 0,
4097                                                                 0);
4098                                                 }
4099                                                 else
4100                                                 {
4101                                                         drag_pixmap = new BC_Pixmap(gui,
4102                                                                 frame,
4103                                                                 PIXMAP_ALPHA);
4104                                                 }
4105 //printf("TrackCanvas::test_plugins 8\n");
4106                                                 break;
4107                                         }
4108                                         
4109                                         case PLUGIN_SHAREDPLUGIN:
4110                                                 drag_pixmap = new BC_Pixmap(gui,
4111                                                         mwindow->theme->clip_icon,
4112                                                         PIXMAP_ALPHA);
4113                                                 break;
4115                                         case PLUGIN_SHAREDMODULE:
4116                                                 drag_pixmap = new BC_Pixmap(gui,
4117                                                         mwindow->theme->clip_icon,
4118                                                         PIXMAP_ALPHA);
4119                                                 break;
4120 //printf("test plugins %d %p\n", mwindow->edl->session->editing_mode, mwindow->session->drag_plugin);
4121                                 }
4123 //printf("TrackCanvas::test_plugins 9 %p\n");
4124                                 drag_popup = new BC_DragWindow(gui, 
4125                                         drag_pixmap, 
4126                                         get_abs_cursor_x() - drag_pixmap->get_w() / 2,
4127                                         get_abs_cursor_y() - drag_pixmap->get_h() / 2);
4128 //printf("TrackCanvas::test_plugins 10\n");
4129                                 result = 1;
4130                         }
4131                 }
4132         }
4134 //printf("TrackCanvas::test_plugins 11\n");
4135         return result;
4138 int TrackCanvas::test_transitions(int cursor_x, 
4139         int cursor_y, 
4140         int button_press,
4141         int &new_cursor,
4142         int &update_cursor)
4144         Transition *transition = 0;
4145         int result = 0;
4146         int64_t x, y, w, h;
4147         
4148         for(Track *track = mwindow->edl->tracks->first;
4149                 track && !result;
4150                 track = track->next)
4151         {
4152                 for(Edit *edit = track->edits->first;
4153                         edit;
4154                         edit = edit->next)
4155                 {
4156                         if(edit->transition)
4157                         {
4158                                 edit_dimensions(edit, x, y, w, h);
4159                                 get_transition_coords(x, y, w, h);
4161                                 if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
4162                                         MWindowGUI::visible(y, y + h, 0, get_h()))
4163                                 {
4164                                         if(cursor_x >= x && cursor_x < x + w &&
4165                                                 cursor_y >= y && cursor_y < y + h)
4166                                         {
4167                                                 transition = edit->transition;
4168                                                 result = 1;
4169                                                 break;
4170                                         }
4171                                 }
4172                         }
4173                 }
4174         }
4175         
4176         update_cursor = 1;
4177         if(transition)
4178         {
4179                 if(!button_press)
4180                 {
4181                         new_cursor = UPRIGHT_ARROW_CURSOR;
4182                 }
4183                 else
4184                 if(get_buttonpress() == 3)
4185                 {
4186                         gui->transition_menu->update(transition);
4187                         gui->transition_menu->activate_menu();
4188                 }
4189         }
4191         return result;
4194 int TrackCanvas::button_press_event()
4196         int result = 0;
4197         int cursor_x, cursor_y;
4198         int new_cursor, update_cursor;
4200 //printf("TrackCanvas::button_press_event 1\n");
4201         cursor_x = get_cursor_x();
4202         cursor_y = get_cursor_y();
4204         if(is_event_win() && cursor_inside())
4205         {
4206                 if(!active)
4207                 {
4208                         activate();
4209                 }
4211                 if(get_buttonpress() == 1)
4212                 {
4213                         gui->unlock_window();
4214                         gui->mbuttons->transport->handle_transport(STOP, 1);
4215                         gui->lock_window();
4216                 }
4218                 int update_overlay = 0, update_cursor = 0, rerender = 0;
4220                 if(get_buttonpress() == 4)
4221                 {
4222 //printf("TrackCanvas::button_press_event 1\n");
4223                         mwindow->move_up(get_h() / 10);
4224                         result = 1;
4225                 }
4226                 else
4227                 if(get_buttonpress() == 5)
4228                 {
4229 //printf("TrackCanvas::button_press_event 2\n");
4230                         mwindow->move_down(get_h() / 10);
4231                         result = 1;
4232                 }
4233                 else
4234                 switch(mwindow->edl->session->editing_mode)
4235                 {
4236 // Test handles and resource boundaries and highlight a track
4237                         case EDITING_ARROW:
4238                         {
4239                                 Edit *edit;
4240                                 int handle;
4241                                 if(mwindow->edl->session->auto_conf->transitions && 
4242                                         test_transitions(cursor_x, 
4243                                                 cursor_y, 
4244                                                 1, 
4245                                                 new_cursor, 
4246                                                 update_cursor))
4247                                 {
4248                                         break;
4249                                 }
4250                                 else
4251                                 if(do_keyframes(cursor_x, 
4252                                         cursor_y, 
4253                                         0, 
4254                                         1, 
4255                                         new_cursor, 
4256                                         update_cursor,
4257                                         rerender))
4258                                 {
4259                                         break;
4260                                 }
4261                                 else
4262 // Test edit boundaries
4263                                 if(test_edit_handles(cursor_x, cursor_y, 1, new_cursor, update_cursor))
4264                                 {
4265                                         break;
4266                                 }
4267                                 else
4268 // Test plugin boundaries
4269                                 if(test_plugin_handles(cursor_x, cursor_y, 1, new_cursor, update_cursor))
4270                                 {
4271                                         break;
4272                                 }
4273                                 else
4274                                 if(test_edits(cursor_x, cursor_y, 1, 0, update_cursor, rerender, new_cursor, update_cursor))
4275                                 {
4276                                         break;
4277                                 }
4278                                 else
4279                                 if(test_plugins(cursor_x, cursor_y, 0, 1))
4280                                 {
4281                                         break;
4282                                 }
4283                                 else
4284                                 if(test_resources(cursor_x, cursor_y))
4285                                 {
4286                                         break;
4287                                 }
4288                                 else
4289                                 if(test_tracks(cursor_x, cursor_y, 1))
4290                                 {
4291                                         break;
4292                                 }
4293                                 break;
4294                         }
4296 // Test handles only and select a region
4297                         case EDITING_IBEAM:
4298                         {
4299                                 double position = (double)cursor_x * 
4300                                         mwindow->edl->local_session->zoom_sample /
4301                                         mwindow->edl->session->sample_rate + 
4302                                         (double)mwindow->edl->local_session->view_start * 
4303                                         mwindow->edl->local_session->zoom_sample /
4304                                         mwindow->edl->session->sample_rate;
4305 //printf("TrackCanvas::button_press_event %d\n", position);
4307                                 if(mwindow->edl->session->auto_conf->transitions && 
4308                                         test_transitions(cursor_x, 
4309                                                 cursor_y, 
4310                                                 1, 
4311                                                 new_cursor, 
4312                                                 update_cursor))
4313                                 {
4314                                         break;
4315                                 }
4316                                 else
4317                                 if(do_keyframes(cursor_x, 
4318                                         cursor_y, 
4319                                         0, 
4320                                         1, 
4321                                         new_cursor, 
4322                                         update_cursor,
4323                                         rerender))
4324                                 {
4325                                         update_overlay = 1;
4326                                         break;
4327                                 }
4328                                 else
4329 // Test edit boundaries
4330                                 if(test_edit_handles(cursor_x, cursor_y, 1, new_cursor, update_cursor))
4331                                 {
4332                                         break;
4333                                 }
4334                                 else
4335 // Test plugin boundaries
4336                                 if(test_plugin_handles(cursor_x, cursor_y, 1, new_cursor, update_cursor))
4337                                 {
4338                                         break;
4339                                 }
4340                                 else
4341                                 if(test_edits(cursor_x, cursor_y, 1, 0, update_cursor, rerender, new_cursor, update_cursor))
4342                                 {
4343                                         break;
4344                                 }
4345                                 else
4346                                 if(test_plugins(cursor_x, cursor_y, 0, 1))
4347                                 {
4348                                         break;
4349                                 }
4350                                 else
4351                                 if(test_tracks(cursor_x, cursor_y, 1))
4352                                 {
4353                                         break;
4354                                 }
4355 // Highlight selection
4356                                 else
4357                                 {
4358                                         rerender = start_selection(position);
4359                                         mwindow->session->current_operation = SELECT_REGION;
4360                                         update_cursor = 1;
4361                                 }
4363                                 break;
4364                         }
4365                 }
4368                 if(rerender)
4369                 {
4370                         mwindow->cwindow->update(1, 0, 0, 0, 1);
4371 // Update faders
4372                         mwindow->update_plugin_guis();
4373                         gui->patchbay->update();
4374                 }
4376                 if(update_overlay)
4377                 {
4378                         draw_overlays();
4379                         flash();
4380                 }
4382                 if(update_cursor)
4383                 {
4384                         gui->timebar->update_highlights();
4385                         gui->cursor->hide();
4386                         gui->cursor->show();
4387                         gui->zoombar->update();
4388                         flash();
4389                         result = 1;
4390                 }
4394         }
4395         return result;
4398 int TrackCanvas::start_selection(double position)
4400         int rerender = 0;
4401         position = mwindow->edl->align_to_frame(position, 0);
4403 // Extend a border
4404         if(shift_down())
4405         {
4406                 double midpoint = (mwindow->edl->local_session->selectionstart + 
4407                         mwindow->edl->local_session->selectionend) / 2;
4409                 if(position < midpoint)
4410                 {
4411                         mwindow->edl->local_session->selectionstart = position;
4412                         selection_midpoint1 = mwindow->edl->local_session->selectionend;
4413 // Que the CWindow
4414                         rerender = 1;
4415                 }
4416                 else
4417                 {
4418                         mwindow->edl->local_session->selectionend = position;
4419                         selection_midpoint1 = mwindow->edl->local_session->selectionstart;
4420 // Don't que the CWindow for the end
4421                 }
4422         }
4423         else
4424 // Start a new selection
4425         {
4426 //printf("TrackCanvas::start_selection %f\n", position);
4427                 mwindow->edl->local_session->selectionstart = 
4428                         mwindow->edl->local_session->selectionend = 
4429                         position;
4430                 selection_midpoint1 = position;
4431 // Que the CWindow
4432                 rerender = 1;
4433         }
4434         
4435         return rerender;
4438 void TrackCanvas::end_edithandle_selection()
4440         mwindow->modify_edithandles();
4443 void TrackCanvas::end_pluginhandle_selection()
4445         mwindow->modify_pluginhandles();
4449 double TrackCanvas::time_visible()
4451         return (double)get_w() * 
4452                 mwindow->edl->local_session->zoom_sample / 
4453                 mwindow->edl->session->sample_rate;
4496 void TrackCanvas::draw_automation()
4501 int TrackCanvas::set_index_file(int flash, Asset *asset)
4503         return 0;
4507 int TrackCanvas::button_release()
4509         return 0;
4513 int TrackCanvas::auto_reposition(int &cursor_x, int &cursor_y, int64_t cursor_position)
4515         return 0;
4519 int TrackCanvas::draw_floating_handle(int flash)
4521         return 0;
4524 int TrackCanvas::draw_loop_point(int64_t position, int flash)
4526         return 0;
4529 int TrackCanvas::draw_playback_cursor(int pixel, int flash)
4531         return 0;
4535 int TrackCanvas::update_handle_selection(int64_t cursor_position)
4537         return 0;
4540 int TrackCanvas::end_translation()
4542         return 0;