From: Good Guy Date: Wed, 9 Jan 2019 17:53:02 +0000 (-0700) Subject: fast drag/drop rework, modify labels in mwin->cwin locks, mods to cut/paste, marks... X-Git-Tag: 2019-08~122 X-Git-Url: https://git.cinelerra-gg.org/git/?a=commitdiff_plain;h=15b020d5c21b2cc5545227f7c092f06086666b4a;p=goodguy%2Fcinelerra.git fast drag/drop rework, modify labels in mwin->cwin locks, mods to cut/paste, marks for group handle edge drag --- diff --git a/cinelerra-5.1/cinelerra/edl.C b/cinelerra-5.1/cinelerra/edl.C index c7db139e..d033b8d5 100644 --- a/cinelerra-5.1/cinelerra/edl.C +++ b/cinelerra-5.1/cinelerra/edl.C @@ -805,8 +805,6 @@ static int dead_edit_cmp(Edit**ap, Edit**bp) void EDL::delete_edits(ArrayList *edits, int collapse) { edits->sort(dead_edit_cmp); - if( session->labels_follow_edits ) - delete_edit_labels(edits, collapse); for( int i=0; isize(); ++i ) { Edit *edit = edits->get(i); Track *track = edit->track; @@ -821,7 +819,8 @@ void EDL::delete_edits(ArrayList *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 *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 { diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index fecb5258..ce85ca9f 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -403,8 +403,7 @@ public: void cut_selected_edits(int collapse, int packed); // Move edit to new position void move_edits(ArrayList *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, diff --git a/cinelerra-5.1/cinelerra/mwindowedit.C b/cinelerra-5.1/cinelerra/mwindowedit.C index c64ab7c1..67f4402c 100644 --- a/cinelerra-5.1/cinelerra/mwindowedit.C +++ b/cinelerra-5.1/cinelerra/mwindowedit.C @@ -1101,6 +1101,8 @@ void MWindow::delete_edits(ArrayList *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 *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"); ArrayListedits; 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(); diff --git a/cinelerra-5.1/cinelerra/pluginset.C b/cinelerra-5.1/cinelerra/pluginset.C index cdc4a784..a0d3b6c2 100644 --- a/cinelerra-5.1/cinelerra/pluginset.C +++ b/cinelerra-5.1/cinelerra/pluginset.C @@ -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"); diff --git a/cinelerra-5.1/cinelerra/pluginset.h b/cinelerra-5.1/cinelerra/pluginset.h index f072e62b..4e149e76 100644 --- a/cinelerra-5.1/cinelerra/pluginset.h +++ b/cinelerra-5.1/cinelerra/pluginset.h @@ -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, diff --git a/cinelerra-5.1/cinelerra/trackcanvas.C b/cinelerra-5.1/cinelerra/trackcanvas.C index 07e4f49a..03fac258 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.C +++ b/cinelerra-5.1/cinelerra/trackcanvas.C @@ -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; diff --git a/cinelerra-5.1/cinelerra/tracks.h b/cinelerra-5.1/cinelerra/tracks.h index 1f3c288e..abcc0af4 100644 --- a/cinelerra-5.1/cinelerra/tracks.h +++ b/cinelerra-5.1/cinelerra/tracks.h @@ -50,7 +50,7 @@ public: int &track_offset, uint32_t load_flags); void move_edits(ArrayList *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); diff --git a/cinelerra-5.1/cinelerra/tracksedit.C b/cinelerra-5.1/cinelerra/tracksedit.C index 4b23eb1e..afe491f3 100644 --- a/cinelerra-5.1/cinelerra/tracksedit.C +++ b/cinelerra-5.1/cinelerra/tracksedit.C @@ -576,168 +576,114 @@ int Tracks::delete_tracks() return total_deleted; } -void Tracks::move_edits(ArrayList *edits, - Track *track, - double position, - int edit_labels, // Ignored - int edit_plugins, // Ignored - int edit_autos, // Ignored - int behaviour) +void Tracks::move_edits(ArrayList *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 edits; + for( int i=0; isize(); ++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; kplugin_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)