From df72ca6732207dc25472a23169ff79ef6d4cca1c Mon Sep 17 00:00:00 2001 From: Good Guy Date: Tue, 27 Mar 2018 17:14:55 -0600 Subject: [PATCH] add edit speed duration update, autogroup select when modify auto --- cinelerra-5.1/cinelerra/floatauto.C | 12 ++ cinelerra-5.1/cinelerra/floatauto.h | 1 + cinelerra-5.1/cinelerra/floatautos.C | 22 +++- cinelerra-5.1/cinelerra/floatautos.h | 1 + cinelerra-5.1/cinelerra/keyframepopup.C | 5 +- cinelerra-5.1/cinelerra/mwindow.C | 3 +- cinelerra-5.1/cinelerra/mwindow.h | 6 + cinelerra-5.1/cinelerra/mwindowedit.C | 149 +++++++++++++++--------- cinelerra-5.1/cinelerra/trackcanvas.C | 54 ++++++--- cinelerra-5.1/cinelerra/trackcanvas.h | 2 + 10 files changed, 177 insertions(+), 78 deletions(-) diff --git a/cinelerra-5.1/cinelerra/floatauto.C b/cinelerra-5.1/cinelerra/floatauto.C index bab8160f..8e3e6368 100644 --- a/cinelerra-5.1/cinelerra/floatauto.C +++ b/cinelerra-5.1/cinelerra/floatauto.C @@ -74,6 +74,18 @@ int FloatAuto::identical(FloatAuto *src) // curve_mode is ignored, no recalculations } +// exactly equals +int FloatAuto::equals(FloatAuto *that) +{ + return this->value == that->value && + this->control_in_value == that->control_in_value && + this->control_out_value == that->control_out_value && + this->control_in_position == that->control_in_position && + this->control_out_position == that->control_out_position && + this->curve_mode == that->curve_mode; +} + + /* Note: the following is essentially display-code and has been moved to: * TrackCanvas::value_to_percentage(float auto_value, int autogrouptype) * diff --git a/cinelerra-5.1/cinelerra/floatauto.h b/cinelerra-5.1/cinelerra/floatauto.h index be0b304e..cc4168c4 100644 --- a/cinelerra-5.1/cinelerra/floatauto.h +++ b/cinelerra-5.1/cinelerra/floatauto.h @@ -42,6 +42,7 @@ public: int operator==(Auto &that); int operator==(FloatAuto &that); int identical(FloatAuto *src); + int equals(FloatAuto *src); void copy_from(Auto *that); void copy_from(FloatAuto *that); int interpolate_from(Auto *a1, Auto *a2, int64_t pos, Auto *templ=0); // bezier interpolation diff --git a/cinelerra-5.1/cinelerra/floatautos.C b/cinelerra-5.1/cinelerra/floatautos.C index 04741afe..95dcace9 100644 --- a/cinelerra-5.1/cinelerra/floatautos.C +++ b/cinelerra-5.1/cinelerra/floatautos.C @@ -449,12 +449,10 @@ double FloatAutos::automation_integral(int64_t start, int64_t length, int direct length += start; start = 0; } - int64_t end = start + length; - double value = 0, track_length = track->get_length(); - int64_t pos = start, len = track->to_units(track_length,0); - if( end > len ) end = len; + double value = 0; + int64_t pos = start, len = length, end = pos + len; while( pos < end ) { - int64_t prev_pos = 0, next_pos = len; + int64_t prev_pos = 0, next_pos = end; Auto *zprev = 0, *znext = 0; FloatAuto *prev = (FloatAuto*)get_prev_auto(pos, direction, zprev, 0); if( prev ) prev_pos = prev->position; @@ -491,3 +489,17 @@ double FloatAutos::automation_integral(int64_t start, int64_t length, int direct return value + 1e-6; } +int64_t FloatAutos::speed_position(double pos) +{ + double length = track->get_length(); + int64_t l = -1, r = track->to_units(length, 1); + if( r < 1 ) r = 1; + for( int i=32; --i >= 0 && automation_integral(0,r,PLAY_FORWARD) <= pos; r*=2 ); + for( int i=64; --i >= 0 && (r-l)>1; ) { + int64_t m = (l + r) / 2; + double t = automation_integral(0,m,PLAY_FORWARD) - pos; + *(t >= 0 ? &r : &l) = m; + } + return r; +} + diff --git a/cinelerra-5.1/cinelerra/floatautos.h b/cinelerra-5.1/cinelerra/floatautos.h index 96d06d63..0e7fa195 100644 --- a/cinelerra-5.1/cinelerra/floatautos.h +++ b/cinelerra-5.1/cinelerra/floatautos.h @@ -65,6 +65,7 @@ public: void set_automation_mode(int64_t start, int64_t end, int mode); void set_proxy(int orig_scale, int new_scale); double automation_integral(int64_t start, int64_t length, int direction); + int64_t speed_position(double pos); void dump(); Auto* new_auto(); diff --git a/cinelerra-5.1/cinelerra/keyframepopup.C b/cinelerra-5.1/cinelerra/keyframepopup.C index aff99d6d..3813e744 100644 --- a/cinelerra-5.1/cinelerra/keyframepopup.C +++ b/cinelerra-5.1/cinelerra/keyframepopup.C @@ -622,6 +622,7 @@ KeySpeedValue::KeySpeedValue(KeySpeedPatch *key_speed_patch) key_speed_patch->mwindow->get_float_auto(key_speed_patch->patch, AUTOMATION_SPEED)->get_value()) { this->key_speed_patch = key_speed_patch; + key_speed_patch->mwindow->speed_before(); set_precision(0.01); } @@ -632,6 +633,8 @@ KeySpeedValue::~KeySpeedValue() int KeySpeedValue::button_release_event() { BC_FSlider::button_release_event(); + key_speed_patch->mwindow->speed_after(1); + key_speed_patch->mwindow->resync_guis(); return 0; } @@ -645,7 +648,7 @@ void KeySpeedValue::update_edl() mwindow->undo->update_undo_before(_("speed"), need_undo ? 0 : this); FloatAuto *current = (FloatAuto*)speed_autos->get_auto_for_editing(position); current->set_value(get_value()); - mwindow->undo->update_undo_after(_("speed"), LOAD_AUTOMATION); + mwindow->undo->update_undo_after(_("speed"), LOAD_AUTOMATION+LOAD_EDITS); } int KeySpeedValue::handle_event() diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index ff4de507..9731b4bb 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -230,6 +230,7 @@ MWindow::MWindow() restart_status = 0; screens = 1; in_destructor = 0; + speed_edl = 0; } @@ -251,7 +252,7 @@ MWindow::~MWindow() commit_commercial(); if( commercials && !commercials->remove_user() ) commercials = 0; close_mixers(); - + if( speed_edl ) { speed_edl->remove_user(); speed_edl = 0; } // Save defaults for open plugins plugin_gui_lock->lock("MWindow::~MWindow"); for(int i = 0; i < plugin_guis->size(); i++) { diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index 252f96db..895314a2 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -557,6 +557,8 @@ public: static Commercials *commercials; int commercial_active; int has_commercials(); +// copy of edl created in speed_before, used in speed_after to normalize_speed + EDL *speed_edl; // Menu items ArrayList colormodels; @@ -655,6 +657,7 @@ public: void commit_commercial(); void undo_commercial(); void cut_commercials(); + void update_gui(int changed_edl); int paste_subtitle_text(char *text, double start, double end); void init_error(); @@ -702,6 +705,9 @@ public: void init_commercials(); static void add_plugins(ArrayList &plugins); static void delete_plugins(); + void speed_before(); + int speed_after(int done); + int normalize_speed(EDL *old_edl, EDL *new_edl); // void clean_indexes(); // TimeBomb timebomb; diff --git a/cinelerra-5.1/cinelerra/mwindowedit.C b/cinelerra-5.1/cinelerra/mwindowedit.C index 142c2a38..d69496dc 100644 --- a/cinelerra-5.1/cinelerra/mwindowedit.C +++ b/cinelerra-5.1/cinelerra/mwindowedit.C @@ -325,55 +325,60 @@ void MWindow::clear(int clear_handle) } } +void MWindow::update_gui(int changed_edl) +{ + restart_brender(); + update_plugin_guis(); + if( changed_edl ) { + gui->update(1, 2, 1, 1, 1, 1, 0); + cwindow->update(1, 0, 0, 0, 1); + cwindow->refresh_frame(CHANGE_EDL); + } + else { + gui->draw_overlays(1); + sync_parameters(CHANGE_PARAMS); + gui->update_patchbay(); + cwindow->update(1, 0, 0); + } +} + void MWindow::set_automation_mode(int mode) { undo->update_undo_before(); + speed_before(); edl->tracks->set_automation_mode( edl->local_session->get_selectionstart(), edl->local_session->get_selectionend(), mode); + int changed_edl = speed_after(1); save_backup(); char string[BCSTRLEN]; sprintf(string,"set %s", FloatAuto::curve_name(mode)); undo->update_undo_after(string, LOAD_AUTOMATION); - - restart_brender(); - update_plugin_guis(); - gui->draw_overlays(1); - sync_parameters(CHANGE_PARAMS); - gui->update_patchbay(); - cwindow->update(1, 0, 0); + update_gui(changed_edl); } void MWindow::clear_automation() { undo->update_undo_before(); + speed_before(); edl->tracks->clear_automation(edl->local_session->get_selectionstart(), edl->local_session->get_selectionend()); + int changed_edl = speed_after(1); save_backup(); undo->update_undo_after(_("clear keyframes"), LOAD_AUTOMATION); - - restart_brender(); - update_plugin_guis(); - gui->draw_overlays(1); - sync_parameters(CHANGE_PARAMS); - gui->update_patchbay(); - cwindow->update(1, 0, 0); + update_gui(changed_edl); } int MWindow::clear_default_keyframe() { undo->update_undo_before(); + speed_before(); edl->tracks->clear_default_keyframe(); + int changed_edl = speed_after(1); save_backup(); undo->update_undo_after(_("clear default keyframe"), LOAD_AUTOMATION); - - restart_brender(); - gui->draw_overlays(1); - sync_parameters(CHANGE_PARAMS); - gui->update_patchbay(); - cwindow->update(1, 0, 0); - + update_gui(changed_edl); return 0; } @@ -593,21 +598,14 @@ void MWindow::cut_right_label() int MWindow::cut_automation() { undo->update_undo_before(); - + speed_before(); copy_automation(); - edl->tracks->clear_automation(edl->local_session->get_selectionstart(), edl->local_session->get_selectionend()); + int changed_edl = speed_after(1); save_backup(); undo->update_undo_after(_("cut keyframes"), LOAD_AUTOMATION); - - - restart_brender(); - update_plugin_guis(); - gui->draw_overlays(1); - sync_parameters(CHANGE_PARAMS); - gui->update_patchbay(); - cwindow->update(1, 0, 0); + update_gui(changed_edl); return 0; } @@ -615,18 +613,13 @@ int MWindow::cut_default_keyframe() { undo->update_undo_before(); + speed_before(); copy_default_keyframe(); edl->tracks->clear_default_keyframe(); - undo->update_undo_after(_("cut default keyframe"), LOAD_AUTOMATION); - - restart_brender(); - gui->draw_overlays(1); - sync_parameters(CHANGE_PARAMS); - gui->update_patchbay(); - cwindow->update(1, 0, 0); + int changed_edl = speed_after(1); save_backup(); - - + undo->update_undo_after(_("cut default keyframe"), LOAD_AUTOMATION); + update_gui(changed_edl); return 0; } @@ -1243,6 +1236,7 @@ int MWindow::paste_automation() if( len ) { undo->update_undo_before(); + speed_before(); char *string = new char[len]; gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); FileXML file; @@ -1253,16 +1247,11 @@ int MWindow::paste_automation() edl->tracks->clear_automation(start, end); edl->tracks->paste_automation(start, &file, 0, 1, edl->session->typeless_keyframes); + int changed_edl = speed_after(1); save_backup(); undo->update_undo_after(_("paste keyframes"), LOAD_AUTOMATION); delete [] string; - - restart_brender(); - update_plugin_guis(); - gui->draw_overlays(1); - sync_parameters(CHANGE_PARAMS); - gui->update_patchbay(); - cwindow->update(1, 0, 0); + update_gui(changed_edl); } return 0; @@ -1274,6 +1263,7 @@ int MWindow::paste_default_keyframe() if( len ) { undo->update_undo_before(); + speed_before(); char *string = new char[len]; gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); FileXML file; @@ -1283,15 +1273,10 @@ int MWindow::paste_default_keyframe() edl->session->typeless_keyframes); // edl->tracks->paste_default_keyframe(&file); undo->update_undo_after(_("paste default keyframe"), LOAD_AUTOMATION); - - restart_brender(); - update_plugin_guis(); - gui->draw_overlays(1); - sync_parameters(CHANGE_PARAMS); - gui->update_patchbay(); - cwindow->update(1, 0, 0); - delete [] string; + int changed_edl = speed_after(1); save_backup(); + delete [] string; + update_gui(changed_edl); } return 0; @@ -2442,4 +2427,58 @@ void MWindow::cut_commercials() cwindow->refresh_frame(CHANGE_EDL); } +int MWindow::normalize_speed(EDL *old_edl, EDL *new_edl) +{ + int result = 0; + Track *old_track = old_edl->tracks->first; + Track *new_track = new_edl->tracks->first; + for( ; old_track && new_track; old_track=old_track->next, new_track=new_track->next ) { + if( old_track->data_type != new_track->data_type ) continue; + FloatAutos *old_speeds = (FloatAutos *)old_track->automation->autos[AUTOMATION_SPEED]; + FloatAutos *new_speeds = (FloatAutos *)new_track->automation->autos[AUTOMATION_SPEED]; + if( !old_speeds || !new_speeds ) continue; + FloatAuto *old_speed = (FloatAuto *)old_speeds->first; + FloatAuto *new_speed = (FloatAuto *)new_speeds->first; + while( old_speed && new_speed && old_speed->equals(new_speed) ) { + old_speed = (FloatAuto *)old_speed->next; + new_speed = (FloatAuto *)new_speed->next; + } + Edit *old_edit = old_track->edits->first; + Edit *new_edit = new_track->edits->first; + for( ; old_edit && new_edit; old_edit=old_edit->next, new_edit=new_edit->next ) { + int64_t edit_start = old_edit->startproject, edit_end = edit_start + old_edit->length; + if( old_speed || new_speed ) { + double orig_start = old_speeds->automation_integral(0, edit_start, PLAY_FORWARD); + double orig_end = old_speeds->automation_integral(0, edit_end, PLAY_FORWARD); + edit_start = new_speeds->speed_position(orig_start); + edit_end = new_speeds->speed_position(orig_end); + result = 1; + } + new_edit->startproject = edit_start; + new_edit->length = edit_end - edit_start; + } + } + return result; +} + +void MWindow::speed_before() +{ + if( !speed_edl ) { + speed_edl = new EDL; + speed_edl->create_objects(); + } + speed_edl->copy_all(edl); +} + +int MWindow::speed_after(int done) +{ + int result = 0; + if( speed_edl && done >= 0 ) + result = normalize_speed(speed_edl, edl); + if( done ) { + speed_edl->remove_user(); + speed_edl = 0; + } + return result; +} diff --git a/cinelerra-5.1/cinelerra/trackcanvas.C b/cinelerra-5.1/cinelerra/trackcanvas.C index 6a34b7f1..62aa0b28 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.C +++ b/cinelerra-5.1/cinelerra/trackcanvas.C @@ -2046,16 +2046,27 @@ int TrackCanvas::do_keyframes(int cursor_x, case Autos::AUTOMATION_TYPE_FLOAT: { Automation automation(0, track); int grouptype = automation.autogrouptype(i, track); + if( buttonpress && i == AUTOMATION_SPEED ) { + mwindow->speed_before(); + } + if(draw) // Do dropshadow result = do_float_autos(track, autos, cursor_x, cursor_y, draw, buttonpress, 1, 1, MDGREY, auto_keyframe, grouptype); - result = do_float_autos(track, autos, cursor_x, cursor_y, draw, buttonpress, 0, 0, GWindowGUI::auto_colors[i], auto_keyframe, grouptype); + + if( !result && buttonpress && i == AUTOMATION_SPEED ) + mwindow->speed_after(-1); + int current_grouptype = mwindow->edl->local_session->zoombar_showautotype; + if( result && buttonpress && grouptype != current_grouptype ) { + mwindow->edl->local_session->zoombar_showautotype = grouptype; + mwindow->gui->zoombar->update_autozoom(); + } break; } case Autos::AUTOMATION_TYPE_INT: { @@ -3902,7 +3913,7 @@ void TrackCanvas::update_drag_caption() -int TrackCanvas::cursor_motion_event() +int TrackCanvas::cursor_update(int in_motion) { int result = 0; int cursor_x = 0; @@ -3915,7 +3926,7 @@ int TrackCanvas::cursor_motion_event() int new_cursor = 0; int rerender = 0; double position = 0.; -//printf("TrackCanvas::cursor_motion_event %d\n", __LINE__); +//printf("TrackCanvas::cursor_update %d\n", __LINE__); // Default cursor switch(mwindow->edl->session->editing_mode) @@ -3978,6 +3989,8 @@ int TrackCanvas::cursor_motion_event() case DRAG_PROJECTOR_Z: 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); break; case DRAG_PLAY: @@ -4043,7 +4056,7 @@ int TrackCanvas::cursor_motion_event() start != mwindow->edl->local_session->get_selectionstart(1) ? 1 : end != mwindow->edl->local_session->get_selectionend(1) ? -1 : 0; mwindow->cwindow->update(dir, 0, 0, 0, 1); - gui->lock_window("TrackCanvas::cursor_motion_event 1"); + gui->lock_window("TrackCanvas::cursor_update 1"); // Update the faders mwindow->update_plugin_guis(); gui->update_patchbay(); @@ -4078,7 +4091,7 @@ int TrackCanvas::cursor_motion_event() for(int i = 0; i < TOTAL_PANES; i++) if(gui->pane[i]) gui->pane[i]->canvas->timebar_position = position; -//printf("TrackCanvas::cursor_motion_event %d %d %p %p\n", __LINE__, pane->number, pane, pane->timebar); +//printf("TrackCanvas::cursor_update %d %d %p %p\n", __LINE__, pane->number, pane, pane->timebar); gui->update_timebar(0); // Update cursor if(do_transitions(get_cursor_x(), get_cursor_y(), @@ -4096,13 +4109,13 @@ int TrackCanvas::cursor_motion_event() break; } -//printf("TrackCanvas::cursor_motion_event 1\n"); +//printf("TrackCanvas::cursor_update 1\n"); if(update_cursor && new_cursor != get_cursor()) { set_cursor(new_cursor, 0, 1); } -//printf("TrackCanvas::cursor_motion_event 1 %d\n", rerender); +//printf("TrackCanvas::cursor_update 1 %d\n", rerender); if(rerender && render_timer->get_difference() > 0.25 ) { render_timer->update(); mwindow->restart_brender(); @@ -4110,7 +4123,7 @@ int TrackCanvas::cursor_motion_event() mwindow->update_plugin_guis(); gui->unlock_window(); mwindow->cwindow->update(1, 0, 0, 0, 1); - gui->lock_window("TrackCanvas::cursor_motion_event 2"); + gui->lock_window("TrackCanvas::cursor_update 2"); } if(rerender) { // Update faders @@ -4141,10 +4154,15 @@ int TrackCanvas::cursor_motion_event() gui->draw_overlays(1); } -//printf("TrackCanvas::cursor_motion_event %d\n", __LINE__); +//printf("TrackCanvas::cursor_update %d\n", __LINE__); return result; } +int TrackCanvas::cursor_motion_event() +{ + return cursor_update(1); +} + void TrackCanvas::start_dragscroll() { if(!drag_scroll) { @@ -4244,7 +4262,8 @@ int TrackCanvas::repeat_event(int64_t duration) int TrackCanvas::button_release_event() { - int redraw = 0, update_overlay = 0, result = 0; + int redraw = -1, update_overlay = 0; + int result = 0, load_flags = 0; // printf("TrackCanvas::button_release_event %d\n", // mwindow->session->current_operation); @@ -4278,8 +4297,10 @@ int TrackCanvas::button_release_event() result = 1; break; - case DRAG_FADE: case DRAG_SPEED: + redraw = FORCE_REDRAW; + load_flags |= LOAD_EDITS; + case DRAG_FADE: // delete the drag_auto_gang first and remove out of order keys synchronize_autos(0, 0, 0, -1); case DRAG_CZOOM: @@ -4296,6 +4317,7 @@ int TrackCanvas::button_release_event() case DRAG_PROJECTOR_Y: case DRAG_PROJECTOR_Z: case DRAG_PLUGINKEY: + load_flags |= LOAD_AUTOMATION; mwindow->session->current_operation = NO_OPERATION; mwindow->session->drag_handle = 0; // Remove any out-of-order keyframe @@ -4306,8 +4328,7 @@ int TrackCanvas::button_release_event() update_overlay = 1; } - - mwindow->undo->update_undo_after(_("keyframe"), LOAD_AUTOMATION); + mwindow->undo->update_undo_after(_("keyframe"), load_flags); result = 1; break; @@ -4334,13 +4355,14 @@ int TrackCanvas::button_release_event() } if (result) - cursor_motion_event(); + cursor_update(0); if(update_overlay) { gui->draw_overlays(1); } - if(redraw) { - gui->draw_canvas(NORMAL_DRAW, 0); + if(redraw >= 0) { + gui->draw_canvas(redraw, 0); + gui->flash_canvas(1); } return result; } diff --git a/cinelerra-5.1/cinelerra/trackcanvas.h b/cinelerra-5.1/cinelerra/trackcanvas.h index 61a88949..2bda2ea9 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.h +++ b/cinelerra-5.1/cinelerra/trackcanvas.h @@ -328,6 +328,7 @@ public: int max_y); int button_press_event(); int button_release_event(); + int cursor_update(int in_motion); int cursor_motion_event(); int activate(); int deactivate(); @@ -416,6 +417,7 @@ public: double selection_midpoint; // division between current ends int snapped; // drag handle snapping + EDL *speed_edl; // drag speed handle start edl }; #endif -- 2.26.2