fast drag/drop rework, modify labels in mwin->cwin locks, mods to cut/paste, marks...
authorGood Guy <good1.2guy@gmail.com>
Wed, 9 Jan 2019 17:53:02 +0000 (10:53 -0700)
committerGood Guy <good1.2guy@gmail.com>
Wed, 9 Jan 2019 17:53:02 +0000 (10:53 -0700)
cinelerra-5.1/cinelerra/edl.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/mwindowedit.C
cinelerra-5.1/cinelerra/pluginset.C
cinelerra-5.1/cinelerra/pluginset.h
cinelerra-5.1/cinelerra/trackcanvas.C
cinelerra-5.1/cinelerra/tracks.h
cinelerra-5.1/cinelerra/tracksedit.C

index c7db139..d033b8d 100644 (file)
@@ -805,8 +805,6 @@ static int dead_edit_cmp(Edit**ap, Edit**bp)
 void EDL::delete_edits(ArrayList<Edit*> *edits, int collapse)
 {
        edits->sort(dead_edit_cmp);
-       if( session->labels_follow_edits )
-               delete_edit_labels(edits, collapse);
        for( int i=0; i<edits->size(); ++i ) {
                Edit *edit = edits->get(i);
                Track *track = edit->track;
@@ -821,7 +819,8 @@ void EDL::delete_edits(ArrayList<Edit*> *edits, int collapse)
                                PluginSet *plugin_set = track->plugin_set[k];
                                plugin_set->clear(start, end, 1);
                                if( !collapse )
-                                       plugin_set->paste_silence(start, end);
+                                       plugin_set->paste_silence(start, end, 1);
+                               plugin_set->optimize();
                        }
                }
                Edit *dead_edit = edit;
@@ -830,11 +829,8 @@ void EDL::delete_edits(ArrayList<Edit*> *edits, int collapse)
                                edit->startproject -= length;
                }
                delete dead_edit;
-       }
-// optimize edits only.
-//  full optimize deletes pluginsets, mistargeting drag and drop
-       for( Track *track=tracks->first; track; track=track->next )
                track->edits->optimize();
