version update
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / trackcanvas.C
index a2b758886826b3ce50be6e04293e8373e1f8be54..c0fea44a35d82970fa662baf7f558a5e07a00a24 100644 (file)
@@ -1658,6 +1658,9 @@ void TrackCanvas::draw_highlighting()
                        }
                        break;
 
+               case DRAG_SPEED:
+                       draw_speed_highlight();
+                       break;
        }
 
        if( draw_box )
@@ -1666,6 +1669,33 @@ void TrackCanvas::draw_highlighting()
        draw_selected_edits(mwindow->edl, 0, 0, GREEN+BLUE, RED);
 }
 
+void TrackCanvas::draw_speed_highlight()
+{
+       FloatAuto *drag_speed = (FloatAuto*)mwindow->session->drag_auto;
+       if( !drag_speed ) return;
+       draw_speed_track(drag_speed->autos->track);
+       ArrayList<Auto*> &speed_gang = *mwindow->session->drag_auto_gang;
+       for( int i=0, sz=speed_gang.size(); i<sz; ++i ) {
+               Track *track = speed_gang[i]->autos->track;
+               if( track->is_hidden() ) continue;
+               draw_speed_track(track);
+       }
+}
+
+void TrackCanvas::draw_speed_track(Track *track)
+{
+       for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+               int64_t x, y, w, h;
+               edit_dimensions(edit, x, y, w, h);
+               if( !MWindowGUI::visible(x, x + w, 0, get_w()) ) continue;
+               if( !MWindowGUI::visible(y, y + h, 0, get_h()) ) continue;
+               int color = 0xc00cc0;
+               set_color(color);
+               set_opaque();
+               draw_selected(x, y, w, h);
+       }
+}
+
 // x does not reliably draw a really big rectangle
 void TrackCanvas::draw_selected(int x, int y, int w, int h)
 {
@@ -1937,7 +1967,8 @@ void TrackCanvas::draw_inout_points()
 void TrackCanvas::draw_drag_handle()
 {
        if( mwindow->session->current_operation != DRAG_EDITHANDLE2 &&
-           mwindow->session->current_operation != DRAG_PLUGINHANDLE2 ) return;
+           mwindow->session->current_operation != DRAG_PLUGINHANDLE2 &&
+           mwindow->session->current_operation != DRAG_TRANSNHANDLE2 ) return;
        int64_t pixel1 = Units::round(mwindow->session->drag_position *
                mwindow->edl->session->sample_rate /
                mwindow->edl->local_session->zoom_sample -
@@ -2240,7 +2271,7 @@ int TrackCanvas::do_keyframes(int cursor_x,
                                                        auto_keyframe, grouptype);
 
                                                if( !result && buttonpress && i == AUTOMATION_SPEED )
-                                                       mwindow->speed_after(-1);
+                                                       mwindow->speed_after(-1, 0);
                                                if( result && buttonpress ) {
                                                        int color = GWindowGUI::auto_colors[i];
                                                        mwindow->gui->zoombar->update_autozoom(grouptype, color);
@@ -2966,9 +2997,9 @@ void TrackCanvas::fill_ganged_autos(int gang, float change, Track *skip, FloatAu
        int edge = patch ? patch->edge : 0;
        int span = patch ? patch->span : 0;
        for(Track *current = mwindow->edl->tracks->first; current; current = NEXT) {
-               if( (gang || current->data_type == skip->data_type) &&
-                   current->armed_gang(skip) && current->is_armed() &&
-                   current != skip ) {
+               if( current == skip || !current->is_armed() ) continue;
+               if( !gang && current->data_type != skip->data_type ) continue;
+               if( skip->armed_gang(current) || get_double_click() ) {
                        FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[autoidx];
                        FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position);
                        int64_t current_position = current->to_units(position, 1);
@@ -2976,8 +3007,7 @@ void TrackCanvas::fill_ganged_autos(int gang, float change, Track *skip, FloatAu
 // keyframe exists, just change it
                                keyframe->bump_update(current_position, change, edge, span);
                        }
-                       else if( gang >= 0 && ( get_double_click() ||
-                                  mwindow->edl->session->auto_keyframes ) ) {
+                       else if( gang >= 0 ) {
 // create keyframe on neighbouring track at the point in time given by fauto
                                FloatAuto *previous = 0, *next = 0;
                                float value = fade_autos->get_value(current_position, PLAY_FORWARD, previous, next);
@@ -3817,14 +3847,8 @@ void TrackCanvas::update_drag_handle()
        double new_position;
        int cursor_x = get_cursor_x();
 
-       new_position =
-               (double)(cursor_x +
-               mwindow->edl->local_session->view_start[pane->number]) *
-               mwindow->edl->local_session->zoom_sample /
-               mwindow->edl->session->sample_rate;
-
-       new_position =
-               mwindow->edl->align_to_frame(new_position, 0);
+       new_position = mwindow->edl->get_cursor_position(cursor_x, pane->number);
+       new_position = mwindow->edl->align_to_frame(new_position, 0);
 
        if( ctrl_down() && alt_down() ) {
 #define snapper(v) do { \
@@ -4292,42 +4316,46 @@ int TrackCanvas::cursor_update(int in_motion)
        {
                case DRAG_EDITHANDLE1:
 // Outside threshold.  Upgrade status
-                       if(active)
-                       {
-                               if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
-                               {
-                                       mwindow->session->current_operation = DRAG_EDITHANDLE2;
-                                       update_overlay = 1;
-                               }
+                       if( !active ) break;
+                       if( labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W ) {
+                               mwindow->session->current_operation = DRAG_EDITHANDLE2;
+                               update_overlay = 1;
                        }
                        break;
-
                case DRAG_EDITHANDLE2:
-                       if(active)
-                       {
-                               update_drag_handle();
-                               update_overlay = 1;
-                       }
+                       if( !active ) break;
+                       update_drag_handle();
+                       update_overlay = 1;
                        break;
 
                case DRAG_PLUGINHANDLE1:
-                       if(active)
-                       {
-                               if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
-                               {
-                                       mwindow->session->current_operation = DRAG_PLUGINHANDLE2;
-                                       update_overlay = 1;
-                               }
+                       if( !active ) break;
+                       if( labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W ) {
+                               mwindow->session->current_operation = DRAG_PLUGINHANDLE2;
+                               update_overlay = 1;
                        }
                        break;
-
                case DRAG_PLUGINHANDLE2:
-                       if(active)
-                       {
-                               update_drag_handle();
+                       if( !active ) break;
+                       update_drag_handle();
+                       update_overlay = 1;
+                       break;
+
+               case DRAG_TRANSNHANDLE1:
+                       if( !active ) break;
+                       if( labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W ) {
+                               mwindow->session->current_operation = DRAG_TRANSNHANDLE2;
                                update_overlay = 1;
                        }
                        break;
+               case DRAG_TRANSNHANDLE2: {
+                       if( !active ) break;
+                       position = mwindow->edl->get_cursor_position(get_cursor_x(), pane->number);
+                       position = mwindow->edl->align_to_frame(position, 1);
+                       drag_transition_handle(position);
+                       rerender = 1;
+                       update_overlay = 1;
+                       break; }
 
 // Rubber band curves
                case DRAG_FADE:
@@ -4343,7 +4371,7 @@ int TrackCanvas::cursor_update(int in_motion)
                        if(active) rerender = update_overlay =
                                update_drag_floatauto(get_cursor_x(), get_cursor_y());
                        if( rerender && mwindow->session->current_operation == DRAG_SPEED )
-                               mwindow->speed_after(!in_motion ? 1 : 0);
+                               mwindow->speed_after(!in_motion ? 1 : 0, 0);
                        break;
 
                case DRAG_PLAY:
@@ -4450,6 +4478,8 @@ int TrackCanvas::cursor_update(int in_motion)
                                                0, new_cursor, update_cursor)) break;
                                if(do_keyframes(get_cursor_x(), get_cursor_y(),
                                        0, 0, new_cursor, update_cursor, rerender)) break;
+                               if(do_transition_handles(get_cursor_x(), get_cursor_y(),
+                                       0, rerender, update_overlay, new_cursor, update_cursor)) break;
                                if(do_edit_handles(get_cursor_x(), get_cursor_y(),
                                        0, rerender, update_overlay, new_cursor, update_cursor)) break;
 // Plugin boundaries
@@ -4649,9 +4679,23 @@ int TrackCanvas::button_release_event()
                        result = 1;
                        break;
 
+               case DRAG_TRANSNHANDLE2:
+                       mwindow->session->current_operation = NO_OPERATION;
+                       drag_scroll = 0;
+                       result = 1;
+
+                       end_transnhandle_selection();
+                       break;
+
+               case DRAG_TRANSNHANDLE1:
+                       mwindow->session->current_operation = NO_OPERATION;
+                       drag_scroll = 0;
+                       result = 1;
+                       break;
+
                case DRAG_SPEED:
                        redraw = FORCE_REDRAW;
-                       load_flags |= LOAD_EDITS;
+                       load_flags |= LOAD_EDITS | LOAD_TIMEBAR;
                case DRAG_FADE:
 // delete the drag_auto_gang first and remove out of order keys
                        clear_ganged_autos();
@@ -4971,6 +5015,95 @@ int TrackCanvas::do_plugin_handles(int cursor_x,
        return result;
 }
 
+int TrackCanvas::do_transition_handles(int cursor_x, int cursor_y, int button_press,
+               int &rerender, int &update_overlay, int &new_cursor, int &update_cursor)
+{
+       Transition *trans_result = 0;
+       int result = 0;
+
+       Track *track = mwindow->edl->tracks->first;
+       for( ; track && !result; track=track->next) {
+               if( track->is_hidden() ) continue;
+               Edit *edit = track->edits->first;
+               for( ; edit && !result; edit=edit->next ) {
+                       Transition *trans = edit->transition;
+                       if( !trans ) continue;
+                       int64_t x, y, w, h;
+                       edit_dimensions(edit, x, y, w, h);
+                       int strip_x = x, edit_y = y;
+                       get_transition_coords(edit, x, y, w, h);
+                       VFrame *strip = mwindow->theme->get_image("plugin_bg_data");
+                       int strip_y = y - strip->get_h();
+                       if( track->show_assets() && track->show_titles() )
+                               edit_y += mwindow->theme->get_image("title_bg_data")->get_h();
+                       if( strip_y < edit_y ) strip_y = edit_y;
+                       int strip_w = Units::round(edit->track->from_units(edit->transition->length) *
+                               mwindow->edl->session->sample_rate / mwindow->edl->local_session->zoom_sample);
+                       int x1 = strip_x + strip_w - HANDLE_W/2, x2 = x1 + HANDLE_W;
+                       int y1 = strip_y + strip->get_h()/2 - HANDLE_H/2, y2 = y1 + HANDLE_W;
+                       if( cursor_x >= x1 && cursor_x < x2 &&
+                           cursor_y >= y1 && cursor_y < y2 ) {
+                               trans_result = trans;
+                               result = 1;
+                       }
+               }
+       }
+
+       if( result ) {
+               if( button_press ) {
+                       mwindow->session->drag_transition = trans_result;
+                       mwindow->session->drag_handle = 1;
+                       mwindow->session->drag_button = get_buttonpress() - 1;
+                       int64_t trans_end = trans_result->edit->startproject + trans_result->length;
+                       double position = trans_result->edit->track->from_units(trans_end);
+                       mwindow->session->drag_position = position;
+                       mwindow->session->drag_start = position;
+                       mwindow->session->current_operation = DRAG_TRANSNHANDLE1;
+                       mwindow->session->drag_origin_x = get_cursor_x();
+                       mwindow->session->drag_origin_y = get_cursor_y();
+                       update_cursor = 1;
+               }
+               new_cursor = RIGHT_CURSOR;
+               update_overlay = 1;
+       }
+
+       return result;
+}
+
+int TrackCanvas::drag_transition_handle(double position)
+{
+       Transition *transition = mwindow->session->drag_transition;
+       if( !transition ) return 1;
+       mwindow->session->drag_position = position;
+       mwindow->edl->local_session->set_selectionstart(position);
+       mwindow->edl->local_session->set_selectionend(position);
+       char string[BCSTRLEN];
+       int64_t length = transition->length;
+       Track *track = transition->edit->track;
+       int64_t start_pos = track->to_units(mwindow->session->drag_start, 0);
+       int64_t end_pos = track->to_units(mwindow->session->drag_position, 0);
+       length += end_pos - start_pos;
+       if( length < 0 ) length = 0;
+       double time = track->from_units(length);
+       Units::totext(string, time,
+               mwindow->edl->session->time_format,
+               mwindow->edl->session->sample_rate,
+               mwindow->edl->session->frame_rate,
+               mwindow->edl->session->frames_per_foot);
+       mwindow->gui->show_message(string);
+       if( mwindow->gui->transition_menu->length_thread->running() ) {
+               TransitionLengthDialog *dialog = (TransitionLengthDialog *)
+                        mwindow->gui->transition_menu->length_thread->get_gui();
+               if( dialog ) {
+                       dialog->lock_window("TrackCanvas::drag_transition_handle");
+                       dialog->update_text(time);
+                       dialog->thread->new_length = time;
+                       dialog->unlock_window();
+               }
+       }
+       return 0;
+}
+
 
 int TrackCanvas::do_tracks(int cursor_x, int cursor_y, int button_press)
 {
@@ -5392,6 +5525,10 @@ int TrackCanvas::button_press_event()
                                        0, get_buttonpress(), new_cursor,
                                        update_cursor, rerender) ) break;
                                update_message = 1;
+
+                               if( do_transition_handles(cursor_x, cursor_y,
+                                       1, rerender, update_overlay, new_cursor,
+                                       update_cursor) ) break;
 // Test edit boundaries
                                if( do_edit_handles(cursor_x, cursor_y,
                                        1, rerender, update_overlay, new_cursor,
@@ -5428,6 +5565,8 @@ int TrackCanvas::button_press_event()
                                        break;
                                }
                                update_message = 1;
+                               if( do_transition_handles(cursor_x, cursor_y,
+                                       1, rerender, update_overlay, new_cursor, update_cursor) ) break;
 // Test edit boundaries
                                if( do_edit_handles(cursor_x, cursor_y,
                                        1, rerender, update_overlay, new_cursor, update_cursor) ) break;
@@ -5524,11 +5663,19 @@ int TrackCanvas::start_selection(double position)
 void TrackCanvas::end_edithandle_selection()
 {
        mwindow->modify_edithandles();
+       mwindow->session->drag_edit = 0;
 }
 
 void TrackCanvas::end_pluginhandle_selection()
 {
        mwindow->modify_pluginhandles();
+       mwindow->session->drag_plugin = 0;
+}
+
+void TrackCanvas::end_transnhandle_selection()
+{
+       mwindow->modify_transnhandles();
+       mwindow->session->drag_transition = 0;
 }