X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Ftrackcanvas.C;h=fdd3112bb6b2fb62f315fc7c2f3fb70de94bf9ba;hp=061545bac18728ba5f25be967788c789a304367f;hb=7eded24eb31529ad7652dea64e34b0a6210e5be1;hpb=9f0e523f895dabf635f694efc854f2be479d712c diff --git a/cinelerra-5.1/cinelerra/trackcanvas.C b/cinelerra-5.1/cinelerra/trackcanvas.C index 061545ba..fdd3112b 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.C +++ b/cinelerra-5.1/cinelerra/trackcanvas.C @@ -27,6 +27,8 @@ #include "bctimer.h" #include "clip.h" #include "bccolors.h" +#include "cache.h" +#include "canvas.h" #include "cplayback.h" #include "cursors.h" #include "cwindowgui.h" @@ -67,6 +69,7 @@ #include "pluginset.h" #include "plugintoggles.h" #include "preferences.h" +#include "renderengine.h" #include "resourcepixmap.h" #include "resourcethread.h" #include "swindow.h" @@ -80,6 +83,7 @@ #include "transportque.h" #include "vframe.h" #include "vpatchgui.inc" +#include "vrender.h" #include "zoombar.h" #include @@ -1392,11 +1396,17 @@ void TrackCanvas::get_transition_coords(Edit *edit, int64_t &x, int64_t &y, int64_t &w, int64_t &h) { int transition_w = 30, transition_h = 30; - - if( edit->track->show_titles() ) - y += mwindow->theme->get_image("title_bg_data")->get_h(); - if( edit->track->show_assets() ) - y += resource_h() / 2; + int has_titles = edit->track->show_titles(); + int has_assets = edit->track->show_assets(); + double title_bg_h = mwindow->theme->get_image("title_bg_data")->get_h(); + double asset_h = resource_h(); + double ys = has_assets ? asset_h : has_titles ? title_bg_h : 0; + double dy = has_titles ? + ( has_assets ? title_bg_h + asset_h/2 : title_bg_h/2 ) : + ( has_assets ? asset_h/2 : 0) ; + double title_h = mwindow->theme->title_h; + if( dy < title_h / 2 ) { ys = title_h; dy = ys / 2; } + y += dy; x -= transition_w / 2; y -= transition_h / 2; @@ -1837,32 +1847,32 @@ void TrackCanvas::draw_transitions() for(Edit *edit = track->edits->first; edit; edit = edit->next) { if(!edit->transition) continue; edit_dimensions(edit, x, y, w, h); - int strip_x = x, strip_y = y; - if( track->show_titles() ) - strip_y += mwindow->theme->get_image("title_bg_data")->get_h(); + int strip_x = x, edit_y = y; get_transition_coords(edit, x, y, w, h); + int strip_y = y - mwindow->theme->get_image("plugin_bg_data")->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); if( MWindowGUI::visible(x, x + w, 0, get_w()) && - MWindowGUI::visible(y, y + h, 0, get_h()) ) - { + MWindowGUI::visible(y, y + h, 0, get_h()) ) { PluginServer *server = mwindow->scan_plugindb(edit->transition->title, track->data_type); if( !server ) continue; VFrame *picon = server->get_picon(); if( !picon ) continue; - draw_vframe(picon, x, y, w, h, 0, 0, picon->get_w(), picon->get_h()); + int picon_w = picon->get_w(), picon_h = picon->get_h(); + int track_h = edit->track->vertical_span(mwindow->theme); + if( picon_h > track_h ) picon_h = track_h; + draw_vframe(picon, x, y, w, h, 0, 0, picon_w, picon_h); } if(MWindowGUI::visible(strip_x, strip_x + strip_w, 0, get_w()) && - MWindowGUI::visible(strip_y, strip_y + h, 0, get_h())) - { + MWindowGUI::visible(strip_y, strip_y + h, 0, get_h())) { int x = strip_x, w = strip_w; - if(x < 0) - { - w -= -x; - x = 0; - } - if(w + x > get_w()) w -= (w + x) - get_w(); + if( x < 0 ) { w -= -x; x = 0; } + if( w + x > get_w() ) w -= (w + x) - get_w(); draw_3segmenth( x, strip_y, w, strip_x, strip_w, mwindow->theme->get_image("plugin_bg_data"), 0); @@ -2085,10 +2095,8 @@ int TrackCanvas::do_keyframes(int cursor_x, if (buttonpress != 3) { if(i == AUTOMATION_FADE || i == AUTOMATION_SPEED) - synchronize_autos(0, - track, - (FloatAuto*)mwindow->session->drag_auto, - 1); + fill_ganged_autos(get_double_click(), 0, track, + (FloatAuto*)mwindow->session->drag_auto); mwindow->session->current_operation = pre_auto_operations[i]; update_drag_caption(); rerender = 1; @@ -2167,34 +2175,37 @@ void TrackCanvas::draw_keyframe_reticle() int current_op = mwindow->session->current_operation, dragging = 0; for( int i=0; !dragging && isession->drag_auto ) dragging = 0; - if( keyframe_hairline == HAIRLINE_DRAGGING && dragging ) { - if( mwindow->session->drag_auto && get_buttonpress() == 1 ) { - draw_hairline(mwindow->session->drag_auto, RED); - return; - } + int autoidx = dragging && keyframe_hairline != HAIRLINE_ALWAYS ? + mwindow->session->drag_auto->autos->autoidx : -1; + + if( get_buttonpress() == 1 && dragging && + keyframe_hairline == HAIRLINE_DRAGGING ) { + draw_hairline(mwindow->session->drag_auto, RED, 1); + return; } if( keyframe_hairline == HAIRLINE_ALWAYS || ( get_buttonpress() == 2 && keyframe_hairline == HAIRLINE_DRAGGING && dragging ) ) { - for( Track *track = mwindow->edl->tracks->first; track; - track=track->next ) { + int show = dragging || keyframe_hairline == HAIRLINE_ALWAYS ? 1 : 0; + for( Track *track = mwindow->edl->tracks->first; track; track=track->next ) { Automation *automation = track->automation; for( int i=0; iedl->session->auto_conf->autos[i] ) continue; // automation visible Autos *autos = automation->autos[i]; if( !autos ) continue; + if( autoidx >= 0 && autos->autoidx != autoidx ) continue; for( Auto *auto_keyframe=autos->first; auto_keyframe; auto_keyframe = auto_keyframe->next ) { - draw_hairline(auto_keyframe, BLUE); + draw_hairline(auto_keyframe, BLUE, show); } } - - if( dragging && mwindow->session->drag_auto ) { - draw_hairline(mwindow->session->drag_auto, RED); - } } + + if( dragging ) + draw_hairline(mwindow->session->drag_auto, RED, 1); } } @@ -2710,69 +2721,68 @@ int TrackCanvas::test_floatline(int center_pixel, } -void TrackCanvas::synchronize_autos(float change, - Track *skip, FloatAuto *fauto, int fill_gangs) +void TrackCanvas::fill_ganged_autos(int all, float change, Track *skip, FloatAuto *fauto) { + if( !skip->gang ) return; // Handles the special case of modifying a fadeauto // when there are ganged faders on several tracks -// (skip and fauto may be NULL if fill_gangs==-1) - - if( fill_gangs > 0 && skip->gang ) { - double position = skip->from_units(fauto->position); - int autoidx = fauto->autos->autoidx; - - for(Track *current = mwindow->edl->tracks->first; current; current = NEXT) { - if( (current->data_type == skip->data_type || get_double_click()) && - current->gang && current->record && current != skip ) { - int64_t current_position = current->to_units(position, 1); - FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[autoidx]; - float auto_min = mwindow->edl->local_session->automation_mins[fade_autos->autogrouptype]; - float auto_max = mwindow->edl->local_session->automation_maxs[fade_autos->autogrouptype]; - FloatAuto *previous = 0, *next = 0; - FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_at_position(current_position); - if( !keyframe ) { -// create keyframe on neighbouring track at the point in time given by fauto - float init_value = fade_autos->get_value(current_position, PLAY_FORWARD, previous, next); - float new_value = init_value + change; - CLAMP(new_value, auto_min, auto_max); - keyframe = (FloatAuto*)fade_autos->insert_auto(current_position); - keyframe->set_value(new_value); - } - else { + double position = skip->from_units(fauto->position); + int autoidx = fauto->autos->autoidx; + + for(Track *current = mwindow->edl->tracks->first; current; current = NEXT) { + if( (all || current->data_type == skip->data_type) && + current->gang && current->record && current != skip ) { + FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[autoidx]; + float auto_min = mwindow->edl->local_session->automation_mins[fade_autos->autogrouptype]; + float auto_max = mwindow->edl->local_session->automation_maxs[fade_autos->autogrouptype]; + int64_t current_position = current->to_units(position, 1); + FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position); + if( keyframe ) { // keyframe exists, just change it - float new_value = keyframe->get_value() + change; - CLAMP(new_value, auto_min, auto_max); - keyframe->adjust_to_new_coordinates(current_position, new_value); -// need to (re)set the position, as the existing node could be on a "equivalent" position (within half a frame) - } - - mwindow->session->drag_auto_gang->append((Auto *)keyframe); + float value = keyframe->get_value(); + float new_value = value + change; + CLAMP(new_value, auto_min, auto_max); + keyframe->adjust_to_new_coordinates(current_position, new_value); } + else if( mwindow->edl->session->auto_keyframes ) { +// 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); + float new_value = value + change; + CLAMP(new_value, auto_min, auto_max); + keyframe = (FloatAuto*)fade_autos->insert_auto(current_position); + keyframe->set_value(new_value); + } + else + continue; + mwindow->session->drag_auto_gang->append((Auto *)keyframe); } } - else if( !fill_gangs ) { - double position = skip->from_units(fauto->position); -// Move the gangs - for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) { - FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i]; - int64_t keyframe_position = keyframe->autos->track->to_units(position, 1); - float new_value = keyframe->get_value() + change; - CLAMP(new_value, - mwindow->edl->local_session->automation_mins[keyframe->autos->autogrouptype], - mwindow->edl->local_session->automation_maxs[keyframe->autos->autogrouptype]); - keyframe->adjust_to_new_coordinates(keyframe_position, new_value); - } +} +void TrackCanvas::update_ganged_autos(float change, Track *skip, FloatAuto *fauto) +{ + double position = skip->from_units(fauto->position); +// Move the gangs + for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) { + FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i]; + int64_t keyframe_position = keyframe->autos->track->to_units(position, 1); + float new_value = keyframe->get_value() + change; + CLAMP(new_value, + mwindow->edl->local_session->automation_mins[keyframe->autos->autogrouptype], + mwindow->edl->local_session->automation_maxs[keyframe->autos->autogrouptype]); + keyframe->adjust_to_new_coordinates(keyframe_position, new_value); } - else { +} + +void TrackCanvas::clear_ganged_autos() +{ // remove the gangs - for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) { - FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i]; - keyframe->autos->remove_nonsequential( - keyframe); - } - mwindow->session->drag_auto_gang->remove_all(); + for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) { + FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i]; + keyframe->autos->remove_nonsequential(keyframe); } + mwindow->session->drag_auto_gang->remove_all(); } @@ -2852,6 +2862,7 @@ void TrackCanvas::calculate_viewport(Track *track, double &zoom_sample, double &zoom_units) { + view_start = (double)mwindow->edl->local_session->view_start[pane->number] * mwindow->edl->local_session->zoom_sample / mwindow->edl->session->sample_rate; @@ -2861,15 +2872,23 @@ void TrackCanvas::calculate_viewport(Track *track, mwindow->edl->local_session->zoom_sample / mwindow->edl->session->sample_rate; unit_end = track->to_doubleunits(view_end); - yscale = resource_h(); - center_pixel = track->y_pixel + + int y = track->y_pixel - mwindow->edl->local_session->track_start[pane->number]; - if( track->show_assets() ) - center_pixel += yscale / 2; - if( track->show_titles() ) - center_pixel += mwindow->theme->get_image("title_bg_data")->get_h(); - zoom_sample = mwindow->edl->local_session->zoom_sample; + int has_titles = track->show_titles(); + int has_assets = track->show_assets(); + double title_bg_h = mwindow->theme->get_image("title_bg_data")->get_h(); + double asset_h = resource_h(); + double title_h = mwindow->theme->title_h; + double ys = has_assets ? asset_h : has_titles ? title_bg_h : 0; + double dy = has_titles ? + ( has_assets ? title_bg_h + asset_h/2 : title_bg_h/2) : + ( has_assets ? asset_h/2 : 0) ; + if( dy < title_h/2 ) { ys = title_h; dy = ys / 2; } + yscale = ys; + center_pixel = y + dy; + zoom_sample = mwindow->edl->local_session->zoom_sample; zoom_units = track->to_doubleunits(zoom_sample / mwindow->edl->session->sample_rate); } @@ -3439,10 +3458,10 @@ int TrackCanvas::do_plugin_autos(Track *track, int cursor_x, int cursor_y, return result; } -int TrackCanvas::draw_hairline(Auto *auto_keyframe, int color) +int TrackCanvas::draw_hairline(Auto *auto_keyframe, int color, int show) { Track *track = auto_keyframe->autos->track; - int autogrouptype = auto_keyframe->autos->get_type(); + int autogrouptype = auto_keyframe->autos->autogrouptype; int center_pixel; double view_start, unit_start; @@ -3458,6 +3477,31 @@ int TrackCanvas::draw_hairline(Auto *auto_keyframe, int color) set_color(color); draw_line(ax, 0, ax, get_h()); + + if( show ) { + char text[BCSTRLEN]; + if( auto_keyframe->is_floatauto() ) { + FloatAuto *float_auto = (FloatAuto *)auto_keyframe; + sprintf(text, "%0.2f", float_auto->get_value()); + } + else { + IntAuto *int_auto = (IntAuto *)auto_keyframe; + sprintf(text, "%d", int_auto->value); + } + int font = MEDIUMFONT; + int tw = get_text_width(font, text) + TOOLTIP_MARGIN * 2; + int th = get_text_height(font, text) + TOOLTIP_MARGIN * 2; + set_color(get_resources()->tooltip_bg_color); + ax += HANDLE_W/2; + ay += center_pixel + HANDLE_W/2; + draw_box(ax, ay, tw, th); + set_color(BLACK); + draw_rectangle(ax, ay, tw, th); + set_font(font); + ax += TOOLTIP_MARGIN; + ay += TOOLTIP_MARGIN + get_text_ascent(font); + draw_text(ax, ay, text); + } return 0; } @@ -3582,16 +3626,89 @@ void TrackCanvas::update_drag_handle() { mwindow->session->drag_position = new_position; gui->mainclock->update(new_position); - - timebar_position = new_position; gui->update_timebar(0); -// Que the CWindow. Doesn't do anything if selectionstart and selection end -// aren't changed. -// mwindow->cwindow->update(1, 0, 0); + + EDL *edl = new EDL; + edl->create_objects(); + edl->copy_all(mwindow->edl); + MainSession *session = mwindow->session; + int edit_mode = mwindow->edl->session->edit_handle_mode[session->drag_button]; + edl->modify_edithandles(session->drag_start, + session->drag_position, + session->drag_handle, + edit_mode, + edl->session->labels_follow_edits, + edl->session->plugins_follow_edits, + edl->session->autos_follow_edits); + double position = edit_mode != MOVE_NO_EDITS && + ( session->drag_handle || edit_mode == MOVE_ONE_EDIT ) ? + session->drag_position : session->drag_start; + Track *track = session->drag_handle_track(); + int64_t pos = track->to_units(position, 0); + render_handle_frame(edl, pos, shift_down() ? 0 : + session->drag_handle ? 1 : 2); + edl->remove_user(); } } +int TrackCanvas::render_handle_frame(EDL *edl, int64_t pos, int mode) +{ + int result = 0; + int64_t left = pos-1; + if( left < 0 ) left = 0; + switch( mode ) { + case 0: { + VFrame vlt(edl->get_w(), edl->get_h(), edl->session->color_model); + VFrame vrt(edl->get_w(), edl->get_h(), edl->session->color_model); + TransportCommand command; + command.command = CURRENT_FRAME; + command.get_edl()->copy_all((EDL *)edl); + command.change_type = CHANGE_ALL; + command.realtime = 0; + Preferences *preferences = mwindow->preferences; + RenderEngine *render_engine = new RenderEngine(0, preferences, 0, 0); + CICache *video_cache = new CICache(preferences); + render_engine->set_vcache(video_cache); + render_engine->arm_command(&command); + int64_t left = pos-1; + if( left < 0 ) left = 0; + VRender *vrender = render_engine->vrender; + result = vrender && + !vrender->process_buffer(&vlt, left, 0) && + !vrender->process_buffer(&vrt, pos , 0) ? 0 : 1; + delete render_engine; + delete video_cache; + mwindow->cwindow->gui->lock_window("TrackCanvas::render_handle_frame 0"); + Canvas *canvas = mwindow->cwindow->gui->canvas; + canvas->lock_canvas("TrackCanvas::render_handle_frame 1"); + int w = canvas->w, h = canvas->h, w2 = w/2, h2 = h/2; + int lx = 0, ly = h2/2, rx = w2, ry = h2/2; + BC_WindowBase *window = canvas->get_canvas(); + window->set_color(BLACK); + window->clear_box(0,0, window->get_w(),window->get_h()); + window->draw_vframe(&vlt, lx,ly, w2,h2, 0,0,vlt.get_w(),vlt.get_h()); + window->draw_vframe(&vrt, rx,ry, w2,h2, 0,0,vrt.get_w(),vrt.get_h()); + window->flash(1); + canvas->unlock_canvas(); + mwindow->cwindow->gui->unlock_window(); + break; } + case 1: + case 2: { + Track *track = mwindow->session->drag_handle_track(); + double position = track->from_units(mode == 1 ? left : pos); + if( position < 0 ) position = 0; + edl->local_session->set_selectionstart(position); + edl->local_session->set_selectionend(position); + PlaybackEngine *playback_engine = mwindow->cwindow->playback_engine; + if( playback_engine->is_playing_back ) + playback_engine->stop_playback(1); + mwindow->cwindow->playback_engine->refresh_frame(CHANGE_EDL, edl, 0); + break; } + } + return result; +} + int TrackCanvas::update_drag_edit() { int result = 0; @@ -3728,7 +3845,7 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y) result = 1; float change = value - old_value; current->adjust_to_new_coordinates(position, value); - synchronize_autos(change, current->autos->track, current, 0); + update_ganged_autos(change, current->autos->track, current); show_message(current, 1,", %.2f", current->get_value()); } break; @@ -3747,7 +3864,7 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y) current->set_control_in_value( value * levered_position(position - current->position, current->get_control_in_position())); - synchronize_autos(0, current->autos->track, current, 0); + update_ganged_autos(0, current->autos->track, current); show_message(current, 1,", %.2f", current->get_control_in_value()); } break; } @@ -3761,7 +3878,7 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y) current->set_control_out_value( value * levered_position(position - current->position, current->get_control_out_position())); - synchronize_autos(0, current->autos->track, current, 0); + update_ganged_autos(0, current->autos->track, current); show_message(current, 1,", %.2f", current->get_control_out_value()); } break; } @@ -4288,7 +4405,7 @@ int TrackCanvas::button_release_event() 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); + clear_ganged_autos(); case DRAG_CZOOM: case DRAG_PZOOM: case DRAG_PLAY: @@ -4361,8 +4478,6 @@ int TrackCanvas::do_edit_handles(int cursor_x, int cursor_y, int button_press, int result = 0; for( Track *track=mwindow->edl->tracks->first; track && !result; track=track->next) { - if( !track->show_assets() ) continue; - for( Edit *edit=track->edits->first; edit && !result; edit=edit->next ) { int64_t edit_x, edit_y, edit_w, edit_h; edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h); @@ -4372,7 +4487,8 @@ int TrackCanvas::do_edit_handles(int cursor_x, int cursor_y, int button_press, if( cursor_x < edit_x + HANDLE_W ) { edit_result = edit; handle_result = 0; - if( cursor_y >= edit_y+edit_h - HANDLE_W ) { + if( cursor_y >= edit_y+edit_h - HANDLE_W && + track->show_assets() ) { new_cursor = DOWNLEFT_RESIZE; if( button_press == LEFT_BUTTON ) result = -1; @@ -4383,7 +4499,8 @@ int TrackCanvas::do_edit_handles(int cursor_x, int cursor_y, int button_press, else if( cursor_x >= edit_x + edit_w - HANDLE_W ) { edit_result = edit; handle_result = 1; - if( cursor_y >= edit_y+edit_h - HANDLE_W ) { + if( cursor_y >= edit_y+edit_h - HANDLE_W && + track->show_assets() ) { new_cursor = DOWNRIGHT_RESIZE; if( button_press == LEFT_BUTTON ) result = -1; @@ -4422,7 +4539,7 @@ int TrackCanvas::do_edit_handles(int cursor_x, int cursor_y, int button_press, update_overlay = 1; } } - else if( result < 0) { + else if( result < 0 ) { mwindow->undo->update_undo_before(); if( !shift_down() ) { if( handle_result == 0 ) @@ -4572,8 +4689,6 @@ int TrackCanvas::do_edits(int cursor_x, int cursor_y, int button_press, int drag int result = 0; for(Track *track = mwindow->edl->tracks->first; track && !result; track = track->next) { - if( !track->show_assets() ) continue; - for(Edit *edit = track->edits->first; edit && !result; edit = edit->next) { int64_t edit_x, edit_y, edit_w, edit_h; edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);