+       }
 }
 
 class Range {
index fecb525..ce85ca9 100644 (file)
@@ -403,8 +403,7 @@ public:
        void cut_selected_edits(int collapse, int packed);
 // Move edit to new position
        void move_edits(ArrayList<Edit*> *edits, Track *track, double position,
-// 0 - old style (cut and insert elswhere), 1- new style - (clear and overwrite elsewere)
-               int behaviour);
+               int mode); // mode: 0 - mute and overwrite,  1 - cut and paste
        void paste_edits(EDL *clip, Track *first_track, double position, int overwrite,
                int edit_edits, int edit_labels, int edit_autos, int edit_plugins);
        void paste_clipboard(Track *first_track, double position, int overwrite,
index c64ab7c..67f4402 100644 (file)
@@ -1101,6 +1101,8 @@ void MWindow::delete_edits(ArrayList<Edit*> *edits, const char *msg, int collaps
 {
        if( !edits->size() ) return;
        undo->update_undo_before();
+       if( edl->session->labels_follow_edits )
+               edl->delete_edit_labels(edits, collapse);
        edl->delete_edits(edits, collapse);
        edl->optimize();
        save_backup();
@@ -1131,22 +1133,18 @@ void MWindow::cut_selected_edits(int collapse, int packed)
 
 
 void MWindow::move_edits(ArrayList<Edit*> *edits,
-               Track *track,
-               double position,
-               int behaviour)
+               Track *track, double position, int mode)
 {
        undo->update_undo_before();
-
-       EDL *clip = selected_edits_to_clip(0, 0, 0,
-               edl->session->labels_follow_edits,
-               edl->session->autos_follow_edits,
-               edl->session->plugins_follow_edits);
-       edl->delete_edits(edits, 0);
-       paste_edits(clip, track, position, behaviour, 1,
+// lockout timebar labels update
+//  labels can be deleted with tooltip repeater running
+       cwindow->gui->lock_window("Tracks::move_edits");
+       edl->tracks->move_edits(edits, track, position,
                edl->session->labels_follow_edits,
-               edl->session->autos_follow_edits,
-               edl->session->plugins_follow_edits);
-       edl->tracks->clear_selected_edits();
+               edl->session->plugins_follow_edits,
+               edl->session->autos_follow_edits, mode);
+       cwindow->gui->timebar->update(1);
+       cwindow->gui->unlock_window();
 
        save_backup();
        undo->update_undo_after(_("move edit"), LOAD_ALL);
@@ -1207,7 +1205,7 @@ void MWindow::paste_edits(EDL *clip, Track *first_track, double position, int ov
                                                        if( plugin->startproject >= start )
                                                                plugin->startproject += edit->length;
                                                        else if( plugin->startproject+plugin->length > end )
-                                                               plugin->length += end - start;
+                                                               plugin->length += edit->length;
                                                        Auto *default_keyframe = plugin->keyframes->default_auto;
                                                        if( default_keyframe->position >= start )
                                                                default_keyframe->position += edit->length;
@@ -1259,6 +1257,11 @@ void MWindow::paste_edits(EDL *clip, Track *first_track, double position, int ov
                                                int64_t keyframe_pos = pos + keyframe->position;
                                                new_plugin->keyframes->insert_auto(keyframe_pos, keyframe);
                                        }
+                                       while( (new_plugin=(Plugin *)new_plugin->next) ) {
+                                               KeyFrame *keyframe = (KeyFrame*)new_plugin->keyframes->first;
+                                               for( ; keyframe; keyframe=(KeyFrame*)keyframe->next )
+                                                       keyframe->position += plugin->length;
+                                       }
                                }
                        }
                }
@@ -1310,14 +1313,21 @@ void MWindow::paste_clipboard(Track *first_track, double position, int overwrite
 void MWindow::move_group(EDL *group, Track *first_track, double position, int overwrite)
 {
        undo->update_undo_before();
+// lockout timebar labels update
+//  labels can be deleted with tooltip repeater running
+       cwindow->gui->lock_window("Tracks::move_group");
 
        ArrayList<Edit *>edits;
        edl->tracks->get_selected_edits(&edits);
+       if( edl->session->labels_follow_edits )
+               edl->delete_edit_labels(&edits, 0);
        edl->delete_edits(&edits, 0);
        paste_edits(group, first_track, position, overwrite, 1,
                edl->session->labels_follow_edits,
                edl->session->autos_follow_edits,
                edl->session->plugins_follow_edits);
+       cwindow->gui->timebar->update(1);
+       cwindow->gui->unlock_window();
 // big debate over whether to do this, must either clear selected, or no tweaking
 //     edl->tracks->clear_selected_edits();
 
index cdc4a78..a0d3b6c 100644 (file)
@@ -343,6 +343,19 @@ void PluginSet::shift_effects(int64_t start, int64_t length, int edit_autos)
        }
 }
 
+void PluginSet::paste_silence(int64_t start, int64_t end, int edit_autos)
+{
+       Plugin *new_plugin = (Plugin *) insert_new_edit(start);
+       int64_t length = end - start;
+       new_plugin->length = length;
+       while( (new_plugin=(Plugin *)new_plugin->next) != 0 ) {
+               new_plugin->startproject += length;
+               if( !edit_autos ) continue;
+               new_plugin->keyframes->default_auto->position += length;
+               new_plugin->keyframes->paste_silence(start, end);
+       }
+}
+
 void PluginSet::copy(int64_t start, int64_t end, FileXML *file)
 {
        file->tag.set_title("PLUGINSET");
index f072e62..4e149e7 100644 (file)
@@ -57,6 +57,7 @@ public:
                int use_default, int active_only);
        void paste_keyframes(int64_t start, int64_t length, FileXML *file,
                int use_default, int active_only);
+       void paste_silence(int64_t start, int64_t end, int edit_autos);
 // Return the nearest boundary of any kind in the plugin edits
        int64_t plugin_change_duration(int64_t input_position,
                int64_t input_length,
index 07e4f49..03fac25 100644 (file)
@@ -493,7 +493,7 @@ int TrackCanvas::drag_stop(int *redraw)
                                        double track_position = track->from_units(drop_position);
                                        track_position = mwindow->edl->align_to_frame(track_position, 0);
                                        mwindow->move_edits(mwindow->session->drag_edits,
-                                                       track, track_position, !insertion);
+                                                       track, track_position, insertion);
                                }
 
                                result = 1;
