add edit speed duration update, autogroup select when modify auto
authorGood Guy <good1.2guy@gmail.com>
Tue, 27 Mar 2018 23:14:55 +0000 (17:14 -0600)
committerGood Guy <good1.2guy@gmail.com>
Tue, 27 Mar 2018 23:14:55 +0000 (17:14 -0600)
cinelerra-5.1/cinelerra/floatauto.C
cinelerra-5.1/cinelerra/floatauto.h
cinelerra-5.1/cinelerra/floatautos.C
cinelerra-5.1/cinelerra/floatautos.h
cinelerra-5.1/cinelerra/keyframepopup.C
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/mwindowedit.C
cinelerra-5.1/cinelerra/trackcanvas.C
cinelerra-5.1/cinelerra/trackcanvas.h

index bab8160f28675345819dacd269665e5de85fc78e..8e3e63682af1a56e43d3d474bb3f8076d9909041 100644 (file)
@@ -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)
  *
index be0b304e720f529c6aaafe81bae7b64127ccc442..cc4168c46c824b60f526a136459d1742f155b1bc 100644 (file)
@@ -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
index 04741afe145fabd6fdefc63b31daab1c641f7bb4..95dcace9ce6d97288a6357a7e93512ec7a825eb6 100644 (file)
@@ -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;
+}
+
index 96d06d6390c582a127005dc4f91a9e507b3d84d3..0e7fa195f4ceb597d989b1af449faa2455f94c53 100644 (file)
@@ -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();
index aff99d6d69cb6880b264ca3af0c50fb79d57af5f..3813e744d49c997a9498c0ff48bf341b80362277 100644 (file)
@@ -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()
index ff4de5071a26300fa2277b87fd5bb6256c4f3661..9731b4bbcb089d48aec86b183b3bf423c9dd3c9c 100644 (file)
@@ -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++) {
index 252f96dbf99e5a741dfff8062063b14cd82ca06b..895314a2f6a97ad185e0f6b8d80b94d6bda25409 100644 (file)
@@ -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<ColormodelItem*> 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<PluginServer*> &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;
index 142c2a3849e9f06d5098bd28401abbfa598547e0..d69496dc7e9d99533bcbf83c982248ec17e698f1 100644 (file)
@@ -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;
+}
 
index 6a34b7f1d33deff5abd4f5b01ff533358765f743..62aa0b282388ab8c71bab0164e09ff5d3ad5e024 100644 (file)
@@ -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;
 }
index 61a88949930531bc685e1434c27bd231c5bf941e..2bda2ea97aad50e154796144750399e0aa5b7fad 100644 (file)
@@ -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