X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Ftrackcanvas.C;h=536fabc6325e5d31e07c9ea444680291fa997ae0;hp=a2b758886826b3ce50be6e04293e8373e1f8be54;hb=4d76ed2e81154119f8335aeb70724468e08dbb94;hpb=84ac8a2bb3357c04a3f67cf763b0f61ddbbd021d diff --git a/cinelerra-5.1/cinelerra/trackcanvas.C b/cinelerra-5.1/cinelerra/trackcanvas.C index a2b75888..536fabc6 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.C +++ b/cinelerra-5.1/cinelerra/trackcanvas.C @@ -188,6 +188,7 @@ int TrackCanvas::drag_motion( Track **over_track, Edit **over_edit, PluginSet **over_pluginset, Plugin **over_plugin) { + int update_scroll = 0; int cursor_x = get_relative_cursor_x(); int cursor_y = get_relative_cursor_y(); if( get_cursor_over_window() ) { @@ -196,6 +197,28 @@ int TrackCanvas::drag_motion( } if( over_track && !*over_track ) *over_track = pane->over_patchbay(); + + switch( mwindow->session->current_operation ) { + case DRAG_EDIT_SELECT: { + Edit *edit = over_edit ? *over_edit : 0; + double position = mwindow->edl->get_cursor_position(cursor_x, pane->number); + mwindow->session->drag_position = mwindow->edl->align_to_frame(position, 0); + drag_edit_select(edit, 0, 1); + update_scroll = 1; + break; } + } + + if( update_scroll ) { + if( !drag_scroll && + (cursor_x >= get_w() || cursor_x < 0 || + cursor_y >= get_h() || cursor_y < 0)) + start_dragscroll(); + else if( drag_scroll && + cursor_x < get_w() && cursor_x >= 0 && + cursor_y < get_h() && cursor_y >= 0 ) + stop_dragscroll(); + } + return 0; } @@ -500,7 +523,7 @@ int TrackCanvas::drag_stop(int *redraw) result = 1; } break; - case DRAG_GROUP: + case DRAG_GROUP: { mwindow->session->current_operation = NO_OPERATION; EDL *drag_group = mwindow->session->drag_group; if( drag_group ) { @@ -532,10 +555,21 @@ int TrackCanvas::drag_stop(int *redraw) } } result = 1; + break; } + case DRAG_EDIT_SELECT: + int select = ctrl_down() ? -1 : 1; + drag_edit_select(mwindow->session->edit_highlighted, select, 0); break; } } + switch( mwindow->session->current_operation ) { + case DRAG_EDIT_SELECT: + mwindow->session->current_operation = NO_OPERATION; + result = 1; + break; + } + return result; } @@ -1658,6 +1692,9 @@ void TrackCanvas::draw_highlighting() } break; + case DRAG_SPEED: + draw_speed_highlight(); + break; } if( draw_box ) @@ -1666,6 +1703,33 @@ void TrackCanvas::draw_highlighting() draw_selected_edits(mwindow->edl, 0, 0, GREEN+BLUE, RED); } +void TrackCanvas::draw_speed_highlight() +{ + FloatAuto *drag_speed = (FloatAuto*)mwindow->session->drag_auto; + if( !drag_speed ) return; + draw_speed_track(drag_speed->autos->track); + ArrayList &speed_gang = *mwindow->session->drag_auto_gang; + for( int i=0, sz=speed_gang.size(); iautos->track; + if( track->is_hidden() ) continue; + draw_speed_track(track); + } +} + +void TrackCanvas::draw_speed_track(Track *track) +{ + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + int64_t x, y, w, h; + edit_dimensions(edit, x, y, w, h); + if( !MWindowGUI::visible(x, x + w, 0, get_w()) ) continue; + if( !MWindowGUI::visible(y, y + h, 0, get_h()) ) continue; + int color = 0xc00cc0; + set_color(color); + set_opaque(); + draw_selected(x, y, w, h); + } +} + // x does not reliably draw a really big rectangle void TrackCanvas::draw_selected(int x, int y, int w, int h) { @@ -1937,7 +2001,8 @@ void TrackCanvas::draw_inout_points() void TrackCanvas::draw_drag_handle() { if( mwindow->session->current_operation != DRAG_EDITHANDLE2 && - mwindow->session->current_operation != DRAG_PLUGINHANDLE2 ) return; + mwindow->session->current_operation != DRAG_PLUGINHANDLE2 && + mwindow->session->current_operation != DRAG_TRANSNHANDLE2 ) return; int64_t pixel1 = Units::round(mwindow->session->drag_position * mwindow->edl->session->sample_rate / mwindow->edl->local_session->zoom_sample - @@ -2020,6 +2085,7 @@ void TrackCanvas::draw_drag_handle() void TrackCanvas::draw_transitions() { int64_t x, y, w, h; + if( !mwindow->edl->session->auto_conf->transitions ) return; for(Track *track = mwindow->edl->tracks->first; track; track = track->next) { if( track->is_hidden() ) continue; @@ -2240,7 +2306,7 @@ int TrackCanvas::do_keyframes(int cursor_x, auto_keyframe, grouptype); if( !result && buttonpress && i == AUTOMATION_SPEED ) - mwindow->speed_after(-1); + mwindow->speed_after(-1, 0); if( result && buttonpress ) { int color = GWindowGUI::auto_colors[i]; mwindow->gui->zoombar->update_autozoom(grouptype, color); @@ -2966,9 +3032,9 @@ void TrackCanvas::fill_ganged_autos(int gang, float change, Track *skip, FloatAu int edge = patch ? patch->edge : 0; int span = patch ? patch->span : 0; for(Track *current = mwindow->edl->tracks->first; current; current = NEXT) { - if( (gang || current->data_type == skip->data_type) && - current->armed_gang(skip) && current->is_armed() && - current != skip ) { + if( current == skip || !current->is_armed() ) continue; + if( !gang && current->data_type != skip->data_type ) continue; + if( skip->armed_gang(current) || get_double_click() ) { FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[autoidx]; FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position); int64_t current_position = current->to_units(position, 1); @@ -2976,8 +3042,7 @@ void TrackCanvas::fill_ganged_autos(int gang, float change, Track *skip, FloatAu // keyframe exists, just change it keyframe->bump_update(current_position, change, edge, span); } - else if( gang >= 0 && ( get_double_click() || - mwindow->edl->session->auto_keyframes ) ) { + else if( gang >= 0 ) { // create keyframe on neighbouring track at the point in time given by fauto FloatAuto *previous = 0, *next = 0; float value = fade_autos->get_value(current_position, PLAY_FORWARD, previous, next); @@ -3817,14 +3882,8 @@ void TrackCanvas::update_drag_handle() double new_position; int cursor_x = get_cursor_x(); - new_position = - (double)(cursor_x + - mwindow->edl->local_session->view_start[pane->number]) * - mwindow->edl->local_session->zoom_sample / - mwindow->edl->session->sample_rate; - - new_position = - mwindow->edl->align_to_frame(new_position, 0); + new_position = mwindow->edl->get_cursor_position(cursor_x, pane->number); + new_position = mwindow->edl->align_to_frame(new_position, 0); if( ctrl_down() && alt_down() ) { #define snapper(v) do { \ @@ -4268,6 +4327,53 @@ void TrackCanvas::update_drag_caption() } +void TrackCanvas::drag_edit_select(Edit *over_edit, int select, int draw) +{ + if( !over_edit ) return; + if( !mwindow->session->drag_edit ) return; + Track *drag_track = mwindow->session->drag_edit->track; + Track *over_track = over_edit->track; + if( !drag_track || !over_track ) return; + if( drag_track->number_of() > over_track->number_of() ) { + Track *trk = drag_track; + drag_track = over_track; + over_track = trk; + } + double start_pos = mwindow->session->drag_start; + double end_pos = mwindow->session->drag_position; + if( start_pos > end_pos ) { + double pos = start_pos; + start_pos = end_pos; + end_pos = pos; + } + int done = 0, do_flash = 0; + for( Track *track=drag_track; !done; track=track->next ) { + if( !track->is_armed() ) continue; + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + int64_t pos = edit->startproject; + int64_t end = pos + edit->length; + double edit_start = track->from_units(pos); + double edit_end = track->from_units(end); + if( start_pos >= edit_end ) continue; + if( edit_start > end_pos ) continue; + if( select > 0 ) + edit->is_selected = 1; + else if( select < 0 ) + edit->is_selected = 0; + if( draw ) { + int64_t edit_x, edit_y, edit_w, edit_h; + edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h); + set_color(YELLOW); + draw_rectangle(edit_x, edit_y, edit_w, edit_h); + do_flash = 1; + } + } + if( track == over_track ) done = 1; + } + if( do_flash ) + flash(); +} + int TrackCanvas::cursor_update(int in_motion) { @@ -4281,7 +4387,7 @@ int TrackCanvas::cursor_update(int in_motion) int update_cursor = 0; int rerender = 0; double position = 0.; -//printf("TrackCanvas::cursor_update %d\n", __LINE__); +//printf("TrackCanvas::cursor_update %d %d,%d\n", __LINE__, get_cursor_x(), get_cursor_y()); // Default cursor int new_cursor = @@ -4292,42 +4398,46 @@ int TrackCanvas::cursor_update(int in_motion) { case DRAG_EDITHANDLE1: // Outside threshold. Upgrade status - if(active) - { - if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W) - { - mwindow->session->current_operation = DRAG_EDITHANDLE2; - update_overlay = 1; - } + if( !active ) break; + if( labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W ) { + mwindow->session->current_operation = DRAG_EDITHANDLE2; + update_overlay = 1; } break; - case DRAG_EDITHANDLE2: - if(active) - { - update_drag_handle(); - update_overlay = 1; - } + if( !active ) break; + update_drag_handle(); + update_overlay = 1; break; case DRAG_PLUGINHANDLE1: - if(active) - { - if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W) - { - mwindow->session->current_operation = DRAG_PLUGINHANDLE2; - update_overlay = 1; - } + if( !active ) break; + if( labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W ) { + mwindow->session->current_operation = DRAG_PLUGINHANDLE2; + update_overlay = 1; } break; - case DRAG_PLUGINHANDLE2: - if(active) - { - update_drag_handle(); + if( !active ) break; + update_drag_handle(); + update_overlay = 1; + break; + + case DRAG_TRANSNHANDLE1: + if( !active ) break; + if( labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W ) { + mwindow->session->current_operation = DRAG_TRANSNHANDLE2; update_overlay = 1; } break; + case DRAG_TRANSNHANDLE2: { + if( !active ) break; + position = mwindow->edl->get_cursor_position(get_cursor_x(), pane->number); + position = mwindow->edl->align_to_frame(position, 1); + drag_transition_handle(position); + rerender = 1; + update_overlay = 1; + break; } // Rubber band curves case DRAG_FADE: @@ -4343,7 +4453,7 @@ int TrackCanvas::cursor_update(int in_motion) if(active) rerender = update_overlay = update_drag_floatauto(get_cursor_x(), get_cursor_y()); if( rerender && mwindow->session->current_operation == DRAG_SPEED ) - mwindow->speed_after(!in_motion ? 1 : 0); + mwindow->speed_after(!in_motion ? 1 : 0, 0); break; case DRAG_PLAY: @@ -4450,6 +4560,8 @@ int TrackCanvas::cursor_update(int in_motion) 0, new_cursor, update_cursor)) break; if(do_keyframes(get_cursor_x(), get_cursor_y(), 0, 0, new_cursor, update_cursor, rerender)) break; + if(do_transition_handles(get_cursor_x(), get_cursor_y(), + 0, rerender, update_overlay, new_cursor, update_cursor)) break; if(do_edit_handles(get_cursor_x(), get_cursor_y(), 0, rerender, update_overlay, new_cursor, update_cursor)) break; // Plugin boundaries @@ -4546,6 +4658,7 @@ int TrackCanvas::repeat_event(int64_t duration) int result = 0; switch(mwindow->session->current_operation) { + case DRAG_EDIT_SELECT: case SELECT_REGION: //printf("TrackCanvas::repeat_event 1 %d\n", mwindow->edl->local_session->view_start); if(get_cursor_x() > get_w()) { @@ -4649,9 +4762,23 @@ int TrackCanvas::button_release_event() result = 1; break; + case DRAG_TRANSNHANDLE2: + mwindow->session->current_operation = NO_OPERATION; + drag_scroll = 0; + result = 1; + + end_transnhandle_selection(); + break; + + case DRAG_TRANSNHANDLE1: + mwindow->session->current_operation = NO_OPERATION; + drag_scroll = 0; + result = 1; + break; + case DRAG_SPEED: redraw = FORCE_REDRAW; - load_flags |= LOAD_EDITS; + load_flags |= LOAD_EDITS | LOAD_TIMEBAR; case DRAG_FADE: // delete the drag_auto_gang first and remove out of order keys clear_ganged_autos(); @@ -4729,6 +4856,10 @@ int TrackCanvas::button_release_event() drag_scroll = 0; break; } + case DRAG_EDIT_SELECT: + //result = 0; + break; + default: if( mwindow->session->current_operation ) { // if(mwindow->session->current_operation == SELECT_REGION) { @@ -4971,6 +5102,95 @@ int TrackCanvas::do_plugin_handles(int cursor_x, return result; } +int TrackCanvas::do_transition_handles(int cursor_x, int cursor_y, int button_press, + int &rerender, int &update_overlay, int &new_cursor, int &update_cursor) +{ + Transition *trans_result = 0; + int result = 0; + + Track *track = mwindow->edl->tracks->first; + for( ; track && !result; track=track->next) { + if( track->is_hidden() ) continue; + Edit *edit = track->edits->first; + for( ; edit && !result; edit=edit->next ) { + Transition *trans = edit->transition; + if( !trans ) continue; + int64_t x, y, w, h; + edit_dimensions(edit, x, y, w, h); + int strip_x = x, edit_y = y; + get_transition_coords(edit, x, y, w, h); + VFrame *strip = mwindow->theme->get_image("plugin_bg_data"); + int strip_y = y - strip->get_h(); + if( track->show_assets() && track->show_titles() ) + edit_y += mwindow->theme->get_image("title_bg_data")->get_h(); + if( strip_y < edit_y ) strip_y = edit_y; + int strip_w = Units::round(edit->track->from_units(edit->transition->length) * + mwindow->edl->session->sample_rate / mwindow->edl->local_session->zoom_sample); + int x1 = strip_x + strip_w - HANDLE_W/2, x2 = x1 + HANDLE_W; + int y1 = strip_y + strip->get_h()/2 - HANDLE_H/2, y2 = y1 + HANDLE_W; + if( cursor_x >= x1 && cursor_x < x2 && + cursor_y >= y1 && cursor_y < y2 ) { + trans_result = trans; + result = 1; + } + } + } + + if( result ) { + if( button_press ) { + mwindow->session->drag_transition = trans_result; + mwindow->session->drag_handle = 1; + mwindow->session->drag_button = get_buttonpress() - 1; + int64_t trans_end = trans_result->edit->startproject + trans_result->length; + double position = trans_result->edit->track->from_units(trans_end); + mwindow->session->drag_position = position; + mwindow->session->drag_start = position; + mwindow->session->current_operation = DRAG_TRANSNHANDLE1; + mwindow->session->drag_origin_x = get_cursor_x(); + mwindow->session->drag_origin_y = get_cursor_y(); + update_cursor = 1; + } + new_cursor = RIGHT_CURSOR; + update_overlay = 1; + } + + return result; +} + +int TrackCanvas::drag_transition_handle(double position) +{ + Transition *transition = mwindow->session->drag_transition; + if( !transition ) return 1; + mwindow->session->drag_position = position; + mwindow->edl->local_session->set_selectionstart(position); + mwindow->edl->local_session->set_selectionend(position); + char string[BCSTRLEN]; + int64_t length = transition->length; + Track *track = transition->edit->track; + int64_t start_pos = track->to_units(mwindow->session->drag_start, 0); + int64_t end_pos = track->to_units(mwindow->session->drag_position, 0); + length += end_pos - start_pos; + if( length < 0 ) length = 0; + double time = track->from_units(length); + Units::totext(string, time, + mwindow->edl->session->time_format, + mwindow->edl->session->sample_rate, + mwindow->edl->session->frame_rate, + mwindow->edl->session->frames_per_foot); + mwindow->gui->show_message(string); + if( mwindow->gui->transition_menu->length_thread->running() ) { + TransitionLengthDialog *dialog = (TransitionLengthDialog *) + mwindow->gui->transition_menu->length_thread->get_gui(); + if( dialog ) { + dialog->lock_window("TrackCanvas::drag_transition_handle"); + dialog->update_text(time); + dialog->thread->new_length = time; + dialog->unlock_window(); + } + } + return 0; +} + int TrackCanvas::do_tracks(int cursor_x, int cursor_y, int button_press) { @@ -5051,8 +5271,15 @@ int TrackCanvas::do_edits(int cursor_x, int cursor_y, int button_press, int drag mwindow->session->drag_origin_x = cursor_x; mwindow->session->drag_origin_y = cursor_y; // Where the drag started, so we know relative position inside the edit later - mwindow->session->drag_position = - mwindow->edl->get_cursor_position(cursor_x, pane->number); + double position = mwindow->edl->get_cursor_position(cursor_x, pane->number); + mwindow->session->drag_position = mwindow->edl->align_to_frame(position, 1); + if( get_buttonpress() == LEFT_BUTTON && alt_down() ) { + mwindow->session->drag_start = mwindow->session->drag_position; + drag_edit_select(edit, 0, 1); + mwindow->session->current_operation = DRAG_EDIT_SELECT; + result = 1; + continue; + } drag_start = 0; // if unselected "fast" drag if( !edit->silence() && !edit->is_selected ) { mwindow->edl->tracks->clear_selected_edits(); @@ -5392,6 +5619,10 @@ int TrackCanvas::button_press_event() 0, get_buttonpress(), new_cursor, update_cursor, rerender) ) break; update_message = 1; + + if( do_transition_handles(cursor_x, cursor_y, + 1, rerender, update_overlay, new_cursor, + update_cursor) ) break; // Test edit boundaries if( do_edit_handles(cursor_x, cursor_y, 1, rerender, update_overlay, new_cursor, @@ -5428,6 +5659,8 @@ int TrackCanvas::button_press_event() break; } update_message = 1; + if( do_transition_handles(cursor_x, cursor_y, + 1, rerender, update_overlay, new_cursor, update_cursor) ) break; // Test edit boundaries if( do_edit_handles(cursor_x, cursor_y, 1, rerender, update_overlay, new_cursor, update_cursor) ) break; @@ -5524,11 +5757,19 @@ int TrackCanvas::start_selection(double position) void TrackCanvas::end_edithandle_selection() { mwindow->modify_edithandles(); + mwindow->session->drag_edit = 0; } void TrackCanvas::end_pluginhandle_selection() { mwindow->modify_pluginhandles(); + mwindow->session->drag_plugin = 0; +} + +void TrackCanvas::end_transnhandle_selection() +{ + mwindow->modify_transnhandles(); + mwindow->session->drag_transition = 0; }