@@ -1928,22 +1928,72 @@ void TrackCanvas::draw_inout_points()
 
 void TrackCanvas::draw_drag_handle()
 {
-       if(mwindow->session->current_operation == DRAG_EDITHANDLE2 ||
-               mwindow->session->current_operation == DRAG_PLUGINHANDLE2)
-       {
-//printf("TrackCanvas::draw_drag_handle 1 %ld %ld\n", mwindow->session->drag_sample, mwindow->edl->local_session->view_start);
-               int64_t pixel1 = Units::round(mwindow->session->drag_position *
-                       mwindow->edl->session->sample_rate /
-                       mwindow->edl->local_session->zoom_sample -
-                       mwindow->edl->local_session->view_start[pane->number]);
-//printf("TrackCanvas::draw_drag_handle 2 %d %jd\n", pane->number, pixel1);
-               set_color(!snapped ? GREEN : (snapped=0, YELLOW));
-               set_inverse();
-//printf("TrackCanvas::draw_drag_handle 3\n");
-               draw_line(pixel1, 0, pixel1, get_h());
-               set_opaque();
-//printf("TrackCanvas::draw_drag_handle 4\n");
+       if( mwindow->session->current_operation != DRAG_EDITHANDLE2 &&
+           mwindow->session->current_operation != DRAG_PLUGINHANDLE2 ) return;
+       int64_t pixel1 = Units::round(mwindow->session->drag_position *
+               mwindow->edl->session->sample_rate /
+               mwindow->edl->local_session->zoom_sample -
+               mwindow->edl->local_session->view_start[pane->number]);
+       set_color(!snapped ? GREEN : (snapped=0, YELLOW));
+       set_inverse();
+       draw_line(pixel1, 0, pixel1, get_h());
+       set_opaque();
+
+       if( mwindow->session->current_operation != DRAG_EDITHANDLE2 ) return;
+       if( !mwindow->session->drag_edit ) return;
+       int group_id = mwindow->session->drag_edit->group_id;
+        if( !group_id ) return;
+       int drag_handle = mwindow->session->drag_handle;
+       set_color(RED);
+       set_line_width(3);
+
+       for( Track *track=mwindow->edl->tracks->first; track; track=track->next ) {
+               Edit *left = 0, *right = 0;
+               double start = DBL_MAX, end = DBL_MIN;
+               for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+                       if( edit->group_id != group_id ) continue;
+                       double edit_start = edit->track->from_units(edit->startproject);
+                       if( edit_start < start ) { start = edit_start;  left = edit; }
+                       double edit_end = edit->track->from_units(edit->startproject+edit->length);
+                       if( edit_end > end ) { end = edit_end;  right = edit; }
+               }
+               Edit *edit = !drag_handle ? left : right;
+               if( !edit ) continue;
+               Indexable *idxbl = edit->asset;
+               if( !idxbl ) idxbl = edit->nested_edl;
+               int can_drag = idxbl ? 1 : 0;
+               if( drag_handle ) {
+                       int64_t source_len = !idxbl ? -1 :
+                               edit->track->data_type == TRACK_AUDIO ?
+                                       idxbl->get_audio_samples() :
+                               edit->track->data_type == TRACK_VIDEO ?
+                                       idxbl->get_video_frames() : -1;
+                       if( edit->startsource + edit->length >= source_len )
+                               can_drag = 0;
+               }
+               else if( !edit->startsource )
+                       can_drag = 0;
+               int64_t x, y, w, h;
+               edit_dimensions(edit, x, y, w, h);
+               int edge_x = !drag_handle ? x : x + w;
+               int edge_y = y + h/2, k = 10;
+               if( edge_x >= 0 && edge_x < get_w() &&
+                   edge_y >= 0 && edge_y < get_h() ) {
+                       if( !can_drag ) {
+                               draw_line(edge_x-k,edge_y-k, edge_x+k,edge_y+k);
+                               draw_line(edge_x-k,edge_y+k, edge_x+k,edge_y-k);
+                       }
+                       else if( !drag_handle ) {
+                               draw_line(edge_x+k,edge_y-k, edge_x,edge_y);
+                               draw_line(edge_x+k,edge_y+k, edge_x,edge_y);
+                       }
+                       else {
+                               draw_line(edge_x,edge_y, edge_x-k,edge_y-k);
+                               draw_line(edge_x,edge_y, edge_x-k,edge_y+k);
+                       }
+               }
        }
+       set_line_width(1);
 }
 
 
