merge hv v6, rework trace methods
[goodguy/history.git] / cinelerra-5.1 / cinelerra / trackcanvas.C
index 3a5bdadeeb22e17f599c3562c862e3498b625d9d..87e6f0747606343d7fca48030254797ee135ca45 100644 (file)
@@ -38,6 +38,7 @@
 #include "edlsession.h"
 #include "floatauto.h"
 #include "floatautos.h"
+#include "gwindowgui.h"
 #include "indexstate.h"
 #include "intauto.h"
 #include "intautos.h"
@@ -203,15 +204,24 @@ int TrackCanvas::drag_motion(Track **over_track,
                                {
                                        int64_t edit_x, edit_y, edit_w, edit_h;
                                        edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
-
-                                       if(cursor_x >= edit_x &&
-                                               cursor_y >= edit_y &&
-                                               cursor_x < edit_x + edit_w &&
-                                               cursor_y < edit_y + edit_h)
-                                       {
+                                       if( cursor_y < edit_y || cursor_y >= edit_y + edit_h ) continue;
+                                       if( cursor_x >= edit_x && cursor_x < edit_x + edit_w ) {
                                                *over_edit = edit;
                                                break;
                                        }
+                                       if( edit != track->edits->last ) continue;
+                                       if( mwindow->session->current_operation != DRAG_ATRANSITION &&
+                                           mwindow->session->current_operation != DRAG_VTRANSITION ) continue;
+                                       if( !edit->silence() ) {
+                                               // add silence to allow drag transition past last edit
+                                               //  will be deleted by Edits::optimize if not used
+                                               double length = mwindow->edl->session->default_transition_length;
+                                               int64_t start = edit->startproject+edit->length;
+                                               int64_t units = track->to_units(length, 1); 
+                                               track->edits->create_silence(start, start+units);
+                                               continue;
+                                       }
+                                       if( cursor_x >= edit_x ) { *over_edit = edit; break; }
                                }
 
                                for(int i = 0; i < track->plugin_set.total; i++)
@@ -244,7 +254,7 @@ int TrackCanvas::drag_motion(Track **over_track,
        }
 
         if( !*over_track )
-               *over_track = pane->is_over_patchbay();
+               *over_track = pane->over_patchbay();
 
        return 0;
 }
@@ -272,7 +282,7 @@ int TrackCanvas::drag_stop(int *redraw)
                    (cursor_y = get_relative_cursor_y()) >= 0 && cursor_y < get_h() )
                        over_window = 1;
                else {
-                       Track *track = pane->is_over_patchbay();
+                       Track *track = pane->over_patchbay();
                        if( track && mwindow->session->track_highlighted == track )
                                over_window = 1;
                }
@@ -1842,41 +1852,34 @@ void TrackCanvas::draw_loop_points()
 //printf("TrackCanvas::draw_loop_points 7\n");
 }
 
-void TrackCanvas::draw_brender_start()
+void TrackCanvas::draw_brender_range()
 {
        if(mwindow->preferences->use_brender)
        {
-               int64_t x = Units::round(mwindow->edl->session->brender_start *
+               int64_t x1 = Units::round(mwindow->edl->session->brender_start *
                        mwindow->edl->session->sample_rate /
-                       mwindow->edl->local_session->zoom_sample -
+                       mwindow->edl->local_session->zoom_sample - 
+                       mwindow->edl->local_session->view_start[pane->number]);
+               if(MWindowGUI::visible(x1, x1 + 1, 0, get_w()))
+               {
+                       set_color(RED);
+                       draw_line(x1, 0, x1, get_h());
+               }
+               int64_t x2 = Units::round(mwindow->edl->session->brender_end *
+                       mwindow->edl->session->sample_rate /
+                       mwindow->edl->local_session->zoom_sample - 
                        mwindow->edl->local_session->view_start[pane->number]);
 
-               if(MWindowGUI::visible(x, x + 1, 0, get_w()))
+               if(MWindowGUI::visible(x2, x2 + 1, 0, get_w()))
                {
                        set_color(RED);
-                       draw_line(x, 0, x, get_h());
+                       draw_line(x2, 0, x2, get_h());
                }
        }
 }
 
-static int auto_colors[AUTOMATION_TOTAL] =
-{
-       BLUE,
-       RED,
-       GREEN,
-       BLUE,
-       RED,
-       GREEN,
-       BLUE,
-       WHITE,
-       0,
-       0,
-       0,
-       WHITE
-};
-
 // The operations which correspond to each automation type
-static int auto_operations[AUTOMATION_TOTAL] =
+int TrackCanvas::auto_operations[AUTOMATION_TOTAL] =
 {
        DRAG_MUTE,
        DRAG_CAMERA_X,
@@ -1981,8 +1984,8 @@ int TrackCanvas::do_keyframes(int cursor_x,
                                                                auto_keyframe, grouptype);
 
                                                result = do_float_autos(track, autos,
-                                                       cursor_x, cursor_y, draw, 
-                                                       buttonpress, 0, 0, auto_colors[i],
+                                                       cursor_x, cursor_y, draw, buttonpress,
+                                                       0, 0, GWindowGUI::auto_colors[i],
                                                        auto_keyframe, grouptype);
                                                break; }
 
@@ -1993,8 +1996,8 @@ int TrackCanvas::do_keyframes(int cursor_x,
                                                                buttonpress, 1, 1, MDGREY,
                                                                auto_keyframe);
                                                result = do_int_autos(track, autos,
-                                                       cursor_x, cursor_y, draw, 
-                                                       buttonpress, 0, 0, auto_colors[i],
+                                                       cursor_x, cursor_y, draw, buttonpress,
+                                                       0, 0, GWindowGUI::auto_colors[i],
                                                        auto_keyframe);
                                                break; }
                                        }
