fixes for selection and popup behaviors
[goodguy/history.git] / cinelerra-5.1 / cinelerra / trackcanvas.C
index 016e6aa3b5bff84e127f45e25d46d7443f1bc1fc..1c2c50fc6d36bc8f4fefaa4ae64f7efb839c90c3 100644 (file)
@@ -203,15 +203,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 +253,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 +281,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;
                }
@@ -2031,6 +2040,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 +2100,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,
@@ -2506,7 +2560,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
@@ -2529,6 +2583,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;
@@ -2853,10 +2908,10 @@ int TrackCanvas::do_float_autos(Track *track, Autos *autos, int cursor_x, int cu
                 autos->first ? autos->first : autos->default_auto;
 
        double ax = 0, ay = 0, ax2 = 0, ay2 = 0;
-       if( first_auto )
+       if( first_auto ) {
                calculate_auto_position(&ax, &ay, 0, 0, 0, 0,
                        first_auto, unit_start, zoom_units, yscale, autogrouptype);
-
+       }
        if( current )
                current = NEXT;
        else {
@@ -3321,6 +3376,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;
@@ -3362,6 +3439,8 @@ void TrackCanvas::draw_overlays()
 // Playback cursor
        draw_playback_cursor();
 
+       draw_keyframe_reticle();
+
        show_window(0);
 }
 
@@ -4138,7 +4217,11 @@ int TrackCanvas::button_release_event()
 
 
                default:
-                       if(mwindow->session->current_operation) {
+                       if( !mwindow->session->current_operation ) {
+                               if( get_buttonpress() == 3 )
+                                       result = do_edit_popup();
+                       }
+                       else {
 //                             if(mwindow->session->current_operation == SELECT_REGION) {
 //                                     mwindow->undo->update_undo_after(_("select"), LOAD_SESSION, 0, 0);
 //                             }
@@ -4310,8 +4393,13 @@ int TrackCanvas::do_plugin_handles(int cursor_x,
 
 int TrackCanvas::do_tracks(int cursor_x, int cursor_y, int button_press)
 {
-       int result = 0;
+       return 0;
+}
 
+int TrackCanvas::do_edit_popup()
+{
+       int result = 0;
+       int cursor_y = get_cursor_y();
 //     if(!mwindow->edl->session->show_assets) return 0;
 
        for(Track *track = mwindow->edl->tracks->first;
@@ -4320,8 +4408,7 @@ int TrackCanvas::do_tracks(int cursor_x, int cursor_y, int button_press)
                int64_t track_x, track_y, track_w, track_h;
                track_dimensions(track, track_x, track_y, track_w, track_h);
 
-               if(button_press && get_buttonpress() == 3 &&
-                       cursor_y >= track_y && cursor_y < track_y + track_h) {
+               if( cursor_y >= track_y && cursor_y < track_y + track_h ) {
                        gui->edit_menu->update(track, 0);
                        gui->edit_menu->activate_menu();
                        result = 1;
@@ -4642,8 +4729,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,
@@ -4682,8 +4768,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,
@@ -4705,6 +4790,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;
@@ -4724,17 +4810,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;
 }