@@ -4664,6 +4714,25 @@ int TrackCanvas::do_edit_handles(int cursor_x, int cursor_y, int button_press,
                }
        }
 
+       if( result > 0 ) {
+               int group_id = edit_result->group_id;
+               if( group_id > 0 ) {
+                       Track *track = edit_result->track;
+                       Edit *left = 0, *right = 0;
+                       double start = DBL_MAX, end = DBL_MIN;
+                       for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+                               if( edit->group_id != group_id ) continue;
+                               double edit_start = edit->track->from_units(edit->startproject);
+                               if( edit_start < start ) { start = edit_start;  left = edit; }
+                               double edit_end = edit->track->from_units(edit->startproject+edit->length);
+                               if( edit_end > end ) { end = edit_end;  right = edit; }
+                       }
+                       Edit *edit = !handle_result ? left : right;
+                       if( edit != edit_result )
+                               result = 0;
+               }
+       }
+
        update_cursor = 1;
        if( result > 0 ) {
                double position = 0;
index 1f3c288..abcc0af 100644 (file)
@@ -50,7 +50,7 @@ public:
                int &track_offset,
                uint32_t load_flags);
        void move_edits(ArrayList<Edit*> *edits, Track *track, double position,
-               int edit_labels, int edit_plugins, int edit_autos, int behaviour);
+               int edit_labels, int edit_plugins, int edit_autos, int mode);
        void move_group(EDL *group, Track *first_track, double position, int overwrite);
        void move_effect(Plugin *plugin, Track *track, int64_t position);
        void move_effect(Plugin *plugin, PluginSet *plugin_set, int64_t position);
index 4b23eb1..afe491f 100644 (file)
@@ -576,168 +576,114 @@ int Tracks::delete_tracks()
        return total_deleted;
 }
 