@@ -2014,7 +2017,7 @@ int TrackCanvas::do_keyframes(int cursor_x,
                                        {
                                                if (buttonpress != 3)
                                                {
-                                                       if(i == AUTOMATION_FADE)
+                                                       if(i == AUTOMATION_FADE || i == AUTOMATION_SPEED)
                                                                synchronize_autos(0,
                                                                        track,
                                                                        (FloatAuto*)mwindow->session->drag_auto,
@@ -2031,6 +2034,12 @@ int TrackCanvas::do_keyframes(int cursor_x,
                                                        gui->keyframe_menu->activate_menu();
                                                        rerender = 1; // the position changes
                                                }
+                                               else if( autos )
+                                               {
+                                                       gui->keyframe_hide->update(autos);
+                                                       gui->keyframe_hide->activate_menu();
+                                                       rerender = 1; // the position changes
+                                               }
                                                if(buttonpress == 1 && ctrl_down() &&
                                                   AUTOMATION_TYPE_FLOAT == autos->get_type())
                                                        rerender = 1; // special case: curve mode changed
@@ -2085,6 +2094,45 @@ int TrackCanvas::do_keyframes(int cursor_x,
        return result;
 }
 
+void TrackCanvas::draw_keyframe_reticle()
+{
+       int keyframe_hairline = mwindow->preferences->keyframe_reticle;
+       if( keyframe_hairline == HAIRLINE_NEVER ) return;
+
+       int current_op = mwindow->session->current_operation, dragging = 0;
+       for( int i=0; !dragging && i<AUTOMATION_TOTAL; ++i )
+               if( current_op == auto_operations[i] ) dragging = 1;
+
+       if( keyframe_hairline == HAIRLINE_DRAGGING && dragging ) {
+               if( mwindow->session->drag_auto && get_buttonpress() == 1 ) {
+                       draw_hairline(mwindow->session->drag_auto, RED);
+                       return;
+               }
+       }
+
+       if( keyframe_hairline == HAIRLINE_ALWAYS || ( get_buttonpress() == 2 &&
+           keyframe_hairline == HAIRLINE_DRAGGING && dragging ) ) {
+               for( Track *track = mwindow->edl->tracks->first; track;
+                    track=track->next ) {
+                       Automation *automation = track->automation;
+                       for( int i=0; i<AUTOMATION_TOTAL; ++i ) {
+                               if( !mwindow->edl->session->auto_conf->autos[i] ) continue;
+                               // automation visible
+                               Autos *autos = automation->autos[i];
+                               if( !autos ) continue;
+                               for( Auto *auto_keyframe=autos->first; auto_keyframe;
+                                    auto_keyframe = auto_keyframe->next ) {
+                                       draw_hairline(auto_keyframe, GREEN);
+                               }
+                       }
+
+                       if( dragging && mwindow->session->drag_auto ) {
+                               draw_hairline(mwindow->session->drag_auto, RED);
+                       }
+               }
+       }
+}
+
 void TrackCanvas::draw_auto(Auto *current,
        int x,
        int y,
@@ -2311,8 +2359,7 @@ float levered_position(float position, float ref_pos)
 {
        if( 1e-6 > fabs(ref_pos) || isnan(ref_pos)) 
                return 0.0;
-       else 
-               return ref_pos / position;
+       return ref_pos / position;
 }
 
 
@@ -2324,10 +2371,9 @@ float TrackCanvas::value_to_percentage(float auto_value, int autogrouptype)
        float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
        float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
        float automation_range = automation_max - automation_min;
-       if(0 == automation_range || isnan(auto_value) || isinf(auto_value))
+       if( 0 >= automation_range || isnan(auto_value) || isinf(auto_value) )
                return 0;
-       else
-               return (auto_value - automation_min) / automation_range;
+       return (auto_value - automation_min) / automation_range;
 }
 
 
@@ -2508,7 +2554,7 @@ void TrackCanvas::draw_floatline(int center_pixel,
 
 // Not using slope intercept
        x1 = MAX(0, x1);
-       int prev_y = y1;
+       int prev_y = y1 + center_pixel;
 
 
 // Call by reference fails for some reason here
@@ -2531,6 +2577,7 @@ void TrackCanvas::draw_floatline(int center_pixel,
 // (int)(center_pixel - yscale / 2),
 // (int)(center_pixel + yscale / 2 - 1));
 
+//printf("draw_line(%d,%d,  %d,%d)\n", x - 1, prev_y  , x, y);
                        draw_line(x - 1, prev_y  , x, y   );
                }
                prev_y = y;
@@ -2580,7 +2627,10 @@ int TrackCanvas::test_floatline(int center_pixel,
                {
                        Auto *current;
                        mwindow->undo->update_undo_before();
-                       current = mwindow->session->drag_auto = autos->insert_auto(position1);
+                       double position = autos->track->from_units(position1);
+                       position = mwindow->edl->align_to_frame(position, 0);
+                       int64_t new_position = autos->track->to_units(position,0);
+                       current = mwindow->session->drag_auto = autos->insert_auto(new_position);
                        ((FloatAuto*)current)->set_value(value);
                        mwindow->session->drag_start_percentage = value_to_percentage(value, autogrouptype);
                        mwindow->session->drag_start_position = current->position;
@@ -2596,71 +2646,62 @@ int TrackCanvas::test_floatline(int center_pixel,
 
 
 void TrackCanvas::synchronize_autos(float change,
-       Track *skip,
-       FloatAuto *fauto,
-       int fill_gangs)
+               Track *skip, FloatAuto *fauto, int fill_gangs)
 {
 // Handles the special case of modifying a fadeauto
 // when there are ganged faders on several tracks
 // (skip and fauto may be NULL if fill_gangs==-1)
-       if (fill_gangs == 1 && skip->gang)
-       {
-               for(Track *current = mwindow->edl->tracks->first;
-                       current;
-                       current = NEXT)
-               {
-                       if(current->data_type == skip->data_type &&
-                               current->gang &&
-                               current->record &&
-                               current != skip)
-                       {
-                               FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
-                               double position = skip->from_units(fauto->position);
-                               FloatAuto *previous = 0, *next = 0;
-
-                               float init_value = fade_autos->get_value(fauto->position, PLAY_FORWARD, previous, next);
-                               FloatAuto *keyframe;
-                               keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position);
 
-                               if (!keyframe)
-                               {
+       if( fill_gangs > 0 && skip->gang ) {
+               double position = skip->from_units(fauto->position);
+               int autoidx = fauto->autos->autoidx;
+
+               for(Track *current = mwindow->edl->tracks->first; current; current = NEXT) {
+                       if( (current->data_type == skip->data_type || get_double_click()) &&
+                           current->gang && current->record && current != skip ) {
+                               int64_t current_position = current->to_units(position, 1);
+                               FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[autoidx];
+                               float auto_min = mwindow->edl->local_session->automation_mins[fade_autos->autogrouptype];
+                               float auto_max = mwindow->edl->local_session->automation_maxs[fade_autos->autogrouptype];
+                               FloatAuto *previous = 0, *next = 0;
+                               FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_at_position(current_position);
+                               if( !keyframe ) {
 // create keyframe on neighbouring track at the point in time given by fauto
-                                       keyframe = (FloatAuto*)fade_autos->insert_auto(fauto->position);
-                                       keyframe->set_value(init_value + change);
+                                       float init_value = fade_autos->get_value(current_position, PLAY_FORWARD, previous, next);
+                                       float new_value = init_value + change;
+                                       CLAMP(new_value, auto_min, auto_max);
+                                       keyframe = (FloatAuto*)fade_autos->insert_auto(current_position);
+                                       keyframe->set_value(new_value);
                                }
-                               else
-                               {
+                               else {
 // keyframe exists, just change it
-                                       keyframe->adjust_to_new_coordinates(fauto->position, keyframe->get_value() + change);
+                                       float new_value = keyframe->get_value() + change;
+                                       CLAMP(new_value, auto_min, auto_max);
+                                       keyframe->adjust_to_new_coordinates(current_position, new_value);
 // need to (re)set the position, as the existing node could be on a "equivalent" position (within half a frame)
                                }
 
                                mwindow->session->drag_auto_gang->append((Auto *)keyframe);
                        }
                }
-       } else
-// move the gangs
-       if (fill_gangs == 0)
-       {
-// Move the gang!
-               for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
-               {
+       }
+       else if( !fill_gangs ) {
+               double position = skip->from_units(fauto->position);
+// Move the gangs
+               for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) {
                        FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
-
+                       int64_t keyframe_position = keyframe->autos->track->to_units(position, 1);
                        float new_value = keyframe->get_value() + change;
                        CLAMP(new_value,
                              mwindow->edl->local_session->automation_mins[keyframe->autos->autogrouptype],
                              mwindow->edl->local_session->automation_maxs[keyframe->autos->autogrouptype]);
-                       keyframe->adjust_to_new_coordinates(fauto->position, new_value);
+                       keyframe->adjust_to_new_coordinates(keyframe_position, new_value);
                }
 
        }
-       else
+       else {
 // remove the gangs
-       if (fill_gangs == -1)
-       {
-               for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
-               {
+               for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) {
                        FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
                        keyframe->autos->remove_nonsequential(
                                        keyframe);
@@ -2842,7 +2883,6 @@ int TrackCanvas::do_float_autos(Track *track, Autos *autos, int cursor_x, int cu
        double view_start, unit_start;
        double view_end, unit_end, yscale;
        double zoom_sample, zoom_units;
-       double ax, ay, ax2, ay2, ax0, ay0;
        double in_x2, in_y2, out_x2, out_y2;
        double slope;
        //int skip = 0;
@@ -2857,25 +2897,24 @@ int TrackCanvas::do_float_autos(Track *track, Autos *autos, int cursor_x, int cu
 // Get first auto before start
        Auto *current = 0, *previous = 0;
 
-       ax0 = ay0 = -1;
        for( current = autos->last;
                current && current->position >= unit_start;
                current = PREVIOUS ) ;
 
-       if( !current ) {
-               current = autos->first ? autos->first : autos->default_auto;
-               ax0 = 0;
-       }
-       if( current ) {
+       Auto *first_auto = current ? current :
+                autos->first ? autos->first : autos->default_auto;
+
+       double ax = 0, ay = 0, ax2 = 0, ay2 = 0;
+       if( first_auto ) {
                calculate_auto_position(&ax, &ay, 0, 0, 0, 0,
-                       current, unit_start, zoom_units, yscale, autogrouptype);
-               if( ax0 < 0 ) current = NEXT;
+                       first_auto, unit_start, zoom_units, yscale, autogrouptype);
+       }
+       if( current )
+               current = NEXT;
+       else {
+               current = autos->first;
+               ax = 0;
        }
-       else
-               ay0 = 0;
-
-       if( ax0 >= 0 ) ax = ax0;
-       if( ay0 >= 0 ) ay = ay0;
 
        do {
                //skip = 0;
@@ -2891,17 +2930,15 @@ int TrackCanvas::do_float_autos(Track *track, Autos *autos, int cursor_x, int cu
                        //skip = 1;
                }
 
-               slope = (ay2 - ay) / (ax2 - ax);
+               slope = ax2 > ax ? (ay2 - ay) / (ax2 - ax) : 0;
 
-               if(ax2 > get_w())
-               {
+               if(ax2 > get_w()) {
                        draw_auto = 0;
                        ax2 = get_w();
                        ay2 = ay + slope * (get_w() - ax);
                }
 
-               if(ax < 0)
-               {
+               if(ax < 0) {
                        ay = ay + slope * (0 - ax);
                        ax = 0;
                }
@@ -3336,6 +3373,28 @@ int TrackCanvas::do_plugin_autos(Track *track, int cursor_x, int cursor_y,
        return result;
 }
 
+int TrackCanvas::draw_hairline(Auto *auto_keyframe, int color)
+{
+       Track *track = auto_keyframe->autos->track;
+       int autogrouptype = auto_keyframe->autos->get_type();
+
+       int center_pixel;
+       double view_start, unit_start;
+       double view_end, unit_end, yscale;
+       double zoom_sample, zoom_units;
+
+       calculate_viewport(track, view_start, unit_start, view_end, unit_end,
+                       yscale, center_pixel, zoom_sample, zoom_units);
+
+       double ax = 0, ay = 0;
+       calculate_auto_position(&ax, &ay, 0, 0, 0, 0,
+               auto_keyframe, unit_start, zoom_units, yscale, autogrouptype);
+
+       set_color(color);
+       draw_line(ax, 0, ax, get_h());
+       return 0;
+}
+
 void TrackCanvas::draw_overlays()
 {
        int new_cursor, update_cursor, rerender;
@@ -3360,7 +3419,7 @@ void TrackCanvas::draw_overlays()
 
 // Loop points
        draw_loop_points();
-       draw_brender_start();
+       draw_brender_range();
 
 // Highlighted areas
        draw_highlighting();
@@ -3377,6 +3436,8 @@ void TrackCanvas::draw_overlays()
 // Playback cursor
        draw_playback_cursor();
 
+       draw_keyframe_reticle();
+
        show_window(0);
 }
 
@@ -3489,36 +3550,22 @@ int TrackCanvas::get_drag_values(float *percentage,
 
 
 #define UPDATE_DRAG_HEAD(do_clamp) \
-       int result = 0; \
+       int result = 0, center_pixel; \
        if(!current->autos->track->record) return 0; \
-       double view_start; \
-       double unit_start; \
-       double view_end; \
-       double unit_end; \
-       double yscale; \
-       int center_pixel; \
-       double zoom_sample; \
-       double zoom_units; \
+       double view_start, unit_start, view_end, unit_end; \
+       double yscale, zoom_sample, zoom_units; \
  \
        calculate_viewport(current->autos->track,  \
-               view_start, \
-               unit_start, \
-               view_end, \
-               unit_end, \
-               yscale, \
-               center_pixel, \
-               zoom_sample, \
-               zoom_units); \
+               view_start, unit_start, view_end, unit_end, \
+               yscale, center_pixel, zoom_sample, zoom_units); \
  \
        float percentage = (float)(mwindow->session->drag_origin_y - cursor_y) / \
-               yscale +  \
-               mwindow->session->drag_start_percentage; \
+               yscale +  mwindow->session->drag_start_percentage; \
        if(do_clamp) CLAMP(percentage, 0, 1); \
  \
        int64_t position = Units::to_int64(zoom_units * \
                (cursor_x - mwindow->session->drag_origin_x) + \
                mwindow->session->drag_start_position); \
- \
        if((do_clamp) && position < 0) position = 0;
 
 
@@ -3527,119 +3574,99 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y)
        FloatAuto *current = (FloatAuto*)mwindow->session->drag_auto;
 
        UPDATE_DRAG_HEAD(mwindow->session->drag_handle == 0);
-       int x = cursor_x - mwindow->session->drag_origin_x; \
-       int y = cursor_y - mwindow->session->drag_origin_y; \
-
-       float value;
-       float old_value;
+       int x = cursor_x - mwindow->session->drag_origin_x;
+       int y = cursor_y - mwindow->session->drag_origin_y;
+       float value, old_value;
+
+       if( mwindow->session->drag_handle == 0 && (ctrl_down() && !shift_down()) ) {
+// not really editing the node, rather start editing the curve
+// tangent is editable and drag movement is significant
+               if( (FloatAuto::FREE == current->curve_mode ||
+                    FloatAuto::TFREE==current->curve_mode) &&                                          
+                   (fabs(x) > HANDLE_W / 2 || fabs(y) > HANDLE_W / 2))
+                       mwindow->session->drag_handle = x < 0 ? 1 : 2;
+       }
 
-       switch(mwindow->session->drag_handle)
-       {
-// Center
-               case 0:
-                       if(ctrl_down())
-                       // not really editing the node, rather start editing the curve
-                       {
-                               // tangent is editable and drag movement is significant
-                               if( (FloatAuto::FREE == current->curve_mode ||
-                                    FloatAuto::TFREE==current->curve_mode) &&                                          
-                                   (fabs(x) > HANDLE_W / 2 || fabs(y) > HANDLE_W / 2))
-                                       mwindow->session->drag_handle = x < 0 ? 1 : 2;
-                               break;
-                       }
+       switch(mwindow->session->drag_handle) {
+       case 0: // Center
 // Snap to nearby values
-                       old_value = current->get_value();
-                       if(shift_down())
-                       {
-                               double value1;
-                               double distance1;
-                               double value2;
-                               double distance2;
+               old_value = current->get_value();
+               if(shift_down()) {
+                       double value1, value2, distance1, distance2;
 
-                               if(current->previous)
-                               {
-                                       int autogrouptype = current->previous->autos->autogrouptype;
-                                       value = percentage_to_value(percentage, 0, 0, autogrouptype);
-                                       value1 = ((FloatAuto*)current->previous)->get_value();
-                                       distance1 = fabs(value - value1);
-                                       current->set_value(value1);
-                               }
-
-                               if(current->next)
-                               {
-                                       int autogrouptype = current->next->autos->autogrouptype;
-                                       value = percentage_to_value(percentage, 0, 0, autogrouptype);
-                                       value2 = ((FloatAuto*)current->next)->get_value();
-                                       distance2 = fabs(value - value2);
-                                       if(!current->previous || distance2 < distance1)
-                                       {
-                                               current->set_value(value2);
-                                       }
-                               }
+                       if(current->previous) {
+                               int autogrouptype = current->previous->autos->autogrouptype;
+                               value = percentage_to_value(percentage, 0, 0, autogrouptype);
+                               value1 = ((FloatAuto*)current->previous)->get_value();
+                               distance1 = fabs(value - value1);
+                               current->set_value(value1);
+                       }
 
-                               if(!current->previous && !current->next)
-                               {
-                                       current->set_value( ((FloatAutos*)current->autos)->default_);
+                       if(current->next) {
+                               int autogrouptype = current->next->autos->autogrouptype;
+                               value = percentage_to_value(percentage, 0, 0, autogrouptype);
+                               value2 = ((FloatAuto*)current->next)->get_value();
+                               distance2 = fabs(value - value2);
+                               if(!current->previous || distance2 < distance1) {
+                                       current->set_value(value2);
                                }
-                               value = current->get_value();
                        }
-                       else
-                       {
-                               int autogrouptype = current->autos->autogrouptype;
-                               value = percentage_to_value(percentage, 0, 0, autogrouptype);
+
+                       if(!current->previous && !current->next) {
+                               current->set_value( ((FloatAutos*)current->autos)->default_);
                        }
+                       value = current->get_value();
+               }
+               else {
+                       int autogrouptype = current->autos->autogrouptype;
+                       value = percentage_to_value(percentage, 0, 0, autogrouptype);
+               }
 
-                       if(alt_down())
+               if(alt_down() && !shift_down())
 // ALT constrains movement: fixed position, only changing the value
-                               position = mwindow->session->drag_start_position;
+                       position = mwindow->session->drag_start_position;
 
-                       if(value != old_value || position != current->position)
-                       {
-                               result = 1;
-                               float change = value - old_value;               
-                               current->adjust_to_new_coordinates(position, value);
-                               synchronize_autos(change, current->autos->track, current, 0);
-                               show_message(current, 1,", %.2f", current->get_value());
-                       }
-                       break;
+               if(value != old_value || position != current->position) {
+                       result = 1;
+                       float change = value - old_value;               
+                       current->adjust_to_new_coordinates(position, value);
+                       synchronize_autos(change, current->autos->track, current, 0);
+                       show_message(current, 1,", %.2f", current->get_value());
+               }
+               break;
 
 // In control
-               case 1:
+       case 1: {
+               int autogrouptype = current->autos->autogrouptype;
+               value = percentage_to_value(percentage, 0, current, autogrouptype);
+               if(value != current->get_control_in_value())
                {
-                       int autogrouptype = current->autos->autogrouptype;
-                       value = percentage_to_value(percentage, 0, current, autogrouptype);
-                       if(value != current->get_control_in_value())
-                       {
-                               result = 1;
-                               // note: (position,value) need not be at the location of the ctrl point,
-                               // but could be somewhere in between on the curve (or even outward or
-                               // on the opposit side). We set the new control point such as
-                               // to point the curve through (position,value)
-                               current->set_control_in_value(
-                                       value * levered_position(position - current->position,
-                                                                current->get_control_in_position()));
-                               synchronize_autos(0, current->autos->track, current, 0);
-                               show_message(current, 1,", %.2f", current->get_control_in_value());
-                       }
+                       result = 1;
+                       // note: (position,value) need not be at the location of the ctrl point,
+                       // but could be somewhere in between on the curve (or even outward or
+                       // on the opposit side). We set the new control point such as
+                       // to point the curve through (position,value)
+                       current->set_control_in_value(
+                               value * levered_position(position - current->position,
+                                                        current->get_control_in_position()));
+                       synchronize_autos(0, current->autos->track, current, 0);
+                       show_message(current, 1,", %.2f", current->get_control_in_value());
                }
-                       break;
+               break; }
 
 // Out control
-               case 2:
-               {
-                       int autogrouptype = current->autos->autogrouptype;
-                       value = percentage_to_value(percentage, 0, current, autogrouptype);
-                       if(value != current->get_control_out_value())
-                       {
-                               result = 1;
-                               current->set_control_out_value(
-                                       value * levered_position(position - current->position,
-                                                                current->get_control_out_position()));
-                               synchronize_autos(0, current->autos->track, current, 0);
-                               show_message(current, 1,", %.2f", current->get_control_out_value());
-                       }
+       case 2: {
+               int autogrouptype = current->autos->autogrouptype;
+               value = percentage_to_value(percentage, 0, current, autogrouptype);
+               if(value != current->get_control_out_value()) {
+                       result = 1;
+                       current->set_control_out_value(
+                               value * levered_position(position - current->position,
+                                                        current->get_control_out_position()));
+                       synchronize_autos(0, current->autos->track, current, 0);
+                       show_message(current, 1,", %.2f", current->get_control_out_value());
                }
-                       break;
+               break; }
        }
 
        return result;
@@ -4691,8 +4718,7 @@ int TrackCanvas::button_press_event()
                        switch(mwindow->edl->session->editing_mode) {
 // Test handles and resource boundaries and highlight a track
                        case EDITING_ARROW: {
-                               if( mwindow->edl->session->auto_conf->transitions &&
-                                       do_transitions(cursor_x, cursor_y,
+                               if( do_transitions(cursor_x, cursor_y,
                                                1, new_cursor, update_cursor) ) break;
 
                                if( do_keyframes(cursor_x, cursor_y,
@@ -4731,8 +4757,7 @@ int TrackCanvas::button_press_event()
                                        mwindow->edl->session->sample_rate;
 //printf("TrackCanvas::button_press_event %d\n", position);
 
-                               if(mwindow->edl->session->auto_conf->transitions &&
-                                       do_transitions(cursor_x, cursor_y,
+                               if( do_transitions(cursor_x, cursor_y,
                                                1, new_cursor, update_cursor)) break;
                                if(do_keyframes(cursor_x, cursor_y,
                                        0, get_buttonpress(), new_cursor,
@@ -4754,6 +4779,7 @@ int TrackCanvas::button_press_event()
 
                                if( do_tracks(cursor_x, cursor_y, 1) ) break;
 // Highlight selection
+                               if( get_buttonpress() != LEFT_BUTTON ) break;
                                rerender = start_selection(position);
                                mwindow->session->current_operation = SELECT_REGION;
                                update_cursor = 1;
@@ -4773,17 +4799,17 @@ int TrackCanvas::button_press_event()
                if( update_overlay ) {
                        gui->draw_overlays(1);
                }
-
-               if( update_cursor > 0 ) {
+               if( update_cursor < 0 ) {
+// double_click edit
+                       gui->swindow->update_selection();
+               }
+               if( update_cursor ) {
                        gui->update_timebar(0);
                        gui->hide_cursor(0);
                        gui->show_cursor(1);
                        gui->zoombar->update();
                        gui->flash_canvas(1);
                }
-               else if(update_cursor < 0) {
-                       gui->swindow->update_selection();
-               }
        }
        return result;
 }