-void Tracks::move_edits(ArrayList<Edit*> *edits,
-       Track *track,
-       double position,
-       int edit_labels,  // Ignored
-       int edit_plugins,  // Ignored
-       int edit_autos, // Ignored
-       int behaviour)
+void Tracks::move_edits(ArrayList<Edit*> *in_edits, Track *track, double position,
+       int edit_labels, int edit_plugins, int edit_autos, int mode)
 {
+// have to make a copy, optimize kills edits
+       ArrayList<Edit*> edits;
+       for( int i=0; i<in_edits->size(); ++i ) {
+               Edit *edit = in_edits->get(i);
+               Edit *new_edit = new Edit(edit->edl, edit->track);
+               new_edit->copy_from(edit);
+               edits.append(new_edit);
+       }
+
+       int current_aedit = 0, current_vedit = 0;
 //printf("Tracks::move_edits 1\n");
-       for(Track *dest_track = track; dest_track; dest_track = dest_track->next)
-       {
-               if(dest_track->record)
-               {
+       for( Track *dest_track=track; dest_track; dest_track=dest_track->next ) {
+               if( !dest_track->record ) continue;
 // Need a local copy of the source edit since the original source edit may
 // change in the editing operation.
-                       Edit *source_edit = 0;
-                       Track *source_track = 0;
-
-
-// Get source track
-                       if(dest_track->data_type == TRACK_AUDIO)
-                       {
-                               int current_aedit = 0;
-
-                               while(current_aedit < edits->total &&
-                                       edits->values[current_aedit]->track->data_type != TRACK_AUDIO)
-                                       current_aedit++;
-
-                               if(current_aedit < edits->total)
-                               {
-                                       source_edit = edits->values[current_aedit];
-                                       source_track = source_edit->track;
-                                       edits->remove_number(current_aedit);
+// Get source edit
+               Edit *source_edit = 0;
+               Track *clip_track = 0;
+               switch( dest_track->data_type ) {
+               case TRACK_AUDIO: {
+                       while( current_aedit < edits.size() ) {
+                               Edit *edit = edits[current_aedit++];
+                               if( edit->track->data_type == TRACK_AUDIO ) {
+                                       source_edit = edit;
+                                       ATrack *atrack = new ATrack(dest_track->edl, 0);
+                                       atrack->create_objects();
+                                       clip_track = atrack;
+                                       break;
                                }
                        }
-                       else
-                       if(dest_track->data_type == TRACK_VIDEO)
-                       {
-                               int current_vedit = 0;
-                               while(current_vedit < edits->total &&
-                                       edits->values[current_vedit]->track->data_type != TRACK_VIDEO)
-                                       current_vedit++;
-
-                               if(current_vedit < edits->total)
-                               {
-                                       source_edit = edits->values[current_vedit];
-                                       source_track = source_edit->track;
-                                       edits->remove_number(current_vedit);
+                       break; }
+               case TRACK_VIDEO: {
+                       while( current_vedit < edits.size() ) {
+                               Edit *edit = edits[current_vedit++];
+                               if( edit->track->data_type == TRACK_VIDEO ) {
+                                       source_edit = edit;
+                                       VTrack *vtrack = new VTrack(dest_track->edl, 0);
+                                       vtrack->create_objects();
+                                       clip_track = vtrack;
+                                       break;
                                }
                        }
+                       break; }
+               }
+               if( !source_edit ) continue;
+
+               Track *source_track = source_edit->track;
+               int64_t start = source_edit->startproject;
+               int64_t length = source_edit->length, end = start + length;
+               double source_start = source_track->from_units(start);
+               double source_end = source_track->from_units(start+length);
+               double len = source_end - source_start;
+               double dest_start = position;
+               double dest_end = dest_start + len;
+
+               if( edit_labels && dest_track == track ) {
+                       FileXML label_xml;
+                       Labels labels(0, "LABELS");
+                       source_edit->edl->labels->copy(source_start, source_end, &label_xml);
+                       source_edit->edl->labels->clear(source_start, source_end, mode);
+                       if( !label_xml.read_tag() )
+                               labels.load(&label_xml, LOAD_ALL);
+                       double pos = dest_start;
+                       if( mode && source_start < dest_start ) pos -= len;
+                       edl->labels->insert_labels(&labels, pos, len, mode);
+                       edit_labels = 0;
+               }
 
-//printf("Tracks::move_edits 2 %s %s %d\n", source_track->title, dest_track->title, source_edit->length);
-                       if(source_edit)
-                       {
-                               int64_t position_i = source_track->to_units(position, 0);
-// Source edit changes
-                               int64_t source_length = source_edit->length;
-                               int64_t source_startproject = source_edit->startproject;
-
-                               if (behaviour == 0)
-                               {
-                               // This works like this: CUT edit, INSERT edit at final position, keyframes also follow
-                               // FIXME: there should be a GUI way to tell whenever user also wants to move autos or not
-// this is all screwed up
-//  inserts defaults/bogus everywhere
-#if 0
-// Copy keyframes
-                                       FileXML temp;
-                                       AutoConf temp_autoconf;
-
-                                       temp_autoconf.set_all(1);
-
-                                       source_track->automation->copy(source_edit->startproject,
-                                               source_edit->startproject + source_edit->length,
-                                               &temp,
-                                               0,
-                                               0);
-                                       temp.terminate_string();
-                                       temp.rewind();
-// Insert new keyframes
-//printf("Tracks::move_edits 2 %d %p\n", result->startproject, result->asset);
-                                       source_track->automation->clear(source_edit->startproject,
-                                               source_edit->startproject + source_edit->length,
-                                               &temp_autoconf,
-                                               1);
-                                       int64_t position_a = position_i;
-                                       if (dest_track == source_track)
-                                       {
-                                               if (position_a > source_edit->startproject)
-                                                       position_a -= source_length;
-                                       }
-
-                                       dest_track->automation->paste_silence(position_a,
-                                               position_a + source_length);
-                                       while(!temp.read_tag())
-                                               dest_track->automation->paste(position_a,
-                                                       source_length, 1.0, &temp, 0, 1,
-                                                       &temp_autoconf);
-#endif
-// Insert new edit
-                                       Edit *dest_edit = dest_track->edits->shift(position_i,
-                                               source_length);
-                                       Edit *result = dest_track->edits->insert_before(dest_edit,
-                                               dest_track->edits->create_edit());
-                                       result->copy_from(source_edit);
-                                       result->startproject = position_i;
-                                       result->length = source_length;
-
-// Clear source
-                                       source_track->edits->clear(source_edit->startproject,
-                                               source_edit->startproject + source_length);
-
-       /*
-//this is outline for future thinking how it is supposed to be done trough C&P mechanisms
-                                       temp.reset_tag();
-                                       source_track->cut(source_edit->startproject,
-                                               source_edit->startproject + source_edit->length,
-                                               &temp,
-                                               NULL);
-                                       temp.terminate_string();
-                                       temp.rewind();
-                                       dest_track->paste_silence(position_a,
-                                               position_a + source_length,
-                                               edit_plugins);
-                                       while(!temp.read_tag())
-                                               dest_track->paste(position_a,          // MISSING PIECE OF FUNCTIONALITY
-                                                       source_length,
-                                                       1.0,
-                                                       &temp,
-                                                       0,
-                                                       &temp_autoconf);
-       */
-
-
-                               } else
-                               if (behaviour == 1)
-                               // ONLY edit is moved, all other edits stay where they are
-                               {
-                                       // Copy edit to temp, delete the edit, insert the edit
-                                       Edit *temp_edit = dest_track->edits->create_edit();
-                                       temp_edit->copy_from(source_edit);
-                                       // we call the edits directly since we do not want to move keyframes or anything else
-                                       source_track->edits->clear(source_startproject,
-                                               source_startproject + source_length);
-                                       source_track->edits->paste_silence(source_startproject,
-                                               source_startproject + source_length);
-
-                                       dest_track->edits->clear(position_i,
-                                               position_i + source_length);
-                                       Edit *dest_edit = dest_track->edits->shift(position_i,  source_length);
-                                       Edit *result = dest_track->edits->insert_before(dest_edit,
-                                               dest_track->edits->create_edit());
-                                       result->copy_from(temp_edit);
-                                       result->startproject = position_i;
-                                       result->length = source_length;
-                                       delete temp_edit;
-                               }
-                               source_track->optimize();
-                               dest_track->optimize();
+               FileXML track_xml;
+               source_track->copy(source_start, source_end, &track_xml, "");
+               if( !track_xml.read_tag() )
+                       clip_track->load(&track_xml, 0, LOAD_ALL);
+
+               if( !mode ) { // mute and overwrite
+                       source_track->clear(start, end, 1, 0,
+                               edit_plugins, edit_autos, 0);
+                       source_track->edits->paste_silence(start, end);
+                       if( edit_autos )
+                               source_track->shift_keyframes(start, length);
+                       if( edit_plugins ) {
+                               int n = source_track->plugin_set.size();
+                               if( n > 0 ) dest_track->expand_view = 1;
+                               for( int k=0; k<n; ++k )
+                                       source_track->plugin_set[k]->paste_silence(start, end, 1);
+                       }
+                       dest_track->clear(dest_start, dest_end, 1, 0,
+                               edit_plugins, edit_autos, 0);
+                       dest_track->insert_track(clip_track, dest_start, 0,
+                               edit_plugins, edit_autos, len);
+               }
+               else { // cut and paste
+                       dest_track->insert_track(clip_track, dest_start, 0,
+                               edit_plugins, edit_autos, len);
+                       if( source_track == dest_track && dest_start < source_start ) {
+                               source_start += len;   source_end += len;
                        }
+                       source_track->clear(source_start, source_end, 1, 0,
+                               edit_plugins, edit_autos, 0);
                }
+
+               delete clip_track;
+               dest_track->optimize();
        }
+
+       edits.remove_all_objects();
 }
 
 void Tracks::move_effect(Plugin *plugin, Track *track, int64_t position)